setdb (const char *dbname) { if (strcmp ("db", dbname)) { /* db is not implemented for hosts, networks */ __nss_configure_lookup ("hosts", dbname); __nss_configure_lookup ("networks", dbname); } __nss_configure_lookup ("protocols", dbname); __nss_configure_lookup ("services", dbname); }
static int do_test (void) { /* Avoid network-based NSS modules and initialize nss_files with a dummy lookup. This has to come before mtrace because NSS does not free all memory. */ __nss_configure_lookup ("passwd", "files"); (void) getpwnam ("root"); mtrace (); repeat = xmalloc (repeat_size + 1); memset (repeat, 'x', repeat_size); repeat[repeat_size] = '\0'; /* These numbers control the size of the user name. The values cover the minimum (0), a typical size (8), a large stack-allocated size (100000), and a somewhat large heap-allocated size (largest_base_size). */ static const int base_sizes[] = { 0, 8, 100, 100000, largest_base_size, -1 }; for (do_onlydir = 0; do_onlydir < 2; ++do_onlydir) for (do_nocheck = 0; do_nocheck < 2; ++do_nocheck) for (do_mark = 0; do_mark < 2; ++do_mark) for (do_noescape = 0; do_noescape < 2; ++do_noescape) for (int base_idx = 0; base_sizes[base_idx] >= 0; ++base_idx) { for (int size_skew = -max_size_skew; size_skew <= max_size_skew; ++size_skew) { int size = base_sizes[base_idx] + size_skew; if (size < 0) continue; const char *user_name = repeating_string (size); one_test ("~", user_name, "/a/b"); one_test ("~", user_name, "x\\x\\x////x\\a"); } const char *user_name = repeating_string (base_sizes[base_idx]); one_test ("~", user_name, ""); one_test ("~", user_name, "/"); one_test ("~", user_name, "/a"); one_test ("~", user_name, "/*/*"); one_test ("~", user_name, "\\/"); one_test ("/~", user_name, ""); one_test ("*/~", user_name, "/a/b"); } free (repeat); return 0; }
static int do_test (void) { int retval = 0; int i; __nss_configure_lookup ("passwd", "test1 test2"); setpwent (); i = 0; for (struct passwd *p = getpwent (); p != NULL; ++i, p = getpwent ()) { retval += compare_passwds (i, & pwd_expected[i], p); if (p->pw_uid != pwd_expected[i].pw_uid || strcmp (p->pw_name, pwd_expected[i].pw_name) != 0) { printf ("FAIL: getpwent for %u.%s returned %u.%s\n", pwd_expected[i].pw_uid, pwd_expected[i].pw_name, p->pw_uid, p->pw_name); retval = 1; break; } } endpwent (); for (i=0; tests[i].name; i++) { struct passwd *p = getpwnam (tests[i].name); if (strcmp (p->pw_name, tests[i].name) != 0 || p->pw_uid != tests[i].uid) { printf("FAIL: getpwnam for %u.%s returned %u.%s\n", tests[i].uid, tests[i].name, p->pw_uid, p->pw_name); retval = 1; } p = getpwuid (tests[i].uid); if (strcmp (p->pw_name, tests[i].name) != 0 || p->pw_uid != tests[i].uid) { printf("FAIL: getpwuid for %u.%s returned %u.%s\n", tests[i].uid, tests[i].name, p->pw_uid, p->pw_name); retval = 1; } } return retval; }
/* function to disable lookups through the nss_ldap module to avoid lookup loops */ static void disable_nss_ldap(void) { void *handle; char *error; char **version_info; int *enable_flag; /* try to load the NSS module */ #ifdef RTLD_NODELETE handle = dlopen(NSS_LDAP_SONAME, RTLD_LAZY | RTLD_NODELETE); #else /* not RTLD_NODELETE */ handle = dlopen(NSS_LDAP_SONAME, RTLD_LAZY); #endif /* RTLD_NODELETE */ if (handle == NULL) { log_log(LOG_WARNING, "Warning: NSS_LDAP module not loaded: %s", dlerror()); return; } /* clear any existing errors */ dlerror(); /* lookup the NSS version if possible */ version_info = (char **)dlsym(handle, "_nss_ldap_version"); error = dlerror(); if ((version_info != NULL) && (error == NULL)) log_log(LOG_DEBUG, "NSS_LDAP %s %s", version_info[0], version_info[1]); else log_log(LOG_WARNING, "Warning: NSS_LDAP version missing: %s", error); /* clear any existing errors */ dlerror(); /* try to look up the flag */ enable_flag = (int *)dlsym(handle, "_nss_ldap_enablelookups"); error = dlerror(); if ((enable_flag == NULL) || (error != NULL)) { log_log(LOG_WARNING, "Warning: %s (probably older NSS module loaded)", error); /* fall back to changing the way host lookup is done */ #ifdef HAVE___NSS_CONFIGURE_LOOKUP if (__nss_configure_lookup("hosts", "files dns")) log_log(LOG_ERR, "unable to override hosts lookup method: %s", strerror(errno)); #endif /* HAVE___NSS_CONFIGURE_LOOKUP */ dlclose(handle); return; } /* disable nss_ldap */ *enable_flag = 0; #ifdef RTLD_NODELETE /* only close the handle if RTLD_NODELETE was used */ dlclose(handle); #endif /* RTLD_NODELETE */ }
static int do_test (void) { int retval = 0; __nss_configure_lookup ("passwd", "test1"); /* This must match the pwd_table above. */ static const unsigned int pwdids[] = { 100, 30, 200, 60, 20000 }; #define npwdids (sizeof (pwdids) / sizeof (pwdids[0])) setpwent (); const unsigned int *np = pwdids; for (struct passwd *p = getpwent (); p != NULL; ++np, p = getpwent ()) { retval += compare_passwds (np-pwdids, p, & pwd_table[np-pwdids]); if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0 || atol (p->pw_name + 4) != *np) { printf ("FAIL: passwd entry %td wrong (%s, %u)\n", np - pwdids, p->pw_name, p->pw_uid); retval = 1; break; } } endpwent (); for (int i = npwdids - 1; i >= 0; --i) { char buf[30]; snprintf (buf, sizeof (buf), "name%u", pwdids[i]); struct passwd *p = getpwnam (buf); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("FAIL: passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i]); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("FAIL: passwd entry %u wrong\n", pwdids[i]); retval = 1; } snprintf (buf, sizeof (buf), "name%u", pwdids[i] + 1); p = getpwnam (buf); if (p != NULL) { printf ("FAIL: passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i] + 1); if (p != NULL) { printf ("FAIL: passwd entry %u wrong\n", pwdids[i] + 1); retval = 1; } } if (!hook_called) { retval = 1; printf("FAIL: init hook never called\n"); } return retval; }
static int do_test (void) { int retval = 0; __nss_configure_lookup ("passwd", "test1"); static const unsigned int pwdids[] = { 100, 30, 200, 60, 20000 }; #define npwdids (sizeof (pwdids) / sizeof (pwdids[0])) setpwent (); const unsigned int *np = pwdids; for (struct passwd *p = getpwent (); p != NULL; ++np, p = getpwent ()) if (p->pw_uid != *np || strncmp (p->pw_name, "name", 4) != 0 || atol (p->pw_name + 4) != *np) { printf ("passwd entry %ju wrong (%s, %u)\n", np - pwdids, p->pw_name, p->pw_uid); retval = 1; break; } endpwent (); for (int i = npwdids - 1; i >= 0; --i) { char buf[30]; snprintf (buf, sizeof (buf), "name%u", pwdids[i]); struct passwd *p = getpwnam (buf); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i]); if (p == NULL || p->pw_uid != pwdids[i] || strcmp (buf, p->pw_name) != 0) { printf ("passwd entry %u wrong\n", pwdids[i]); retval = 1; } snprintf (buf, sizeof (buf), "name%u", pwdids[i] + 1); p = getpwnam (buf); if (p != NULL) { printf ("passwd entry \"%s\" wrong\n", buf); retval = 1; } p = getpwuid (pwdids[i] + 1); if (p != NULL) { printf ("passwd entry %u wrong\n", pwdids[i] + 1); retval = 1; } } return retval; }
int main(int argc, char *argv[]) { struct netconfig *nconf; void *nc_handle; /* Net config handle */ struct rlimit rl; int maxrec = RPC_MAXDATASIZE; parseargs(argc, argv); /* Check that another rpcbind isn't already running. */ if ((rpcbindlockfd = (open(RPCBINDDLOCK, O_RDONLY|O_CREAT, 0444))) == -1) err(1, "%s", RPCBINDDLOCK); if(flock(rpcbindlockfd, LOCK_EX|LOCK_NB) == -1 && errno == EWOULDBLOCK) errx(1, "another rpcbind is already running. Aborting"); getrlimit(RLIMIT_NOFILE, &rl); if (rl.rlim_cur < 128) { if (rl.rlim_max <= 128) rl.rlim_cur = rl.rlim_max; else rl.rlim_cur = 128; setrlimit(RLIMIT_NOFILE, &rl); } openlog("rpcbind", LOG_CONS, LOG_DAEMON); if (geteuid()) { /* This command allowed only to root */ fprintf(stderr, "Sorry. You are not superuser\n"); exit(1); } /* * Make sure we use the local service file * for service lookkups */ __nss_configure_lookup("services", "files"); nc_handle = setnetconfig(); /* open netconfig file */ if (nc_handle == NULL) { syslog(LOG_ERR, "could not read /etc/netconfig"); exit(1); } nconf = getnetconfigent("local"); if (nconf == NULL) nconf = getnetconfigent("unix"); if (nconf == NULL) { syslog(LOG_ERR, "%s: can't find local transport\n", argv[0]); exit(1); } rpc_control(RPC_SVC_CONNMAXREC_SET, &maxrec); init_transport(nconf); while ((nconf = getnetconfig(nc_handle))) { if (nconf->nc_flag & NC_VISIBLE) init_transport(nconf); } endnetconfig(nc_handle); #ifdef PORTMAP if (!udptrans) udptrans = ""; if (!tcptrans) tcptrans = ""; #endif /* catch the usual termination signals for graceful exit */ (void) signal(SIGCHLD, reap); (void) signal(SIGINT, terminate); (void) signal(SIGTERM, terminate); (void) signal(SIGQUIT, terminate); /* ignore others that could get sent */ (void) signal(SIGPIPE, SIG_IGN); (void) signal(SIGHUP, SIG_IGN); (void) signal(SIGUSR1, SIG_IGN); (void) signal(SIGUSR2, SIG_IGN); if (debugging) { #ifdef RPCBIND_DEBUG printf("rpcbind debugging enabled."); if (doabort) { printf(" Will abort on errors!\n"); } else { printf("\n"); } #endif } else { if (daemon(0, 0)) err(1, "fork failed"); } if (runasdaemon || rpcbinduser) { struct passwd *p; char *id = runasdaemon ? RUN_AS : rpcbinduser; /* * Make sure we use the local password file * for these lookups. */ __nss_configure_lookup("passwd", "files"); if((p = getpwnam(id)) == NULL) { syslog(LOG_ERR, "cannot get uid of '%s': %m", id); exit(1); } if (setgid(p->pw_gid) == -1) { syslog(LOG_ERR, "setgid to '%s' (%d) failed: %m", id, p->pw_gid); exit(1); } if (setuid(p->pw_uid) == -1) { syslog(LOG_ERR, "setuid to '%s' (%d) failed: %m", id, p->pw_uid); exit(1); } } #ifdef WARMSTART if (warmstart) { read_warmstart(); } #endif network_init(); my_svc_run(); syslog(LOG_ERR, "svc_run returned unexpectedly"); rpcbind_abort(); /* NOTREACHED */ return 0; }