static BOOL reload_nmbd_services(BOOL test) { BOOL ret; set_remote_machine_name("nmbd", False); if ( lp_loaded() ) { pstring fname; pstrcpy( fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,dyn_CONFIGFILE)) { pstrcpy(dyn_CONFIGFILE,fname); test = False; } } if ( test && !lp_file_list_changed() ) return(True); ret = lp_load( dyn_CONFIGFILE, True , False, False, True); /* perhaps the config filename is now set */ if ( !test ) { DEBUG( 3, ( "services not loaded\n" ) ); reload_nmbd_services( True ); } return(ret); }
static bool reload_nmbd_services(bool test) { bool ret; set_remote_machine_name("nmbd", False); if ( lp_loaded() ) { const char *fname = lp_configfile(); if (file_exist(fname) && !strcsequal(fname,get_dyn_CONFIGFILE())) { set_dyn_CONFIGFILE(fname); test = False; } } if ( test && !lp_file_list_changed() ) return(True); ret = lp_load_global(get_dyn_CONFIGFILE()); /* perhaps the config filename is now set */ if ( !test ) { DEBUG( 3, ( "services not loaded\n" ) ); reload_nmbd_services( True ); } return(ret); }
static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) { AUTH_NTLMSSP_STATE *auth_ntlmssp_state = (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context; struct auth_usersupplied_info *user_info = NULL; NTSTATUS nt_status; bool username_was_mapped; /* the client has given us its machine name (which we otherwise would not get on port 445). we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->workstation, True); /* setup the string used by %U */ /* sub_set_smb_name checks for weird internally */ sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user); reload_services(True); nt_status = make_user_info_map(&user_info, auth_ntlmssp_state->ntlmssp_state->user, auth_ntlmssp_state->ntlmssp_state->domain, auth_ntlmssp_state->ntlmssp_state->workstation, auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL, auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL, NULL, NULL, NULL, True); user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT; if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, user_info, &auth_ntlmssp_state->server_info); username_was_mapped = user_info->was_mapped; free_user_info(&user_info); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } auth_ntlmssp_state->server_info->nss_token |= username_was_mapped; nt_status = create_local_token(auth_ntlmssp_state->server_info); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(10, ("create_local_token failed: %s\n", nt_errstr(nt_status))); return nt_status; } if (auth_ntlmssp_state->server_info->user_session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length)); *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, auth_ntlmssp_state->server_info->user_session_key.data, auth_ntlmssp_state->server_info->user_session_key.length); } if (auth_ntlmssp_state->server_info->lm_session_key.length) { DEBUG(10, ("Got LM session key of length %u\n", (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length)); *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, auth_ntlmssp_state->server_info->lm_session_key.data, auth_ntlmssp_state->server_info->lm_session_key.length); } return nt_status; }
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_COMMON_DYNCONFIG POPT_TABLEEND }; struct smbd_parent_context *parent = NULL; TALLOC_CTX *frame; NTSTATUS status; uint64_t unique_id; struct tevent_context *ev_ctx; struct messaging_context *msg_ctx; /* * Do this before any other talloc operation */ talloc_enable_null_tracking(); frame = talloc_stackframe(); setup_logging(argv[0], DEBUG_DEFAULT_STDOUT); load_case_tables(); 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()); /* 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) < 2 || sizeof(uint32) < 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); } /* 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, -1, False)) { exit(1); } /* ...NOTE... Log files are working from this point! */ DEBUG(3,("loaded services\n")); init_structs(); #ifdef WITH_PROFILE if (!profile_setup(msg_ctx, False)) { DEBUG(0,("ERROR: failed to setup profiling\n")); return -1; } if (profile_level != NULL) { int pl = atoi(profile_level); struct server_id src; DEBUG(1, ("setting profiling level: %s\n",profile_level)); src.pid = getpid(); set_profile_level(pl, src); } #endif if (!is_daemon && !is_a_socket(0)) { if (!interactive) DEBUG(0,("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); } generate_random_buffer((uint8_t *)&unique_id, sizeof(unique_id)); set_my_unique_id(unique_id); #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_lockdir())) mkdir(lp_lockdir(), 0755); if (is_daemon) pidfile_create("smbd"); status = reinit_after_fork(msg_ctx, ev_ctx, procid_self(), false); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("reinit_after_fork() failed\n")); exit(1); } smbd_server_conn->msg_ctx = msg_ctx; smbd_setup_sig_term_handler(); smbd_setup_sig_hup_handler(ev_ctx, msg_ctx); /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */ if (smbd_memcache() == NULL) { exit(1); } 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()) { DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n")); exit(1); } if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) { struct loadparm_context *lp_ctx = loadparm_init_s3(NULL, loadparm_s3_context()); if (!open_schannel_session_store(NULL, lp_ctx)) { DEBUG(0,("ERROR: Samba cannot open schannel store for secured NETLOGON operations.\n")); exit(1); } TALLOC_FREE(lp_ctx); } if(!get_global_sam_sid()) { DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n")); exit(1); } if (!sessionid_init()) { exit(1); } if (!connections_init(True)) exit(1); if (!locking_init()) exit(1); if (!messaging_tdb_parent_init(ev_ctx)) { exit(1); } if (!notify_internal_parent_init(ev_ctx)) { exit(1); } if (!serverid_parent_init(ev_ctx)) { exit(1); } if (!W_ERROR_IS_OK(registry_init_full())) exit(1); /* 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()) { DEBUG(0,("ERROR: failed to load share info db.\n")); exit(1); } status = init_system_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(smbd_server_conn)) { DEBUG(0, ("ERROR: file_init failed\n")); return -1; } /* 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(), geteuid(), 0755)) { DEBUG(0, ("Failed to create pipe directory %s - %s\n", lp_ncalrpc_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(1); } /* 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 (!_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(1); } } } 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) { /* 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 */ smbd_server_conn->sock = dup(0); /* close our standard file descriptors */ if (!debug_get_output_is_stdout()) { close_low_fds(False); /* Don't close stderr */ } #ifdef HAVE_ATEXIT atexit(killkids); #endif /* Stop zombies */ smbd_setup_sig_chld_handler(ev_ctx); smbd_process(ev_ctx, smbd_server_conn); exit_server_cleanly(NULL); return(0); } parent = talloc_zero(ev_ctx, struct smbd_parent_context); if (!parent) { exit_server("talloc(struct smbd_parent_context) failed"); } parent->interactive = interactive; 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 */ printing_subsystem_update(ev_ctx, msg_ctx, false); TALLOC_FREE(frame); /* make sure we always have a valid stackframe */ frame = talloc_stackframe(); smbd_parent_loop(ev_ctx, parent); exit_server_cleanly(NULL); TALLOC_FREE(frame); return(0); }
static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key) { AUTH_NTLMSSP_STATE *auth_ntlmssp_state = ntlmssp_state->auth_context; uint32 auth_flags = AUTH_FLAG_NONE; auth_usersupplied_info *user_info = NULL; DATA_BLOB plaintext_password = data_blob(NULL, 0); NTSTATUS nt_status; if (auth_ntlmssp_state->ntlmssp_state->lm_resp.length) { auth_flags |= AUTH_FLAG_LM_RESP; } if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length == 24) { auth_flags |= AUTH_FLAG_NTLM_RESP; } else if (auth_ntlmssp_state->ntlmssp_state->nt_resp.length > 24) { auth_flags |= AUTH_FLAG_NTLMv2_RESP; } /* the client has given us its machine name (which we otherwise would not get on port 445). we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->workstation, True); /* setup the string used by %U */ /* sub_set_smb_name checks for weird internally */ sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user); reload_services(True); nt_status = make_user_info_map(&user_info, auth_ntlmssp_state->ntlmssp_state->user, auth_ntlmssp_state->ntlmssp_state->domain, auth_ntlmssp_state->ntlmssp_state->workstation, auth_ntlmssp_state->ntlmssp_state->lm_resp, auth_ntlmssp_state->ntlmssp_state->nt_resp, plaintext_password, auth_flags, True); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, user_info, &auth_ntlmssp_state->server_info); free_user_info(&user_info); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } if (auth_ntlmssp_state->server_info->nt_session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", auth_ntlmssp_state->server_info->nt_session_key.length)); *nt_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, auth_ntlmssp_state->server_info->nt_session_key.data, auth_ntlmssp_state->server_info->nt_session_key.length); } if (auth_ntlmssp_state->server_info->lm_session_key.length) { DEBUG(10, ("Got LM session key of length %u\n", auth_ntlmssp_state->server_info->lm_session_key.length)); *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx, auth_ntlmssp_state->server_info->lm_session_key.data, auth_ntlmssp_state->server_info->lm_session_key.length); } return nt_status; }
NTSTATUS auth3_check_password(struct auth4_context *auth4_context, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, void **server_returned_info, DATA_BLOB *session_key, DATA_BLOB *lm_session_key) { struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data, struct auth_context); struct auth_usersupplied_info *mapped_user_info = NULL; struct auth_serversupplied_info *server_info; NTSTATUS nt_status; bool username_was_mapped; /* The client has given us its machine name (which we only get over NBT transport). We need to possibly reload smb.conf if smb.conf includes depend on the machine name. */ set_remote_machine_name(user_info->workstation_name, True); /* setup the string used by %U */ /* sub_set_smb_name checks for weird internally */ sub_set_smb_name(user_info->client.account_name); lp_load_with_shares(get_dyn_CONFIGFILE()); nt_status = make_user_info_map(talloc_tos(), &mapped_user_info, user_info->client.account_name, user_info->client.domain_name, user_info->workstation_name, user_info->remote_host, user_info->password.response.lanman.data ? &user_info->password.response.lanman : NULL, user_info->password.response.nt.data ? &user_info->password.response.nt : NULL, NULL, NULL, NULL, AUTH_PASSWORD_RESPONSE); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } mapped_user_info->logon_parameters = user_info->logon_parameters; mapped_user_info->flags = user_info->flags; nt_status = auth_check_ntlm_password(mem_ctx, auth_context, mapped_user_info, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(5,("Checking NTLMSSP password for %s\\%s failed: %s\n", user_info->client.domain_name, user_info->client.account_name, nt_errstr(nt_status))); } username_was_mapped = mapped_user_info->was_mapped; TALLOC_FREE(mapped_user_info); if (!NT_STATUS_IS_OK(nt_status)) { nt_status = do_map_to_guest_server_info(mem_ctx, nt_status, user_info->client.account_name, user_info->client.domain_name, &server_info); *server_returned_info = talloc_steal(mem_ctx, server_info); return nt_status; } server_info->nss_token |= username_was_mapped; /* Clear out the session keys, and pass them to the caller. * They will not be used in this form again - instead the * NTLMSSP code will decide on the final correct session key, * and supply it to create_local_token() */ if (session_key) { DEBUG(10, ("Got NT session key of length %u\n", (unsigned int)server_info->session_key.length)); *session_key = server_info->session_key; talloc_steal(mem_ctx, server_info->session_key.data); server_info->session_key = data_blob_null; } if (lm_session_key) { DEBUG(10, ("Got LM session key of length %u\n", (unsigned int)server_info->lm_session_key.length)); *lm_session_key = server_info->lm_session_key; talloc_steal(mem_ctx, server_info->lm_session_key.data); server_info->lm_session_key = data_blob_null; } *server_returned_info = talloc_steal(mem_ctx, server_info); return nt_status; }
int main(int argc, char **argv) { pstring logfile; static BOOL interactive = False; static BOOL Fork = True; static BOOL log_stdout = False; struct poptOption long_options[] = { POPT_AUTOHELP { "stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "Log to stdout" }, { "foreground", 'F', POPT_ARG_VAL, &Fork, False, "Daemon in foreground mode" }, { "interactive", 'i', POPT_ARG_NONE, NULL, 'i', "Interactive mode" }, { "single-daemon", 'Y', POPT_ARG_VAL, &opt_dual_daemon, False, "Single daemon mode" }, { "no-caching", 'n', POPT_ARG_VAL, &opt_nocache, True, "Disable caching" }, POPT_COMMON_SAMBA POPT_TABLEEND }; poptContext pc; int opt; /* glibc (?) likes to print "User defined signal 1" and exit if a SIGUSR[12] is received before a handler is installed */ CatchSignal(SIGUSR1, SIG_IGN); CatchSignal(SIGUSR2, SIG_IGN); fault_setup((void (*)(void *))fault_quit ); /* Initialise for running in non-root mode */ sec_init(); set_remote_machine_name("winbindd", False); /* Set environment variable so we don't recursively call ourselves. This may also be useful interactively. */ setenv(WINBINDD_DONT_ENV, "1", 1); /* Initialise samba/rpc client stuff */ pc = poptGetContext("winbindd", argc, (const char **)argv, long_options, POPT_CONTEXT_KEEP_FIRST); while ((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { /* Don't become a daemon */ case 'i': interactive = True; log_stdout = True; Fork = False; break; } } if (log_stdout && Fork) { printf("Can't log to stdout (-S) unless daemon is in foreground +(-F) or interactive (-i)\n"); poptPrintUsage(pc, stderr, 0); exit(1); } pstr_sprintf(logfile, "%s/log.winbindd", dyn_LOGFILEBASE); lp_set_logfile(logfile); setup_logging("winbindd", log_stdout); reopen_logs(); DEBUG(1, ("winbindd version %s started.\n", SAMBA_VERSION_STRING) ); DEBUGADD( 1, ( "Copyright The Samba Team 2000-2004\n" ) ); if (!reload_services_file()) { DEBUG(0, ("error opening config file\n")); exit(1); } /* Setup names. */ if (!init_names()) exit(1); load_interfaces(); if (!secrets_init()) { DEBUG(0,("Could not initialize domain trust account secrets. Giving up\n")); return False; } /* Enable netbios namecache */ namecache_enable(); /* Check winbindd parameters are valid */ ZERO_STRUCT(server_state); /* Winbind daemon initialisation */ if ( (!winbindd_param_init()) || (!winbindd_upgrade_idmap()) || (!idmap_init(lp_idmap_backend())) ) { DEBUG(1, ("Could not init idmap -- netlogon proxy only\n")); idmap_proxyonly(); } generate_wellknown_sids(); /* Unblock all signals we are interested in as they may have been blocked by the parent process. */ BlockSignals(False, SIGINT); BlockSignals(False, SIGQUIT); BlockSignals(False, SIGTERM); BlockSignals(False, SIGUSR1); BlockSignals(False, SIGUSR2); BlockSignals(False, SIGHUP); BlockSignals(False, SIGCHLD); /* Setup signal handlers */ CatchSignal(SIGINT, termination_handler); /* Exit on these sigs */ CatchSignal(SIGQUIT, termination_handler); CatchSignal(SIGTERM, termination_handler); CatchSignal(SIGCHLD, sigchld_handler); CatchSignal(SIGPIPE, SIG_IGN); /* Ignore sigpipe */ CatchSignal(SIGUSR2, sigusr2_handler); /* Debugging sigs */ CatchSignal(SIGHUP, sighup_handler); if (!interactive) become_daemon(Fork); pidfile_create("winbindd"); #if HAVE_SETPGID /* * If we're interactive we want to set our own process group for * signal management. */ if (interactive) setpgid( (pid_t)0, (pid_t)0); #endif if (opt_dual_daemon) { do_dual_daemon(); } /* Initialise messaging system */ if (!message_init()) { DEBUG(0, ("unable to initialise messaging system\n")); exit(1); } /* React on 'smbcontrol winbindd reload-config' in the same way as to SIGHUP signal */ message_register(MSG_SMB_CONF_UPDATED, msg_reload_services); message_register(MSG_SHUTDOWN, msg_shutdown); poptFreeContext(pc); netsamlogon_cache_init(); /* Non-critical */ init_domain_list(); /* Loop waiting for requests */ process_loop(); trustdom_cache_shutdown(); return 0; }
static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx, DATA_BLOB *session_key, DATA_BLOB *lm_session_key) { struct gensec_ntlmssp_context *gensec_ntlmssp = (struct gensec_ntlmssp_context *)ntlmssp_state->callback_private; struct auth_usersupplied_info *user_info = NULL; NTSTATUS nt_status; bool username_was_mapped; /* the client has given us its machine name (which we otherwise would not get on port 445). we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ set_remote_machine_name(gensec_ntlmssp->ntlmssp_state->client.netbios_name, True); /* setup the string used by %U */ /* sub_set_smb_name checks for weird internally */ sub_set_smb_name(gensec_ntlmssp->ntlmssp_state->user); lp_load(get_dyn_CONFIGFILE(), false, false, true, true); nt_status = make_user_info_map(&user_info, gensec_ntlmssp->ntlmssp_state->user, gensec_ntlmssp->ntlmssp_state->domain, gensec_ntlmssp->ntlmssp_state->client.netbios_name, gensec_get_remote_address(gensec_ntlmssp->gensec_security), gensec_ntlmssp->ntlmssp_state->lm_resp.data ? &gensec_ntlmssp->ntlmssp_state->lm_resp : NULL, gensec_ntlmssp->ntlmssp_state->nt_resp.data ? &gensec_ntlmssp->ntlmssp_state->nt_resp : NULL, NULL, NULL, NULL, AUTH_PASSWORD_RESPONSE); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT; nt_status = gensec_ntlmssp->auth_context->check_ntlm_password(gensec_ntlmssp->auth_context, user_info, &gensec_ntlmssp->server_info); username_was_mapped = user_info->was_mapped; free_user_info(&user_info); if (!NT_STATUS_IS_OK(nt_status)) { nt_status = do_map_to_guest_server_info(nt_status, &gensec_ntlmssp->server_info, gensec_ntlmssp->ntlmssp_state->user, gensec_ntlmssp->ntlmssp_state->domain); return nt_status; } if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } gensec_ntlmssp->server_info->nss_token |= username_was_mapped; /* Clear out the session keys, and pass them to the caller. * They will not be used in this form again - instead the * NTLMSSP code will decide on the final correct session key, * and supply it to create_local_token() */ if (gensec_ntlmssp->server_info->session_key.length) { DEBUG(10, ("Got NT session key of length %u\n", (unsigned int)gensec_ntlmssp->server_info->session_key.length)); *session_key = gensec_ntlmssp->server_info->session_key; talloc_steal(mem_ctx, gensec_ntlmssp->server_info->session_key.data); gensec_ntlmssp->server_info->session_key = data_blob_null; } if (gensec_ntlmssp->server_info->lm_session_key.length) { DEBUG(10, ("Got LM session key of length %u\n", (unsigned int)gensec_ntlmssp->server_info->lm_session_key.length)); *lm_session_key = gensec_ntlmssp->server_info->lm_session_key; talloc_steal(mem_ctx, gensec_ntlmssp->server_info->lm_session_key.data); gensec_ntlmssp->server_info->lm_session_key = data_blob_null; } return nt_status; }
int main2(int argc,const char *argv[]) { /* shall I run as a daemon */ static BOOL is_daemon = False; static BOOL interactive = False; static BOOL Fork = True; static BOOL no_process_group = False; static BOOL log_stdout = False; static char *ports = NULL; int opt; #ifndef _XBOX poptContext pc; struct poptOption long_options[] = { POPT_AUTOHELP {"daemon", 'D', POPT_ARG_VAL, &is_daemon, True, "Become a daemon (default)" }, {"interactive", 'i', POPT_ARG_VAL, &interactive, True, "Run interactive (not a daemon)"}, {"foreground", 'F', POPT_ARG_VAL, &Fork, False, "Run daemon in foreground (for daemontools, etc.)" }, {"no-process-group", '\0', POPT_ARG_VAL, &no_process_group, True, "Don't create a new process group" }, {"log-stdout", 'S', POPT_ARG_VAL, &log_stdout, True, "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"}, POPT_COMMON_SAMBA POPT_COMMON_DYNCONFIG POPT_TABLEEND }; #else interactive = True; log_stdout = True; #endif load_case_tables(); #ifdef HAVE_SET_AUTH_PARAMETERS set_auth_parameters(argc,argv); #endif #ifndef _XBOX pc = poptGetContext("smbd", argc, argv, long_options, 0); while((opt = poptGetNextOpt(pc)) != -1) { switch (opt) { case 'b': build_options(True); /* Display output to screen as well as debug */ exit(0); break; } } poptFreeContext(pc); #endif #ifdef HAVE_SETLUID /* needed for SecureWare on SCO */ setluid(0); #endif sec_init(); set_remote_machine_name("smbd", False); if (interactive) { Fork = False; log_stdout = True; } 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); } setup_logging(argv[0],log_stdout); /* we want to re-seed early to prevent time delays causing client problems at a later date. (tridge) */ generate_random_buffer(NULL, 0); /* 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(); #ifndef _XBOX fault_setup((void (*)(void *))exit_server_fault); dump_core_setup("smbd"); #endif CatchSignal(SIGTERM , SIGNAL_CAST sig_term); #ifndef _XBOX CatchSignal(SIGHUP,SIGNAL_CAST sig_hup); /* we are never interested in SIGPIPE */ BlockSignals(True,SIGPIPE); #endif #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. */ #ifndef _XBOX BlockSignals(False, SIGHUP); #endif BlockSignals(False, SIGUSR1); BlockSignals(False, SIGTERM); /* we want total control over the permissions on created files, so set our umask to 0 */ umask(0); init_sec_ctx(); 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) < 2 || sizeof(uint32) < 4) { DEBUG(0,("ERROR: Samba is not configured correctly for the word size on your machine\n")); exit(1); } /* * Do this before reload_services. */ if (!reload_services(False)) return(-1); init_structs(); #ifdef WITH_PROFILE if (!profile_setup(False)) { DEBUG(0,("ERROR: failed to setup profiling\n")); return -1; } #endif DEBUG(3,( "loaded services\n")); if (!is_daemon && !is_a_socket(0)) { if (!interactive) DEBUG(0,("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); } #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_lockdir(), NULL)) mkdir(lp_lockdir(), 0755); #ifndef _XBOX if (is_daemon) pidfile_create("smbd"); #endif /* Setup all the TDB's - including CLEAR_IF_FIRST tdb's. */ if (!message_init()) exit(1); /* Initialize our global sam sid first -- quite a lot of the other * initialization routines further down depend on it. */ /* 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)) exit(1); /* Fail gracefully if we can't open secrets.tdb */ if (!secrets_init()) { DEBUG(0, ("ERROR: smbd can not open secrets.tdb\n")); exit(1); } if(!get_global_sam_sid()) { DEBUG(0,("ERROR: Samba cannot create a SAM SID.\n")); exit(1); } if (!session_init()) exit(1); if (conn_tdb_ctx() == NULL) exit(1); if (!locking_init(0)) exit(1); namecache_enable(); if (!init_registry()) exit(1); #if 0 if (!init_svcctl_db()) exit(1); #endif #ifndef _XBOX if (!print_backend_init()) exit(1); #endif if (!init_guest_info()) { DEBUG(0,("ERROR: failed to setup guest info.\n")); return -1; } /* Setup the main smbd so that we can get messages. */ /* don't worry about general printing messages here */ claim_connection(NULL,"",0,True,FLAG_MSG_GENERAL|FLAG_MSG_SMBD); /* only start the background queue daemon 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 */ #ifndef _XBOX if ( is_daemon && !interactive ) start_background_queue(); #endif /* Always attempt to initialize DMAPI. We will only use it later if * lp_dmapi_support is set on the share, but we need a single global * session to work with. */ dmapi_init_session(); if (!open_sockets_smbd(is_daemon, interactive, ports)) exit(1); /* * everything after this point is run after the fork() */ static_init_rpc; init_modules(); /* possibly reload the services file. */ reload_services(True); if (!init_account_policy()) { DEBUG(0,("Could not open account policy tdb.\n")); exit(1); } if (*lp_rootdir()) { if (sys_chroot(lp_rootdir()) == 0) DEBUG(2,("Changed root to %s\n", lp_rootdir())); } /* Setup oplocks */ if (!init_oplocks()) exit(1); /* Setup change notify */ if (!init_change_notify()) exit(1); /* Setup aio signal handler. */ initialize_async_io_handler(); /* re-initialise the timezone */ TimeInit(); /* register our message handlers */ message_register(MSG_SMB_FORCE_TDIS, msg_force_tdis); smbd_process(); #ifdef _XBOX xb_DecClientCount(); #endif namecache_shutdown(); exit_server_cleanly(NULL); return(0); }
static BOOL open_sockets_smbd(BOOL is_daemon, BOOL interactive, const char *smb_ports) { int num_interfaces = iface_count(); int num_sockets = 0; int fd_listenset[FD_SETSIZE]; fd_set listen_set; int s; int maxfd = 0; int i; char *ports; if (!is_daemon) { return open_sockets_inetd(); } #ifdef HAVE_ATEXIT { static int atexit_set; if(atexit_set == 0) { atexit_set=1; atexit(killkids); } } #endif #ifndef _XBOX /* Stop zombies */ CatchChild(); #endif FD_ZERO(&listen_set); /* use a reasonable default set of ports - listing on 445 and 139 */ if (!smb_ports) { ports = lp_smb_ports(); if (!ports || !*ports) { ports = smb_xstrdup(SMB_PORTS); } else { ports = smb_xstrdup(ports); } } else { ports = smb_xstrdup(smb_ports); } if (lp_interfaces() && lp_bind_interfaces_only()) { /* We have been given an interfaces line, and been told to only bind to those interfaces. Create a socket per interface and bind to only these. */ /* Now open a listen socket for each of the interfaces. */ for(i = 0; i < num_interfaces; i++) { struct in_addr *ifip = iface_n_ip(i); fstring tok; const char *ptr; if(ifip == NULL) { DEBUG(0,("open_sockets_smbd: interface %d has NULL IP address !\n", i)); continue; } for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { unsigned port = atoi(tok); if (port == 0) { continue; } s = fd_listenset[num_sockets] = open_socket_in(SOCK_STREAM, port, 0, ifip->s_addr, True); if(s == -1) return False; /* ready to listen */ set_socket_options(s,"SO_KEEPALIVE"); set_socket_options(s,user_socket_options); /* Set server socket to non-blocking for the accept. */ set_blocking(s,False); if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("listen: %s\n",strerror(errno))); close(s); return False; } FD_SET(s,&listen_set); maxfd = MAX( maxfd, s); num_sockets++; if (num_sockets >= FD_SETSIZE) { DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n")); return False; } } } } else { /* Just bind to 0.0.0.0 - accept connections from anywhere. */ fstring tok; const char *ptr; num_interfaces = 1; for (ptr=ports; next_token(&ptr, tok, " \t,", sizeof(tok)); ) { unsigned port = atoi(tok); if (port == 0) continue; /* open an incoming socket */ s = open_socket_in(SOCK_STREAM, port, 0, interpret_addr(lp_socket_address()),True); if (s == -1) return(False); /* ready to listen */ #ifndef _XBOX set_socket_options(s,"SO_KEEPALIVE"); #endif set_socket_options(s,user_socket_options); /* Set server socket to non-blocking for the accept. */ set_blocking(s,False); if (listen(s, SMBD_LISTEN_BACKLOG) == -1) { DEBUG(0,("open_sockets_smbd: listen: %s\n", strerror(errno))); close(s); return False; } fd_listenset[num_sockets] = s; FD_SET(s,&listen_set); maxfd = MAX( maxfd, s); num_sockets++; if (num_sockets >= FD_SETSIZE) { DEBUG(0,("open_sockets_smbd: Too many sockets to bind to\n")); return False; } } } SAFE_FREE(ports); /* Listen to messages */ message_register(MSG_SMB_SAM_SYNC, msg_sam_sync); message_register(MSG_SMB_SAM_REPL, msg_sam_repl); message_register(MSG_SHUTDOWN, msg_exit_server); message_register(MSG_SMB_FILE_RENAME, msg_file_was_renamed); message_register(MSG_SMB_CONF_UPDATED, smb_conf_updated); #ifdef DEVELOPER message_register(MSG_SMB_INJECT_FAULT, msg_inject_fault); #endif /* now accept incoming connections - forking a new process for each incoming connection */ DEBUG(2,("waiting for a connection\n")); while (1) { fd_set lfds; int num; /* Free up temporary memory from the main smbd. */ lp_TALLOC_FREE(); /* Ensure we respond to PING and DEBUG messages from the main smbd. */ message_dispatch(); memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set)); num = sys_select(maxfd+1,&lfds,NULL,NULL,NULL); if (num == -1 && errno == EINTR) { if (got_sig_term) { exit_server_cleanly(NULL); } /* check for sighup processing */ if (reload_after_sighup) { change_to_root_user(); DEBUG(1,("Reloading services after SIGHUP\n")); reload_services(False); reload_after_sighup = 0; } continue; } /* check if we need to reload services */ check_reload(time(NULL)); /* Find the sockets that are read-ready - accept on these. */ for( ; num > 0; num--) { struct sockaddr addr; socklen_t in_addrlen = sizeof(addr); s = -1; for(i = 0; i < num_sockets; i++) { if(FD_ISSET(fd_listenset[i],&lfds)) { s = fd_listenset[i]; /* Clear this so we don't look at it again. */ FD_CLR(fd_listenset[i],&lfds); break; } } smbd_set_server_fd(accept(s,&addr,&in_addrlen)); if (smbd_server_fd() == -1 && errno == EINTR) continue; if (smbd_server_fd() == -1) { DEBUG(0,("open_sockets_smbd: accept: %s\n", strerror(errno))); continue; } /* Ensure child is set to blocking mode */ set_blocking(smbd_server_fd(),True); if (smbd_server_fd() != -1 && interactive) { #ifdef _XBOX xb_IncClientCount(); #endif return True; } if (allowable_number_of_smbd_processes() && smbd_server_fd() != -1 && sys_fork()==0) { /* Child code ... */ /* close the listening socket(s) */ for(i = 0; i < num_sockets; i++) close(fd_listenset[i]); /* close our standard file descriptors */ close_low_fds(False); am_parent = 0; set_socket_options(smbd_server_fd(),"SO_KEEPALIVE"); set_socket_options(smbd_server_fd(),user_socket_options); /* this is needed so that we get decent entries in smbstatus for port 445 connects */ set_remote_machine_name(get_peer_addr(smbd_server_fd()), False); /* Reset the state of the random * number generation system, so * children do not get the same random * numbers as each other */ set_need_random_reseed(); /* tdb needs special fork handling - remove CLEAR_IF_FIRST flags */ if (tdb_reopen_all(1) == -1) { DEBUG(0,("tdb_reopen_all failed.\n")); smb_panic("tdb_reopen_all failed."); } return True; } /* The parent doesn't need this socket */ close(smbd_server_fd()); /* Sun May 6 18:56:14 2001 [email protected]: Clear the closed fd info out of server_fd -- and more importantly, out of client_fd in util_sock.c, to avoid a possible getpeername failure if we reopen the logs and use %I in the filename. */ smbd_set_server_fd(-1); /* Force parent to check log size after * spawning child. Fix from * [email protected]. The * parent smbd will log to logserver.smb. It * writes only two messages for each child * started/finished. But each child writes, * say, 50 messages also in logserver.smb, * begining with the debug_count of the * parent, before the child opens its own log * file logserver.client. In a worst case * scenario the size of logserver.smb would be * checked after about 50*50=2500 messages * (ca. 100kb). * */ force_check_log_size(); } /* end for num */ } /* end while 1 */ /* NOTREACHED return True; */ }