//tunnel process function block<input type="checkbox" n<input type="checkbox" name="" value="">ame="" value=""> //success :1 ; fail :0; int setup_tunnel(struct vty *vty,char *src_ip,char *dst_ip,int lsp_id){ printf("Debug msg(setup_tunnel): src_ip :%s\t dst_ip:%s\t lsp_id :%d\n",src_ip,dst_ip,lsp_id); char buf[255]; tunnel_entry *tunnel=tunnel_get(); if(!tunnel){//no tunnel entry to add first new tunnel_entry tunnel=tunnel_new(); if(add_new_tunnel_entry(inet_addr(dst_ip),tunnel)){ vty_out(vty,"Create a new tunnel fail. %s",VTY_NEWLINE); return 0; }else{//create new tunnel connect_daemon(VTYSH_INDEX_RSVPD); RSVP_New_Command cmd; cmd=SEND_PATH_MSG; sprintf(buf,"rsvp_cmd_type %d arg0 %s arg1 %s arg2 %d arg3 %s\n",cmd,src_ip,dst_ip,lsp_id,"NULL"); vtysh_client_execute(&vtysh_client[VTYSH_INDEX_RSVPD], buf, stdout); exit_daemon(VTYSH_INDEX_RSVPD); return 1; } }else{//have one or more tunnel_entry to check remote_ip address is used or unused; //need to check remote_ip is used or unused printf("Tunnel is exit then create new tunnel entry.\n"); if(qurray_tunnel_entry(inet_addr(dst_ip),tunnel)){ tunnel=tunnel_new_more(tunnel); if(add_new_tunnel_entry(inet_addr(dst_ip),tunnel)){ vty_out(vty,"Create a new tunnel fail. %s",VTY_NEWLINE); return 0; }else{ //need to check rsvp daemon is setup tunnel or not; those codes doesn't ready. RSVP_New_Command cmd; cmd=SEND_PATH_MSG; connect_daemon(VTYSH_INDEX_RSVPD); sprintf(buf,"rsvp_cmd_type %d arg0 %s arg1 %s arg2 %d arg3 %s\n",cmd,src_ip,dst_ip,lsp_id,"NULL"); vtysh_client_execute(&vtysh_client[VTYSH_INDEX_RSVPD], buf, stdout); exit_daemon(VTYSH_INDEX_RSVPD); return 1; } //tunnel->out_state = PROCESSING; //return CMD_WARNING; }else{ vty_out(vty,"The remote_ip is already exit.\n"); return 0; } } }
void handle_signal(int sig, short event, void *arg) { /* * Signal handler rules don't apply, libevent decouples for us. */ logmsg(LOG_ERR, "exiting on signal %d", sig); exit_daemon(); }
void * /*ARGSUSED*/ event_handler(void *par) { iscsi_wait_event_parameters_t evtp; int rc; DEB(99, ("Event handler starts\n")); (void) memset(&evtp, 0x0, sizeof(evtp)); evtp.event_id = event_reg.event_id; do { if (nothreads) rc = ioctl(driver, ISCSI_POLL_EVENT, &evtp); else rc = ioctl(driver, ISCSI_WAIT_EVENT, &evtp); if (rc != 0) { perror("ioctl"); break; } DEB(1, ("Got Event: kind %d, status %d, sid %d, cid %d, reason %d\n", evtp.event_kind, evtp.status, evtp.session_id, evtp.connection_id, evtp.reason)); if (evtp.status) break; switch (evtp.event_kind) { case ISCSI_SESSION_TERMINATED: event_kill_session(evtp.session_id); break; case ISCSI_CONNECTION_TERMINATED: event_kill_connection(evtp.session_id, evtp.connection_id); break; case ISCSI_RECOVER_CONNECTION: event_recover_connection(evtp.session_id, evtp.connection_id); break; default: break; } } while (evtp.event_kind != ISCSI_DRIVER_TERMINATING); if (nothreads && evtp.event_kind == ISCSI_DRIVER_TERMINATING) exit_daemon(); return NULL; }
int main(int argc, const char *argv[]) { bool is_daemon = false; bool opt_interactive = false; bool Fork = true; bool no_process_group = false; bool log_stdout = false; poptContext pc; char *p_lmhosts = NULL; int opt; struct messaging_context *msg; enum { OPT_DAEMON = 1000, OPT_INTERACTIVE, OPT_FORK, OPT_NO_PROCESS_GROUP, OPT_LOG_STDOUT }; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon(default)" }, {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)" }, {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools & etc)" }, {"no-process-group", 0, POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" }, {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" }, {"hosts", 'H', POPT_ARG_STRING, &p_lmhosts, 0, "Load a netbios hosts file"}, {"port", 'p', POPT_ARG_INT, &global_nmb_port, 0, "Listen on the specified port" }, POPT_COMMON_SAMBA POPT_COMMON_DYNCONFIG POPT_TABLEEND }; TALLOC_CTX *frame; NTSTATUS status; bool ok; /* * Do this before any other talloc operation */ talloc_enable_null_tracking(); frame = talloc_stackframe(); /* * We want total control over the permissions on created files, * so set our umask to 0. */ umask(0); setup_logging(argv[0], DEBUG_DEFAULT_STDOUT); load_case_tables(); global_nmb_port = NMB_PORT; pc = poptGetContext("nmbd", argc, argv, long_options, 0); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_DAEMON: is_daemon = true; break; case OPT_INTERACTIVE: opt_interactive = true; break; case OPT_FORK: Fork = false; break; case OPT_NO_PROCESS_GROUP: no_process_group = true; break; case OPT_LOG_STDOUT: log_stdout = true; break; default: d_fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); exit(1); } }; poptFreeContext(pc); global_in_nmbd = true; StartupTime = time(NULL); sys_srandom(time(NULL) ^ getpid()); if (!override_logfile) { char *lfile = NULL; if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) { exit(1); } lp_set_logfile(lfile); SAFE_FREE(lfile); } fault_setup(); dump_core_setup("nmbd", lp_logfile(talloc_tos())); /* POSIX demands that signals are inherited. If the invoking process has * these signals masked, we will have problems, as we won't receive them. */ BlockSignals(False, SIGHUP); BlockSignals(False, SIGUSR1); BlockSignals(False, SIGTERM); #if defined(SIGFPE) /* we are never interested in SIGFPE */ BlockSignals(True,SIGFPE); #endif /* We no longer use USR2... */ #if defined(SIGUSR2) BlockSignals(True, SIGUSR2); #endif /* Ignore children - no zombies. */ CatchChild(); if ( opt_interactive ) { Fork = False; log_stdout = True; } if ( log_stdout && Fork ) { DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n")); exit(1); } if (log_stdout) { setup_logging(argv[0], DEBUG_STDOUT); } else { setup_logging( argv[0], DEBUG_FILE); } reopen_logs(); DEBUG(0,("nmbd version %s started.\n", samba_version_string())); DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE)); if (!lp_load_initial_only(get_dyn_CONFIGFILE())) { DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE())); exit(1); } reopen_logs(); if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC && !lp_parm_bool(-1, "server role check", "inhibit", false)) { /* TODO: when we have a merged set of defaults for * loadparm, we could possibly check if the internal * nbt server is in the list, and allow a startup if disabled */ DEBUG(0, ("server role = 'active directory domain controller' not compatible with running nmbd standalone. \n")); DEBUGADD(0, ("You should start 'samba' instead, and it will control starting the internal nbt server\n")); exit(1); } msg = messaging_init(NULL, server_event_context()); if (msg == NULL) { return 1; } if ( !reload_nmbd_services(False) ) return(-1); if(!init_names()) return -1; reload_nmbd_services( True ); if (strequal(lp_workgroup(),"*")) { DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n")); exit(1); } set_samba_nb_type(); if (!is_daemon && !is_a_socket(0)) { DEBUG(0,("standard input is not a socket, assuming -D option\n")); is_daemon = True; } if (is_daemon && !opt_interactive) { DEBUG( 2, ( "Becoming a daemon.\n" ) ); become_daemon(Fork, no_process_group, log_stdout); } #if HAVE_SETPGID /* * If we're interactive we want to set our own process group for * signal management. */ if (opt_interactive && !no_process_group) setpgid( (pid_t)0, (pid_t)0 ); #endif #ifndef SYNC_DNS /* Setup the async dns. We do it here so it doesn't have all the other stuff initialised and thus chewing memory and sockets */ if(lp_we_are_a_wins_server() && lp_wins_dns_proxy()) { start_async_dns(msg); } #endif ok = directory_create_or_exist(lp_lockdir(), geteuid(), 0755); if (!ok) { exit_daemon("Failed to create directory for lock files, check 'lock directory'", errno); } ok = directory_create_or_exist(lp_piddir(), geteuid(), 0755); if (!ok) { exit_daemon("Failed to create directory for pid files, check 'pid directory'", errno); } pidfile_create(lp_piddir(), "nmbd"); status = reinit_after_fork(msg, nmbd_event_context(), false); if (!NT_STATUS_IS_OK(status)) { exit_daemon("reinit_after_fork() failed", map_errno_from_nt_status(status)); } /* * Do not initialize the parent-child-pipe before becoming * a daemon: this is used to detect a died parent in the child * process. */ status = init_before_fork(); if (!NT_STATUS_IS_OK(status)) { exit_daemon(nt_errstr(status), map_errno_from_nt_status(status)); } if (!nmbd_setup_sig_term_handler(msg)) exit_daemon("NMBD failed to setup signal handler", EINVAL); if (!nmbd_setup_stdin_handler(msg, !Fork)) exit_daemon("NMBD failed to setup stdin handler", EINVAL); if (!nmbd_setup_sig_hup_handler(msg)) exit_daemon("NMBD failed to setup SIGHUP handler", EINVAL); /* get broadcast messages */ if (!serverid_register(messaging_server_id(msg), FLAG_MSG_GENERAL | FLAG_MSG_NMBD | FLAG_MSG_DBWRAP)) { exit_daemon("Could not register NMBD process in serverid.tdb", EACCES); } messaging_register(msg, NULL, MSG_FORCE_ELECTION, nmbd_message_election); #if 0 /* Until winsrepl is done. */ messaging_register(msg, NULL, MSG_WINS_NEW_ENTRY, nmbd_wins_new_entry); #endif messaging_register(msg, NULL, MSG_SHUTDOWN, nmbd_terminate); messaging_register(msg, NULL, MSG_SMB_CONF_UPDATED, msg_reload_nmbd_services); messaging_register(msg, NULL, MSG_SEND_PACKET, msg_nmbd_send_packet); TimeInit(); DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) ); if ( !open_sockets( is_daemon, global_nmb_port ) ) { kill_async_dns_child(); return 1; } /* Determine all the IP addresses we have. */ load_interfaces(); /* Create an nmbd subnet record for each of the above. */ if( False == create_subnets() ) { kill_async_dns_child(); exit_daemon("NMBD failed when creating subnet lists", EACCES); } /* Load in any static local names. */ if (p_lmhosts) { set_dyn_LMHOSTSFILE(p_lmhosts); } load_lmhosts_file(get_dyn_LMHOSTSFILE()); DEBUG(3,("Loaded hosts file %s\n", get_dyn_LMHOSTSFILE())); /* If we are acting as a WINS server, initialise data structures. */ if( !initialise_wins() ) { kill_async_dns_child(); exit_daemon( "NMBD failed when initialising WINS server.", EACCES); } /* * Register nmbd primary workgroup and nmbd names on all * the broadcast subnets, and on the WINS server (if specified). * Also initiate the startup of our primary workgroup (start * elections if we are setup as being able to be a local * master browser. */ if( False == register_my_workgroup_and_names() ) { kill_async_dns_child(); exit_daemon( "NMBD failed when creating my workgroup.", EACCES); } if (!initialize_nmbd_proxy_logon()) { kill_async_dns_child(); exit_daemon( "NMBD failed to setup nmbd_proxy_logon.", EACCES); } if (!nmbd_init_packet_server()) { kill_async_dns_child(); exit_daemon( "NMBD failed to setup packet server.", EACCES); } if (is_daemon && !opt_interactive) { daemon_ready("nmbd"); } TALLOC_FREE(frame); process(msg); kill_async_dns_child(); return(0); }
int main(int argc,const char *argv[]) { /* shall I run as a daemon */ bool is_daemon = false; bool interactive = false; bool Fork = true; bool no_process_group = false; bool log_stdout = false; char *ports = NULL; char *profile_level = NULL; int opt; poptContext pc; bool print_build_options = False; enum { OPT_DAEMON = 1000, OPT_INTERACTIVE, OPT_FORK, OPT_NO_PROCESS_GROUP, OPT_LOG_STDOUT }; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)" }, {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)"}, {"foreground", 'F', POPT_ARG_NONE, NULL, OPT_FORK, "Run daemon in foreground (for daemontools, etc.)" }, {"no-process-group", '\0', POPT_ARG_NONE, NULL, OPT_NO_PROCESS_GROUP, "Don't create a new process group" }, {"log-stdout", 'S', POPT_ARG_NONE, NULL, OPT_LOG_STDOUT, "Log to stdout" }, {"build-options", 'b', POPT_ARG_NONE, NULL, 'b', "Print build options" }, {"port", 'p', POPT_ARG_STRING, &ports, 0, "Listen on the specified ports"}, {"profiling-level", 'P', POPT_ARG_STRING, &profile_level, 0, "Set profiling level","PROFILE_LEVEL"}, POPT_COMMON_SAMBA POPT_TABLEEND }; struct smbd_parent_context *parent = NULL; TALLOC_CTX *frame; NTSTATUS status; struct tevent_context *ev_ctx; struct messaging_context *msg_ctx; struct server_id server_id; struct tevent_signal *se; int profiling_level; char *np_dir = NULL; static const struct smbd_shim smbd_shim_fns = { .cancel_pending_lock_requests_by_fid = smbd_cancel_pending_lock_requests_by_fid, .send_stat_cache_delete_message = smbd_send_stat_cache_delete_message, .change_to_root_user = smbd_change_to_root_user, .become_authenticated_pipe_user = smbd_become_authenticated_pipe_user, .unbecome_authenticated_pipe_user = smbd_unbecome_authenticated_pipe_user, .contend_level2_oplocks_begin = smbd_contend_level2_oplocks_begin, .contend_level2_oplocks_end = smbd_contend_level2_oplocks_end, .become_root = smbd_become_root, .unbecome_root = smbd_unbecome_root, .exit_server = smbd_exit_server, .exit_server_cleanly = smbd_exit_server_cleanly, }; /* * Do this before any other talloc operation */ talloc_enable_null_tracking(); frame = talloc_stackframe(); setup_logging(argv[0], DEBUG_DEFAULT_STDOUT); smb_init_locale(); set_smbd_shim(&smbd_shim_fns); smbd_init_globals(); TimeInit(); #ifdef HAVE_SET_AUTH_PARAMETERS set_auth_parameters(argc,argv); #endif pc = poptGetContext("smbd", argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case OPT_DAEMON: is_daemon = true; break; case OPT_INTERACTIVE: interactive = true; break; case OPT_FORK: Fork = false; break; case OPT_NO_PROCESS_GROUP: no_process_group = true; break; case OPT_LOG_STDOUT: log_stdout = true; break; case 'b': print_build_options = True; break; default: d_fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); exit(1); } } poptFreeContext(pc); if (interactive) { Fork = False; log_stdout = True; } if (log_stdout) { setup_logging(argv[0], DEBUG_STDOUT); } else { setup_logging(argv[0], DEBUG_FILE); } if (print_build_options) { build_options(True); /* Display output to screen as well as debug */ exit(0); } #ifdef HAVE_SETLUID /* needed for SecureWare on SCO */ setluid(0); #endif set_remote_machine_name("smbd", False); if (interactive && (DEBUGLEVEL >= 9)) { talloc_enable_leak_report(); } if (log_stdout && Fork) { DEBUG(0,("ERROR: Can't log to stdout (-S) unless daemon is in foreground (-F) or interactive (-i)\n")); exit(1); } /* we want to re-seed early to prevent time delays causing client problems at a later date. (tridge) */ generate_random_buffer(NULL, 0); /* get initial effective uid and gid */ sec_init(); /* make absolutely sure we run as root - to handle cases where people are crazy enough to have it setuid */ gain_root_privilege(); gain_root_group_privilege(); fault_setup(); dump_core_setup("smbd", lp_logfile(talloc_tos())); /* we are never interested in SIGPIPE */ BlockSignals(True,SIGPIPE); #if defined(SIGFPE) /* we are never interested in SIGFPE */ BlockSignals(True,SIGFPE); #endif #if defined(SIGUSR2) /* We are no longer interested in USR2 */ BlockSignals(True,SIGUSR2); #endif /* POSIX demands that signals are inherited. If the invoking process has * these signals masked, we will have problems, as we won't recieve them. */ BlockSignals(False, SIGHUP); BlockSignals(False, SIGUSR1); BlockSignals(False, SIGTERM); /* Ensure we leave no zombies until we * correctly set up child handling below. */ CatchChild(); /* we want total control over the permissions on created files, so set our umask to 0 */ umask(0); reopen_logs(); DEBUG(0,("smbd version %s started.\n", samba_version_string())); DEBUGADD(0,("%s\n", COPYRIGHT_STARTUP_MESSAGE)); DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n", (int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid())); /* Output the build options to the debug log */ build_options(False); if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4) { DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n")); exit(1); } if (!lp_load_initial_only(get_dyn_CONFIGFILE())) { DEBUG(0, ("error opening config file '%s'\n", get_dyn_CONFIGFILE())); exit(1); } if (!cluster_probe_ok()) { exit(1); } /* Init the security context and global current_user */ init_sec_ctx(); /* * Initialize the event context. The event context needs to be * initialized before the messaging context, cause the messaging * context holds an event context. * FIXME: This should be s3_tevent_context_init() */ ev_ctx = server_event_context(); if (ev_ctx == NULL) { exit(1); } /* * Init the messaging context * FIXME: This should only call messaging_init() */ msg_ctx = server_messaging_context(); if (msg_ctx == NULL) { exit(1); } /* * Reloading of the printers will not work here as we don't have a * server info and rpc services set up. It will be called later. */ if (!reload_services(NULL, NULL, false)) { exit(1); } if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC && !lp_parm_bool(-1, "server role check", "inhibit", false)) { DEBUG(0, ("server role = 'active directory domain controller' not compatible with running smbd standalone. \n")); DEBUGADD(0, ("You should start 'samba' instead, and it will control starting smbd if required\n")); exit(1); } /* ...NOTE... Log files are working from this point! */ DEBUG(3,("loaded services\n")); init_structs(); if (!profile_setup(msg_ctx, False)) { DEBUG(0,("ERROR: failed to setup profiling\n")); return -1; } if (profile_level != NULL) { profiling_level = atoi(profile_level); } else { profiling_level = lp_smbd_profiling_level(); } set_profile_level(profiling_level, messaging_server_id(msg_ctx)); if (!is_daemon && !is_a_socket(0)) { if (!interactive) { DEBUG(3, ("Standard input is not a socket, " "assuming -D option\n")); } /* * Setting is_daemon here prevents us from eventually calling * the open_sockets_inetd() */ is_daemon = True; } if (is_daemon && !interactive) { DEBUG(3, ("Becoming a daemon.\n")); become_daemon(Fork, no_process_group, log_stdout); } #if HAVE_SETPGID /* * If we're interactive we want to set our own process group for * signal management. */ if (interactive && !no_process_group) setpgid( (pid_t)0, (pid_t)0); #endif if (!directory_exist(lp_lock_directory())) mkdir(lp_lock_directory(), 0755); if (!directory_exist(lp_pid_directory())) mkdir(lp_pid_directory(), 0755); if (is_daemon) pidfile_create(lp_pid_directory(), "smbd"); status = reinit_after_fork(msg_ctx, ev_ctx, false, NULL); if (!NT_STATUS_IS_OK(status)) { exit_daemon("reinit_after_fork() failed", map_errno_from_nt_status(status)); } if (!interactive) { /* * Do not initialize the parent-child-pipe before becoming a * daemon: this is used to detect a died parent in the child * process. */ status = init_before_fork(); if (!NT_STATUS_IS_OK(status)) { exit_daemon(nt_errstr(status), map_errno_from_nt_status(status)); } } parent = talloc_zero(ev_ctx, struct smbd_parent_context); if (!parent) { exit_server("talloc(struct smbd_parent_context) failed"); } parent->interactive = interactive; parent->ev_ctx = ev_ctx; parent->msg_ctx = msg_ctx; am_parent = parent; se = tevent_add_signal(parent->ev_ctx, parent, SIGTERM, 0, smbd_parent_sig_term_handler, parent); if (!se) { exit_server("failed to setup SIGTERM handler"); } se = tevent_add_signal(parent->ev_ctx, parent, SIGHUP, 0, smbd_parent_sig_hup_handler, parent); if (!se) { exit_server("failed to setup SIGHUP handler"); } /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */ if (smbd_memcache() == NULL) { exit_daemon("no memcache available", EACCES); } memcache_set_global(smbd_memcache()); /* Initialise the password backed before the global_sam_sid to ensure that we fetch from ldap before we make a domain sid up */ if(!initialize_password_db(false, ev_ctx)) exit(1); if (!secrets_init()) { exit_daemon("smbd can not open secrets.tdb", EACCES); } if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) { struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers()); if (!open_schannel_session_store(NULL, lp_ctx)) { exit_daemon("ERROR: Samba cannot open schannel store for secured NETLOGON operations.", EACCES); } TALLOC_FREE(lp_ctx); } if(!get_global_sam_sid()) { exit_daemon("Samba cannot create a SAM SID", EACCES); } server_id = messaging_server_id(msg_ctx); status = smbXsrv_version_global_init(&server_id); if (!NT_STATUS_IS_OK(status)) { exit_daemon("Samba cannot init server context", EACCES); } status = smbXsrv_session_global_init(); if (!NT_STATUS_IS_OK(status)) { exit_daemon("Samba cannot init session context", EACCES); } status = smbXsrv_tcon_global_init(); if (!NT_STATUS_IS_OK(status)) { exit_daemon("Samba cannot init tcon context", EACCES); } if (!locking_init()) exit_daemon("Samba cannot init locking", EACCES); if (!leases_db_init(false)) { exit_daemon("Samba cannot init leases", EACCES); } if (!smbd_notifyd_init(msg_ctx, interactive)) { exit_daemon("Samba cannot init notification", EACCES); } if (!messaging_parent_dgm_cleanup_init(msg_ctx)) { exit(1); } if (!smbd_scavenger_init(NULL, msg_ctx, ev_ctx)) { exit_daemon("Samba cannot init scavenging", EACCES); } if (!serverid_parent_init(ev_ctx)) { exit_daemon("Samba cannot init server id", EACCES); } if (!W_ERROR_IS_OK(registry_init_full())) exit_daemon("Samba cannot init registry", EACCES); /* Open the share_info.tdb here, so we don't have to open after the fork on every single connection. This is a small performance improvment and reduces the total number of system fds used. */ if (!share_info_db_init()) { exit_daemon("ERROR: failed to load share info db.", EACCES); } status = init_system_session_info(); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("ERROR: failed to setup system user info: %s.\n", nt_errstr(status))); return -1; } if (!init_guest_info()) { DEBUG(0,("ERROR: failed to setup guest info.\n")); return -1; } if (!file_init_global()) { DEBUG(0, ("ERROR: file_init_global() failed\n")); return -1; } status = smbXsrv_open_global_init(); if (!NT_STATUS_IS_OK(status)) { exit_daemon("Samba cannot init global open", map_errno_from_nt_status(status)); } /* This MUST be done before start_epmd() because otherwise * start_epmd() forks and races against dcesrv_ep_setup() to * call directory_create_or_exist() */ if (!directory_create_or_exist(lp_ncalrpc_dir(), 0755)) { DEBUG(0, ("Failed to create pipe directory %s - %s\n", lp_ncalrpc_dir(), strerror(errno))); return -1; } np_dir = talloc_asprintf(talloc_tos(), "%s/np", lp_ncalrpc_dir()); if (!np_dir) { DEBUG(0, ("%s: Out of memory\n", __location__)); return -1; } if (!directory_create_or_exist_strict(np_dir, geteuid(), 0700)) { DEBUG(0, ("Failed to create pipe directory %s - %s\n", np_dir, strerror(errno))); return -1; } if (is_daemon && !interactive) { if (rpc_epmapper_daemon() == RPC_DAEMON_FORK) { start_epmd(ev_ctx, msg_ctx); } } if (!dcesrv_ep_setup(ev_ctx, msg_ctx)) { exit_daemon("Samba cannot setup ep pipe", EACCES); } if (is_daemon && !interactive) { daemon_ready("smbd"); } /* only start other daemons if we are running as a daemon * -- bad things will happen if smbd is launched via inetd * and we fork a copy of ourselves here */ if (is_daemon && !interactive) { if (rpc_lsasd_daemon() == RPC_DAEMON_FORK) { start_lsasd(ev_ctx, msg_ctx); } if (rpc_fss_daemon() == RPC_DAEMON_FORK) { start_fssd(ev_ctx, msg_ctx); } if (!lp__disable_spoolss() && (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) { bool bgq = lp_parm_bool(-1, "smbd", "backgroundqueue", true); if (!printing_subsystem_init(ev_ctx, msg_ctx, true, bgq)) { exit_daemon("Samba failed to init printing subsystem", EACCES); } } #ifdef WITH_SPOTLIGHT if ((rpc_mdssvc_mode() == RPC_SERVICE_MODE_EXTERNAL) && (rpc_mdssd_daemon() == RPC_DAEMON_FORK)) { start_mdssd(ev_ctx, msg_ctx); } #endif } else if (!lp__disable_spoolss() && (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) { if (!printing_subsystem_init(ev_ctx, msg_ctx, false, false)) { exit(1); } } if (!is_daemon) { int sock; /* inetd mode */ TALLOC_FREE(frame); /* Started from inetd. fd 0 is the socket. */ /* We will abort gracefully when the client or remote system goes away */ sock = dup(0); /* close stdin, stdout (if not logging to it), but not stderr */ close_low_fds(true, !debug_get_output_is_stdout(), false); #ifdef HAVE_ATEXIT atexit(killkids); #endif /* Stop zombies */ smbd_setup_sig_chld_handler(parent); smbd_process(ev_ctx, msg_ctx, sock, true); exit_server_cleanly(NULL); return(0); } if (!open_sockets_smbd(parent, ev_ctx, msg_ctx, ports)) exit_server("open_sockets_smbd() failed"); /* do a printer update now that all messaging has been set up, * before we allow clients to start connecting */ if (!lp__disable_spoolss() && (rpc_spoolss_daemon() != RPC_DAEMON_DISABLED)) { printing_subsystem_update(ev_ctx, msg_ctx, false); } TALLOC_FREE(frame); /* make sure we always have a valid stackframe */ frame = talloc_stackframe(); if (!Fork) { /* if we are running in the foreground then look for EOF on stdin, and exit if it happens. This allows us to die if the parent process dies Only do this on a pipe or socket, no other device. */ struct stat st; if (fstat(0, &st) != 0) { return false; } if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { tevent_add_fd(ev_ctx, parent, 0, TEVENT_FD_READ, smbd_stdin_handler, NULL); } } smbd_parent_loop(ev_ctx, parent); exit_server_cleanly(NULL); TALLOC_FREE(frame); return(0); }
int /*ARGSUSED*/ main(int argc, char **argv) { int req_temp, rsp_temp, c; ssize_t ret; size_t len; struct sockaddr_un from; socklen_t fromlen; iscsid_request_t *req; iscsid_response_t *rsp; struct timeval seltout = { 2, 0 }; /* 2 second poll interval */ char *p; while ((c = getopt(argc, argv, "d:n")) != -1) switch (c) { case 'n': nothreads++; break; case 'd': debug_level=(int)strtol(optarg, &p, 10); if (*p) errx(EXIT_FAILURE, "illegal debug level -- %s", optarg); break; default: usage(); } client_sock = init_daemon(); if (client_sock < 0) exit(1); printf("iSCSI Daemon loaded\n"); if (!debug_level) daemon(0, 1); if (nothreads) setsockopt(client_sock, SOL_SOCKET, SO_RCVTIMEO, &seltout, sizeof(seltout)); else { ret = pthread_create(&event_thread, NULL, event_handler, NULL); if (ret) { printf("Thread creation failed (%zd)\n", ret); close(client_sock); unlink(ISCSID_SOCK_NAME); deregister_event_handler(); pthread_mutex_destroy(&sesslist_lock); return -1; } } /* ---------------------------------------------------------------------- */ for (;;) { /* First, get size of request */ req = (iscsid_request_t *)(void *)req_buf; fromlen = sizeof(from); len = sizeof(iscsid_request_t); if (nothreads) { do { ret = recvfrom(client_sock, req, len, MSG_PEEK | MSG_WAITALL, (struct sockaddr *)(void *)&from, &fromlen); if (ret == -1) event_handler(NULL); } while (ret == -1 && errno == EAGAIN); } else { do { ret = recvfrom(client_sock, req, len, MSG_PEEK | MSG_WAITALL, (struct sockaddr *) &from, &fromlen); if (ret == -1) event_handler(NULL); } while (ret == -1 && errno == EAGAIN); } if ((size_t)ret != len) { perror("Receiving from socket"); break; } DEB(98, ("Request %d, parlen %d\n", req->request, req->parameter_length)); len += req->parameter_length; /* now that we know the size, get the buffer for it */ req_temp = (len > REQ_BUFFER_SIZE); if (req_temp) { req = malloc(len); if (!req) { printf("Can't alloc %zu bytes\n", len); break; } } /* read the complete request */ fromlen = sizeof(from); ret = recvfrom(client_sock, req, len, MSG_WAITALL, (struct sockaddr *)(void *)&from, &fromlen); if ((size_t)ret != len) { DEBOUT(("Error receiving from socket!\n")); if (req_temp) free(req); continue; } /* terminate? then go die. */ if (req->request == ISCSID_DAEMON_TERMINATE) break; /* No reply required to test message */ if (req->request == ISCSID_DAEMON_TEST) { if (req_temp) free(req); continue; } /* no return path? then we can't send a reply, */ /* so don't process the command */ if (!from.sun_path[0]) { if (req_temp) free(req); DEBOUT(("No Return Address!\n")); continue; } /* process the request */ process_message(req, &rsp, &rsp_temp); if (rsp == NULL) { if (req_temp) free(req); DEBOUT(("Invalid message!\n")); continue; } DEB(98, ("Sending reply: status %d, len %d\n", rsp->status, rsp->parameter_length)); /* send the response */ len = sizeof(iscsid_response_t) + rsp->parameter_length; ret = sendto(client_sock, rsp, len, 0, (struct sockaddr *)(void *)&from, fromlen); if (len != (size_t)ret) { DEBOUT(("Error sending reply!\n")); } /* free temp buffers if we needed them */ if (req_temp) free(req); if (rsp_temp) free(rsp); } exit_daemon(); /* we never get here */ return 0; }
int main(int argc, char *argv[]) { struct rlimit rlp; struct addrinfo hints, *res; struct event ev_sighup, ev_sigint, ev_sigterm; int ch, error, listenfd, on; const char *errstr; /* Defaults. */ anonymous_only = 0; daemonize = 1; fixed_proxy = NULL; fixed_server = NULL; fixed_server_port = "21"; ipv6_mode = 0; listen_ip = NULL; listen_port = "8021"; loglevel = LOG_NOTICE; max_sessions = 100; qname = NULL; rfc_mode = 0; tagname = NULL; timeout = 24 * 3600; verbose = 0; /* Other initialization. */ id_count = 1; session_count = 0; while ((ch = getopt(argc, argv, "6Aa:b:D:dm:P:p:q:R:rT:t:v")) != -1) { switch (ch) { case '6': ipv6_mode = 1; break; case 'A': anonymous_only = 1; break; case 'a': fixed_proxy = optarg; break; case 'b': listen_ip = optarg; break; case 'D': loglevel = strtonum(optarg, LOG_EMERG, LOG_DEBUG, &errstr); if (errstr) errx(1, "loglevel %s", errstr); break; case 'd': daemonize = 0; break; case 'm': max_sessions = strtonum(optarg, 1, 500, &errstr); if (errstr) errx(1, "max sessions %s", errstr); break; case 'P': fixed_server_port = optarg; break; case 'p': listen_port = optarg; break; case 'q': if (strlen(optarg) >= PF_QNAME_SIZE) errx(1, "queuename too long"); qname = optarg; break; case 'R': fixed_server = optarg; break; case 'r': rfc_mode = 1; break; case 'T': if (strlen(optarg) >= PF_TAG_NAME_SIZE) errx(1, "tagname too long"); tagname = optarg; break; case 't': timeout = strtonum(optarg, 0, 86400, &errstr); if (errstr) errx(1, "timeout %s", errstr); break; case 'v': verbose++; if (verbose > 2) usage(); break; default: usage(); } } if (listen_ip == NULL) listen_ip = ipv6_mode ? "::1" : "127.0.0.1"; /* Check for root to save the user from cryptic failure messages. */ if (getuid() != 0) errx(1, "needs to start as root"); /* Raise max. open files limit to satisfy max. sessions. */ rlp.rlim_cur = rlp.rlim_max = (2 * max_sessions) + 10; if (setrlimit(RLIMIT_NOFILE, &rlp) == -1) err(1, "setrlimit"); if (fixed_proxy) { memset(&hints, 0, sizeof hints); hints.ai_flags = AI_NUMERICHOST; hints.ai_family = ipv6_mode ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(fixed_proxy, NULL, &hints, &res); if (error) errx(1, "getaddrinfo fixed proxy address failed: %s", gai_strerror(error)); memcpy(&fixed_proxy_ss, res->ai_addr, res->ai_addrlen); logmsg(LOG_INFO, "using %s to connect to servers", sock_ntop(sstosa(&fixed_proxy_ss))); freeaddrinfo(res); } if (fixed_server) { memset(&hints, 0, sizeof hints); hints.ai_family = ipv6_mode ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(fixed_server, fixed_server_port, &hints, &res); if (error) errx(1, "getaddrinfo fixed server address failed: %s", gai_strerror(error)); memcpy(&fixed_server_ss, res->ai_addr, res->ai_addrlen); logmsg(LOG_INFO, "using fixed server %s", sock_ntop(sstosa(&fixed_server_ss))); freeaddrinfo(res); } /* Setup listener. */ memset(&hints, 0, sizeof hints); hints.ai_flags = AI_NUMERICHOST | AI_PASSIVE; hints.ai_family = ipv6_mode ? AF_INET6 : AF_INET; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(listen_ip, listen_port, &hints, &res); if (error) errx(1, "getaddrinfo listen address failed: %s", gai_strerror(error)); if ((listenfd = socket(res->ai_family, SOCK_STREAM, IPPROTO_TCP)) == -1) errx(1, "socket failed"); on = 1; if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (void *)&on, sizeof on) != 0) err(1, "setsockopt failed"); if (bind(listenfd, (struct sockaddr *)res->ai_addr, (socklen_t)res->ai_addrlen) != 0) err(1, "bind failed"); if (listen(listenfd, TCP_BACKLOG) != 0) err(1, "listen failed"); freeaddrinfo(res); /* Initialize pf. */ init_filter(qname, tagname, verbose); if (daemonize) { if (daemon(0, 0) == -1) err(1, "cannot daemonize"); openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); } /* Use logmsg for output from here on. */ if (!drop_privs()) { logmsg(LOG_ERR, "cannot drop privileges: %s", strerror(errno)); exit(1); } event_init(); /* Setup signal handler. */ signal(SIGPIPE, SIG_IGN); signal_set(&ev_sighup, SIGHUP, handle_signal, NULL); signal_set(&ev_sigint, SIGINT, handle_signal, NULL); signal_set(&ev_sigterm, SIGTERM, handle_signal, NULL); signal_add(&ev_sighup, NULL); signal_add(&ev_sigint, NULL); signal_add(&ev_sigterm, NULL); event_set(&listen_ev, listenfd, EV_READ, handle_connection, NULL); event_add(&listen_ev, NULL); evtimer_set(&pause_accept_ev, handle_connection, NULL); logmsg(LOG_NOTICE, "listening on %s port %s", listen_ip, listen_port); /* Vroom, vroom. */ event_dispatch(); logmsg(LOG_ERR, "event_dispatch error: %s", strerror(errno)); exit_daemon(); /* NOTREACHED */ return (1); }
/* main server. */ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[]) { bool opt_daemon = false; bool opt_interactive = false; int opt; poptContext pc; #define _MODULE_PROTO(init) extern NTSTATUS init(void); STATIC_service_MODULES_PROTO; init_module_fn static_init[] = { STATIC_service_MODULES }; init_module_fn *shared_init; struct tevent_context *event_ctx; uint16_t stdin_event_flags; NTSTATUS status; const char *model = "standard"; int max_runtime = 0; struct stat st; enum { OPT_DAEMON = 1000, OPT_INTERACTIVE, OPT_PROCESS_MODEL, OPT_SHOW_BUILD }; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_NONE, NULL, OPT_DAEMON, "Become a daemon (default)", NULL }, {"interactive", 'i', POPT_ARG_NONE, NULL, OPT_INTERACTIVE, "Run interactive (not a daemon)", NULL}, {"model", 'M', POPT_ARG_STRING, NULL, OPT_PROCESS_MODEL, "Select process model", "MODEL"}, {"maximum-runtime",0, POPT_ARG_INT, &max_runtime, 0, "set maximum runtime of the server process, till autotermination", "seconds"}, {"show-build", 'b', POPT_ARG_NONE, NULL, OPT_SHOW_BUILD, "show build info", NULL }, POPT_COMMON_SAMBA POPT_COMMON_VERSION { NULL } }; pc = poptGetContext(binary_name, argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch(opt) { case OPT_DAEMON: opt_daemon = true; break; case OPT_INTERACTIVE: opt_interactive = true; break; case OPT_PROCESS_MODEL: model = poptGetOptArg(pc); break; case OPT_SHOW_BUILD: show_build(); break; default: fprintf(stderr, "\nInvalid option %s: %s\n\n", poptBadOption(pc, 0), poptStrerror(opt)); poptPrintUsage(pc, stderr, 0); return 1; } } if (opt_daemon && opt_interactive) { fprintf(stderr,"\nERROR: " "Option -i|--interactive is not allowed together with -D|--daemon\n\n"); poptPrintUsage(pc, stderr, 0); return 1; } else if (!opt_interactive) { /* default is --daemon */ opt_daemon = true; } poptFreeContext(pc); talloc_enable_null_tracking(); setup_logging(binary_name, opt_interactive?DEBUG_STDOUT:DEBUG_FILE); setup_signals(); /* we want total control over the permissions on created files, so set our umask to 0 */ umask(0); DEBUG(0,("%s version %s started.\n", binary_name, SAMBA_VERSION_STRING)); DEBUGADD(0,("Copyright Andrew Tridgell and the Samba Team 1992-2016\n")); if (sizeof(uint16_t) < 2 || sizeof(uint32_t) < 4 || sizeof(uint64_t) < 8) { DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n")); DEBUGADD(0,("sizeof(uint16_t) = %u, sizeof(uint32_t) %u, sizeof(uint64_t) = %u\n", (unsigned int)sizeof(uint16_t), (unsigned int)sizeof(uint32_t), (unsigned int)sizeof(uint64_t))); return 1; } if (opt_daemon) { DEBUG(3,("Becoming a daemon.\n")); become_daemon(true, false, false); } cleanup_tmp_files(cmdline_lp_ctx); if (!directory_exist(lpcfg_lock_directory(cmdline_lp_ctx))) { mkdir(lpcfg_lock_directory(cmdline_lp_ctx), 0755); } pidfile_create(lpcfg_pid_directory(cmdline_lp_ctx), binary_name); if (lpcfg_server_role(cmdline_lp_ctx) == ROLE_ACTIVE_DIRECTORY_DC) { if (!open_schannel_session_store(talloc_autofree_context(), cmdline_lp_ctx)) { exit_daemon("Samba cannot open schannel store for secured NETLOGON operations.", EACCES); } } /* make sure we won't go through nss_winbind */ if (!winbind_off()) { exit_daemon("Samba failed to disable recusive winbindd calls.", EACCES); } gensec_init(); /* FIXME: */ ntptr_init(); /* FIXME: maybe run this in the initialization function of the spoolss RPC server instead? */ ntvfs_init(cmdline_lp_ctx); /* FIXME: maybe run this in the initialization functions of the SMB[,2] server instead? */ process_model_init(cmdline_lp_ctx); shared_init = load_samba_modules(NULL, "service"); run_init_functions(static_init); run_init_functions(shared_init); talloc_free(shared_init); /* the event context is the top level structure in smbd. Everything else should hang off that */ event_ctx = s4_event_context_init(talloc_autofree_context()); if (event_ctx == NULL) { exit_daemon("Initializing event context failed", EACCES); } if (opt_interactive) { /* terminate when stdin goes away */ stdin_event_flags = TEVENT_FD_READ; } else { /* stay alive forever */ stdin_event_flags = 0; } /* catch EOF on stdin */ #ifdef SIGTTIN signal(SIGTTIN, SIG_IGN); #endif if (fstat(0, &st) != 0) { exit_daemon("Samba failed to set standard input handler", ENOTTY); } if (S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode)) { tevent_add_fd(event_ctx, event_ctx, 0, stdin_event_flags, server_stdin_handler, discard_const(binary_name)); } if (max_runtime) { DEBUG(0,("Called with maxruntime %d - current ts %llu\n", max_runtime, (unsigned long long) time(NULL))); tevent_add_timer(event_ctx, event_ctx, timeval_current_ofs(max_runtime, 0), max_runtime_handler, discard_const(binary_name)); } if (lpcfg_server_role(cmdline_lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC && !lpcfg_parm_bool(cmdline_lp_ctx, NULL, "server role check", "inhibit", false) && !str_list_check_ci(lpcfg_server_services(cmdline_lp_ctx), "smb") && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(cmdline_lp_ctx), "remote") && !str_list_check_ci(lpcfg_dcerpc_endpoint_servers(cmdline_lp_ctx), "mapiproxy")) { DEBUG(0, ("At this time the 'samba' binary should only be used for either:\n")); DEBUGADD(0, ("'server role = active directory domain controller' or to access the ntvfs file server with 'server services = +smb' or the rpc proxy with 'dcerpc endpoint servers = remote'\n")); DEBUGADD(0, ("You should start smbd/nmbd/winbindd instead for domain member and standalone file server tasks\n")); exit_daemon("Samba detected misconfigured 'server role' and exited. Check logs for details", EINVAL); }; prime_ldb_databases(event_ctx); status = setup_parent_messaging(event_ctx, cmdline_lp_ctx); if (!NT_STATUS_IS_OK(status)) { exit_daemon("Samba failed to setup parent messaging", NT_STATUS_V(status)); } DEBUG(0,("%s: using '%s' process model\n", binary_name, model)); status = server_service_startup(event_ctx, cmdline_lp_ctx, model, lpcfg_server_services(cmdline_lp_ctx)); if (!NT_STATUS_IS_OK(status)) { exit_daemon("Samba failed to start services", NT_STATUS_V(status)); } if (opt_daemon) { daemon_ready("samba"); } /* wait for events - this is where smbd sits for most of its life */ tevent_loop_wait(event_ctx); /* as everything hangs off this event context, freeing it should initiate a clean shutdown of all services */ talloc_free(event_ctx); return 0; }