NTSTATUS make_auth3_context_for_ntlm(TALLOC_CTX *mem_ctx, struct auth_context **auth_context) { const char *methods = NULL; NTSTATUS nt_status; switch (lp_server_role()) { case ROLE_ACTIVE_DIRECTORY_DC: DEBUG(5,("Making default auth method list for server role = " "'active directory domain controller'\n")); return make_auth_context_specific(mem_ctx, auth_context, "samba4"); default: break; } if (lp_auth_methods()) { DEBUG(5,("Using specified auth order\n")); nt_status = make_auth_context_text_list( mem_ctx, auth_context, discard_const_p(char *, lp_auth_methods())); return nt_status; } switch (lp_server_role()) { case ROLE_DOMAIN_MEMBER: DEBUG(5,("Making default auth method list for server role = 'domain member'\n")); methods = "guest sam winbind:ntdomain sam_ignoredomain"; break; case ROLE_DOMAIN_BDC: case ROLE_DOMAIN_PDC: DEBUG(5,("Making default auth method list for DC\n")); methods = "guest sam winbind:trustdomain sam_ignoredomain"; break; case ROLE_STANDALONE: DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = yes\n")); if (lp_encrypt_passwords()) { methods = "guest sam_ignoredomain"; } else { DEBUG(5,("Making default auth method list for server role = 'standalone server', encrypt passwords = no\n")); methods = "guest unix"; } break; default: DEBUG(5,("Unknown auth method!\n")); return NT_STATUS_UNSUCCESSFUL; } return make_auth_context_specific(mem_ctx, auth_context, methods); }
static void reply_lanman1(struct smb_request *req, uint16 choice) { int secword=0; time_t t = time(NULL); struct smbd_server_connection *sconn = req->sconn; uint16_t raw; if (lp_async_smb_echo_handler()) { raw = 0; } else { raw = (lp_read_raw()?1:0) | (lp_write_raw()?2:0); } sconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords(); secword |= NEGOTIATE_SECURITY_USER_LEVEL; if (sconn->smb1.negprot.encrypted_passwords) { secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; } reply_outbuf(req, 13, sconn->smb1.negprot.encrypted_passwords?8:0); SSVAL(req->outbuf,smb_vwv0,choice); SSVAL(req->outbuf,smb_vwv1,secword); /* Create a token value and add it to the outgoing packet. */ if (sconn->smb1.negprot.encrypted_passwords) { get_challenge(sconn, (uint8 *)smb_buf(req->outbuf)); SSVAL(req->outbuf,smb_vwv11, 8); } smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_LANMAN1); /* Reply, SMBlockread, SMBwritelock supported. */ SCVAL(req->outbuf,smb_flg, FLAG_REPLY|FLAG_SUPPORT_LOCKREAD); SSVAL(req->outbuf,smb_vwv2, sconn->smb1.negprot.max_recv); SSVAL(req->outbuf,smb_vwv3, lp_max_mux()); /* maxmux */ SSVAL(req->outbuf,smb_vwv4, 1); SSVAL(req->outbuf,smb_vwv5, raw); /* tell redirector we support readbraw writebraw (possibly) */ SIVAL(req->outbuf,smb_vwv6, getpid()); SSVAL(req->outbuf,smb_vwv10, set_server_zone_offset(t)/60); srv_put_dos_date((char *)req->outbuf,smb_vwv8,t); return; }
static void reply_nt1(struct smb_request *req, uint16 choice) { /* dual names + lock_and_read + nt SMBs + remote API calls */ int capabilities = CAP_NT_FIND|CAP_LOCK_AND_READ| CAP_LEVEL_II_OPLOCKS; int secword=0; bool negotiate_spnego = False; struct timespec ts; ssize_t ret; struct smbd_server_connection *sconn = req->sconn; bool signing_enabled = false; bool signing_required = false; sconn->smb1.negprot.encrypted_passwords = lp_encrypt_passwords(); /* Check the flags field to see if this is Vista. WinXP sets it and Vista does not. But we have to distinguish from NT which doesn't set it either. */ if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) && ((req->flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED) == 0) ) { if (get_remote_arch() != RA_SAMBA) { set_remote_arch( RA_VISTA ); } } reply_outbuf(req,17,0); /* do spnego in user level security if the client supports it and we can do encrypted passwords */ if (sconn->smb1.negprot.encrypted_passwords && lp_use_spnego() && (req->flags2 & FLAGS2_EXTENDED_SECURITY)) { negotiate_spnego = True; capabilities |= CAP_EXTENDED_SECURITY; add_to_common_flags2(FLAGS2_EXTENDED_SECURITY); /* Ensure FLAGS2_EXTENDED_SECURITY gets set in this reply (already partially constructed. */ SSVAL(req->outbuf, smb_flg2, req->flags2 | FLAGS2_EXTENDED_SECURITY); } capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS; if (lp_unicode()) { capabilities |= CAP_UNICODE; } if (lp_unix_extensions()) { capabilities |= CAP_UNIX; } if (lp_large_readwrite()) capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS; capabilities |= CAP_LARGE_FILES; if (!lp_async_smb_echo_handler() && lp_read_raw() && lp_write_raw()) capabilities |= CAP_RAW_MODE; if (lp_nt_status_support()) capabilities |= CAP_STATUS32; if (lp_host_msdfs()) capabilities |= CAP_DFS; secword |= NEGOTIATE_SECURITY_USER_LEVEL; if (sconn->smb1.negprot.encrypted_passwords) { secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE; } signing_enabled = smb_signing_is_allowed(req->sconn->smb1.signing_state); signing_required = smb_signing_is_mandatory(req->sconn->smb1.signing_state); if (signing_enabled) { secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED; /* No raw mode with smb signing. */ capabilities &= ~CAP_RAW_MODE; if (signing_required) { secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; } } SSVAL(req->outbuf,smb_vwv0,choice); SCVAL(req->outbuf,smb_vwv1,secword); smbXsrv_connection_init_tables(req->sconn->conn, PROTOCOL_NT1); SSVAL(req->outbuf,smb_vwv1+1, lp_max_mux()); /* maxmpx */ SSVAL(req->outbuf,smb_vwv2+1, 1); /* num vcs */ SIVAL(req->outbuf,smb_vwv3+1, sconn->smb1.negprot.max_recv); /* max buffer. LOTS! */ SIVAL(req->outbuf,smb_vwv5+1, 0x10000); /* raw size. full 64k */ SIVAL(req->outbuf,smb_vwv7+1, getpid()); /* session key */ SIVAL(req->outbuf,smb_vwv9+1, capabilities); /* capabilities */ clock_gettime(CLOCK_REALTIME,&ts); put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,(char *)req->outbuf+smb_vwv11+1,ts); SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(ts.tv_sec)/60); if (!negotiate_spnego) { /* Create a token value and add it to the outgoing packet. */ if (sconn->smb1.negprot.encrypted_passwords) { uint8 chal[8]; /* note that we do not send a challenge at all if we are using plaintext */ get_challenge(sconn, chal); ret = message_push_blob( &req->outbuf, data_blob_const(chal, sizeof(chal))); if (ret == -1) { DEBUG(0, ("Could not push challenge\n")); reply_nterror(req, NT_STATUS_NO_MEMORY); return; } SCVAL(req->outbuf, smb_vwv16+1, ret); } ret = message_push_string(&req->outbuf, lp_workgroup(), STR_UNICODE|STR_TERMINATE |STR_NOALIGN); if (ret == -1) { DEBUG(0, ("Could not push workgroup string\n")); reply_nterror(req, NT_STATUS_NO_MEMORY); return; } ret = message_push_string(&req->outbuf, lp_netbios_name(), STR_UNICODE|STR_TERMINATE |STR_NOALIGN); if (ret == -1) { DEBUG(0, ("Could not push netbios name string\n")); reply_nterror(req, NT_STATUS_NO_MEMORY); return; } DEBUG(3,("not using SPNEGO\n")); } else { DATA_BLOB spnego_blob = negprot_spnego(req, req->sconn); if (spnego_blob.data == NULL) { reply_nterror(req, NT_STATUS_NO_MEMORY); return; } ret = message_push_blob(&req->outbuf, spnego_blob); if (ret == -1) { DEBUG(0, ("Could not push spnego blob\n")); reply_nterror(req, NT_STATUS_NO_MEMORY); return; } data_blob_free(&spnego_blob); SCVAL(req->outbuf,smb_vwv16+1, 0); DEBUG(3,("using SPNEGO\n")); } return; }
static int do_global_checks(void) { int ret = 0; SMB_STRUCT_STAT st; const char *socket_options; if (lp_security() >= SEC_DOMAIN && !lp_encrypt_passwords()) { fprintf(stderr, "ERROR: in 'security=domain' mode the " "'encrypt passwords' parameter must always be " "set to 'true'.\n\n"); ret = 1; } if (lp_we_are_a_wins_server() && lp_wins_server_list()) { fprintf(stderr, "ERROR: both 'wins support = true' and " "'wins server = <server list>' cannot be set in " "the smb.conf file. nmbd will abort with this " "setting.\n\n"); ret = 1; } if (strequal(lp_workgroup(), lp_netbios_name())) { fprintf(stderr, "WARNING: 'workgroup' and 'netbios name' " "must differ.\n\n"); } if (!directory_exist_stat(lp_lock_directory(), &st)) { fprintf(stderr, "ERROR: lock directory %s does not exist\n\n", lp_lock_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: lock directory %s should have " "permissions 0755 for browsing to work\n\n", lp_lock_directory()); } if (!directory_exist_stat(lp_state_directory(), &st)) { fprintf(stderr, "ERROR: state directory %s does not exist\n\n", lp_state_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: state directory %s should have " "permissions 0755 for browsing to work\n\n", lp_state_directory()); } if (!directory_exist_stat(lp_cache_directory(), &st)) { fprintf(stderr, "ERROR: cache directory %s does not exist\n\n", lp_cache_directory()); ret = 1; } else if ((st.st_ex_mode & 0777) != 0755) { fprintf(stderr, "WARNING: cache directory %s should have " "permissions 0755 for browsing to work\n\n", lp_cache_directory()); } if (!directory_exist_stat(lp_pid_directory(), &st)) { fprintf(stderr, "ERROR: pid directory %s does not exist\n\n", lp_pid_directory()); ret = 1; } if (lp_passdb_expand_explicit()) { fprintf(stderr, "WARNING: passdb expand explicit = yes is " "deprecated\n\n"); } /* * Socket options. */ socket_options = lp_socket_options(); if (socket_options != NULL && (strstr(socket_options, "SO_SNDBUF") || strstr(socket_options, "SO_RCVBUF") || strstr(socket_options, "SO_SNDLOWAT") || strstr(socket_options, "SO_RCVLOWAT"))) { fprintf(stderr, "WARNING: socket options = %s\n" "This warning is printed because you set one of the\n" "following options: SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT,\n" "SO_RCVLOWAT\n" "Modern server operating systems are tuned for\n" "high network performance in the majority of situations;\n" "when you set 'socket options' you are overriding those\n" "settings.\n" "Linux in particular has an auto-tuning mechanism for\n" "buffer sizes (SO_SNDBUF, SO_RCVBUF) that will be\n" "disabled if you specify a socket buffer size. This can\n" "potentially cripple your TCP/IP stack.\n\n" "Getting the 'socket options' correct can make a big\n" "difference to your performance, but getting them wrong\n" "can degrade it by just as much. As with any other low\n" "level setting, if you must make changes to it, make\n " "small changes and test the effect before making any\n" "large changes.\n\n", socket_options); } /* * Password server sanity checks. */ if((lp_security() >= SEC_DOMAIN) && !*lp_password_server()) { const char *sec_setting; if(lp_security() == SEC_DOMAIN) sec_setting = "domain"; else if(lp_security() == SEC_ADS) sec_setting = "ads"; else sec_setting = ""; fprintf(stderr, "ERROR: The setting 'security=%s' requires the " "'password server' parameter be set to the " "default value * or a valid password server.\n\n", sec_setting ); ret = 1; } if((lp_security() >= SEC_DOMAIN) && (strcmp(lp_password_server(), "*") != 0)) { const char *sec_setting; if(lp_security() == SEC_DOMAIN) sec_setting = "domain"; else if(lp_security() == SEC_ADS) sec_setting = "ads"; else sec_setting = ""; fprintf(stderr, "WARNING: The setting 'security=%s' should NOT " "be combined with the 'password server' " "parameter.\n" "(by default Samba will discover the correct DC " "to contact automatically).\n\n", sec_setting ); } /* * Password chat sanity checks. */ if(lp_security() == SEC_USER && lp_unix_password_sync()) { /* * Check that we have a valid lp_passwd_program() if not using pam. */ #ifdef WITH_PAM if (!lp_pam_password_change()) { #endif if((lp_passwd_program(talloc_tos()) == NULL) || (strlen(lp_passwd_program(talloc_tos())) == 0)) { fprintf(stderr, "ERROR: the 'unix password sync' " "parameter is set and there is no valid " "'passwd program' parameter.\n\n"); ret = 1; } else { const char *passwd_prog; char *truncated_prog = NULL; const char *p; passwd_prog = lp_passwd_program(talloc_tos()); p = passwd_prog; next_token_talloc(talloc_tos(), &p, &truncated_prog, NULL); if (truncated_prog && access(truncated_prog, F_OK) == -1) { fprintf(stderr, "ERROR: the 'unix password sync' " "parameter is set and the " "'passwd program' (%s) cannot be " "executed (error was %s).\n\n", truncated_prog, strerror(errno)); ret = 1; } } #ifdef WITH_PAM } #endif if(lp_passwd_chat(talloc_tos()) == NULL) { fprintf(stderr, "ERROR: the 'unix password sync' parameter is " "set and there is no valid 'passwd chat' " "parameter.\n\n"); ret = 1; } if ((lp_passwd_program(talloc_tos()) != NULL) && (strlen(lp_passwd_program(talloc_tos())) > 0)) { /* check if there's a %u parameter present */ if(strstr_m(lp_passwd_program(talloc_tos()), "%u") == NULL) { fprintf(stderr, "ERROR: the 'passwd program' (%s) " "requires a '%%u' parameter.\n\n", lp_passwd_program(talloc_tos())); ret = 1; } } /* * Check that we have a valid script and that it hasn't * been written to expect the old password. */ if(lp_encrypt_passwords()) { if(strstr_m( lp_passwd_chat(talloc_tos()), "%o")!=NULL) { fprintf(stderr, "ERROR: the 'passwd chat' script [%s] " "expects to use the old plaintext " "password via the %%o substitution. With " "encrypted passwords this is not " "possible.\n\n", lp_passwd_chat(talloc_tos()) ); ret = 1; } } } if (strlen(lp_winbind_separator()) != 1) { fprintf(stderr, "ERROR: the 'winbind separator' parameter must " "be a single character.\n\n"); ret = 1; } if (*lp_winbind_separator() == '+') { fprintf(stderr, "'winbind separator = +' might cause problems " "with group membership.\n\n"); } if (lp_algorithmic_rid_base() < BASE_RID) { /* Try to prevent admin foot-shooting, we can't put algorithmic rids below 1000, that's the 'well known RIDs' on NT */ fprintf(stderr, "'algorithmic rid base' must be equal to or " "above %lu\n\n", BASE_RID); } if (lp_algorithmic_rid_base() & 1) { fprintf(stderr, "'algorithmic rid base' must be even.\n\n"); } #ifndef HAVE_DLOPEN if (lp_preload_modules()) { fprintf(stderr, "WARNING: 'preload modules = ' set while loading " "plugins not supported.\n\n"); } #endif if (!lp_passdb_backend()) { fprintf(stderr, "ERROR: passdb backend must have a value or be " "left out\n\n"); } if (lp_os_level() > 255) { fprintf(stderr, "WARNING: Maximum value for 'os level' is " "255!\n\n"); } if (strequal(lp_dos_charset(), "UTF8") || strequal(lp_dos_charset(), "UTF-8")) { fprintf(stderr, "ERROR: 'dos charset' must not be UTF8\n\n"); ret = 1; } return ret; }