int getprotobynumber_r(int proto, struct protoent *pptr, char *buffer, size_t buflen, struct protoent **result) { #ifdef NS_CACHING static const nss_cache_info cache_info = NS_COMMON_CACHE_INFO_INITIALIZER( protocols, (void *)nss_lt_id, __proto_id_func, __proto_marshal_func, __proto_unmarshal_func); #endif static const ns_dtab dtab[] = { { NSSRC_FILES, files_getprotobynumber, NULL }, #ifdef NS_CACHING NS_CACHE_CB(&cache_info) #endif { NULL, NULL, NULL } }; int rv, ret_errno; ret_errno = 0; *result = NULL; rv = nsdispatch(result, dtab, NSDB_PROTOCOLS, "getprotobynumber_r", defaultsrc, proto, pptr, buffer, buflen, &ret_errno); if (rv != NS_SUCCESS) { errno = ret_errno; return (ret_errno); } return (0); }
struct hostent * gethostbyname2(const char *name, int type) { static struct hostent host, *hp; static char hostbuf[BUFSIZ]; static int herr; int rval; static const ns_dtab dtab[] = { NS_FILES_CB(_ht_gethostbyname, NULL) { NSSRC_DNS, _dns_gethostbyname, NULL }, NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */ { 0 } }; #ifdef HAVE_DD_LOCK __lock_acquire(name_lock); #endif rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname", default_src, name, type, &host, hostbuf, BUFSIZ, &herr); #ifdef HAVE_DD_LOCK __lock_release(name_lock); #endif if (rval != NS_SUCCESS) return NULL; else return hp; }
int getgrnam_r(const char *name, struct group *grp, char *buffer, size_t buflen, struct group **result) { int rv, retval; static const ns_dtab dtab[] = { NS_FILES_CB(_files_getgrnam_r, NULL) NS_DNS_CB(_dns_getgrnam_r, NULL) NS_NIS_CB(_nis_getgrnam_r, NULL) NS_COMPAT_CB(_compat_getgrnam_r, NULL) NS_NULL_CB }; _DIAGASSERT(name != NULL); _DIAGASSERT(grp != NULL); _DIAGASSERT(buffer != NULL); _DIAGASSERT(result != NULL); *result = NULL; retval = 0; mutex_lock(&__grmutex); rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam_r", __nsdefaultcompat, &retval, name, grp, buffer, buflen, result); mutex_unlock(&__grmutex); switch (rv) { case NS_SUCCESS: case NS_NOTFOUND: return 0; default: return retval; } }
int __gethostbyname_r(const char *name, struct hostent *result, void *buffer, int buflen, struct hostent **hp, int *herr) { int rval; int type; static const ns_dtab dtab[] = { NS_FILES_CB(_ht_gethostbyname, NULL) { NSSRC_DNS, _dns_gethostbyname, NULL }, NS_NIS_CB(_nis_gethostbyname, NULL) /* force -DHESIOD */ { 0 } }; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return HOST_NOT_FOUND; } if (_res.options & RES_USE_INET6) type = AF_INET6; else type = AF_INET; rval = nsdispatch((void *)hp, dtab, NSDB_HOSTS, "gethostbyname", default_src, name, type, result, buffer, buflen, herr); if (rval != NS_SUCCESS) return rval; else return 0; }
/*ARGSUSED*/ static int _compat_setgroupent(void *nsrv, void *nscb, va_list ap) { int *retval = va_arg(ap, int *); int stayopen = va_arg(ap, int); int rv; static const ns_dtab dtab[] = { NS_FILES_CB(__grbad_compat, "files") NS_DNS_CB(_dns_setgroupent, NULL) NS_NIS_CB(_nis_setgroupent, NULL) NS_COMPAT_CB(__grbad_compat, "compat") NS_NULL_CB }; /* force group_compat setgroupent() */ (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "setgroupent", __nsdefaultnis_forceall, &rv, stayopen); _compat_state.stayopen = stayopen; rv = __grstart_compat(&_compat_state); *retval = (rv == NS_SUCCESS); return rv; }
/* compat backend implementation */ static int compat_setservent(void *retval, void *mdata, va_list ap) { static const ns_src compat_src[] = { #ifdef YP { NSSRC_NIS, NS_SUCCESS }, #endif { NULL, 0 } }; ns_dtab compat_dtab[] = { { NSSRC_DB, db_setservent, mdata }, #ifdef YP { NSSRC_NIS, nis_setservent, mdata }, #endif { NULL, NULL, NULL } }; int f; (void)files_setservent(retval, mdata, ap); switch ((enum constants)mdata) { case SETSERVENT: f = va_arg(ap,int); (void)nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "setservent", compat_src, f); break; case ENDSERVENT: (void)nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "endservent", compat_src); break; default: break; } return (NS_UNAVAIL); }
static int func2(void *rv, void *cb_data, va_list ap) { static const ns_dtab dtab[] = { { "test", func3, NULL }, { NULL, NULL, NULL } }; int r; (void)printf("func2: enter\n"); r = nsdispatch(NULL, dtab, "test", "test", testsrc); (void)printf("func2: exit\n"); return r; }
static int func1(void) { static const ns_dtab dtab[] = { { "test", func2, NULL }, { NULL, NULL, NULL } }; int r; (void)printf("func1: enter\n"); r = nsdispatch(NULL, dtab, "test", "test", testsrc); (void)printf("func1: exit\n"); return r; }
void setgrent(void) { static const ns_dtab dtab[] = { NS_FILES_CB(_files_setgrent, NULL) NS_DNS_CB(_dns_setgrent, NULL) NS_NIS_CB(_nis_setgrent, NULL) NS_COMPAT_CB(_compat_setgrent, NULL) NS_NULL_CB }; mutex_lock(&__grmutex); /* force all setgrent() methods */ (void) nsdispatch(NULL, dtab, NSDB_GROUP, "setgrent", __nsdefaultcompat_forceall); mutex_unlock(&__grmutex); }
static struct hostent * _ghbyname(const char *name, int af, int flags, int *errp) { struct hostent *hp; int rval; static const ns_dtab dtab[] = { NS_FILES_CB(_files_ghbyname, NULL) { NSSRC_DNS, _dns_ghbyname, NULL }, NS_NIS_CB(_nis_ghbyname, NULL) { 0 } }; if (flags & AI_ADDRCONFIG) { int s; /* * TODO: * Note that implementation dependent test for address * configuration should be done everytime called * (or apropriate interval), * because addresses will be dynamically assigned or deleted. */ if (af == AF_UNSPEC) { if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) af = AF_INET; else { close(s); if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) af = AF_INET6; else close(s); } } if (af != AF_UNSPEC) { if ((s = socket(af, SOCK_DGRAM, 0)) < 0) return NULL; close(s); } } rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyname", default_src, name, af, errp); return (rval == NS_SUCCESS) ? hp : NULL; }
int setgroupent(int stayopen) { static const ns_dtab dtab[] = { NS_FILES_CB(_files_setgroupent, NULL) NS_DNS_CB(_dns_setgroupent, NULL) NS_NIS_CB(_nis_setgroupent, NULL) NS_COMPAT_CB(_compat_setgroupent, NULL) NS_NULL_CB }; int rv, retval; mutex_lock(&__grmutex); /* force all setgroupent() methods */ rv = nsdispatch(NULL, dtab, NSDB_GROUP, "setgroupent", __nsdefaultcompat_forceall, &retval, stayopen); mutex_unlock(&__grmutex); return (rv == NS_SUCCESS) ? retval : 0; }
/*ARGSUSED*/ static int _compat_endgrent(void *nsrv, void *nscb, va_list ap) { static const ns_dtab dtab[] = { NS_FILES_CB(__grbad_compat, "files") NS_DNS_CB(_dns_endgrent, NULL) NS_NIS_CB(_nis_endgrent, NULL) NS_COMPAT_CB(__grbad_compat, "compat") NS_NULL_CB }; /* force group_compat endgrent() */ (void) nsdispatch(NULL, dtab, NSDB_GROUP_COMPAT, "endgrent", __nsdefaultnis_forceall); /* reset state, close fp */ _compat_state.stayopen = 0; return __grend_compat(&_compat_state); }
struct group * getgrnam(const char *name) { int rv; struct group *retval; static const ns_dtab dtab[] = { NS_FILES_CB(_files_getgrnam, NULL) NS_DNS_CB(_dns_getgrnam, NULL) NS_NIS_CB(_nis_getgrnam, NULL) NS_COMPAT_CB(_compat_getgrnam, NULL) NS_NULL_CB }; mutex_lock(&__grmutex); rv = nsdispatch(NULL, dtab, NSDB_GROUP, "getgrnam", __nsdefaultcompat, &retval, name); mutex_unlock(&__grmutex); return (rv == NS_SUCCESS) ? retval : NULL; }
int __gethostbyaddr_r (const char *addr, int len, int type, struct hostent *result, void *buffer, int buflen, struct hostent **hp, int *herr) { int rval; static const ns_dtab dtab[] = { NS_FILES_CB(_ht_gethostbyaddr, NULL) { NSSRC_DNS, _dns_gethostbyaddr, NULL }, NS_NIS_CB(_nis_gethostbyaddr, NULL) /* force -DHESIOD */ { 0 } }; rval = nsdispatch((void *)hp, dtab, NSDB_HOSTS, "gethostbyaddr", default_src, addr, len, type, result, buffer, buflen, herr); if(rval != NS_SUCCESS) return rval; else return 0; }
/* * __grscan_compat * Scan state->fp for the next desired entry. * If search is zero, return the next entry. * If search is non-zero, look for a specific name (if name != NULL), * or a specific gid (if name == NULL). * Sets *retval to the errno if the result is not NS_SUCCESS or * NS_NOTFOUND. * * searchfunc is invoked when a compat "+" lookup is required; * searchcookie is passed as the first argument to searchfunc, * the second argument is the group result. * This should return NS_NOTFOUND when "no more groups" from compat src. * If searchfunc is NULL then nsdispatch of getgrent is used. * This is primarily intended for getgroupmembership(3)'s compat backend. */ int __grscan_compat(int *retval, struct group *grp, char *buffer, size_t buflen, struct __grstate_compat *state, int search, const char *name, gid_t gid, int (*searchfunc)(void *, struct group **), void *searchcookie) { int rv; char filebuf[_GETGR_R_SIZE_MAX], *ep; static const ns_dtab compatentdtab[] = { NS_FILES_CB(__grbad_compat, "files") NS_DNS_CB(_dns_getgrent_r, NULL) NS_NIS_CB(_nis_getgrent_r, NULL) NS_COMPAT_CB(__grbad_compat, "compat") NS_NULL_CB }; static const ns_dtab compatgiddtab[] = { NS_FILES_CB(__grbad_compat, "files") NS_DNS_CB(_dns_getgrgid_r, NULL) NS_NIS_CB(_nis_getgrgid_r, NULL) NS_COMPAT_CB(__grbad_compat, "compat") NS_NULL_CB }; static const ns_dtab compatnamdtab[] = { NS_FILES_CB(__grbad_compat, "files") NS_DNS_CB(_dns_getgrnam_r, NULL) NS_NIS_CB(_nis_getgrnam_r, NULL) NS_COMPAT_CB(__grbad_compat, "compat") NS_NULL_CB }; _DIAGASSERT(retval != NULL); _DIAGASSERT(grp != NULL); _DIAGASSERT(buffer != NULL); _DIAGASSERT(state != NULL); /* name is NULL to indicate searching for gid */ *retval = 0; if (state->fp == NULL) { /* only start if file not open yet */ rv = __grstart_compat(state); if (rv != NS_SUCCESS) goto compatgrscan_out; } rv = NS_NOTFOUND; for (;;) { /* loop through file */ if (state->name != NULL) { /* processing compat entry */ int crv, cretval; struct group cgrp, *cgrpres; if (state->name[0]) { /* specific +group: */ crv = nsdispatch(NULL, compatnamdtab, NSDB_GROUP_COMPAT, "getgrnam_r", __nsdefaultnis, &cretval, state->name, &cgrp, filebuf, sizeof(filebuf), &cgrpres); free(state->name); /* (only check 1 grp) */ state->name = NULL; } else if (!search) { /* any group */ if (searchfunc) { crv = searchfunc(searchcookie, &cgrpres); } else { crv = nsdispatch(NULL, compatentdtab, NSDB_GROUP_COMPAT, "getgrent_r", __nsdefaultnis, &cretval, &cgrp, filebuf, sizeof(filebuf), &cgrpres); } } else if (name) { /* specific group */ crv = nsdispatch(NULL, compatnamdtab, NSDB_GROUP_COMPAT, "getgrnam_r", __nsdefaultnis, &cretval, name, &cgrp, filebuf, sizeof(filebuf), &cgrpres); } else { /* specific gid */ crv = nsdispatch(NULL, compatgiddtab, NSDB_GROUP_COMPAT, "getgrgid_r", __nsdefaultnis, &cretval, gid, &cgrp, filebuf, sizeof(filebuf), &cgrpres); } if (crv != NS_SUCCESS) { /* not found */ free(state->name); state->name = NULL; continue; /* try next line */ } if (!_gr_copy(cgrpres, grp, buffer, buflen)) { rv = NS_UNAVAIL; break; } goto compatgrscan_cmpgrp; /* skip to grp test */ } /* get next file line */ if (fgets(filebuf, (int)sizeof(filebuf), state->fp) == NULL) break; ep = strchr(filebuf, '\n'); if (ep == NULL) { /* skip lines that are too big */ int ch; while ((ch = getc(state->fp)) != '\n' && ch != EOF) continue; continue; } *ep = '\0'; /* clear trailing \n */ if (filebuf[0] == '+') { /* parse compat line */ if (state->name) free(state->name); state->name = NULL; switch(filebuf[1]) { case ':': case '\0': state->name = strdup(""); break; default: ep = strchr(filebuf + 1, ':'); if (ep == NULL) break; *ep = '\0'; state->name = strdup(filebuf + 1); break; } if (state->name == NULL) { rv = NS_UNAVAIL; break; } continue; } /* validate line */ if (! _gr_parse(filebuf, grp, buffer, buflen)) { continue; /* skip bad lines */ } compatgrscan_cmpgrp: if (! search) { /* just want this one */ rv = NS_SUCCESS; break; } /* want specific */ if ((name && strcmp(name, grp->gr_name) == 0) || (!name && gid == grp->gr_gid)) { rv = NS_SUCCESS; break; } } compatgrscan_out: if (rv != NS_SUCCESS && rv != NS_NOTFOUND) *retval = errno; return rv; }
/* * compat structures. compat and files sources functionalities are almost * equal, so they all are managed by files_servent function */ static int files_servent(void *retval, void *mdata, va_list ap) { static const ns_src compat_src[] = { #ifdef YP { NSSRC_NIS, NS_SUCCESS }, #endif { NULL, 0 } }; ns_dtab compat_dtab[] = { { NSSRC_DB, db_servent, (void *)((struct servent_mdata *)mdata)->how }, #ifdef YP { NSSRC_NIS, nis_servent, (void *)((struct servent_mdata *)mdata)->how }, #endif { NULL, NULL, NULL } }; struct files_state *st; int rv; int stayopen; struct servent_mdata *serv_mdata; char *name; char *proto; int port; struct servent *serv; char *buffer; size_t bufsize; int *errnop; size_t linesize; char *line; char **cp; name = NULL; proto = NULL; serv_mdata = (struct servent_mdata *)mdata; switch (serv_mdata->how) { case nss_lt_name: name = va_arg(ap, char *); proto = va_arg(ap, char *); break; case nss_lt_id: port = va_arg(ap, int); proto = va_arg(ap, char *); break; case nss_lt_all: break; default: return NS_NOTFOUND; }; serv = va_arg(ap, struct servent *); buffer = va_arg(ap, char *); bufsize = va_arg(ap, size_t); errnop = va_arg(ap,int *); *errnop = files_getstate(&st); if (*errnop != 0) return (NS_UNAVAIL); if (st->fp == NULL) st->compat_mode_active = 0; if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) { *errnop = errno; return (NS_UNAVAIL); } if (serv_mdata->how == nss_lt_all) stayopen = 1; else { rewind(st->fp); stayopen = st->stayopen; } rv = NS_NOTFOUND; do { if (!st->compat_mode_active) { if ((line = fgetln(st->fp, &linesize)) == NULL) { *errnop = errno; rv = NS_RETURN; break; } if (*line=='+' && serv_mdata->compat_mode != 0) st->compat_mode_active = 1; } if (st->compat_mode_active != 0) { switch (serv_mdata->how) { case nss_lt_name: rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyname_r", compat_src, name, proto, serv, buffer, bufsize, errnop); break; case nss_lt_id: rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyport_r", compat_src, port, proto, serv, buffer, bufsize, errnop); break; case nss_lt_all: rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservent_r", compat_src, serv, buffer, bufsize, errnop); break; } if (!(rv & NS_TERMINATE) || serv_mdata->how != nss_lt_all) st->compat_mode_active = 0; continue; } rv = parse_result(serv, buffer, bufsize, line, linesize, errnop); if (rv == NS_NOTFOUND) continue; if (rv == NS_RETURN) break; rv = NS_NOTFOUND; switch (serv_mdata->how) { case nss_lt_name: if (strcmp(name, serv->s_name) == 0) goto gotname; for (cp = serv->s_aliases; *cp; cp++) if (strcmp(name, *cp) == 0) goto gotname; continue; gotname: if (proto == 0 || strcmp(serv->s_proto, proto) == 0) rv = NS_SUCCESS; break; case nss_lt_id: if (port != serv->s_port) continue; if (proto == 0 || strcmp(serv->s_proto, proto) == 0) rv = NS_SUCCESS; break; case nss_lt_all: rv = NS_SUCCESS; break; } } while (!(rv & NS_TERMINATE)); if (!stayopen && st->fp != NULL) { fclose(st->fp); st->fp = NULL; } if ((rv == NS_SUCCESS) && (retval != NULL)) *(struct servent **)retval=serv; return (rv); }
struct hostent * getipnodebyaddr(const void *src, size_t len, int af, int *errp) { struct hostent *hp; int rval; #ifdef INET6 struct in6_addr addrbuf; #else struct in_addr addrbuf; #endif static const ns_dtab dtab[] = { NS_FILES_CB(_files_ghbyaddr, NULL) { NSSRC_DNS, _dns_ghbyaddr, NULL }, NS_NIS_CB(_nis_ghbyaddr, NULL) #ifdef ICMPNL { NSSRC_ICMP, _icmp_ghbyaddr, NULL }, #endif { 0 } }; *errp = HOST_NOT_FOUND; switch (af) { case AF_INET: if (len != sizeof(struct in_addr)) { *errp = NO_RECOVERY; return NULL; } if ((long)src & ~(sizeof(struct in_addr) - 1)) { memcpy(&addrbuf, src, len); src = &addrbuf; } if (((struct in_addr *)src)->s_addr == 0) return NULL; break; #ifdef INET6 case AF_INET6: if (len != sizeof(struct in6_addr)) { *errp = NO_RECOVERY; return NULL; } if ((long)src & ~(sizeof(struct in6_addr) / 2 - 1)) { /*XXX*/ memcpy(&addrbuf, src, len); src = &addrbuf; } if (IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *)src)) return NULL; if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src) || IN6_IS_ADDR_V4COMPAT((struct in6_addr *)src)) { src = (char *)src + (sizeof(struct in6_addr) - sizeof(struct in_addr)); af = AF_INET; len = sizeof(struct in_addr); } break; #endif default: *errp = NO_RECOVERY; return NULL; } rval = nsdispatch(&hp, dtab, NSDB_HOSTS, "ghbyaddr", default_src, src, len, af, errp); return (rval == NS_SUCCESS) ? hp : NULL; }