diff options
-rw-r--r-- | ChangeLog | 15 | ||||
-rw-r--r-- | nis/nss_nis/nis-service.c | 30 | ||||
-rw-r--r-- | nss/getent.c | 55 |
3 files changed, 44 insertions, 56 deletions
diff --git a/ChangeLog b/ChangeLog index c2de3d5a9e..9ad8a51cfd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,20 @@ +2004-03-30 Jakub Jelinek <jakub@redhat.com> + + * nis/nss_nis/nis-service.c (_nss_nis_getservbyname_r): If protocol + == NULL, try name/tcp and name/udp first before falling back into + the sequential scanning. Use services.byname database for + sequential scanning. + (_nss_nis_getservbyport_r): Likewise. Just allocate sizeof (int) * 3 + chars for integer. + + * nis/nss_nis/nis-service.c (_nss_nis_getservbyport_r): Convert + proto to host by order for snprintf. + 2004-03-30 Ulrich Drepper <drepper@redhat.com> + * nss/getent.c (services_keys): Don't implement lookups with + missing protocol using getservent loop, just pass NULL. + * sysdeps/unix/sysv/linux/i386/setgroups.c (setgroups): Avoid comparison with limit if we can rely on the syscall being available. diff --git a/nis/nss_nis/nis-service.c b/nis/nss_nis/nis-service.c index b0a6236b69..84c938aad9 100644 --- a/nis/nss_nis/nis-service.c +++ b/nis/nss_nis/nis-service.c @@ -279,18 +279,21 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol, return NSS_STATUS_UNAVAIL; /* If the protocol is given, we could try if our NIS server knows - about services.byservicename map. If yes, we only need one query */ - if (protocol != NULL) + about services.byservicename map. If yes, we only need one query. + If the protocol is not given, try first name/tcp, then name/udp + and then fallback to sequential scanning of services.byname map. */ + const char *proto = protocol != NULL ? protocol : "tcp"; + do { - char key[strlen (name) + strlen (protocol) + 2]; + char key[strlen (name) + strlen (proto) + 2]; char *cp, *result; size_t keylen, len; int int_len; - /* key is: "name/protocol" */ + /* key is: "name/proto" */ cp = stpcpy (key, name); *cp++ = '/'; - stpcpy (cp, protocol); + stpcpy (cp, proto); keylen = strlen (key); status = yperr2nss (yp_match (domain, "services.byservicename", key, keylen, &result, &int_len)); @@ -329,6 +332,7 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol, return NSS_STATUS_SUCCESS; } } + while (protocol == NULL && (proto[0] == 't' ? (proto = "udp") : NULL)); struct ypall_callback ypcb; struct search_t req; @@ -343,7 +347,7 @@ _nss_nis_getservbyname_r (const char *name, const char *protocol, req.buflen = buflen; req.errnop = errnop; req.status = NSS_STATUS_NOTFOUND; - status = yperr2nss (yp_all (domain, "services.byservicename", &ypcb)); + status = yperr2nss (yp_all (domain, "services.byname", &ypcb)); if (status != NSS_STATUS_SUCCESS) return status; @@ -362,16 +366,19 @@ _nss_nis_getservbyport_r (int port, const char *protocol, if (yp_get_default_domain (&domain)) return NSS_STATUS_UNAVAIL; - /* If the protocol is given, we only need one query */ - if (protocol != NULL) + /* If the protocol is given, we only need one query. + Otherwise try first port/tcp, then port/udp and then fallback + to sequential scanning of services.byname. */ + const char *proto = protocol != NULL ? protocol : "tcp"; + do { - char key[100 + strlen (protocol) + 2]; + char key[sizeof (int) * 3 + strlen (proto) + 2]; char *result; size_t keylen, len; int int_len; - /* key is: "port/protocol" */ - keylen = snprintf (key, sizeof (key), "%d/%s", port, protocol); + /* key is: "port/proto" */ + keylen = snprintf (key, sizeof (key), "%d/%s", ntohs (port), proto); status = yperr2nss (yp_match (domain, "services.byname", key, keylen, &result, &int_len)); len = int_len; @@ -409,6 +416,7 @@ _nss_nis_getservbyport_r (int port, const char *protocol, return NSS_STATUS_SUCCESS; } } + while (protocol == NULL && (proto[0] == 't' ? (proto = "udp") : NULL)); if (port == -1) return NSS_STATUS_NOTFOUND; diff --git a/nss/getent.c b/nss/getent.c index f43bc635dc..5738affd53 100644 --- a/nss/getent.c +++ b/nss/getent.c @@ -638,53 +638,18 @@ services_keys (int number, char *key[]) struct servent *serv; char *proto = strchr (key[i], '/'); - if (proto == NULL) - { - setservent (0); - if (isdigit (key[i][0])) - { - int port = htons (atol (key[i])); - while ((serv = getservent ()) != NULL) - if (serv->s_port == port) - { - print_services (serv); - break; - } - } - else - { - int j; - - while ((serv = getservent ()) != NULL) - if (strcmp (serv->s_name, key[i]) == 0) - { - print_services (serv); - break; - } - else - for (j = 0; serv->s_aliases[j]; ++j) - if (strcmp (serv->s_aliases[j], key[i]) == 0) - { - print_services (serv); - break; - } - } - endservent (); - } - else - { - *proto++ = '\0'; + if (proto != NULL) + *proto++ = '\0'; - if (isdigit (key[i][0])) - serv = getservbyport (htons (atol (key[i])), proto); - else - serv = getservbyname (key[i], proto); + if (isdigit (key[i][0])) + serv = getservbyport (htons (atol (key[i])), proto); + else + serv = getservbyname (key[i], proto); - if (serv == NULL) - result = 2; - else - print_services (serv); - } + if (serv == NULL) + result = 2; + else + print_services (serv); } return result; |