int attribute_compat_text_section __nss_next (service_user **ni, const char *fct_name, void **fctp, int status, int all_values) { return __nss_next2 (ni, fct_name, NULL, fctp, status, all_values); }
static int internal_function __internal_setnetgrent_reuse (const char *group, struct __netgrent *datap, int *errnop) { union { enum nss_status (*f) (const char *, struct __netgrent *); void *ptr; } fct; enum nss_status status = NSS_STATUS_UNAVAIL; struct name_list *new_elem; /* Free data from previous service. */ endnetgrent_hook (datap); /* Cycle through all the services and run their setnetgrent functions. */ int no_more = setup (&fct.ptr, &datap->nip); while (! no_more) { assert (datap->data == NULL); /* Ignore status, we force check in `__nss_next2'. */ status = DL_CALL_FCT (*fct.f, (group, datap)); service_user *old_nip = datap->nip; no_more = __nss_next2 (&datap->nip, "setnetgrent", NULL, &fct.ptr, status, 0); if (status == NSS_STATUS_SUCCESS && ! no_more) { enum nss_status (*endfct) (struct __netgrent *); endfct = __nss_lookup_function (old_nip, "endnetgrent"); if (endfct != NULL) (void) DL_CALL_FCT (*endfct, (datap)); } } /* Add the current group to the list of known groups. */ size_t group_len = strlen (group) + 1; new_elem = (struct name_list *) malloc (sizeof (struct name_list) + group_len); if (new_elem == NULL) { *errnop = errno; status = NSS_STATUS_TRYAGAIN; } else { new_elem->next = datap->known_groups; memcpy (new_elem->name, group, group_len); datap->known_groups = new_elem; } return status == NSS_STATUS_SUCCESS; }
int ether_ntohost (char *hostname, const struct ether_addr *addr) { static service_user *startp; static lookup_function start_fct; service_user *nip; union { lookup_function f; void *ptr; } fct; int no_more; enum nss_status status = NSS_STATUS_UNAVAIL; struct etherent etherent; if (startp == NULL) { no_more = __nss_ethers_lookup (&nip, "getntohost_r", &fct.ptr); if (no_more) startp = (service_user *) -1; else { startp = nip; start_fct = fct.f; } } else { fct.f = start_fct; no_more = (nip = startp) == (service_user *) -1; } while (no_more == 0) { char buffer[1024]; status = (*fct.f) (addr, ðerent, buffer, sizeof buffer, &errno); no_more = __nss_next2 (&nip, "getntohost_r", NULL, &fct.ptr, status, 0); } if (status == NSS_STATUS_SUCCESS) /* XXX This is a potential cause of trouble because the size of the HOSTNAME buffer is not known but the interface does not provide this information. */ strcpy (hostname, etherent.e_name); return status == NSS_STATUS_SUCCESS ? 0 : -1; }
int ether_hostton (const char *hostname, struct ether_addr *addr) { static service_user *startp; static lookup_function start_fct; service_user *nip; union { lookup_function f; void *ptr; } fct; int no_more; enum nss_status status = NSS_STATUS_UNAVAIL; struct etherent etherent; if (startp == NULL) { no_more = __nss_ethers_lookup (&nip, "gethostton_r", &fct.ptr); if (no_more) startp = (service_user *) -1; else { startp = nip; start_fct = fct.f; } } else { fct.f = start_fct; no_more = (nip = startp) == (service_user *) -1; } while (no_more == 0) { char buffer[1024]; status = (*fct.f) (hostname, ðerent, buffer, sizeof buffer, &errno); no_more = __nss_next2 (&nip, "gethostton_r", NULL, &fct.ptr, status, 0); } if (status == NSS_STATUS_SUCCESS) memcpy (addr, etherent.e_addr.ether_addr_octet, sizeof (struct ether_addr)); return status == NSS_STATUS_SUCCESS ? 0 : -1; }
int netname2user (const char netname[MAXNETNAMELEN + 1], uid_t * uidp, gid_t * gidp, int *gidlenp, gid_t * gidlist) { static service_user *startp; static netname2user_function start_fct; service_user *nip; union { netname2user_function f; void *ptr; } fct; enum nss_status status = NSS_STATUS_UNAVAIL; int no_more; if (startp == NULL) { no_more = __nss_publickey_lookup (&nip, "netname2user", &fct.ptr); if (no_more) startp = (service_user *) - 1; else { startp = nip; start_fct = fct.f; } } else { fct.f = start_fct; no_more = (nip = startp) == (service_user *) - 1; } while (!no_more) { status = (*fct.f) (netname, uidp, gidp, gidlenp, gidlist); no_more = __nss_next2 (&nip, "netname2user", NULL, &fct.ptr, status, 0); } return status == NSS_STATUS_SUCCESS; }
int getsecretkey (const char *name, char *key, const char *passwd) { static service_user *startp; static secret_function start_fct; service_user *nip; union { secret_function f; void *ptr; } fct; enum nss_status status = NSS_STATUS_UNAVAIL; int no_more; if (startp == NULL) { no_more = __nss_publickey_lookup (&nip, "getsecretkey", &fct.ptr); if (no_more) startp = (service_user *) -1; else { startp = nip; start_fct = fct.f; } } else { fct.f = start_fct; no_more = (nip = startp) == (service_user *) -1; } while (! no_more) { status = (*fct.f) (name, key, passwd, &errno); no_more = __nss_next2 (&nip, "getsecretkey", NULL, &fct.ptr, status, 0); } return status == NSS_STATUS_SUCCESS; }
/* Test whether given (host,user,domain) triple is in NETGROUP. */ int innetgr (const char *netgroup, const char *host, const char *user, const char *domain) { #ifdef USE_NSCD if (__nss_not_use_nscd_netgroup > 0 && ++__nss_not_use_nscd_netgroup > NSS_NSCD_RETRY) __nss_not_use_nscd_netgroup = 0; if (!__nss_not_use_nscd_netgroup && !__nss_database_custom[NSS_DBSIDX_netgroup]) { int result = __nscd_innetgr (netgroup, host, user, domain); if (result >= 0) return result; } #endif union { enum nss_status (*f) (const char *, struct __netgrent *); void *ptr; } setfct; void (*endfct) (struct __netgrent *); int (*getfct) (struct __netgrent *, char *, size_t, int *); struct __netgrent entry; int result = 0; const char *current_group = netgroup; memset (&entry, '\0', sizeof (entry)); /* Walk through the services until we found an answer or we shall not work further. We can do some optimization here. Since all services must provide the `setnetgrent' function we can do all the work during one walk through the service list. */ while (1) { int no_more = setup (&setfct.ptr, &entry.nip); while (! no_more) { assert (entry.data == NULL); /* Open netgroup. */ enum nss_status status = DL_CALL_FCT (*setfct.f, (current_group, &entry)); if (status == NSS_STATUS_SUCCESS && (getfct = __nss_lookup_function (entry.nip, "getnetgrent_r")) != NULL) { char buffer[1024]; while (DL_CALL_FCT (*getfct, (&entry, buffer, sizeof buffer, &errno)) == NSS_STATUS_SUCCESS) { if (entry.type == group_val) { /* Make sure we haven't seen the name before. */ struct name_list *namep; for (namep = entry.known_groups; namep != NULL; namep = namep->next) if (strcmp (entry.val.group, namep->name) == 0) break; if (namep == NULL) for (namep = entry.needed_groups; namep != NULL; namep = namep->next) if (strcmp (entry.val.group, namep->name) == 0) break; if (namep == NULL && strcmp (netgroup, entry.val.group) != 0) { size_t group_len = strlen (entry.val.group) + 1; namep = (struct name_list *) malloc (sizeof (*namep) + group_len); if (namep == NULL) { /* Out of memory, simply return. */ result = -1; break; } namep->next = entry.needed_groups; memcpy (namep->name, entry.val.group, group_len); entry.needed_groups = namep; } } else { if ((entry.val.triple.host == NULL || host == NULL || __strcasecmp (entry.val.triple.host, host) == 0) && (entry.val.triple.user == NULL || user == NULL || strcmp (entry.val.triple.user, user) == 0) && (entry.val.triple.domain == NULL || domain == NULL || __strcasecmp (entry.val.triple.domain, domain) == 0)) { result = 1; break; } } } /* If we found one service which does know the given netgroup we don't try further. */ status = NSS_STATUS_RETURN; } /* Free all resources of the service. */ endfct = __nss_lookup_function (entry.nip, "endnetgrent"); if (endfct != NULL) DL_CALL_FCT (*endfct, (&entry)); if (result != 0) break; /* Look for the next service. */ no_more = __nss_next2 (&entry.nip, "setnetgrent", NULL, &setfct.ptr, status, 0); } if (result == 0 && entry.needed_groups != NULL) { struct name_list *tmp = entry.needed_groups; entry.needed_groups = tmp->next; tmp->next = entry.known_groups; entry.known_groups = tmp; current_group = tmp->name; continue; } /* No way out. */ break; } /* Free the memory. */ free_memory (&entry); return result == 1; }