summaryrefslogtreecommitdiff
path: root/source3/auth
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2002-07-15 10:35:28 +0000
committerAndrew Tridgell <tridge@samba.org>2002-07-15 10:35:28 +0000
commite90b65284812aaa5ff9e9935ce9bbad7791cbbcd (patch)
tree9e744d1dc2f93934a4b49166a37383d3cb2b2139 /source3/auth
parentec167dc9cc0ec2ee461837c25a371d2981744208 (diff)
downloadsamba-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.c82
-rw-r--r--source3/auth/auth_builtin.c118
-rw-r--r--source3/auth/auth_compat.c3
-rw-r--r--source3/auth/auth_domain.c118
-rw-r--r--source3/auth/auth_rhosts.c15
-rw-r--r--source3/auth/auth_sam.c19
-rw-r--r--source3/auth/auth_server.c57
-rw-r--r--source3/auth/auth_unix.c15
-rw-r--r--source3/auth/auth_util.c218
-rw-r--r--source3/auth/auth_winbind.c10
-rw-r--r--source3/auth/pampass.c13
-rw-r--r--source3/auth/pass_check.c65
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;
}