diff options
author | Andrew Tridgell <tridge@samba.org> | 2002-07-15 10:35:28 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2002-07-15 10:35:28 +0000 |
commit | e90b65284812aaa5ff9e9935ce9bbad7791cbbcd (patch) | |
tree | 9e744d1dc2f93934a4b49166a37383d3cb2b2139 /source3/auth | |
parent | ec167dc9cc0ec2ee461837c25a371d2981744208 (diff) | |
download | samba-e90b65284812aaa5ff9e9935ce9bbad7791cbbcd.tar.gz samba-e90b65284812aaa5ff9e9935ce9bbad7791cbbcd.tar.bz2 samba-e90b65284812aaa5ff9e9935ce9bbad7791cbbcd.zip |
updated the 3.0 branch from the head branch - ready for alpha18
(This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce)
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, 501 insertions, 232 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c index c7b9fcc1d8..4f7a5c24a0 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -20,9 +20,12 @@ #include "includes.h" -/** List of various built-in authenticaion modules */ +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH -const struct auth_init_function builtin_auth_init_functions[] = { +/** List of various built-in authentication modules */ + +const struct auth_init_function_entry builtin_auth_init_functions[] = { { "guest", auth_init_guest }, { "rhosts", auth_init_rhosts }, { "hostsequiv", auth_init_hostsequiv }, @@ -35,12 +38,14 @@ const struct auth_init_function 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 authenticaion modules. + Try to get a challenge out of the various authentication modules. Returns a const char of length 8 bytes. ****************************************************************************/ @@ -65,7 +70,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: authenticaion method %s has already specified a challenge. Challenge by %s ignored.\n", + DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authentication method %s has already specified a challenge. Challenge by %s ignored.\n", challenge_set_by, auth_method->name)); continue; } @@ -77,7 +82,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 authenticaion method %s FAILED.\n", + DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", auth_method->name)); } else { DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name)); @@ -161,7 +166,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 authenticaion, + * @param server_info If successful, contains information about the authentication, * including a SAM_ACCOUNT struct describing the user. * * @return An NTSTATUS with NT_STATUS_OK or an appropriate error. @@ -254,7 +259,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: %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", + ("check_password: %sauthentication for user [%s] -> [%s] -> [%s] suceeded\n", (*server_info)->guest ? "guest " : "", user_info->smb_name.str, user_info->internal_username.str, @@ -263,7 +268,7 @@ static NTSTATUS check_ntlm_password(const struct auth_context *auth_context, } if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(2, ("check_password: Authenticaion for user [%s] -> [%s] FAILED with error %s\n", + DEBUG(2, ("check_password: Authentication 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); @@ -337,14 +342,31 @@ 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 (builtin_auth_init_functions[i].init(*auth_context, &t)) { + if (NT_STATUS_IS_OK(builtin_auth_init_functions[i].init(*auth_context, module_params, &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; } } @@ -364,7 +386,7 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) char **auth_method_list = NULL; NTSTATUS nt_status; - if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) { + if (lp_auth_methods() && !str_list_copy(&auth_method_list, lp_auth_methods())) { return NT_STATUS_NO_MEMORY; } @@ -373,33 +395,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 = lp_list_make("guest samstrict ntdomain"); + auth_method_list = str_list_make("guest sam ntdomain"); break; case SEC_SERVER: DEBUG(5,("Making default auth method list for security=server\n")); - auth_method_list = lp_list_make("guest samstrict smbserver"); + auth_method_list = str_list_make("guest sam 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 = lp_list_make("guest sam"); + auth_method_list = str_list_make("guest sam"); } else { DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n")); - auth_method_list = lp_list_make("guest unix"); + auth_method_list = str_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 = lp_list_make("guest sam"); + auth_method_list = str_list_make("guest sam"); } else { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n")); - auth_method_list = lp_list_make("guest unix"); + auth_method_list = str_list_make("guest unix"); } break; case SEC_ADS: DEBUG(5,("Making default auth method list for security=ADS\n")); - auth_method_list = lp_list_make("guest samstrict ads ntdomain"); + auth_method_list = str_list_make("guest sam ads ntdomain"); break; default: DEBUG(5,("Unknown auth method!\n")); @@ -410,31 +432,11 @@ 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))) { - lp_list_free(&auth_method_list); + str_list_free(&auth_method_list); return nt_status; } - 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"; - + str_list_free(&auth_method_list); return nt_status; } diff --git a/source3/auth/auth_builtin.c b/source3/auth/auth_builtin.c index 6e999b0d14..5ce7075ab9 100644 --- a/source3/auth/auth_builtin.c +++ b/source3/auth/auth_builtin.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. Generic authenticaion types - Copyright (C) Andrew Bartlett 2001 + Copyright (C) Andrew Bartlett 2001-2002 + Copyright (C) Jelmer Vernooij 2002 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 @@ -20,11 +21,14 @@ #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 delt with in one place. Non-gust logons 'fail' + * guest logons to be dealt with in one place. Non-guest logons 'fail' * and pass onto the next module. **/ @@ -49,14 +53,15 @@ static NTSTATUS check_guest_security(const struct auth_context *auth_context, } /* Guest modules initialisation */ -BOOL auth_init_guest(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *options, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } (*auth_method)->auth = check_guest_security; - return True; + (*auth_method)->name = "guest"; + return NT_STATUS_OK; } /** @@ -99,13 +104,110 @@ static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_ } /** Module initailisation function */ -BOOL auth_init_name_to_ntstatus(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } (*auth_method)->auth = check_name_to_ntstatus_security; - return True; + (*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); } + diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c index 857cf2b7d9..a70f1e98b7 100644 --- a/source3/auth/auth_compat.c +++ b/source3/auth/auth_compat.c @@ -20,6 +20,9 @@ #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 af353ef812..3352c5f9c8 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -21,6 +21,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + BOOL global_machine_password_needs_changing = False; extern pstring global_myname; @@ -66,7 +69,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); + standard_sub_basic(current_user_info.smb_name, remote_machine, sizeof(remote_machine)); strupper(remote_machine); if(!resolve_name( remote_machine, &dest_ip, 0x20)) { @@ -84,21 +87,25 @@ 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 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)); + /* 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)) 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; } @@ -121,12 +128,14 @@ 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; } @@ -138,9 +147,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 result; } + /* We exit here with the mutex *locked*. JRA */ + return NT_STATUS_OK; } @@ -270,14 +282,13 @@ 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, + unsigned char trust_passwd[16], 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 @@ -321,63 +332,15 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, user_info->domain.str, cli->srv_name_slash, nt_errstr(nt_status))); } else { - 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; - } - } - } + 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 - /* 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); } @@ -397,8 +360,6 @@ 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..... */ @@ -406,6 +367,7 @@ 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; } @@ -448,7 +410,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", lp_workgroup())); + DEBUG(0, ("check_ntdomain_security: could not fetch trust account password for domain '%s'\n", domain)); return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -473,14 +435,15 @@ static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context, } /* module initialisation */ -BOOL auth_init_ntdomain(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } + (*auth_method)->name = "ntdomain"; (*auth_method)->auth = check_ntdomain_security; - return True; + return NT_STATUS_OK; } @@ -527,7 +490,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte } /* - * Get the machine account password for the trusted domain + * Get the trusted account password for the trusted domain * No need to become_root() as secrets_init() is done at startup. */ @@ -560,12 +523,13 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte } /* module initialisation */ -BOOL auth_init_trustdomain(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } + (*auth_method)->name = "trustdomain"; (*auth_method)->auth = check_trustdomain_security; - return True; + return NT_STATUS_OK; } diff --git a/source3/auth/auth_rhosts.c b/source3/auth/auth_rhosts.c index 9586d1d65e..4ed0e6bbc4 100644 --- a/source3/auth/auth_rhosts.c +++ b/source3/auth/auth_rhosts.c @@ -20,6 +20,9 @@ #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. @@ -176,14 +179,14 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex } /* module initialisation */ -BOOL auth_init_hostsequiv(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } (*auth_method)->auth = check_hostsequiv_security; - return True; + return NT_STATUS_OK; } @@ -220,12 +223,12 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context, } /* module initialisation */ -BOOL auth_init_rhosts(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } (*auth_method)->auth = check_rhosts_security; - return True; + return NT_STATUS_OK; } diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 6753951c89..76579150ce 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -22,6 +22,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + /**************************************************************************** core of smb password checking routine. ****************************************************************************/ @@ -401,14 +404,15 @@ static NTSTATUS check_sam_security(const struct auth_context *auth_context, } /* module initialisation */ -BOOL auth_init_sam(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } - (*auth_method)->auth = check_sam_security; - return True; + (*auth_method)->auth = check_sam_security; + (*auth_method)->name = "sam"; + return NT_STATUS_OK; } @@ -439,14 +443,15 @@ static NTSTATUS check_samstrict_security(const struct auth_context *auth_context } /* module initialisation */ -BOOL auth_init_samstrict(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_samstrict(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } (*auth_method)->auth = check_samstrict_security; - return True; + (*auth_method)->name = "samstrict"; + return NT_STATUS_OK; } diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index 5190d45c20..23faedc0ba 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -21,6 +21,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + extern pstring global_myname; extern userdom_struct current_user_info; @@ -46,7 +49,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); + standard_sub_basic(current_user_info.smb_name, desthost, sizeof(desthost)); strupper(desthost); if(!resolve_name( desthost, &dest_ip, 0x20)) { @@ -59,6 +62,15 @@ 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; @@ -67,13 +79,19 @@ 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)) + + 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); return NULL; + } if (strequal(desthost,myhostname())) { exit_server("Password server loop!"); @@ -83,19 +101,37 @@ 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 & 1)) { + !(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { DEBUG(1,("%s isn't in user level security mode\n",desthost)); + release_server_mutex(); cli_shutdown(cli); return NULL; } - DEBUG(3,("password server OK\n")); + /* 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; } @@ -142,7 +178,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 & 2) == 0) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 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")); @@ -213,7 +249,7 @@ static NTSTATUS check_smbserver_security(const struct auth_context *auth_context return NT_STATUS_LOGON_FAILURE; } - if ((cli->sec_mode & 2) == 0) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 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; @@ -354,14 +390,15 @@ use this machine as the password server.\n")); return(nt_status); } -BOOL auth_init_smbserver(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } + (*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 True; + return NT_STATUS_OK; } diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c index 05646f554e..6f4b3f8b15 100644 --- a/source3/auth/auth_unix.c +++ b/source3/auth/auth_unix.c @@ -20,12 +20,15 @@ #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(char *user, char *password) +static BOOL update_smbpassword_file(const char *user, const char *password) { SAM_ACCOUNT *sampass = NULL; BOOL ret; @@ -67,8 +70,6 @@ static BOOL update_smbpassword_file(char *user, char *password) DEBUG(3,("pdb_update_sam_account returned %d\n",ret)); } - memset(password, '\0', strlen(password)); - pdb_free_sam(&sampass); return ret; } @@ -118,12 +119,14 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, } /* module initialisation */ -BOOL auth_init_unix(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } + (*auth_method)->name = "unix"; (*auth_method)->auth = check_unix_security; - return True; + return NT_STATUS_OK; } + diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index d80c927c19..3ade220c0f 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -22,6 +22,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + extern fstring remote_machine; extern pstring global_myname; @@ -46,24 +49,6 @@ 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. ****************************************************************************/ @@ -85,16 +70,6 @@ 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); - } } } @@ -165,7 +140,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info, return False; } - DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username)); + DEBUG(5,("making 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); @@ -485,7 +460,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info) Make a user_info struct ***************************************************************************/ -BOOL make_server_info(auth_serversupplied_info **server_info) +static BOOL make_server_info(auth_serversupplied_info **server_info) { *server_info = malloc(sizeof(**server_info)); if (!*server_info) { @@ -591,6 +566,183 @@ 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 ***************************************************************************/ @@ -621,9 +773,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 bc19b36b54..671e198bf5 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -23,6 +23,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + /* Prototypes from common.h */ NSS_STATUS winbindd_request(int req_type, @@ -100,12 +103,13 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, } /* module initialisation */ -BOOL auth_init_winbind(struct auth_context *auth_context, auth_methods **auth_method) +NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method) { if (!make_auth_methods(auth_context, auth_method)) { - return False; + return NT_STATUS_NO_MEMORY; } + (*auth_method)->name = "winbind"; (*auth_method)->auth = check_winbind_security; - return True; + return NT_STATUS_OK; } diff --git a/source3/auth/pampass.c b/source3/auth/pampass.c index 1428e929f1..1a3e55dd44 100644 --- a/source3/auth/pampass.c +++ b/source3/auth/pampass.c @@ -29,6 +29,9 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + #ifdef WITH_PAM /******************************************************************* @@ -183,7 +186,7 @@ static void special_char_sub(char *buf) static void pwd_sub(char *buf, const char *username, const char *oldpass, const char *newpass) { - pstring_sub(buf, "%u", username); + fstring_sub(buf, "%u", username); all_string_sub(buf, "%o", oldpass, sizeof(fstring)); all_string_sub(buf, "%n", newpass, sizeof(fstring)); } @@ -494,7 +497,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, char *user) +static NTSTATUS smb_pam_auth(pam_handle_t *pamh, const char *user) { int pam_error; NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; @@ -579,7 +582,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, char * user) +static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, const char * user) { int pam_error; NTSTATUS nt_status = NT_STATUS_NO_TOKEN; @@ -619,7 +622,7 @@ static NTSTATUS smb_pam_setcred(pam_handle_t *pamh, char * user) /* * PAM Internal Session Handler */ -static BOOL smb_internal_pam_session(pam_handle_t *pamh, char *user, char *tty, BOOL flag) +static BOOL smb_internal_pam_session(pam_handle_t *pamh, const char *user, const char *tty, BOOL flag) { int pam_error; @@ -785,7 +788,7 @@ NTSTATUS smb_pam_accountcheck(const char * user) * PAM Password Validation Suite */ -NTSTATUS smb_pam_passcheck(char * user, char * password) +NTSTATUS smb_pam_passcheck(const char * user, const 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 47c9664a74..63918796ef 100644 --- a/source3/auth/pass_check.c +++ b/source3/auth/pass_check.c @@ -23,6 +23,9 @@ #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) @@ -433,7 +436,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) (char *), +static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const char *), int N) { int len = strlen(s); @@ -467,7 +470,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) (char *), int N) +static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int N) { int n; NTSTATUS nt_status; @@ -481,7 +484,7 @@ static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (char *), int N) /**************************************************************************** core of password checking routine ****************************************************************************/ -static NTSTATUS password_check(char *password) +static NTSTATUS password_check(const char *password) { #ifdef WITH_PAM return smb_pam_passcheck(this_user, password); @@ -588,16 +591,13 @@ 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 *input_pass, char *user, char *password, - int pwlen, BOOL (*fn) (char *, char *), BOOL run_cracker) +NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password, + int pwlen, BOOL (*fn) (const char *, const 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,12 +624,16 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen)); - if (!input_pass) { + if (!pass) { DEBUG(3, ("Couldn't find user %s\n", user)); return NT_STATUS_NO_SUCH_USER; } - pass = make_modifyable_passwd(input_pass); + + /* 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); #ifdef HAVE_GETSPNAM { @@ -642,7 +646,7 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, spass = getspnam(pass->pw_name); if (spass && spass->sp_pwdp) - pstrcpy(pass->pw_passwd, spass->sp_pwdp); + fstrcpy(this_crypted, spass->sp_pwdp); } #elif defined(IA_UINFO) { @@ -660,7 +664,7 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, { struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); if (pr_pw && pr_pw->ufld.fd_encrypt) - pstrcpy(pass->pw_passwd, pr_pw->ufld.fd_encrypt); + fstrcpy(this_crypted, pr_pw->ufld.fd_encrypt); } #endif @@ -669,7 +673,7 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, struct passwd_adjunct *pwret; pwret = getpwanam(s); if (pwret && pwret->pwa_passwd) - pstrcpy(pass->pw_passwd,pwret->pwa_passwd); + fstrcpy(this_crypted, pwret->pwa_passwd); } #endif @@ -680,8 +684,8 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, user)); mypasswd = getprpwnam(user); if (mypasswd) { - fstrcpy(pass->pw_name, mypasswd->ufld.fd_name); - fstrcpy(pass->pw_passwd, mypasswd->ufld.fd_encrypt); + fstrcpy(this_user, mypasswd->ufld.fd_name); + fstrcpy(this_crypted, mypasswd->ufld.fd_encrypt); } else { DEBUG(5, ("OSF1_ENH_SEC: No entry for user %s in protected database !\n", @@ -694,7 +698,7 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, { AUTHORIZATION *ap = getauthuid(pass->pw_uid); if (ap) { - fstrcpy(pass->pw_passwd, ap->a_password); + fstrcpy(this_crypted, ap->a_password); endauthent(); } } @@ -709,27 +713,20 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, 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 */ @@ -752,42 +749,36 @@ NTSTATUS pass_check(const struct passwd *input_pass, char *user, char *password, * 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 */ - StrnCpy(pass2, password, sizeof(pstring) - 1); + pstrcpy(pass2, password); /* try all lowercase if it's currently all uppercase */ - if (strhasupper(password)) { - strlower(password); - if NT_STATUS_IS_OK(nt_status = password_check(password)) { + if (strhasupper(pass2)) { + strlower(pass2); + if NT_STATUS_IS_OK(nt_status = password_check(pass2)) { if (fn) - fn(user, password); + fn(user, pass2); 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(password); + strlower(pass2); - if NT_STATUS_IS_OK(nt_status = string_combinations(password, password_check, level)) { + if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) { if (fn) - fn(user, password); + fn(user, pass2); return nt_status; } - /* restore it */ - fstrcpy(password, pass2); - return NT_STATUS_WRONG_PASSWORD; } |