summaryrefslogtreecommitdiff
path: root/source3/auth
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2001-11-24 12:12:38 +0000
committerAndrew Bartlett <abartlet@samba.org>2001-11-24 12:12:38 +0000
commitd0a2faf78d316fec200497f5f7997df4c477a1e1 (patch)
treea1d9f9f837b2c88e6154fb5ee6214cbcebc97ad4 /source3/auth
parentaf1a0238aa106a43006902e8ef593d7853913b0e (diff)
downloadsamba-d0a2faf78d316fec200497f5f7997df4c477a1e1.tar.gz
samba-d0a2faf78d316fec200497f5f7997df4c477a1e1.tar.bz2
samba-d0a2faf78d316fec200497f5f7997df4c477a1e1.zip
This is another rather major change to the samba authenticaion
subystem. The particular aim is to modularized the interface - so that we can have arbitrary password back-ends. This code adds one such back-end, a 'winbind' module to authenticate against the winbind_auth_crap functionality. While fully-functional this code is mainly useful as a demonstration, because we don't get back the info3 as we would for direct ntdomain authentication. This commit introduced the new 'auth methods' parameter, in the spirit of the 'auth order' discussed on the lists. It is renamed because not all the methods may be consulted, even if previous methods fail - they may not have a suitable challenge for example. Also, we have a 'local' authentication method, for old-style 'unix if plaintext, sam if encrypted' authentication and a 'guest' module to handle guest logins in a single place. While this current design is not ideal, I feel that it does provide a better infrastructure than the current design, and can be built upon. The following parameters have changed: - use rhosts = This has been replaced by the 'rhosts' authentication method, and can be specified like 'auth methods = guest rhosts' - hosts equiv = This needs both this parameter and an 'auth methods' entry to be effective. (auth methods = guest hostsequiv ....) - plaintext to smbpasswd = This is replaced by specifying 'sam' rather than 'local' in the auth methods. The security = parameter is unchanged, and now provides defaults for the 'auth methods' parameter. The available auth methods are: guest rhosts hostsequiv sam (passdb direct hash access) unix (PAM, crypt() etc) local (the combination of the above, based on encryption) smbserver (old security=server) ntdomain (old security=domain) winbind (use winbind to cache DC connections) Assistance in testing, or the production of new and interesting authentication modules is always appreciated. Andrew Bartlett (This used to be commit 8d31eae52a9757739711dbb82035a4dfe6b40c99)
Diffstat (limited to 'source3/auth')
-rw-r--r--source3/auth/auth.c165
-rw-r--r--source3/auth/auth_builtin.c87
-rw-r--r--source3/auth/auth_domain.c18
-rw-r--r--source3/auth/auth_info.c279
-rw-r--r--source3/auth/auth_rhosts.c72
-rw-r--r--source3/auth/auth_sam.c75
-rw-r--r--source3/auth/auth_server.c172
-rw-r--r--source3/auth/auth_unix.c15
-rw-r--r--source3/auth/auth_util.c208
9 files changed, 799 insertions, 292 deletions
diff --git a/source3/auth/auth.c b/source3/auth/auth.c
index 95c97182b8..c62e2ed5a0 100644
--- a/source3/auth/auth.c
+++ b/source3/auth/auth.c
@@ -58,27 +58,50 @@ static BOOL check_domain_match(char *user, char *domain)
****************************************************************************/
NTSTATUS check_password(const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
- BOOL done_pam = False;
const char *pdb_username;
+ auth_methods *auth_method;
+
+ if (!user_info || !auth_info || !server_info) {
+ return NT_STATUS_LOGON_FAILURE;
+ }
DEBUG(3, ("check_password: Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n",
user_info->client_domain.str, user_info->smb_name.str, user_info->wksta_name.str));
DEBUG(3, ("check_password: mapped user is: [%s]\\[%s]@[%s]\n",
user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str));
-
- if (!NT_STATUS_IS_OK(nt_status)) {
- nt_status = check_guest_security(user_info, server_info);
+ DEBUG(10, ("auth_info challange created by %s\n", auth_info->challange_set_by));
+ DEBUG(10, ("challange is: \n"));
+ dump_data(5, (auth_info)->challange.data, (auth_info)->challange.length);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100, ("user_info has passwords of length %d and %d\n",
+ user_info->lm_resp.length, user_info->nt_resp.length));
+ DEBUG(100, ("lm:\n"));
+ dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
+ DEBUG(100, ("nt:\n"));
+ dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length);
+#endif
+
+ for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next)
+ {
+ nt_status = auth_method->auth(auth_method->private_data, user_info, auth_info, server_info);
if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5, ("check_password: checking guest-account for user [%s] suceeded\n", user_info->smb_name.str));
+ DEBUG(3, ("check_password: %s authentication for user [%s] suceeded\n",
+ auth_method->name, user_info->smb_name.str));
} else {
- DEBUG(10, ("check_password: checking gusst-account for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-
- }
+ DEBUG(5, ("check_password: %s authentication for user [%s] FAILED with error %s\n",
+ auth_method->name, user_info->smb_name.str, get_nt_error_msg(nt_status)));
+ }
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ break;
+ }
}
/* This needs to be sorted: If it doesn't match, what should we do? */
@@ -86,83 +109,47 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
return NT_STATUS_LOGON_FAILURE;
}
- if (!NT_STATUS_IS_OK(nt_status)) {
- nt_status = check_rhosts_security(user_info, server_info);
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(3, ("check_password: Password (rhosts) for user [%s] suceeded\n", user_info->smb_name.str));
- } else {
- DEBUG(10, ("check_password: Password (rhosts) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-
- }
- }
-
- if ((lp_security() == SEC_DOMAIN) && !NT_STATUS_IS_OK(nt_status)) {
- nt_status = check_domain_security(user_info, server_info);
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(7, ("check_password: Password (domain) for user [%s] suceeded\n", user_info->smb_name.str));
- } else {
- DEBUG(5, ("check_password: Password (domain) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-
- }
- }
-
- if ((lp_security() == SEC_SERVER) && !NT_STATUS_IS_OK(nt_status)) {
- nt_status = check_server_security(user_info, server_info);
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(7, ("check_password: Password (server) for user [%s] suceeded\n", user_info->smb_name.str));
- } else {
- DEBUG(5, ("check_password: Password (server) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-
- }
- }
+ /* This is one of the few places the *relies* (rather than just sets defaults
+ on the value of lp_security(). This needs to change. A new paramater
+ perhaps? */
if (lp_security() >= SEC_SERVER) {
smb_user_control(user_info, *server_info, nt_status);
}
- if (!NT_STATUS_IS_OK(nt_status)) {
- if (user_info->encrypted || lp_plaintext_to_smbpasswd()) {
- nt_status = check_smbpasswd_security(user_info, server_info);
- } else {
- nt_status = check_unix_security(user_info, server_info);
- done_pam = True;
- }
-
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(7, ("check_password: Password (unix/smbpasswd) for user [%s] suceeded\n", user_info->smb_name.str));
- } else {
- DEBUG(5, ("check_password: Password (unix/smbpasswd) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-
- }
- }
-
if (NT_STATUS_IS_OK(nt_status)) {
pdb_username = pdb_get_username((*server_info)->sam_account);
- if (!done_pam && !(*server_info)->guest) {
+ if (!(*server_info)->guest) {
/* We might not be root if we are an RPC call */
become_root();
nt_status = smb_pam_accountcheck(pdb_username);
unbecome_root();
if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(5, ("check_password: PAM Account for user [%s] suceeded\n", pdb_username));
+ DEBUG(5, ("check_password: PAM Account for user [%s] suceeded\n",
+ pdb_username));
} else {
- DEBUG(3, ("check_password: PAM Account for user [%s] FAILED with error %s\n", pdb_username, get_nt_error_msg(nt_status)));
+ DEBUG(3, ("check_password: PAM Account for user [%s] FAILED with error %s\n",
+ pdb_username, get_nt_error_msg(nt_status)));
}
}
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ DEBUG((*server_info)->guest ? 5 : 2,
+ ("check_password: %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n",
+ (*server_info)->guest ? "guest " : "",
+ user_info->smb_name.str,
+ user_info->internal_username.str,
+ pdb_username));
+ }
}
- if (NT_STATUS_IS_OK(nt_status)) {
- DEBUG(3, ("check_password: %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n",
- (*server_info)->guest ? "guest " : "",
- user_info->smb_name.str,
- user_info->internal_username.str,
- pdb_username));
- } else {
- DEBUG(3, ("check_password: Authenticaion for user [%s] -> [%s] FAILED with error %s\n", user_info->smb_name.str, user_info->internal_username.str, get_nt_error_msg(nt_status)));
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(2, ("check_password: Authenticaion for user [%s] -> [%s] FAILED with error %s\n",
+ user_info->smb_name.str, user_info->internal_username.str,
+ get_nt_error_msg(nt_status)));
ZERO_STRUCTP(server_info);
- }
-
+ }
return nt_status;
}
@@ -210,16 +197,35 @@ static NTSTATUS pass_check_smb(char *smb_name,
{
NTSTATUS nt_status;
auth_usersupplied_info *user_info = NULL;
+ extern auth_authsupplied_info *negprot_global_auth_info;
auth_serversupplied_info *server_info = NULL;
+ if (encrypted) {
+ make_user_info_for_reply_enc(&user_info, smb_name,
+ domain,
+ lm_pwd,
+ nt_pwd,
+ plaintext_password);
+ nt_status = check_password(user_info, negprot_global_auth_info, &server_info);
+ } else {
+ auth_authsupplied_info *plaintext_auth_info = NULL;
+ DATA_BLOB chal;
+ if (!make_auth_info_subsystem(&plaintext_auth_info)) {
+ return NT_STATUS_NO_MEMORY;
+ }
- make_user_info_for_reply(&user_info, smb_name,
- domain,
- lm_pwd,
- nt_pwd,
- plaintext_password,
- encrypted);
-
- nt_status = check_password(user_info, &server_info);
+ chal = auth_get_challange(plaintext_auth_info);
+
+ if (!make_user_info_for_reply(&user_info,
+ smb_name, domain, chal.data,
+ plaintext_password)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nt_status = check_password(user_info, plaintext_auth_info, &server_info);
+
+ data_blob_free(&chal);
+ free_auth_info(&plaintext_auth_info);
+ }
free_user_info(&user_info);
free_server_info(&server_info);
return nt_status;
@@ -235,22 +241,23 @@ BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
DATA_BLOB null_password = data_blob(NULL, 0);
extern BOOL global_encrypted_passwords_negotiated;
-
- if (global_encrypted_passwords_negotiated) {
+ BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
+
+ if (encrypted) {
/*
* The password could be either NTLM or plain LM. Try NTLM first,
* but fall-through as required.
* NTLMv2 makes no sense here.
*/
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, global_encrypted_passwords_negotiated))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
return True;
}
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, global_encrypted_passwords_negotiated))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
return True;
}
} else {
- if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, global_encrypted_passwords_negotiated))) {
+ if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
return True;
}
}
diff --git a/source3/auth/auth_builtin.c b/source3/auth/auth_builtin.c
new file mode 100644
index 0000000000..6ea6d0bbe0
--- /dev/null
+++ b/source3/auth/auth_builtin.c
@@ -0,0 +1,87 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0.
+ Generic authenticaion types
+ Copyright (C) Andrew Bartlett 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+ Check for a guest logon (username = "") and if so create the required
+ structure.
+****************************************************************************/
+
+static NTSTATUS check_guest_security(void *my_private_data,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
+{
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+
+ if (!(user_info->internal_username.str
+ && *user_info->internal_username.str)) {
+ if (make_server_info_guest(server_info)) {
+ nt_status = NT_STATUS_OK;
+ } else {
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ }
+ }
+
+ return nt_status;
+}
+
+BOOL auth_init_guest(auth_methods **auth_method)
+{
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+
+ (*auth_method)->auth = check_guest_security;
+ return True;
+}
+
+/****************************************************************************
+ Check against either sam or unix, depending on encryption.
+****************************************************************************/
+
+static NTSTATUS check_local_security(void *my_private_data,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
+{
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+
+ if (user_info->encrypted) {
+ nt_status = check_sam_security(my_private_data, user_info, auth_info, server_info);
+ } else {
+ nt_status = check_unix_security(my_private_data, user_info, auth_info, server_info);
+ }
+
+ return nt_status;
+}
+
+BOOL auth_init_local(auth_methods **auth_method)
+{
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+
+ (*auth_method)->auth = check_local_security;
+ return True;
+}
+
diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c
index 4ada7d4a56..ef0e5b2f10 100644
--- a/source3/auth/auth_domain.c
+++ b/source3/auth/auth_domain.c
@@ -28,8 +28,10 @@ BOOL global_machine_password_needs_changing = False;
Check for a valid username and password in security=domain mode.
****************************************************************************/
-NTSTATUS check_domain_security(const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+static NTSTATUS check_ntdomain_security(void *my_private_data,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
char *p, *pserver;
@@ -66,8 +68,18 @@ NTSTATUS check_domain_security(const auth_usersupplied_info *user_info,
if (! *pserver) pserver = "*";
p = pserver;
- nt_status = domain_client_validate(user_info, server_info,
+ nt_status = domain_client_validate(user_info, (uchar *)auth_info->challange.data,server_info,
p, trust_passwd, last_change_time);
return nt_status;
}
+
+BOOL auth_init_ntdomain(auth_methods **auth_method)
+{
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+
+ (*auth_method)->auth = check_ntdomain_security;
+ return True;
+}
diff --git a/source3/auth/auth_info.c b/source3/auth/auth_info.c
new file mode 100644
index 0000000000..12b843d781
--- /dev/null
+++ b/source3/auth/auth_info.c
@@ -0,0 +1,279 @@
+/*
+ Unix SMB/Netbios implementation.
+ Version 3.0.
+ Authentication utility functions
+ Copyright (C) Andrew Bartlett 2001
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+const struct auth_init_function builtin_auth_init_functions[] = {
+ { "guest", auth_init_guest },
+ { "rhosts", auth_init_rhosts },
+ { "hostsequiv", auth_init_hostsequiv },
+ { "sam", auth_init_sam },
+ { "unix", auth_init_unix },
+ { "local", auth_init_local },
+ { "smbserver", auth_init_smbserver },
+ { "ntdomain", auth_init_ntdomain },
+ { "winbind", auth_init_winbind },
+ { NULL, NULL}
+};
+
+/***************************************************************************
+ Make a auth_info struct
+***************************************************************************/
+
+static BOOL make_auth_info(auth_authsupplied_info **auth_info)
+{
+ *auth_info = malloc(sizeof(**auth_info));
+ if (!*auth_info) {
+ DEBUG(0,("make_auth_info: malloc failed!\n"));
+ return False;
+ }
+ ZERO_STRUCTP(*auth_info);
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a specified list.
+***************************************************************************/
+
+BOOL make_auth_info_list(auth_authsupplied_info **auth_info, auth_methods *list)
+{
+ if (!make_auth_info(auth_info)) {
+ return False;
+ }
+
+ (*auth_info)->auth_method_list = list;
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **text_list)
+{
+ auth_methods *list = NULL;
+ auth_methods *t = NULL;
+ auth_methods *tmp;
+ int i;
+
+ for (;*text_list; text_list++)
+ {
+ DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list));
+ for (i = 0; builtin_auth_init_functions[i].name; i++)
+ {
+ if (strequal(builtin_auth_init_functions[i].name, *text_list))
+ {
+ DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i));
+ /* Malloc entry, fill it, link it */
+ t = (auth_methods *)malloc(sizeof(*t));
+ if (!t) {
+ DEBUG(0,("make_pw_chat: malloc failed!\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(t);
+
+ if (builtin_auth_init_functions[i].init(&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(5,("auth method %s DOES NOT have a valid init\n", *text_list));
+ }
+ break;
+ }
+ }
+ }
+
+ make_auth_info_list(auth_info, list);
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+BOOL make_auth_info_subsystem(auth_authsupplied_info **auth_info)
+{
+ char **auth_method_list = NULL;
+
+ if (!make_auth_info(auth_info)) {
+ return False;
+ }
+
+ if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
+ return False;
+ }
+
+ if (auth_method_list == NULL) {
+ switch (lp_security())
+ {
+ case SEC_DOMAIN:
+ DEBUG(5,("Making default auth method list for security=domain\n"));
+ auth_method_list = lp_list_make("guest ntdomain local");
+ break;
+ case SEC_SERVER:
+ DEBUG(5,("Making default auth method list for security=server\n"));
+ auth_method_list = lp_list_make("guest smbserver local");
+ break;
+ case SEC_USER:
+ DEBUG(5,("Making default auth method list for security=user\n"));
+ auth_method_list = lp_list_make("guest local");
+ break;
+ case SEC_SHARE:
+ DEBUG(5,("Making default auth method list for security=share\n"));
+ auth_method_list = lp_list_make("guest local");
+ break;
+ }
+ } else {
+ DEBUG(5,("Using specified auth order\n"));
+ }
+
+ if (!make_auth_info_text_list(auth_info, auth_method_list)) {
+ lp_list_free(&auth_method_list);
+ return False;
+ }
+
+ lp_list_free(&auth_method_list);
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a random challange
+***************************************************************************/
+
+BOOL make_auth_info_random(auth_authsupplied_info **auth_info)
+{
+ uchar chal[8];
+ if (!make_auth_info_subsystem(auth_info)) {
+ return False;
+ }
+
+ generate_random_buffer(chal, sizeof(chal), False);
+ (*auth_info)->challange = data_blob(chal, sizeof(chal));
+
+ (*auth_info)->challange_set_by = "random";
+
+ return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a fixed challange
+***************************************************************************/
+
+BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8])
+{
+ if (!make_auth_info_subsystem(auth_info)) {
+ return False;
+ }
+
+ (*auth_info)->challange = data_blob(chal, 8);
+ return True;
+}
+
+/***************************************************************************
+ Clear out a auth_info struct that has been allocated
+***************************************************************************/
+
+void free_auth_info(auth_authsupplied_info **auth_info)
+{
+ auth_methods *list;
+ if (*auth_info != NULL) {
+ list = (*auth_info)->auth_method_list;
+ while (list) {
+ auth_methods *old_head = list;
+ if (list->free_private_data) {
+ list->free_private_data(&(list->private_data));
+ }
+ DLIST_REMOVE(list, list);
+ SAFE_FREE(old_head);
+ }
+
+ data_blob_free(&(*auth_info)->challange);
+ ZERO_STRUCT(**auth_info);
+ }
+ SAFE_FREE(*auth_info);
+}
+
+/****************************************************************************
+ Try to get a challange out of the various authenticaion modules.
+ It is up to the caller to free it.
+****************************************************************************/
+
+DATA_BLOB auth_get_challange(auth_authsupplied_info *auth_info)
+{
+ DATA_BLOB challange = data_blob(NULL, 0);
+ char *challange_set_by = NULL;
+ auth_methods *auth_method;
+
+ if (auth_info->challange.length) {
+ DEBUG(5, ("auth_get_challange: returning previous challange (normal)\n"));
+ return data_blob(auth_info->challange.data, auth_info->challange.length);
+ }
+
+ for (auth_method = auth_info->auth_method_list; auth_method; auth_method = auth_method->next)
+ {
+ if (auth_method->get_chal) {
+ DEBUG(5, ("auth_get_challange: getting challange from module %s\n", auth_method->name));
+ if (challange_set_by) {
+ DEBUG(1, ("auth_get_challange: CONFIGURATION ERROR: authenticaion method %s has already specified a challange. Challange by %s ignored.\n",
+ challange_set_by, auth_method->name));
+ } else {
+ challange = auth_method->get_chal(&auth_method->private_data, auth_info);
+ if (challange.length) {
+ DEBUG(5, ("auth_get_challange: sucessfully got challange from module %s\n", auth_method->name));
+ auth_info->challange = challange;
+ challange_set_by = auth_method->name;
+ auth_info->challange_set_method = auth_method;
+ } else {
+ DEBUG(3, ("auth_get_challange: getting challange from authenticaion method %s FAILED.\n",
+ auth_method->name));
+ }
+ }
+ } else {
+ DEBUG(5, ("auth_get_challange: module %s did not want to specify a challange\n", auth_method->name));
+ }
+ }
+
+ if (!challange_set_by) {
+ uchar chal[8];
+
+ generate_random_buffer(chal, sizeof(chal), False);
+ auth_info->challange = data_blob(chal, sizeof(chal));
+
+ challange_set_by = "random";
+ }
+
+ DEBUG(5, ("auth_info challange created by %s\n", challange_set_by));
+ DEBUG(5, ("challange is: \n"));
+ dump_data(5, auth_info->challange.data, (auth_info)->challange.length);
+
+ SMB_ASSERT(auth_info->challange.length == 8);
+
+ auth_info->challange_set_by=challange_set_by;
+
+ return data_blob(auth_info->challange.data, auth_info->challange.length);
+}
+
+
diff --git a/source3/auth/auth_rhosts.c b/source3/auth/auth_rhosts.c
index 9c07e48a9b..2605f0770a 100644
--- a/source3/auth/auth_rhosts.c
+++ b/source3/auth/auth_rhosts.c
@@ -135,7 +135,6 @@ check for a possible hosts equiv or rhosts entry for the user
static BOOL check_hosts_equiv(struct passwd *pass)
{
char *fname = NULL;
- pstring rhostsfile;
if (!pass)
return(False);
@@ -148,39 +147,82 @@ static BOOL check_hosts_equiv(struct passwd *pass)
return(True);
}
- if (lp_use_rhosts())
- {
- char *home = pass->pw_dir;
- if (home) {
- slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
- if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
- return(True);
- }
- }
-
return(False);
}
+
/****************************************************************************
Check for a valid .rhosts/hosts.equiv entry for this user
****************************************************************************/
-NTSTATUS check_rhosts_security(const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
+static NTSTATUS check_hostsequiv_security(void *my_private_data,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
{
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
if (pass) {
- become_root();
if (check_hosts_equiv(pass)) {
nt_status = NT_STATUS_OK;
make_server_info_pw(server_info, pass);
}
- unbecome_root();
} else {
nt_status = NT_STATUS_NO_SUCH_USER;
}
return nt_status;
}
+
+
+/****************************************************************************
+ Check for a valid .rhosts/hosts.equiv entry for this user
+****************************************************************************/
+
+static NTSTATUS check_rhosts_security(void *my_private_data,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
+{
+ NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+ struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
+ pstring rhostsfile;
+
+ if (pass) {
+ char *home = pass->pw_dir;
+ if (home) {
+ slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
+ become_root();
+ if (check_user_equiv(pass->pw_name,client_name(),rhostsfile)) {
+ nt_status = NT_STATUS_OK;
+ make_server_info_pw(server_info, pass);
+ }
+ unbecome_root();
+ }
+ } else {
+ nt_status = NT_STATUS_NO_SUCH_USER;
+ }
+
+ return nt_status;
+}
+
+BOOL auth_init_hostsequiv(auth_methods **auth_method)
+{
+
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+ (*auth_method)->auth = check_hostsequiv_security;
+ return True;
+}
+
+BOOL auth_init_rhosts(auth_methods **auth_method)
+{
+
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+ (*auth_method)->auth = check_rhosts_security;
+ return True;
+}
diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c
index 70632fb5df..24a4d4e4e4 100644
--- a/source3/auth/auth_sam.c
+++ b/source3/auth/auth_sam.c
@@ -96,7 +96,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
if (ntv2_response.length < 16) {
/* We MUST have more than 16 bytes, or the stuff below will go
crazy... */
- DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n",
+ DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n",
ntv2_response.length));
return False;
}
@@ -132,15 +132,16 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
Do a specific test for an smb password being correct, given a smb_password and
the lanman and NT responses.
****************************************************************************/
-NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, uint8 user_sess_key[16])
+static NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ uint8 user_sess_key[16])
{
+ uint16 acct_ctrl;
const uint8 *nt_pw, *lm_pw;
- uint16 acct_ctrl = pdb_get_acct_ctrl(sampass);
uint32 ntlmssp_flags;
- if (!user_info || !sampass)
- return NT_STATUS_LOGON_FAILURE;
-
+ acct_ctrl = pdb_get_acct_ctrl(sampass);
if (acct_ctrl & ACB_PWNOTREQ)
{
if (lp_null_passwords())
@@ -173,8 +174,8 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
*/
DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n"));
if (smb_pwd_check_ntlmv2( user_info->nt_resp,
- nt_pw,
- user_info->sec_blob, user_info->smb_name.str,
+ nt_pw, auth_info->challange,
+ user_info->smb_name.str,
user_info->client_domain.str,
user_sess_key))
{
@@ -190,7 +191,7 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
*/
DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
if (smb_pwd_check_ntlmv1(user_info->nt_resp,
- nt_pw, user_info->sec_blob,
+ nt_pw, auth_info->challange,
user_sess_key))
{
return NT_STATUS_OK;
@@ -223,7 +224,7 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
DEBUG(4,("smb_password_ok: Checking LM password\n"));
if (smb_pwd_check_ntlmv1(user_info->lm_resp,
- lm_pw, user_info->sec_blob,
+ lm_pw, auth_info->challange,
user_sess_key))
{
return NT_STATUS_OK;
@@ -265,6 +266,24 @@ static NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_inf
return NT_STATUS_ACCOUNT_EXPIRED;
}
+ if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) {
+ time_t must_change_time = pdb_get_pass_must_change_time(sampass);
+ time_t last_set_time = pdb_get_pass_last_set_time(sampass);
+
+ /* check for immediate expiry "must change at next logon" */
+ if (must_change_time == 0 && last_set_time != 0) {
+ DEBUG(1,("Account for user '%s' password must change!.\n", pdb_get_username(sampass)));
+ return NT_STATUS_PASSWORD_MUST_CHANGE;
+ }
+
+ /* check for expired password */
+ if (must_change_time < time(NULL) && must_change_time != 0) {
+ DEBUG(1,("Account for user '%s' password expired!.\n", pdb_get_username(sampass)));
+ DEBUG(1,("Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time));
+ return NT_STATUS_PASSWORD_EXPIRED;
+ }
+ }
+
/* Test workstation. Workstation list is comma separated. */
workstation_list = strdup(pdb_get_workstations(sampass));
@@ -293,24 +312,6 @@ static NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_inf
SAFE_FREE(workstation_list);
}
- if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) {
- time_t must_change_time = pdb_get_pass_must_change_time(sampass);
- time_t last_set_time = pdb_get_pass_last_set_time(sampass);
-
- /* check for immediate expiry "must change at next logon" */
- if (must_change_time == 0 && last_set_time != 0) {
- DEBUG(1,("Account for user '%s' password must change!.\n", pdb_get_username(sampass)));
- return NT_STATUS_PASSWORD_MUST_CHANGE;
- }
-
- /* check for expired password */
- if (must_change_time < time(NULL) && must_change_time != 0) {
- DEBUG(1,("Account for user '%s' password expired!.\n", pdb_get_username(sampass)));
- DEBUG(1,("Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time));
- return NT_STATUS_PASSWORD_EXPIRED;
- }
- }
-
if (acct_ctrl & ACB_DOMTRUST) {
DEBUG(2,("session_trust_account: Domain trust account %s denied by server\n", pdb_get_username(sampass)));
return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
@@ -336,7 +337,10 @@ SMB hash supplied in the user_info structure
return an NT_STATUS constant.
****************************************************************************/
-NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+NTSTATUS check_sam_security(void *my_private_dat,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
{
SAM_ACCOUNT *sampass=NULL;
BOOL ret;
@@ -344,7 +348,7 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
uint8 user_sess_key[16];
const uint8* lm_hash;
- if (!user_info) {
+ if (!user_info || !auth_info) {
return NT_STATUS_LOGON_FAILURE;
}
@@ -365,7 +369,7 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
return NT_STATUS_NO_SUCH_USER;
}
- nt_status = sam_password_ok(sampass, user_info, user_sess_key);
+ nt_status = sam_password_ok(sampass, user_info, auth_info, user_sess_key);
if (!NT_STATUS_IS_OK(nt_status)) {
pdb_free_sam(&sampass);
@@ -394,6 +398,15 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
return nt_status;
}
+BOOL auth_init_sam(auth_methods **auth_method)
+{
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+
+ (*auth_method)->auth = check_sam_security;
+ return True;
+}
diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c
index ddbc284d50..067b5b2997 100644
--- a/source3/auth/auth_server.c
+++ b/source3/auth/auth_server.c
@@ -25,30 +25,18 @@
extern pstring global_myname;
/****************************************************************************
- Return the client state structure.
-****************************************************************************/
-
-struct cli_state *server_client(void)
-{
- static struct cli_state pw_cli;
- return &pw_cli;
-}
-
-/****************************************************************************
Support for server level security.
****************************************************************************/
-struct cli_state *server_cryptkey(void)
+static struct cli_state *server_cryptkey(void)
{
- struct cli_state *cli;
+ struct cli_state *cli = NULL;
fstring desthost;
struct in_addr dest_ip;
char *p, *pserver;
BOOL connected_ok = False;
- cli = server_client();
-
- if (!cli_initialise(cli))
+ if (!(cli = cli_initialise(cli)))
return NULL;
/* security = server just can't function with spnego */
@@ -88,7 +76,11 @@ struct cli_state *server_cryptkey(void)
if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip))
return NULL;
-
+
+ if (strequal(desthost,myhostname())) {
+ exit_server("Password server loop!");
+ }
+
DEBUG(3,("got session\n"));
if (!cli_negprot(cli)) {
@@ -109,13 +101,82 @@ struct cli_state *server_cryptkey(void)
return cli;
}
+/****************************************************************************
+ Clean up our allocated cli.
+****************************************************************************/
+
+static void free_server_private_data(void **private_data_pointer)
+{
+ struct cli_state **cli = (struct cli_state **)private_data_pointer;
+ if (*cli && (*cli)->initialised) {
+ cli_shutdown(*cli);
+
+ SAFE_FREE(*cli);
+ }
+}
+
+/****************************************************************************
+ Send a 'keepalive' packet down the cli pipe.
+****************************************************************************/
+
+static void send_server_keepalive(void **private_data_pointer)
+{
+ struct cli_state **cli = (struct cli_state **)private_data_pointer;
+
+ /* also send a keepalive to the password server if its still
+ connected */
+ if (cli && *cli && (*cli)->initialised) {
+ if (!send_keepalive((*cli)->fd)) {
+ DEBUG( 2, ( "password server keepalive failed.\n"));
+ cli_shutdown(*cli);
+ SAFE_FREE(*cli);
+ }
+ }
+}
+
+/****************************************************************************
+ Get the challange out of a password server.
+****************************************************************************/
+
+static DATA_BLOB auth_get_challange_server(void **my_private_data, const struct authsupplied_info *auth_info)
+{
+ struct cli_state *cli = server_cryptkey();
+
+ if (cli) {
+ DEBUG(3,("using password server validation\n"));
+ if ((cli->sec_mode & 2) == 0) {
+ /* We can't work with unencrypted password servers
+ unless 'encrypt passwords = no' */
+ DEBUG(5,("make_auth_info_server: Server is unencrypted, no challange available..\n"));
+
+ *my_private_data = (void *)cli;
+ return data_blob(NULL, 0);
+
+ } else if (cli->secblob.length < 8) {
+ /* We can't do much if we don't get a full challange */
+ DEBUG(2,("make_auth_info_server: Didn't receive a full challange from server\n"));
+ cli_shutdown(cli);
+ return data_blob(NULL, 0);
+ }
+
+ *my_private_data = (void *)cli;
+
+ return data_blob(cli->secblob.data,8);
+ } else {
+ return data_blob(NULL, 0);
+ }
+}
+
/****************************************************************************
Check for a valid username and password in security=server mode.
- Validate a password with the password server.
****************************************************************************/
-NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+static NTSTATUS check_smbserver_security(void *my_private_data,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
{
struct cli_state *cli;
static unsigned char badpass[24];
@@ -123,13 +184,32 @@ NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_ser
static BOOL tested_password_server = False;
static BOOL bad_password_server = False;
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+ BOOL locally_made_cli = False;
- cli = server_client();
+ cli = my_private_data;
+
+ if (cli) {
+ } else {
+ cli = server_cryptkey();
+ locally_made_cli = True;
+ }
- if (!cli->initialised) {
+ if (!cli || !cli->initialised) {
DEBUG(1,("password server %s is not connected\n", cli->desthost));
- return(NT_STATUS_LOGON_FAILURE);
+ return NT_STATUS_LOGON_FAILURE;
}
+
+ if ((cli->sec_mode & 2) == 0) {
+ if (user_info->encrypted) {
+ DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost));
+ return NT_STATUS_LOGON_FAILURE;
+ }
+ } else {
+ if (memcmp(cli->secblob.data, auth_info->challange.data, 8) != 0) {
+ DEBUG(1,("the challange that the password server (%s) supplied us is not the one we gave our client. This just can't work :-(\n", cli->desthost));
+ return NT_STATUS_LOGON_FAILURE;
+ }
+ }
if(badpass[0] == 0)
memset(badpass, 0x1f, sizeof(badpass));
@@ -206,17 +286,32 @@ use this machine as the password server.\n"));
* not guest enabled, we can try with the real password.
*/
- if (!cli_session_setup(cli, user_info->smb_name.str,
- (char *)user_info->lm_resp.data,
- user_info->lm_resp.length,
- (char *)user_info->nt_resp.data,
- user_info->nt_resp.length,
- user_info->domain.str)) {
- DEBUG(1,("password server %s rejected the password\n", cli->desthost));
- /* Make this cli_nt_error() when the conversion is in */
- nt_status = cli_nt_error(cli);
+ if (!user_info->encrypted) {
+ /* Plaintext available */
+ if (!cli_session_setup(cli, user_info->smb_name.str,
+ (char *)user_info->plaintext_password.data,
+ user_info->plaintext_password.length,
+ NULL, 0,
+ user_info->domain.str)) {
+ DEBUG(1,("password server %s rejected the password\n", cli->desthost));
+ /* Make this cli_nt_error() when the conversion is in */
+ nt_status = cli_nt_error(cli);
+ } else {
+ nt_status = NT_STATUS_OK;
+ }
} else {
- nt_status = NT_STATUS_OK;
+ if (!cli_session_setup(cli, user_info->smb_name.str,
+ (char *)user_info->lm_resp.data,
+ user_info->lm_resp.length,
+ (char *)user_info->nt_resp.data,
+ user_info->nt_resp.length,
+ user_info->domain.str)) {
+ DEBUG(1,("password server %s rejected the password\n", cli->desthost));
+ /* Make this cli_nt_error() when the conversion is in */
+ nt_status = cli_nt_error(cli);
+ } else {
+ nt_status = NT_STATUS_OK;
+ }
}
/* if logged in as guest then reject */
@@ -238,5 +333,22 @@ use this machine as the password server.\n"));
}
}
+ if (locally_made_cli) {
+ cli_shutdown(cli);
+ SAFE_FREE(cli);
+ }
+
return(nt_status);
}
+
+BOOL auth_init_smbserver(auth_methods **auth_method)
+{
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+ (*auth_method)->auth = check_smbserver_security;
+ (*auth_method)->get_chal = auth_get_challange_server;
+ (*auth_method)->send_keepalive = send_server_keepalive;
+ (*auth_method)->free_private_data = free_server_private_data;
+ return True;
+}
diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c
index 8c4a520350..d134ce6909 100644
--- a/source3/auth/auth_unix.c
+++ b/source3/auth/auth_unix.c
@@ -82,7 +82,10 @@ check if a username/password is OK assuming the password
in PLAIN TEXT
****************************************************************************/
-NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+NTSTATUS check_unix_security(void *my_private_data,
+ const auth_usersupplied_info *user_info,
+ const auth_authsupplied_info *auth_info,
+ auth_serversupplied_info **server_info)
{
NTSTATUS nt_status;
struct passwd *pass = NULL;
@@ -104,9 +107,19 @@ NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serve
if (pass) {
make_server_info_pw(server_info, pass);
} else {
+ /* we need to do somthing more useful here */
nt_status = NT_STATUS_NO_SUCH_USER;
}
}
return nt_status;
}
+
+BOOL auth_init_unix(auth_methods **auth_method)
+{
+ if (!make_auth_methods(auth_method)) {
+ return False;
+ }
+ (*auth_method)->auth = check_unix_security;
+ return True;
+}
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c
index 25e0830fc7..d1b2cc92e5 100644
--- a/source3/auth/auth_util.c
+++ b/source3/auth/auth_util.c
@@ -23,49 +23,9 @@
#include "includes.h"
-/* Data to do lanman1/2 password challenge. */
-static unsigned char saved_challenge[8];
-static BOOL challenge_sent=False;
extern fstring remote_machine;
extern pstring global_myname;
-/*******************************************************************
- Get the next challenge value - no repeats.
-********************************************************************/
-
-void generate_next_challenge(char *challenge)
-{
- unsigned char buf[8];
-
- generate_random_buffer(buf,8,False);
- memcpy(saved_challenge, buf, 8);
- memcpy(challenge,buf,8);
- challenge_sent = True;
-}
-
-/*******************************************************************
- Set the last challenge sent, usually from a password server.
-********************************************************************/
-
-BOOL set_challenge(unsigned char *challenge)
-{
- memcpy(saved_challenge,challenge,8);
- challenge_sent = True;
- return(True);
-}
-
-/*******************************************************************
- Get the last challenge sent.
-********************************************************************/
-
-BOOL last_challenge(unsigned char *challenge)
-{
- if (!challenge_sent)
- return(False);
- memcpy(challenge,saved_challenge,8);
- return(True);
-}
-
/****************************************************************************
Create a UNIX user on demand.
****************************************************************************/
@@ -166,7 +126,6 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
const char *client_domain,
const char *domain,
const char *wksta_name,
- DATA_BLOB sec_blob,
DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
DATA_BLOB plaintext,
uint32 ntlmssp_flags, BOOL encrypted)
@@ -226,7 +185,6 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
- (*user_info)->sec_blob = data_blob(sec_blob.data, sec_blob.length);
(*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
(*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
(*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
@@ -246,7 +204,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
BOOL make_user_info_map(auth_usersupplied_info **user_info,
const char *smb_name,
const char *client_domain,
- const char *wksta_name, DATA_BLOB sec_blob,
+ const char *wksta_name,
DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
DATA_BLOB plaintext,
uint32 ntlmssp_flags, BOOL encrypted)
@@ -265,7 +223,7 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
return make_user_info(user_info,
smb_name, internal_username,
client_domain, domain,
- wksta_name, sec_blob,
+ wksta_name,
lm_pwd, nt_pwd,
plaintext,
ntlmssp_flags, encrypted);
@@ -280,12 +238,11 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
char *smb_name,
char *client_domain,
- char *wksta_name, uchar chal[8],
+ char *wksta_name,
uchar *lm_network_pwd, int lm_pwd_len,
uchar *nt_network_pwd, int nt_pwd_len)
{
BOOL ret;
- DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -301,8 +258,8 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
ret = make_user_info_map(user_info,
smb_name, client_domain,
- wksta_name, sec_blob,
- nt_blob, lm_blob,
+ wksta_name,
+ lm_blob, nt_blob,
plaintext_blob,
ntlmssp_flags, True);
@@ -320,6 +277,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
char *smb_name,
char *client_domain,
char *wksta_name,
+ char chal[8],
uchar lm_interactive_pwd[16],
uchar nt_interactive_pwd[16],
uchar *dc_sess_key)
@@ -329,11 +287,8 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
unsigned char key[16];
- uint8 chal[8];
uint32 ntlmssp_flags = 0;
- generate_random_buffer(chal, 8, False);
-
ZERO_STRUCT(key);
memcpy(key, dc_sess_key, 8);
@@ -362,7 +317,6 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
dump_data(100, nt_pwd, sizeof(nt_pwd));
#endif
- generate_random_buffer(chal, 8, False);
SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
@@ -373,7 +327,6 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
{
BOOL ret;
- DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -385,7 +338,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
ret = make_user_info_map(user_info,
smb_name, client_domain,
- wksta_name, sec_blob,
+ wksta_name,
local_lm_blob,
local_nt_blob,
plaintext_blob,
@@ -402,13 +355,14 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
****************************************************************************/
BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
- char *username,
- char *domain,
- char *password)
+ const char *username,
+ const char *domain,
+ const char *password,
+ char chal[8] /* Give winbind back the challange we used */
+ )
{
unsigned char local_lm_response[24];
unsigned char local_nt_response[24];
- char chal[8];
DATA_BLOB local_lm_blob;
DATA_BLOB local_nt_blob;
DATA_BLOB plaintext_blob;
@@ -453,16 +407,11 @@ BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
{
BOOL ret;
- DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
-
- if (!sec_blob.data) {
- return False;
- }
ret = make_user_info(user_info,
username, username,
domain, domain,
- global_myname, sec_blob,
+ global_myname,
local_nt_blob,
local_lm_blob,
plaintext_blob,
@@ -483,12 +432,10 @@ BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
char *smb_name,
char *client_domain,
- uchar chal[8],
uchar *lm_network_pwd, int lm_pwd_len,
uchar *nt_network_pwd, int nt_pwd_len)
{
BOOL ret;
- DATA_BLOB sec_blob = data_blob(chal, 8);
DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -502,7 +449,7 @@ BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
ret = make_user_info(user_info,
smb_name, smb_name,
client_domain, client_domain,
- global_myname, sec_blob,
+ global_myname,
nt_blob, lm_blob,
plaintext_blob,
ntlmssp_flags, True);
@@ -517,59 +464,30 @@ BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
****************************************************************************/
BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
- char *smb_name,
- char *client_domain,
- DATA_BLOB lm_resp, DATA_BLOB nt_resp,
- DATA_BLOB plaintext_password,
- BOOL encrypted)
+ char *smb_name,
+ char *client_domain,
+ char chal[8],
+ DATA_BLOB plaintext_password)
{
- uchar chal[8];
DATA_BLOB local_lm_blob;
DATA_BLOB local_nt_blob;
- DATA_BLOB sec_blob;
BOOL ret = False;
uint32 ntlmssp_flags = 0;
- if (encrypted) {
- DATA_BLOB no_plaintext_blob = data_blob(NULL, 0);
- if (!last_challenge(chal)) {
- DEBUG(0,("Encrypted login but no challange set!\n"));
- return False;
- }
- sec_blob = data_blob(chal, 8);
-
- if (lm_resp.length == 24) {
- ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
- }
- if (nt_resp.length == 0) {
- } else if (nt_resp.length == 24) {
- ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
- } else {
- ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
- }
-
- return make_user_info_map(user_info, smb_name,
- client_domain,
- remote_machine, sec_blob,
- lm_resp,
- nt_resp,
- no_plaintext_blob,
- ntlmssp_flags, encrypted);
- }
-
- generate_random_buffer(chal, 8, False);
-
- sec_blob = data_blob(chal, 8);
-
/*
* Not encrypted - do so.
*/
- DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
+ DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
if (plaintext_password.data) {
unsigned char local_lm_response[24];
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
+ dump_data(100, plaintext_password.data, plaintext_password.length);
+#endif
SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
local_lm_blob = data_blob(local_lm_response, 24);
@@ -587,23 +505,54 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
ret = make_user_info_map(user_info, smb_name,
client_domain,
remote_machine,
- sec_blob,
local_lm_blob,
local_nt_blob,
plaintext_password,
- ntlmssp_flags, encrypted);
+ ntlmssp_flags, False);
data_blob_free(&local_lm_blob);
return ret;
}
/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
+ char *smb_name,
+ char *client_domain,
+ DATA_BLOB lm_resp, DATA_BLOB nt_resp,
+ DATA_BLOB plaintext_password)
+{
+ uint32 ntlmssp_flags = 0;
+
+ DATA_BLOB no_plaintext_blob = data_blob(NULL, 0);
+
+ if (lm_resp.length == 24) {
+ ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+ }
+ if (nt_resp.length == 0) {
+ } else if (nt_resp.length == 24) {
+ ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
+ } else {
+ ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+ }
+
+ return make_user_info_map(user_info, smb_name,
+ client_domain,
+ remote_machine,
+ lm_resp,
+ nt_resp,
+ no_plaintext_blob,
+ ntlmssp_flags, True);
+}
+
+/****************************************************************************
Create a guest user_info blob, for anonymous authenticaion.
****************************************************************************/
BOOL make_user_info_guest(auth_usersupplied_info **user_info)
{
- DATA_BLOB sec_blob = data_blob(NULL, 0);
DATA_BLOB lm_blob = data_blob(NULL, 0);
DATA_BLOB nt_blob = data_blob(NULL, 0);
DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -612,7 +561,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info)
return make_user_info(user_info,
"","",
"","",
- "", sec_blob,
+ "",
nt_blob, lm_blob,
plaintext_blob,
ntlmssp_flags, True);
@@ -680,7 +629,6 @@ void free_user_info(auth_usersupplied_info **user_info)
SAFE_FREE((*user_info)->internal_username.str);
SAFE_FREE((*user_info)->client_domain.str);
SAFE_FREE((*user_info)->domain.str);
- data_blob_free(&(*user_info)->sec_blob);
data_blob_free(&(*user_info)->lm_resp);
data_blob_free(&(*user_info)->nt_resp);
SAFE_FREE((*user_info)->interactive_password);
@@ -725,6 +673,22 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info)
return False;
}
+/***************************************************************************
+ Make an auth_methods struct
+***************************************************************************/
+
+BOOL make_auth_methods(auth_methods **auth_method)
+{
+ *auth_method = malloc(sizeof(**auth_method));
+ if (!*auth_method) {
+ DEBUG(0,("make_auth_method: malloc failed!\n"));
+ return False;
+ }
+ ZERO_STRUCTP(*auth_method);
+
+ return True;
+}
+
/****************************************************************************
Delete a SID token.
****************************************************************************/
@@ -764,25 +728,3 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
return token;
}
-
-/****************************************************************************
- Check for a guest logon (username = "") and if so create the required
- structure.
-****************************************************************************/
-
-NTSTATUS check_guest_security(const auth_usersupplied_info *user_info,
- auth_serversupplied_info **server_info)
-{
- NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-
- if (!(user_info->internal_username.str
- && *user_info->internal_username.str)) {
- if (make_server_info_guest(server_info)) {
- nt_status = NT_STATUS_OK;
- } else {
- nt_status = NT_STATUS_NO_SUCH_USER;
- }
- }
-
- return nt_status;
-}