diff options
Diffstat (limited to 'source3/auth')
-rw-r--r-- | source3/auth/auth.c | 82 | ||||
-rw-r--r-- | source3/auth/auth_builtin.c | 118 | ||||
-rw-r--r-- | source3/auth/auth_compat.c | 3 | ||||
-rw-r--r-- | source3/auth/auth_domain.c | 118 | ||||
-rw-r--r-- | source3/auth/auth_rhosts.c | 15 | ||||
-rw-r--r-- | source3/auth/auth_sam.c | 19 | ||||
-rw-r--r-- | source3/auth/auth_server.c | 57 | ||||
-rw-r--r-- | source3/auth/auth_unix.c | 15 | ||||
-rw-r--r-- | source3/auth/auth_util.c | 218 | ||||
-rw-r--r-- | source3/auth/auth_winbind.c | 10 | ||||
-rw-r--r-- | source3/auth/pampass.c | 13 | ||||
-rw-r--r-- | source3/auth/pass_check.c | 65 |
12 files changed, 232 insertions, 501 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 4f7a5c24a0..c7b9fcc1d8 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -20,12 +20,9 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH +/** List of various built-in authenticaion modules */ -/** List of various built-in authentication modules */ - -const struct auth_init_function_entry builtin_auth_init_functions[] = { +const struct auth_init_function builtin_auth_init_functions[] = { { "guest", auth_init_guest }, { "rhosts", auth_init_rhosts }, { "hostsequiv", auth_init_hostsequiv }, @@ -38,14 +35,12 @@ const struct auth_init_function_entry builtin_auth_init_functions[] = { { "winbind", auth_init_winbind }, #ifdef DEVELOPER { "name_to_ntstatus", auth_init_name_to_ntstatus }, - { "fixed_challenge", auth_init_fixed_challenge }, #endif - { "plugin", auth_init_plugin }, { NULL, NULL} }; /**************************************************************************** - Try to get a challenge out of the various authentication modules. + Try to get a challenge out of the various authenticaion modules. Returns a const char of length 8 bytes. ****************************************************************************/ @@ -70,7 +65,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) DEBUG(5, ("auth_get_challenge: getting challenge from module %s\n", auth_method->name)); if (challenge_set_by != NULL) { - DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authentication method %s has already specified a challenge. Challenge by %s ignored.\n", + DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authenticaion method %s has already specified a challenge. Challenge by %s ignored.\n", challenge_set_by, auth_method->name)); continue; } @@ -82,7 +77,7 @@ static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) challenge = auth_method->get_chal(auth_context, &auth_method->private_data, mem_ctx); if (!challenge.length) { - DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", + DEBUG(3, ("auth_get_challenge: getting challenge from authenticaion method %s FAILED.\n", auth_method->name)); } else { DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name)); @@ -166,7 +161,7 @@ static BOOL check_domain_match(const char *user, const char *domain) * filled in, either at creation or by calling the challenge geneation * function auth_get_challenge(). * - * @param server_info If successful, contains information about the authentication, + * @param server_info If successful, contains information about the authenticaion, * including a SAM_ACCOUNT struct describing the user. * * @return An NTSTATUS with NT_STATUS_OK or an appropriate error. @@ -259,7 +254,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, if (NT_STATUS_IS_OK(nt_status)) { DEBUG((*server_info)->guest ? 5 : 2, - ("check_password: %sauthentication for user [%s] -> [%s] -> [%s] suceeded\n", + ("check_password: %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", (*server_info)->guest ? "guest " : "", user_info->smb_name.str, user_info->internal_username.str, @@ -268,7 +263,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, } if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2, ("check_password: Authentication for user [%s] -> [%s] FAILED with error %s\n", + DEBUG(2, ("check_password: Authenticaion for user [%s] -> [%s] FAILED with error %s\n", user_info->smb_name.str, user_info->internal_username.str, nt_errstr(nt_status))); ZERO_STRUCTP(server_info); @@ -342,31 +337,14 @@ static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, { if (strequal(builtin_auth_init_functions[i].name, *text_list)) { - - char *module_name = smb_xstrdup(*text_list); - char *module_params = NULL; - char *p; - - p = strchr(module_name, ':'); - - if (p) { - *p = 0; - - module_params = p+1; - - trim_string(module_params, " ", " "); - } - - trim_string(module_name, " ", " "); - DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i)); - if (NT_STATUS_IS_OK(builtin_auth_init_functions[i].init(*auth_context, module_params, &t))) { + if (builtin_auth_init_functions[i].init(*auth_context, &t)) { DEBUG(5,("auth method %s has a valid init\n", *text_list)); + t->name = builtin_auth_init_functions[i].name; DLIST_ADD_END(list, t, tmp); } else { DEBUG(0,("auth method %s did not correctly init\n", *text_list)); } - SAFE_FREE(module_name); break; } } @@ -386,7 +364,7 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) char **auth_method_list = NULL; NTSTATUS nt_status; - if (lp_auth_methods() && !str_list_copy(&auth_method_list, lp_auth_methods())) { + if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) { return NT_STATUS_NO_MEMORY; } @@ -395,33 +373,33 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) { case SEC_DOMAIN: DEBUG(5,("Making default auth method list for security=domain\n")); - auth_method_list = str_list_make("guest sam ntdomain"); + auth_method_list = lp_list_make("guest samstrict ntdomain"); break; case SEC_SERVER: DEBUG(5,("Making default auth method list for security=server\n")); - auth_method_list = str_list_make("guest sam smbserver"); + auth_method_list = lp_list_make("guest samstrict smbserver"); break; case SEC_USER: if (lp_encrypted_passwords()) { DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n")); - auth_method_list = str_list_make("guest sam"); + auth_method_list = lp_list_make("guest sam"); } else { DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n")); - auth_method_list = str_list_make("guest unix"); + auth_method_list = lp_list_make("guest unix"); } break; case SEC_SHARE: if (lp_encrypted_passwords()) { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n")); - auth_method_list = str_list_make("guest sam"); + auth_method_list = lp_list_make("guest sam"); } else { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n")); - auth_method_list = str_list_make("guest unix"); + auth_method_list = lp_list_make("guest unix"); } break; case SEC_ADS: DEBUG(5,("Making default auth method list for security=ADS\n")); - auth_method_list = str_list_make("guest sam ads ntdomain"); + auth_method_list = lp_list_make("guest samstrict ads ntdomain"); break; default: DEBUG(5,("Unknown auth method!\n")); @@ -432,11 +410,31 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) } if (!NT_STATUS_IS_OK(nt_status = make_auth_context_text_list(auth_context, auth_method_list))) { - str_list_free(&auth_method_list); + lp_list_free(&auth_method_list); return nt_status; } - str_list_free(&auth_method_list); + lp_list_free(&auth_method_list); + return nt_status; +} + +/*************************************************************************** + Make a auth_info struct with a random challenge +***************************************************************************/ + +NTSTATUS make_auth_context_random(struct auth_context **auth_context) +{ + uchar chal[8]; + NTSTATUS nt_status; + if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) { + return nt_status; + } + + generate_random_buffer(chal, sizeof(chal), False); + (*auth_context)->challenge = data_blob(chal, sizeof(chal)); + + (*auth_context)->challenge_set_by = "random"; + return nt_status; } diff --git a/source3/auth/auth_builtin.c b/source3/auth/auth_builtin.c index 5ce7075ab9..6e999b0d14 100644 --- a/source3/auth/auth_builtin.c +++ b/source3/auth/auth_builtin.c @@ -1,8 +1,7 @@ /* Unix SMB/CIFS implementation. Generic authenticaion types - Copyright (C) Andrew Bartlett 2001-2002 - Copyright (C) Jelmer Vernooij 2002 + Copyright (C) Andrew Bartlett 2001 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,14 +20,11 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /** * Return a guest logon for guest users (username = "") * * Typically used as the first module in the auth chain, this allows - * guest logons to be dealt with in one place. Non-guest logons 'fail' + * guest logons to be delt with in one place. Non-gust logons 'fail' * and pass onto the next module. **/ @@ -53,15 +49,14 @@ static NTSTATUS check_guest_security(const struct auth_context *auth_context, } /* Guest modules initialisation */ -NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *options, auth_methods **auth_method) +BOOL auth_init_guest(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } (*auth_method)->auth = check_guest_security; - (*auth_method)->name = "guest"; - return NT_STATUS_OK; + return True; } /** @@ -104,110 +99,13 @@ static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_ } /** Module initailisation function */ -NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +BOOL auth_init_name_to_ntstatus(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } (*auth_method)->auth = check_name_to_ntstatus_security; - (*auth_method)->name = "name_to_ntstatus"; - return NT_STATUS_OK; -} - -/** - * Return a 'fixed' challenge instead of a varaible one. - * - * The idea of this function is to make packet snifs consistant - * with a fixed challenge, so as to aid debugging. - * - * This module is of no value to end-users. - * - * This module does not actually authenticate the user, but - * just pretenteds to need a specified challenge. - * This module removes *all* security from the challenge-response system - * - * @return NT_STATUS_UNSUCCESSFUL - **/ - -static NTSTATUS check_fixed_challenge_security(const struct auth_context *auth_context, - void *my_private_data, - TALLOC_CTX *mem_ctx, - const auth_usersupplied_info *user_info, - auth_serversupplied_info **server_info) -{ - return NT_STATUS_UNSUCCESSFUL; -} - -/**************************************************************************** - Get the challenge out of a password server. -****************************************************************************/ - -static DATA_BLOB auth_get_fixed_challenge(const struct auth_context *auth_context, - void **my_private_data, - TALLOC_CTX *mem_ctx) -{ - const char *challenge = "I am a teapot"; - return data_blob(challenge, 8); -} - - -/** Module initailisation function */ -NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, const char *param, auth_methods **auth_method) -{ - if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; - } - - (*auth_method)->auth = check_fixed_challenge_security; - (*auth_method)->get_chal = auth_get_fixed_challenge; - (*auth_method)->name = "fixed_challenge"; - return NT_STATUS_OK; -} - -/** - * Outsorce an auth module to an external loadable .so - * - * Only works on systems with dlopen() etc. - **/ - -/* Plugin modules initialisation */ -NTSTATUS auth_init_plugin(struct auth_context *auth_context, const char *param, auth_methods **auth_method) -{ - void * dl_handle; - char *plugin_param, *plugin_name, *p; - auth_init_function plugin_init; - - if (param == NULL) { - DEBUG(0, ("The plugin module needs an argument!\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - plugin_name = smb_xstrdup(param); - p = strchr(plugin_name, ':'); - if (p) { - *p = 0; - plugin_param = p+1; - trim_string(plugin_param, " ", " "); - } else plugin_param = NULL; - - trim_string(plugin_name, " ", " "); - - DEBUG(5, ("Trying to load auth plugin %s\n", plugin_name)); - dl_handle = sys_dlopen(plugin_name, RTLD_NOW | RTLD_GLOBAL ); - if (!dl_handle) { - DEBUG(0, ("Failed to load auth plugin %s using sys_dlopen (%s)\n", plugin_name, sys_dlerror())); - return NT_STATUS_UNSUCCESSFUL; - } - - plugin_init = sys_dlsym(dl_handle, "auth_init"); - if (!plugin_init){ - DEBUG(0, ("Failed to find function 'pdb_init' using sys_dlsym in sam plugin %s (%s)\n", plugin_name, sys_dlerror())); - return NT_STATUS_UNSUCCESSFUL; - } - - DEBUG(5, ("Starting sam plugin %s with paramater %s\n", plugin_name, plugin_param?plugin_param:"(null)")); - return plugin_init(auth_context, plugin_param, auth_method); + return True; } - diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c index a70f1e98b7..857cf2b7d9 100644 --- a/source3/auth/auth_compat.c +++ b/source3/auth/auth_compat.c @@ -20,9 +20,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /**************************************************************************** COMPATIBILITY INTERFACES: ***************************************************************************/ diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 3352c5f9c8..af353ef812 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -21,9 +21,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - BOOL global_machine_password_needs_changing = False; extern pstring global_myname; @@ -69,7 +66,7 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, fstrcpy(remote_machine, server); } - standard_sub_basic(current_user_info.smb_name, remote_machine, sizeof(remote_machine)); + standard_sub_basic(current_user_info.smb_name, remote_machine); strupper(remote_machine); if(!resolve_name( remote_machine, &dest_ip, 0x20)) { @@ -87,25 +84,21 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, logonserver. We can avoid a 30-second timeout if the DC is down if the SAMLOGON request fails as it is only over UDP. */ - /* we use a mutex to prevent two connections at once - when a - Win2k PDC get two connections where one hasn't completed a - session setup yet it will send a TCP reset to the first - connection (tridge) */ - - /* - * With NT4.x DC's *all* authentication must be serialized to avoid - * ACCESS_DENIED errors if 2 auths are done from the same machine. JRA. - */ - - if (!grab_server_mutex(server)) + /* we use a mutex to prevent two connections at once - when a NT PDC gets + two connections where one hasn't completed a negprot yet it will send a + TCP reset to the first connection (tridge) */ + if (!message_named_mutex(server, 20)) { + DEBUG(1,("connect_to_domain_password_server: domain mutex failed for %s\n", server)); return NT_STATUS_UNSUCCESSFUL; + } /* Attempt connection */ result = cli_full_connection(cli, global_myname, server, &dest_ip, 0, "IPC$", "IPC", "", "", "", 0); + message_named_mutex_release(server); + if (!NT_STATUS_IS_OK(result)) { - release_server_mutex(); return result; } @@ -128,14 +121,12 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); cli_nt_session_close(*cli); cli_ulogoff(*cli); cli_shutdown(*cli); - release_server_mutex(); return NT_STATUS_UNSUCCESSFUL; } snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as); if (!(*cli)->mach_acct) { - release_server_mutex(); return NT_STATUS_NO_MEMORY; } @@ -147,12 +138,9 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); cli_nt_session_close(*cli); cli_ulogoff(*cli); cli_shutdown(*cli); - release_server_mutex(); return result; } - /* We exit here with the mutex *locked*. JRA */ - return NT_STATUS_OK; } @@ -282,13 +270,14 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, auth_serversupplied_info **server_info, char *server, char *setup_creds_as, uint16 sec_chan, - unsigned char trust_passwd[16], + unsigned char *trust_passwd, time_t last_change_time) { fstring remote_machine; NET_USER_INFO_3 info3; struct cli_state *cli = NULL; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + struct passwd *pass; /* * At this point, smb_apasswd points to the lanman response to @@ -332,15 +321,63 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, user_info->domain.str, cli->srv_name_slash, nt_errstr(nt_status))); } else { - nt_status = make_server_info_info3(mem_ctx, user_info->internal_username.str, - user_info->smb_name.str, domain, server_info, &info3); -#if 0 - /* The stuff doesn't work right yet */ - SMB_ASSERT(sizeof((*server_info)->session_key) == sizeof(info3.user_sess_key)); - memcpy((*server_info)->session_key, info3.user_sess_key, sizeof((*server_info)->session_key)/* 16 */); - SamOEMhash((*server_info)->session_key, trust_passwd, sizeof((*server_info)->session_key)); -#endif + char *dom_user; + + /* Check DOMAIN\username first to catch winbind users, then + just the username for local users. */ + + dom_user = talloc_asprintf(mem_ctx, "%s%s%s", user_info->domain.str, + lp_winbind_separator(), + user_info->internal_username.str); + + if (!dom_user) { + DEBUG(0, ("talloc_asprintf failed!\n")); + nt_status = NT_STATUS_NO_MEMORY; + } else { + + if (!(pass = Get_Pwnam(dom_user))) + pass = Get_Pwnam(user_info->internal_username.str); + + if (pass) { + make_server_info_pw(server_info, pass); + if (!server_info) { + nt_status = NT_STATUS_NO_MEMORY; + } + } else { + nt_status = NT_STATUS_NO_SUCH_USER; + } + } + } + /* Store the user group information in the server_info returned to the caller. */ + + if (NT_STATUS_IS_OK(nt_status) && (info3.num_groups2 != 0)) { + int i; + NT_USER_TOKEN *ptok; + auth_serversupplied_info *pserver_info = *server_info; + + if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { + DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); + nt_status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + ptok = pserver_info->ptok; + ptok->num_sids = (size_t)info3.num_groups2; + + if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { + DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); + nt_status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + for (i = 0; i < ptok->num_sids; i++) { + sid_copy(&ptok->user_sids[i], &info3.dom_sid.sid); + sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid); + } + uni_group_cache_store_netlogon(mem_ctx, &info3); } @@ -360,6 +397,8 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, } #endif /* 0 */ + done: + /* Note - once the cli stream is shutdown the mem_ctx used to allocate the other_sids and gids structures has been deleted - so these pointers are no longer valid..... */ @@ -367,7 +406,6 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, cli_nt_session_close(cli); cli_ulogoff(cli); cli_shutdown(cli); - release_server_mutex(); return nt_status; } @@ -410,7 +448,7 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time)) { - DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain)); + DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain %s\n", lp_workgroup())); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -435,15 +473,14 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +BOOL auth_init_ntdomain(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->name = "ntdomain"; (*auth_method)->auth = check_ntdomain_security; - return NT_STATUS_OK; + return True; } @@ -490,7 +527,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte } /* - * Get the trusted account password for the trusted domain + * Get the machine account password for the trusted domain * No need to become_root() as secrets_init() is done at startup. */ @@ -523,13 +560,12 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte } /* module initialisation */ -NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +BOOL auth_init_trustdomain(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->name = "trustdomain"; (*auth_method)->auth = check_trustdomain_security; - return NT_STATUS_OK; + return True; } diff --git a/source3/auth/auth_rhosts.c b/source3/auth/auth_rhosts.c index 4ed0e6bbc4..9586d1d65e 100644 --- a/source3/auth/auth_rhosts.c +++ b/source3/auth/auth_rhosts.c @@ -20,9 +20,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /**************************************************************************** Read the a hosts.equiv or .rhosts file and check if it allows this user from this machine. @@ -179,14 +176,14 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex } /* module initialisation */ -NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +BOOL auth_init_hostsequiv(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } (*auth_method)->auth = check_hostsequiv_security; - return NT_STATUS_OK; + return True; } @@ -223,12 +220,12 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +BOOL auth_init_rhosts(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } (*auth_method)->auth = check_rhosts_security; - return NT_STATUS_OK; + return True; } diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 76579150ce..6753951c89 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -22,9 +22,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /**************************************************************************** core of smb password checking routine. ****************************************************************************/ @@ -404,15 +401,14 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +BOOL auth_init_sam(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->auth = check_sam_security; - (*auth_method)->name = "sam"; - return NT_STATUS_OK; + (*auth_method)->auth = check_sam_security; + return True; } @@ -443,15 +439,14 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context } /* module initialisation */ -NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +BOOL auth_init_samstrict(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } (*auth_method)->auth = check_samstrict_security; - (*auth_method)->name = "samstrict"; - return NT_STATUS_OK; + return True; } diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index 23faedc0ba..5190d45c20 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -21,9 +21,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - extern pstring global_myname; extern userdom_struct current_user_info; @@ -49,7 +46,7 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) p = pserver; while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { - standard_sub_basic(current_user_info.smb_name, desthost, sizeof(desthost)); + standard_sub_basic(current_user_info.smb_name, desthost); strupper(desthost); if(!resolve_name( desthost, &dest_ip, 0x20)) { @@ -62,15 +59,6 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) continue; } - /* we use a mutex to prevent two connections at once - when a - Win2k PDC get two connections where one hasn't completed a - session setup yet it will send a TCP reset to the first - connection (tridge) */ - - if (!grab_server_mutex(desthost)) { - return NULL; - } - if (cli_connect(cli, desthost, &dest_ip)) { DEBUG(3,("connected to password server %s\n",desthost)); connected_ok = True; @@ -79,19 +67,13 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) } if (!connected_ok) { - release_server_mutex(); DEBUG(0,("password server not available\n")); cli_shutdown(cli); return NULL; } - - if (!attempt_netbios_session_request(cli, global_myname, - desthost, &dest_ip)) { - release_server_mutex(); - DEBUG(1,("password server fails session request\n")); - cli_shutdown(cli); + + if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip)) return NULL; - } if (strequal(desthost,myhostname())) { exit_server("Password server loop!"); @@ -101,37 +83,19 @@ static struct cli_state *server_cryptkey(TALLOC_CTX *mem_ctx) if (!cli_negprot(cli)) { DEBUG(1,("%s rejected the negprot\n",desthost)); - release_server_mutex(); cli_shutdown(cli); return NULL; } if (cli->protocol < PROTOCOL_LANMAN2 || - !(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { + !(cli->sec_mode & 1)) { DEBUG(1,("%s isn't in user level security mode\n",desthost)); - release_server_mutex(); cli_shutdown(cli); return NULL; } - /* Get the first session setup done quickly, to avoid silly - Win2k bugs. (The next connection to the server will kill - this one... - */ - - if (!cli_session_setup(cli, "", "", 0, "", 0, - "")) { - DEBUG(0,("%s rejected the initial session setup (%s)\n", - desthost, cli_errstr(cli))); - release_server_mutex(); - cli_shutdown(cli); - return NULL; - } - - release_server_mutex(); - DEBUG(3,("password server OK\n")); - + return cli; } @@ -178,7 +142,7 @@ static DATA_BLOB auth_get_challenge_server(const struct auth_context *auth_conte if (cli) { DEBUG(3,("using password server validation\n")); - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { + if ((cli->sec_mode & 2) == 0) { /* We can't work with unencrypted password servers unless 'encrypt passwords = no' */ DEBUG(5,("make_auth_info_server: Server is unencrypted, no challenge available..\n")); @@ -249,7 +213,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context return NT_STATUS_LOGON_FAILURE; } - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { + if ((cli->sec_mode & 2) == 0) { if (user_info->encrypted) { DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost)); return NT_STATUS_LOGON_FAILURE; @@ -390,15 +354,14 @@ use this machine as the password server.\n")); return(nt_status); } -NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +BOOL auth_init_smbserver(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->name = "smbserver"; (*auth_method)->auth = check_smbserver_security; (*auth_method)->get_chal = auth_get_challenge_server; (*auth_method)->send_keepalive = send_server_keepalive; (*auth_method)->free_private_data = free_server_private_data; - return NT_STATUS_OK; + return True; } diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c index 6f4b3f8b15..05646f554e 100644 --- a/source3/auth/auth_unix.c +++ b/source3/auth/auth_unix.c @@ -20,15 +20,12 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /** * update the encrypted smbpasswd file from the plaintext username and password * * this ugly hack needs to die, but not quite yet, I think people still use it... **/ -static BOOL update_smbpassword_file(const char *user, const char *password) +static BOOL update_smbpassword_file(char *user, char *password) { SAM_ACCOUNT *sampass = NULL; BOOL ret; @@ -70,6 +67,8 @@ static BOOL update_smbpassword_file(const char *user, const char *password) DEBUG(3,("pdb_update_sam_account returned %d\n",ret)); } + memset(password, '\0', strlen(password)); + pdb_free_sam(&sampass); return ret; } @@ -119,14 +118,12 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) +BOOL auth_init_unix(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->name = "unix"; (*auth_method)->auth = check_unix_security; - return NT_STATUS_OK; + return True; } - diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 3ade220c0f..d80c927c19 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -22,9 +22,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - extern fstring remote_machine; extern pstring global_myname; @@ -49,6 +46,24 @@ static int smb_create_user(const char *unix_user, const char *homedir) } /**************************************************************************** + Delete a UNIX user on demand. +****************************************************************************/ + +int smb_delete_user(const char *unix_user) +{ + pstring del_script; + int ret; + + pstrcpy(del_script, lp_deluser_script()); + if (! *del_script) + return -1; + all_string_sub(del_script, "%u", unix_user, sizeof(pstring)); + ret = smbrun(del_script,NULL); + DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret)); + return ret; +} + +/**************************************************************************** Add and Delete UNIX users on demand, based on NTSTATUS codes. ****************************************************************************/ @@ -70,6 +85,16 @@ void smb_user_control(const auth_usersupplied_info *user_info, auth_serversuppli smb_create_user(user_info->internal_username.str, NULL); } } + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) { + /* + * User failed to validate ok against Domain controller. + * If the failure was "user doesn't exist" and admin + * wants us to try and delete that UNIX user on the fly, + * do so. + */ + if (lp_deluser_script()) { + smb_delete_user(user_info->internal_username.str); + } } } @@ -140,7 +165,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, return False; } - DEBUG(5,("making blobs for %s's user_info struct\n", internal_username)); + DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username)); (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length); (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length); @@ -460,7 +485,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info) Make a user_info struct ***************************************************************************/ -static BOOL make_server_info(auth_serversupplied_info **server_info) +BOOL make_server_info(auth_serversupplied_info **server_info) { *server_info = malloc(sizeof(**server_info)); if (!*server_info) { @@ -566,183 +591,6 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info) } /*************************************************************************** - Make a server_info struct from the info3 returned by a domain logon -***************************************************************************/ - -NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, - const char *internal_username, - const char *sent_nt_username, - const char *domain, - auth_serversupplied_info **server_info, - NET_USER_INFO_3 *info3) -{ - NTSTATUS nt_status = NT_STATUS_OK; - - const char *nt_domain; - const char *nt_username; - - SAM_ACCOUNT *sam_account = NULL; - DOM_SID user_sid; - DOM_SID group_sid; - - struct passwd *passwd; - - uid_t uid; - gid_t gid; - - /* - Here is where we should check the list of - trusted domains, and verify that the SID - matches. - */ - - sid_copy(&user_sid, &info3->dom_sid.sid); - if (!sid_append_rid(&user_sid, info3->user_rid)) { - return NT_STATUS_INVALID_PARAMETER; - } - - sid_copy(&group_sid, &info3->dom_sid.sid); - if (!sid_append_rid(&group_sid, info3->group_rid)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) { - /* If the server didn't give us one, just use the one we sent them */ - nt_username = sent_nt_username; - } - - if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) { - /* If the server didn't give us one, just use the one we sent them */ - domain = domain; - } - - if (winbind_sid_to_uid(&uid, &user_sid) - && winbind_sid_to_gid(&gid, &group_sid) - && ((passwd = getpwuid_alloc(uid)))) { - nt_status = pdb_init_sam_pw(&sam_account, passwd); - passwd_free(&passwd); - } else { - char *dom_user; - dom_user = talloc_asprintf(mem_ctx, "%s%s%s", - nt_domain, - lp_winbind_separator(), - internal_username); - - if (!dom_user) { - DEBUG(0, ("talloc_asprintf failed!\n")); - return NT_STATUS_NO_MEMORY; - } else { - - if (!(passwd = Get_Pwnam(dom_user)) - /* Only lookup local for the local - domain, we don't want this for - trusted domains */ - && strequal(nt_domain, lp_workgroup())) { - passwd = Get_Pwnam(internal_username); - } - - if (!passwd) { - return NT_STATUS_NO_SUCH_USER; - } else { - nt_status = pdb_init_sam_pw(&sam_account, passwd); - } - } - } - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n")); - return nt_status; - } - - if (!pdb_set_user_sid(sam_account, &user_sid)) { - pdb_free_sam(&sam_account); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!pdb_set_group_sid(sam_account, &group_sid)) { - pdb_free_sam(&sam_account); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!pdb_set_nt_username(sam_account, nt_username)) { - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - if (!pdb_set_domain(sam_account, nt_domain)) { - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - if (!pdb_set_fullname(sam_account, pdb_unistr2_convert(&(info3->uni_full_name)))) { - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - if (!pdb_set_logon_script(sam_account, pdb_unistr2_convert(&(info3->uni_logon_script)), True)) { - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - if (!pdb_set_profile_path(sam_account, pdb_unistr2_convert(&(info3->uni_profile_path)), True)) { - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - if (!pdb_set_homedir(sam_account, pdb_unistr2_convert(&(info3->uni_home_dir)), True)) { - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - if (!pdb_set_dir_drive(sam_account, pdb_unistr2_convert(&(info3->uni_dir_drive)), True)) { - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - if (!make_server_info_sam(server_info, sam_account)) { - DEBUG(0, ("make_server_info_info3: make_server_info_sam failed!\n")); - pdb_free_sam(&sam_account); - return NT_STATUS_NO_MEMORY; - } - - /* Store the user group information in the server_info - returned to the caller. */ - - if (info3->num_groups2 != 0) { - int i; - NT_USER_TOKEN *ptok; - auth_serversupplied_info *pserver_info = *server_info; - - if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { - DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); - nt_status = NT_STATUS_NO_MEMORY; - free_server_info(server_info); - return nt_status; - } - - ptok = pserver_info->ptok; - ptok->num_sids = (size_t)info3->num_groups2; - - if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { - DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); - nt_status = NT_STATUS_NO_MEMORY; - free_server_info(server_info); - return nt_status; - } - - for (i = 0; i < ptok->num_sids; i++) { - sid_copy(&ptok->user_sids[i], &(info3->dom_sid.sid)); - if (!sid_append_rid(&ptok->user_sids[i], info3->gids[i].g_rid)) { - nt_status = NT_STATUS_INVALID_PARAMETER; - free_server_info(server_info); - return nt_status; - } - } - } - return NT_STATUS_OK; -} - -/*************************************************************************** Make an auth_methods struct ***************************************************************************/ @@ -773,9 +621,9 @@ BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_me void delete_nt_token(NT_USER_TOKEN **pptoken) { if (*pptoken) { - NT_USER_TOKEN *ptoken = *pptoken; - SAFE_FREE( ptoken->user_sids ); - ZERO_STRUCTP(ptoken); + NT_USER_TOKEN *ptoken = *pptoken; + SAFE_FREE( ptoken->user_sids ); + ZERO_STRUCTP(ptoken); } SAFE_FREE(*pptoken); } diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c index 671e198bf5..bc19b36b54 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -23,9 +23,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /* Prototypes from common.h */ NSS_STATUS winbindd_request(int req_type, @@ -103,13 +100,12 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, } /* module initialisation */ -NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method) +BOOL auth_init_winbind(struct auth_context *auth_context, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return NT_STATUS_NO_MEMORY; + return False; } - (*auth_method)->name = "winbind"; (*auth_method)->auth = check_winbind_security; - return NT_STATUS_OK; + return True; } diff --git a/source3/auth/pampass.c b/source3/auth/pampass.c index 1a3e55dd44..1428e929f1 100644 --- a/source3/auth/pampass.c +++ b/source3/auth/pampass.c @@ -29,9 +29,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - #ifdef WITH_PAM /******************************************************************* @@ -186,7 +183,7 @@ static void special_char_sub(char *buf) static void pwd_sub(char *buf, const char *username, const char *oldpass, const char *newpass) { - fstring_sub(buf, "%u", username); + pstring_sub(buf, "%u", username); all_string_sub(buf, "%o", oldpass, sizeof(fstring)); all_string_sub(buf, "%n", newpass, sizeof(fstring)); } @@ -497,7 +494,7 @@ static BOOL smb_pam_start(pam_handle_t **pamh, const char *user, const char *rho /* * PAM Authentication Handler */ -static NTSTATUS smb_pam_auth(pam_handle_t *pamh, const char *user) +static NTSTATUS smb_pam_auth(pam_handle_t *pamh, char *user) { int pam_error; NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; @@ -582,7 +579,7 @@ static NTSTATUS smb_pam_account(pam_handle_t *pamh, const char * user) * PAM Credential Setting */ -static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, const char * user) +static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, char * user) { int pam_error; NTSTATUS nt_status = NT_STATUS_NO_TOKEN; @@ -622,7 +619,7 @@ static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, const char * user) /* * PAM Internal Session Handler */ -static BOOL smb_internal_pam_session(pam_handle_t *pamh, const char *user, const char *tty, BOOL flag) +static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag) { int pam_error; @@ -788,7 +785,7 @@ NTSTATUS smb_pam_accountcheck(const char * user) * PAM Password Validation Suite */ -NTSTATUS smb_pam_passcheck(const char * user, const char * password) +NTSTATUS smb_pam_passcheck(char * user, char * password) { pam_handle_t *pamh = NULL; NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; diff --git a/source3/auth/pass_check.c b/source3/auth/pass_check.c index 63918796ef..47c9664a74 100644 --- a/source3/auth/pass_check.c +++ b/source3/auth/pass_check.c @@ -23,9 +23,6 @@ #include "includes.h" -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_AUTH - /* these are kept here to keep the string_combinations function simple */ static fstring this_user; #if !defined(WITH_PAM) @@ -436,7 +433,7 @@ try all combinations with N uppercase letters. offset is the first char to try and change (start with 0) it assumes the string starts lowercased ****************************************************************************/ -static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const char *), +static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (char *), int N) { int len = strlen(s); @@ -470,7 +467,7 @@ try all combinations with up to N uppercase letters. offset is the first char to try and change (start with 0) it assumes the string starts lowercased ****************************************************************************/ -static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int N) +static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (char *), int N) { int n; NTSTATUS nt_status; @@ -484,7 +481,7 @@ static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int /**************************************************************************** core of password checking routine ****************************************************************************/ -static NTSTATUS password_check(const char *password) +static NTSTATUS password_check(char *password) { #ifdef WITH_PAM return smb_pam_passcheck(this_user, password); @@ -591,13 +588,16 @@ match is found and is used to update the encrypted password file return NT_STATUS_OK on correct match, appropriate error otherwise ****************************************************************************/ -NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password, - int pwlen, BOOL (*fn) (const char *, const char *), BOOL run_cracker) +NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, + int pwlen, BOOL (*fn) (char *, char *), BOOL run_cracker) { + struct passwd *pass; pstring pass2; int level = lp_passwordlevel(); NTSTATUS nt_status; + if (password) + password[pwlen] = 0; #if DEBUG_PASSWORD DEBUG(100, ("checking user=[%s] pass=[%s]\n", user, password)); @@ -624,16 +624,12 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen)); - if (!pass) { + if (!input_pass) { DEBUG(3, ("Couldn't find user %s\n", user)); return NT_STATUS_NO_SUCH_USER; } - - /* Copy into global for the convenience of looping code */ - /* Also the place to keep the 'password' no matter what - crazy struct it started in... */ - fstrcpy(this_crypted, pass->pw_passwd); + pass = make_modifyable_passwd(input_pass); #ifdef HAVE_GETSPNAM { @@ -646,7 +642,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas spass = getspnam(pass->pw_name); if (spass && spass->sp_pwdp) - fstrcpy(this_crypted, spass->sp_pwdp); + pstrcpy(pass->pw_passwd, spass->sp_pwdp); } #elif defined(IA_UINFO) { @@ -664,7 +660,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas { struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); if (pr_pw && pr_pw->ufld.fd_encrypt) - fstrcpy(this_crypted, pr_pw->ufld.fd_encrypt); + pstrcpy(pass->pw_passwd, pr_pw->ufld.fd_encrypt); } #endif @@ -673,7 +669,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas struct passwd_adjunct *pwret; pwret = getpwanam(s); if (pwret && pwret->pwa_passwd) - fstrcpy(this_crypted, pwret->pwa_passwd); + pstrcpy(pass->pw_passwd,pwret->pwa_passwd); } #endif @@ -684,8 +680,8 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas user)); mypasswd = getprpwnam(user); if (mypasswd) { - fstrcpy(this_user, mypasswd->ufld.fd_name); - fstrcpy(this_crypted, mypasswd->ufld.fd_encrypt); + fstrcpy(pass->pw_name, mypasswd->ufld.fd_name); + fstrcpy(pass->pw_passwd, mypasswd->ufld.fd_encrypt); } else { DEBUG(5, ("OSF1_ENH_SEC: No entry for user %s in protected database !\n", @@ -698,7 +694,7 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas { AUTHORIZATION *ap = getauthuid(pass->pw_uid); if (ap) { - fstrcpy(this_crypted, ap->a_password); + fstrcpy(pass->pw_passwd, ap->a_password); endauthent(); } } @@ -713,20 +709,27 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas this_salt[2] = 0; #endif + /* Copy into global for the convenience of looping code */ + fstrcpy(this_crypted, pass->pw_passwd); + if (!*this_crypted) { if (!lp_null_passwords()) { DEBUG(2, ("Disallowing %s with null password\n", this_user)); + passwd_free(&pass); return NT_STATUS_LOGON_FAILURE; } if (!*password) { DEBUG(3, ("Allowing access to %s with null password\n", this_user)); + passwd_free(&pass); return NT_STATUS_OK; } } + passwd_free(&pass); + #endif /* defined(WITH_PAM) */ /* try it as it came to us */ @@ -749,36 +752,42 @@ NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *pas * need to proceed as we know it hasn't been case modified by the * client */ if (strhasupper(password) && strhaslower(password)) { + passwd_free(&pass); return nt_status; } /* make a copy of it */ - pstrcpy(pass2, password); + StrnCpy(pass2, password, sizeof(pstring) - 1); /* try all lowercase if it's currently all uppercase */ - if (strhasupper(pass2)) { - strlower(pass2); - if NT_STATUS_IS_OK(nt_status = password_check(pass2)) { + if (strhasupper(password)) { + strlower(password); + if NT_STATUS_IS_OK(nt_status = password_check(password)) { if (fn) - fn(user, pass2); + fn(user, password); return (nt_status); } } /* give up? */ if (level < 1) { + /* restore it */ + fstrcpy(password, pass2); return NT_STATUS_WRONG_PASSWORD; } /* last chance - all combinations of up to level chars upper! */ - strlower(pass2); + strlower(password); - if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) { + if NT_STATUS_IS_OK(nt_status = string_combinations(password, password_check, level)) { if (fn) - fn(user, pass2); + fn(user, password); return nt_status; } + /* restore it */ + fstrcpy(password, pass2); + return NT_STATUS_WRONG_PASSWORD; } |