/*ARGSUSED*/ static void * smbd_refresh_monitor(void *arg) { smbd_online_wait("smbd_refresh_monitor"); while (!smbd.s_shutting_down) { (void) sleep(SMBD_REFRESH_INTERVAL); (void) pthread_mutex_lock(&refresh_mutex); while ((atomic_swap_uint(&smbd.s_refreshes, 0) == 0) && (!smbd.s_shutting_down)) (void) pthread_cond_wait(&refresh_cond, &refresh_mutex); (void) pthread_mutex_unlock(&refresh_mutex); if (smbd.s_shutting_down) { smbd_service_fini(); /*NOTREACHED*/ } (void) mutex_lock(&smbd_service_mutex); smbd_dc_monitor_refresh(); smb_ccache_remove(SMB_CCACHE_PATH); /* * Clear the DNS zones for the existing interfaces * before updating the NIC interface list. */ dyndns_clear_zones(); if (smbd_nicmon_refresh() != 0) smbd_report("NIC monitor refresh failed"); smb_netbios_name_reconfig(); smb_browser_reconfig(); dyndns_update_zones(); (void) smbd_kernel_bind(); smbd_load_shares(); smbd_load_printers(); (void) mutex_unlock(&smbd_service_mutex); } smbd.s_refresh_tid = 0; return (NULL); }
/* * Use SMF error codes only on return or exit. */ int main(int argc, char *argv[]) { struct sigaction act; sigset_t set; uid_t uid; int pfd = -1; uint_t sigval; struct rlimit rl; int orig_limit; smbd.s_pname = basename(argv[0]); openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); if (smbd_setup_options(argc, argv) != 0) return (SMF_EXIT_ERR_FATAL); if ((uid = getuid()) != smbd.s_uid) { smbd_report("user %d: %s", uid, strerror(EPERM)); return (SMF_EXIT_ERR_FATAL); } if (getzoneid() != GLOBAL_ZONEID) { smbd_report("non-global zones are not supported"); return (SMF_EXIT_ERR_FATAL); } if (is_system_labeled()) { smbd_report("Trusted Extensions not supported"); return (SMF_EXIT_ERR_FATAL); } if (smbd_already_running()) return (SMF_EXIT_OK); /* * Raise the file descriptor limit to accommodate simultaneous user * authentications/file access. */ if ((getrlimit(RLIMIT_NOFILE, &rl) == 0) && (rl.rlim_cur < rl.rlim_max)) { orig_limit = rl.rlim_cur; rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) != 0) smbd_report("Failed to raise file descriptor limit" " from %d to %d", orig_limit, rl.rlim_cur); } (void) sigfillset(&set); (void) sigdelset(&set, SIGABRT); (void) sigfillset(&act.sa_mask); act.sa_handler = smbd_sig_handler; act.sa_flags = 0; (void) sigaction(SIGABRT, &act, NULL); (void) sigaction(SIGTERM, &act, NULL); (void) sigaction(SIGHUP, &act, NULL); (void) sigaction(SIGINT, &act, NULL); (void) sigaction(SIGPIPE, &act, NULL); (void) sigaction(SIGUSR1, &act, NULL); (void) sigdelset(&set, SIGTERM); (void) sigdelset(&set, SIGHUP); (void) sigdelset(&set, SIGINT); (void) sigdelset(&set, SIGPIPE); (void) sigdelset(&set, SIGUSR1); if (smbd.s_fg) { (void) sigdelset(&set, SIGTSTP); (void) sigdelset(&set, SIGTTIN); (void) sigdelset(&set, SIGTTOU); if (smbd_service_init() != 0) { smbd_report("service initialization failed"); exit(SMF_EXIT_ERR_FATAL); } } else { /* * "pfd" is a pipe descriptor -- any fatal errors * during subsequent initialization of the child * process should be written to this pipe and the * parent will report this error as the exit status. */ pfd = smbd_daemonize_init(); if (smbd_service_init() != 0) { smbd_report("daemon initialization failed"); exit(SMF_EXIT_ERR_FATAL); } smbd_daemonize_fini(pfd, SMF_EXIT_OK); } (void) atexit(smb_kmod_stop); while (!smbd.s_shutting_down) { if (smbd.s_sigval == 0 && smbd.s_refreshes == 0) (void) sigsuspend(&set); sigval = atomic_swap_uint(&smbd.s_sigval, 0); switch (sigval) { case 0: case SIGPIPE: case SIGABRT: break; case SIGHUP: syslog(LOG_DEBUG, "refresh requested"); (void) pthread_cond_signal(&refresh_cond); break; case SIGUSR1: smb_log_dumpall(); break; default: /* * Typically SIGINT or SIGTERM. */ smbd.s_shutting_down = B_TRUE; break; } } smbd_service_fini(); closelog(); return ((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK); }
/* * Use SMF error codes only on return or exit. */ int main(int argc, char *argv[]) { sigset_t set; uid_t uid; int pfd = -1; int sigval; struct rlimit rl; int orig_limit; #ifdef FKSMBD fksmbd_init(); #endif smbd.s_pname = basename(argv[0]); openlog(smbd.s_pname, LOG_PID | LOG_NOWAIT, LOG_DAEMON); if (smbd_setup_options(argc, argv) != 0) return (SMF_EXIT_ERR_FATAL); if ((uid = getuid()) != smbd.s_uid) { #ifdef FKSMBD /* Can't manipulate privileges in daemonize. */ if (smbd.s_fg == 0) { smbd.s_fg = 1; smbd_report("user %d (forced -f)", uid); } #else /* FKSMBD */ smbd_report("user %d: %s", uid, strerror(EPERM)); return (SMF_EXIT_ERR_FATAL); #endif /* FKSMBD */ } if (is_system_labeled()) { smbd_report("Trusted Extensions not supported"); return (SMF_EXIT_ERR_FATAL); } if (smbd_already_running()) return (SMF_EXIT_OK); /* * Raise the file descriptor limit to accommodate simultaneous user * authentications/file access. */ if ((getrlimit(RLIMIT_NOFILE, &rl) == 0) && (rl.rlim_cur < rl.rlim_max)) { orig_limit = rl.rlim_cur; rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) != 0) smbd_report("Failed to raise file descriptor limit" " from %d to %d", orig_limit, rl.rlim_cur); } /* * Block async signals in all threads. */ (void) sigemptyset(&set); (void) sigaddset(&set, SIGHUP); (void) sigaddset(&set, SIGINT); (void) sigaddset(&set, SIGQUIT); (void) sigaddset(&set, SIGPIPE); (void) sigaddset(&set, SIGTERM); (void) sigaddset(&set, SIGUSR1); (void) sigaddset(&set, SIGUSR2); (void) sigprocmask(SIG_SETMASK, &set, NULL); if (smbd.s_fg) { if (smbd_service_init() != 0) { smbd_report("service initialization failed"); exit(SMF_EXIT_ERR_FATAL); } } else { /* * "pfd" is a pipe descriptor -- any fatal errors * during subsequent initialization of the child * process should be written to this pipe and the * parent will report this error as the exit status. */ pfd = smbd_daemonize_init(); if (smbd_service_init() != 0) { smbd_report("daemon initialization failed"); exit(SMF_EXIT_ERR_FATAL); } smbd_daemonize_fini(pfd, SMF_EXIT_OK); } while (!smbd.s_shutting_down) { sigval = sigwait(&set); switch (sigval) { case -1: syslog(LOG_DEBUG, "sigwait failed: %s", strerror(errno)); break; case SIGPIPE: break; case SIGHUP: syslog(LOG_DEBUG, "refresh requested"); smbd_refresh_handler(); break; case SIGUSR1: syslog(LOG_DEBUG, "SIGUSR1 ignored"); break; default: /* * Typically SIGINT or SIGTERM. */ smbd.s_shutting_down = B_TRUE; break; } } /* * Allow termination signals while shutting down. */ (void) sigemptyset(&set); if (smbd.s_fg) { (void) sigaddset(&set, SIGHUP); (void) sigaddset(&set, SIGINT); } (void) sigaddset(&set, SIGTERM); (void) sigprocmask(SIG_UNBLOCK, &set, NULL); smbd_service_fini(); return ((smbd.s_fatal_error) ? SMF_EXIT_ERR_FATAL : SMF_EXIT_OK); }