I've decided to move the auth code around a bit more...
authorAndrew Bartlett <abartlet@samba.org>
Sat, 5 Jan 2002 04:55:41 +0000 (04:55 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 5 Jan 2002 04:55:41 +0000 (04:55 +0000)
The auth_authsupplied_info typedef is now just a plain struct - auth_context,
but it has been modified to contain the function pointers to the rest
of the auth subsystem's components.

(Who needs non-static functions anyway?)

In working all this mess out, I fixed a number of memory leaks and moved the
entire auth subsystem over to talloc().

Note that the TALLOC_CTX attached to the auth_context can be rather long-lived,
it is provided for things that are intended to live as long.  (The
global_negprot_auth_context lasts the whole life of the smbd).

I've also adjusted a few things in auth_domain.c, mainly passing the domain as
a paramater to a few functions instead of looking up lp_workgroup().  I'm
hopign to make this entire thing a bit more trusted domains (as PDC) freindly
in the near future.

Other than that, I moved a bit of the code around, hence the rather messy diff.

Andrew Bartlett
(This used to be commit 12f5515f556cf39fea98134fe3e2ac4540501048)

19 files changed:
source3/Makefile.in
source3/auth/auth.c
source3/auth/auth_builtin.c
source3/auth/auth_compat.c [new file with mode: 0644]
source3/auth/auth_domain.c
source3/auth/auth_info.c [deleted file]
source3/auth/auth_rhosts.c
source3/auth/auth_sam.c
source3/auth/auth_server.c
source3/auth/auth_unix.c
source3/auth/auth_util.c
source3/auth/auth_winbind.c
source3/include/auth.h
source3/rpc_server/srv_netlog_nt.c
source3/rpc_server/srv_pipe.c
source3/smbd/negprot.c
source3/smbd/process.c
source3/smbd/server.c
source3/smbd/sesssetup.c

index c0a35b75c704eb6bc5903afbe281d1d3e5e239b2..dacc947d6141bb892fbf0e542394bca65b56cc7c 100644 (file)
@@ -201,7 +201,7 @@ PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
 
 AUTH_OBJ = auth/auth.o auth/auth_sam.o auth/auth_server.o auth/auth_domain.o \
           auth/auth_rhosts.o auth/auth_unix.o auth/auth_util.o auth/auth_winbind.o \
-          auth/auth_info.o auth/auth_builtin.o $(PLAINTEXT_AUTH_OBJ)
+          auth/auth_builtin.o auth/auth_compat.o $(PLAINTEXT_AUTH_OBJ)
 
 
 SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \
index bfd15dff34685962ddb1913bd239d896191e97f2..6b68fa631ac12f3a1774fd290255dd44dc048553 100644 (file)
@@ -1,10 +1,8 @@
 /* 
    Unix SMB/Netbios implementation.
-   Version 1.9.
+   Version 3.0.
    Password and authentication handling
-   Copyright (C) Andrew Tridgell              1992-2000
-   Copyright (C) Luke Kenneth Casson Leighton 1996-2000
-   Copyright (C) Andrew Bartlett              2001
+   Copyright (C) Andrew Bartlett         2001-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
 
 #include "includes.h"
 
+/** List of various built-in authenticaion modules */
+
+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 },       
+       { "samstrict", auth_init_samstrict },
+       { "unix", auth_init_unix },
+       { "smbserver", auth_init_smbserver },
+       { "ntdomain", auth_init_ntdomain },
+       { "winbind", auth_init_winbind },
+#ifdef DEVELOPER
+       { "name_to_ntstatus", auth_init_name_to_ntstatus },
+#endif
+       { NULL, NULL}
+};
+
+/****************************************************************************
+ Try to get a challenge out of the various authenticaion modules.
+ Returns a const char of length 8 bytes.
+****************************************************************************/
+
+static const uint8 *get_ntlm_challenge(struct auth_context *auth_context) 
+{
+       DATA_BLOB challenge = data_blob(NULL, 0);
+       char *challenge_set_by = NULL;
+       auth_methods *auth_method;
+       TALLOC_CTX *mem_ctx;
+
+       if (auth_context->challenge.length) {
+               DEBUG(5, ("get_ntlm_challange (auth subsystem): returning previous challenge (normal)\n"));
+               return auth_context->challenge.data;
+       }
+
+       for (auth_method = auth_context->auth_method_list; auth_method; auth_method = auth_method->next)
+       {
+               if (auth_method->get_chal == NULL) {
+                       DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
+                       continue;
+               }
+
+               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", 
+                                 challenge_set_by, auth_method->name));
+                       continue;
+               }
+
+               mem_ctx = talloc_init_named("auth_get_challange for module %s", auth_method->name);
+               if (!mem_ctx) {
+                       smb_panic("talloc_init_named() failed!");
+               }
+               
+               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", 
+                                 auth_method->name));
+               } else {
+                       DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name));
+                       auth_context->challenge = challenge;
+                       challenge_set_by = auth_method->name;
+                       auth_context->challenge_set_method = auth_method;
+               }
+               talloc_destroy(mem_ctx);
+       }
+       
+       if (!challenge_set_by) {
+               uchar chal[8];
+               
+               generate_random_buffer(chal, sizeof(chal), False);
+               auth_context->challenge = data_blob_talloc(auth_context->mem_ctx, 
+                                                          chal, sizeof(chal));
+               
+               challenge_set_by = "random";
+       } 
+       
+       DEBUG(5, ("auth_context challenge created by %s\n", challenge_set_by));
+       DEBUG(5, ("challenge is: \n"));
+       dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
+       
+       SMB_ASSERT(auth_context->challenge.length == 8);
+
+       auth_context->challenge_set_by=challenge_set_by;
+
+       return auth_context->challenge.data;
+}
+
+
 /**
  * Check user is in correct domain (if required)
  *
@@ -81,9 +168,9 @@ static BOOL check_domain_match(const char *user, const char *domain)
  *
  **/
 
-NTSTATUS check_password(const auth_usersupplied_info *user_info, 
-                       const auth_authsupplied_info *auth_info,
-                       auth_serversupplied_info **server_info)
+static NTSTATUS check_ntlm_password(const struct auth_context *auth_context,
+                                   const struct auth_usersupplied_info *user_info, 
+                                   struct auth_serversupplied_info **server_info)
 {
        
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
@@ -91,7 +178,7 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
        auth_methods *auth_method;
        TALLOC_CTX *mem_ctx;
 
-       if (!user_info || !auth_info || !server_info) {
+       if (!user_info || !auth_context || !server_info) {
                return NT_STATUS_LOGON_FAILURE;
        }
 
@@ -100,11 +187,11 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
 
        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 (auth_info->challenge_set_by) {
-               DEBUG(10, ("auth_info challenge created by %s\n", auth_info->challenge_set_by));
+       if (auth_context->challenge_set_by) {
+               DEBUG(10, ("auth_context challenge created by %s\n", auth_context->challenge_set_by));
        }
        DEBUG(10, ("challenge is: \n"));
-       dump_data(5, (auth_info)->challenge.data, (auth_info)->challenge.length);
+       dump_data(5, auth_context->challenge.data, auth_context->challenge.length);
 
 #ifdef DEBUG_PASSWORD
        DEBUG(100, ("user_info has passwords of length %d and %d\n", 
@@ -120,12 +207,12 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
                return NT_STATUS_LOGON_FAILURE;
        }
 
-       for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next)
+       for (auth_method = auth_context->auth_method_list;auth_method; auth_method = auth_method->next)
        {
                mem_ctx = talloc_init_named("%s authentication for user %s\\%s", auth_method->name, 
                                            user_info->domain.str, user_info->smb_name.str);
 
-               nt_status = auth_method->auth(auth_method->private_data, mem_ctx, user_info, auth_info, server_info);
+               nt_status = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info);
                if (NT_STATUS_IS_OK(nt_status)) {
                        DEBUG(3, ("check_password: %s authentication for user [%s] suceeded\n", 
                                  auth_method->name, user_info->smb_name.str));
@@ -182,124 +269,188 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
                ZERO_STRUCTP(server_info);
        }
        return nt_status;
-
 }
 
-/**
- * Squash an NT_STATUS in line with security requirements.
- * In an attempt to avoid giving the whole game away when users
- * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 
- * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 
- * (session setups in particular).
- *
- * @param nt_status NTSTATUS input for squashing.
- * @return the 'squashed' nt_status
- **/
+/***************************************************************************
+ Clear out a auth_context, and destroy the attached TALLOC_CTX
+***************************************************************************/
 
-NTSTATUS nt_status_squash(NTSTATUS nt_status) 
+static void free_auth_context(struct auth_context **auth_context)
 {
-       if NT_STATUS_IS_OK(nt_status) {
-               return nt_status;               
-       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
-               /* Match WinXP and don't give the game away */
-               return NT_STATUS_LOGON_FAILURE;
-               
-       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
-               /* Match WinXP and don't give the game away */
-               return NT_STATUS_LOGON_FAILURE;
-       } else {
-               return nt_status;
-       }  
+       if (*auth_context != NULL) {
+               talloc_destroy((*auth_context)->mem_ctx);
+       }
+       *auth_context = NULL;
 }
 
+/***************************************************************************
+ Make a auth_info struct
+***************************************************************************/
 
+static NTSTATUS make_auth_context(struct auth_context **auth_context) 
+{
+       TALLOC_CTX *mem_ctx;
 
-/****************************************************************************
- COMPATABILITY INTERFACES:
- ***************************************************************************/
+       mem_ctx = talloc_init_named("authentication context");
+       
+       *auth_context = talloc(mem_ctx, sizeof(**auth_context));
+       if (!*auth_context) {
+               DEBUG(0,("make_auth_context: talloc failed!\n"));
+               talloc_destroy(mem_ctx);
+               return NT_STATUS_NO_MEMORY;
+       }
+       ZERO_STRUCTP(*auth_context);
 
-/****************************************************************************
-check if a username/password is OK assuming the password is a 24 byte
-SMB hash
-return True if the password is correct, False otherwise
-****************************************************************************/
+       (*auth_context)->mem_ctx = mem_ctx;
+       (*auth_context)->check_ntlm_password = check_ntlm_password;
+       (*auth_context)->get_ntlm_challenge = get_ntlm_challenge;
+       (*auth_context)->free = free_auth_context;
+       
+       return NT_STATUS_OK;
+}
 
-static NTSTATUS pass_check_smb(char *smb_name,
-                              char *domain, 
-                              DATA_BLOB lm_pwd,
-                              DATA_BLOB nt_pwd,
-                              DATA_BLOB plaintext_password,
-                              BOOL encrypted)
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
 
+static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, char **text_list) 
 {
+       auth_methods *list = NULL;
+       auth_methods *t = NULL;
+       auth_methods *tmp;
+       int i;
        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;
-               }
-
-               chal = auth_get_challenge(plaintext_auth_info);
 
-               if (!make_user_info_for_reply(&user_info, 
-                                             smb_name, domain, chal.data,
-                                             plaintext_password)) {
-                       return NT_STATUS_NO_MEMORY;
+       if (!text_list) {
+               DEBUG(2,("No auth method list!?\n"));
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+       
+       if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context))) {
+               return nt_status;
+       }
+       
+       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));
+                               if (builtin_auth_init_functions[i].init(*auth_context, &t)) {
+                                       DEBUG(5,("auth method %s has a valid init\n", *text_list));
+                                       t->name = builtin_auth_init_functions[i].name;
+                                       DLIST_ADD_END(list, t, tmp);
+                               } else {
+                                       DEBUG(0,("auth method %s did not correctly init\n", *text_list));
+                               }
+                               break;
+                       }
                }
-               
-               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);
+       }
+       
+       (*auth_context)->auth_method_list = list;
+       
        return nt_status;
 }
 
-/****************************************************************************
-check if a username/password pair is OK either via the system password
-database or the encrypted SMB password database
-return True if the password is correct, False otherwise
-****************************************************************************/
-BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
+/***************************************************************************
+ Make a auth_context struct for the auth subsystem
+***************************************************************************/
+
+NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) 
 {
+       char **auth_method_list = NULL; 
+       NTSTATUS nt_status;
 
-       DATA_BLOB null_password = data_blob(NULL, 0);
-       extern BOOL 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, encrypted))) {
-                       return True;
-               }
-               
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
-                       return True;
+       if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       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 samstrict 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");
+                       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");
+                       } else {
+                               DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
+                               auth_method_list = lp_list_make("guest unix");
+                       }
+                       break;
+               case SEC_SHARE:
+                       if (lp_encrypted_passwords()) {
+                               DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
+                               auth_method_list = lp_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");
+                       }
+                       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");
+                       break;
+               default:
+                       DEBUG(5,("Unknown auth method!\n"));
+                       return NT_STATUS_UNSUCCESSFUL;
                }
        } else {
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
-                       return True;
-               }
+               DEBUG(5,("Using specified auth order\n"));
+       }
+       
+       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_text_list(auth_context, auth_method_list))) {
+               lp_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";
+
+       return nt_status;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a fixed challenge
+***************************************************************************/
 
-       return False;
+NTSTATUS make_auth_context_fixed(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;
+       }
+       
+       (*auth_context)->challenge = data_blob(chal, 8);
+       return nt_status;
 }
 
 
index f76987f685d4df40c7c12ea35c404fbb1d488b38..f1c89689fa61c4facdeb475d236d16e3f2696449 100644 (file)
  * and pass onto the next module.
  **/
 
-static NTSTATUS check_guest_security(void *my_private_data, 
+static NTSTATUS check_guest_security(const struct auth_context *auth_context,
+                                    void *my_private_data, 
                                     TALLOC_CTX *mem_ctx,
                                     const auth_usersupplied_info *user_info, 
-                                    const auth_authsupplied_info *auth_info,
                                     auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
@@ -50,9 +50,9 @@ static NTSTATUS check_guest_security(void *my_private_data,
 }
 
 /* Guest modules initialisation */
-BOOL auth_init_guest(auth_methods **auth_method) 
+BOOL auth_init_guest(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, auth_method)) {
                return False;
        }
 
@@ -73,10 +73,10 @@ BOOL auth_init_guest(auth_methods **auth_method)
  * @return An NTSTATUS value based on the username
  **/
 
-static NTSTATUS check_name_to_ntstatus_security(void *my_private_data,
+static NTSTATUS check_name_to_ntstatus_security(const struct auth_context *auth_context,
+                                               void *my_private_data, 
                                                TALLOC_CTX *mem_ctx,
                                                const auth_usersupplied_info *user_info, 
-                                               const auth_authsupplied_info *auth_info,
                                                auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status;
@@ -100,9 +100,9 @@ static NTSTATUS check_name_to_ntstatus_security(void *my_private_data,
 }
 
 /** Module initailisation function */
-BOOL auth_init_name_to_ntstatus(auth_methods **auth_method) 
+BOOL auth_init_name_to_ntstatus(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, auth_method)) {
                return False;
        }
 
@@ -110,6 +110,3 @@ BOOL auth_init_name_to_ntstatus(auth_methods **auth_method)
        return True;
 }
 
-
-
-
diff --git a/source3/auth/auth_compat.c b/source3/auth/auth_compat.c
new file mode 100644 (file)
index 0000000..4039f0c
--- /dev/null
@@ -0,0 +1,111 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0.
+   Password and authentication handling
+   Copyright (C) Andrew Bartlett         2001-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
+   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"
+
+/****************************************************************************
+ COMPATABILITY INTERFACES:
+ ***************************************************************************/
+
+/****************************************************************************
+check if a username/password is OK assuming the password is a 24 byte
+SMB hash
+return True if the password is correct, False otherwise
+****************************************************************************/
+
+static NTSTATUS pass_check_smb(char *smb_name,
+                              char *domain, 
+                              DATA_BLOB lm_pwd,
+                              DATA_BLOB nt_pwd,
+                              DATA_BLOB plaintext_password,
+                              BOOL encrypted)
+
+{
+       NTSTATUS nt_status;
+       auth_usersupplied_info *user_info = NULL;
+       extern struct auth_context *negprot_global_auth_context;
+       auth_serversupplied_info *server_info = NULL;
+       if (encrypted) {                
+               make_user_info_for_reply_enc(&user_info, smb_name, 
+                                            domain,
+                                            lm_pwd, 
+                                            nt_pwd);
+               nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, 
+                                                                            user_info, &server_info);
+       } else {
+               struct auth_context *plaintext_auth_context = NULL;
+               const uint8 *chal;
+               if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
+                       return nt_status;
+               }
+
+               chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
+
+               if (!make_user_info_for_reply(&user_info, 
+                                             smb_name, domain, chal,
+                                             plaintext_password)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               
+               nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, 
+                                                                       user_info, &server_info); 
+               
+               plaintext_auth_context->free(&plaintext_auth_context);
+       }               
+       free_user_info(&user_info);
+       free_server_info(&server_info);
+       return nt_status;
+}
+
+/****************************************************************************
+check if a username/password pair is ok via the auth subsystem.
+return True if the password is correct, False otherwise
+****************************************************************************/
+BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
+{
+
+       DATA_BLOB null_password = data_blob(NULL, 0);
+       extern BOOL 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, encrypted))) {
+                       return True;
+               }
+               
+               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, encrypted))) {
+                       return True;
+               }
+       }
+
+       return False;
+}
+
+
index 6e3eb643d8c208e4cde93338ddd172d9da1f858d..e8363754063bd771f84ff1f333d40655f041aad3 100644 (file)
@@ -125,8 +125,10 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli)));
  Utility function to attempt a connection to an IP address of a DC.
 ************************************************************************/
 
-static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, struct in_addr *ip, 
-                                 unsigned char *trust_passwd)
+static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, 
+                                     const char *domain, 
+                                     struct in_addr *ip, 
+                                     unsigned char *trust_passwd)
 {
        fstring dc_name;
 
@@ -137,7 +139,7 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, struct in_addr *ip
        if (is_zero_ip(*ip))
                return NT_STATUS_UNSUCCESSFUL;
 
-       if (!lookup_dc_name(global_myname, lp_workgroup(), ip, dc_name))
+       if (!lookup_dc_name(global_myname, domain, ip, dc_name))
                return NT_STATUS_UNSUCCESSFUL;
 
        return connect_to_domain_password_server(cli, dc_name, trust_passwd);
@@ -145,11 +147,12 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, struct in_addr *ip
 
 /***********************************************************************
  We have been asked to dynamcially determine the IP addresses of
- the PDC and BDC's for this DOMAIN, and query them in turn.
+ the PDC and BDC's for DOMAIN, and query them in turn.
 ************************************************************************/
 static NTSTATUS find_connect_pdc(struct cli_state **cli, 
-                               unsigned char *trust_passwd, 
-                               time_t last_change_time)
+                                const char *domain,
+                                unsigned char *trust_passwd, 
+                                time_t last_change_time)
 {
        struct in_addr *ip_list = NULL;
        int count = 0;
@@ -169,7 +172,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
        if (time_now - last_change_time < 3600)
                use_pdc_only = True;
 
-       if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count))
+       if (!get_dc_list(use_pdc_only, domain, &ip_list, &count))
                return NT_STATUS_UNSUCCESSFUL;
 
        /*
@@ -180,7 +183,9 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
                if(!is_local_net(ip_list[i]))
                        continue;
 
-               if(NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, &ip_list[i], trust_passwd))) 
+               if(NT_STATUS_IS_OK(nt_status = 
+                                  attempt_connect_to_dc(cli, domain, 
+                                                        &ip_list[i], trust_passwd))) 
                        break;
                
                zero_ip(&ip_list[i]); /* Tried and failed. */
@@ -192,7 +197,9 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
        if(!NT_STATUS_IS_OK(nt_status)) {
                i = (sys_random() % count);
 
-               if (!NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, &ip_list[i], trust_passwd)))
+               if (!NT_STATUS_IS_OK(nt_status = 
+                                    attempt_connect_to_dc(cli, domain, 
+                                                          &ip_list[i], trust_passwd)))
                         zero_ip(&ip_list[i]); /* Tried and failed. */
        }
 
@@ -206,7 +213,9 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
                 * Note that from a WINS server the #1 IP address is the PDC.
                 */
                for(i = 0; i < count; i++) {
-                       if (NT_STATUS_IS_OK(nt_status = attempt_connect_to_dc(cli, &ip_list[i], trust_passwd)))
+                       if (NT_STATUS_IS_OK(nt_status = 
+                                           attempt_connect_to_dc(cli, domain, 
+                                                                 &ip_list[i], trust_passwd)))
                                break;
                }
        }
@@ -224,6 +233,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli,
 
 static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
                                       const auth_usersupplied_info *user_info, 
+                                      const char *domain,
                                       uchar chal[8],
                                       auth_serversupplied_info **server_info, 
                                       char *server, unsigned char *trust_passwd,
@@ -246,7 +256,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
        while (!NT_STATUS_IS_OK(nt_status) &&
               next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) {
                if(strequal(remote_machine, "*")) {
-                       nt_status = find_connect_pdc(&cli, trust_passwd, last_change_time);
+                       nt_status = find_connect_pdc(&cli, domain, trust_passwd, last_change_time);
                } else {
                        nt_status = connect_to_domain_password_server(&cli, remote_machine, trust_passwd);
                }
@@ -376,18 +386,19 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx,
  Check for a valid username and password in security=domain mode.
 ****************************************************************************/
 
-static NTSTATUS check_ntdomain_security(void *my_private_data,
+static NTSTATUS check_ntdomain_security(const struct auth_context *auth_context,
+                                       void *my_private_data, 
                                        TALLOC_CTX *mem_ctx,
                                        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;
        unsigned char trust_passwd[16];
        time_t last_change_time;
+       char *domain = lp_workgroup();
 
-       if (!user_info || !server_info || !auth_info) {
+       if (!user_info || !server_info || !auth_context) {
                DEBUG(1,("check_ntdomain_security: Critical variables not present.  Failing.\n"));
                return NT_STATUS_LOGON_FAILURE;
        }
@@ -409,7 +420,7 @@ static NTSTATUS check_ntdomain_security(void *my_private_data,
         * Get the machine account password for our primary domain
         */
 
-       if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time))
+       if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time))
        {
                DEBUG(0, ("check_domain_security: could not fetch trust account password for domain %s\n", lp_workgroup()));
                unbecome_root();
@@ -433,18 +444,22 @@ static NTSTATUS check_ntdomain_security(void *my_private_data,
        if (! *pserver) pserver = "*";
        p = pserver;
 
-       nt_status = domain_client_validate(mem_ctx, user_info, (uchar *)auth_info->challenge.data,server_info, 
+       nt_status = domain_client_validate(mem_ctx, user_info, domain,
+                                          (uchar *)auth_context->challenge.data, 
+                                          server_info, 
                                           p, trust_passwd, last_change_time);
        
        return nt_status;
 }
 
-BOOL auth_init_ntdomain(auth_methods **auth_method) 
+/* module initialisation */
+BOOL auth_init_ntdomain(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, 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
deleted file mode 100644 (file)
index 9d399a8..0000000
+++ /dev/null
@@ -1,313 +0,0 @@
-/* 
-   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"
-
-/** List of various built-in authenticaion modules */
-
-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 },       
-       { "samstrict", auth_init_samstrict },
-       { "unix", auth_init_unix },
-       { "smbserver", auth_init_smbserver },
-       { "ntdomain", auth_init_ntdomain },
-       { "winbind", auth_init_winbind },
-#ifdef DEVELOPER
-       { "name_to_ntstatus", auth_init_name_to_ntstatus },
-#endif
-       { NULL, NULL}
-};
-
-/***************************************************************************
- Free a linked list of auth methods
-***************************************************************************/
-
-static void free_auth_methods_list(auth_methods **list)
-{
-       if (list != NULL) {
-               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);
-               }
-               
-       }
-}
-
-/***************************************************************************
- 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;
-
-       if (!text_list) {
-               DEBUG(2,("No auth method list!?\n"));
-               return False;
-       }
-       
-       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));
-                               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;
-                       }
-               }
-       }
-       
-       if (!make_auth_info_list(auth_info, list)) {
-               free_auth_methods_list(&list);
-               return False;
-       }
-       
-       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 (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 samstrict 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");
-                       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");
-                       } else {
-                               DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n"));
-                               auth_method_list = lp_list_make("guest unix");
-                       }
-                       break;
-               case SEC_SHARE:
-                       if (lp_encrypted_passwords()) {
-                               DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n"));
-                               auth_method_list = lp_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");
-                       }
-                       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");
-                       break;
-               default:
-                       DEBUG(5,("Unknown auth method!\n"));
-                       return False;
-               }
-       } 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 challenge
-***************************************************************************/
-
-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)->challenge = data_blob(chal, sizeof(chal));
-
-       (*auth_info)->challenge_set_by = "random";
-
-       return True;
-}
-
-/***************************************************************************
- Make a auth_info struct with a fixed challenge
-***************************************************************************/
-
-BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8]) 
-{
-       if (!make_auth_info_subsystem(auth_info)) {
-               return False;
-       }
-       
-       (*auth_info)->challenge = 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)
-{
-       if (*auth_info != NULL) {
-               free_auth_methods_list(&(*auth_info)->auth_method_list);
-               
-               data_blob_free(&(*auth_info)->challenge);
-               ZERO_STRUCT(**auth_info);
-       }
-       SAFE_FREE(*auth_info);
-}
-
-/****************************************************************************
- Try to get a challenge out of the various authenticaion modules.
- It is up to the caller to free it.
-****************************************************************************/
-
-DATA_BLOB auth_get_challenge(auth_authsupplied_info *auth_info) 
-{
-       DATA_BLOB challenge = data_blob(NULL, 0);
-       char *challenge_set_by = NULL;
-       auth_methods *auth_method;
-       TALLOC_CTX *mem_ctx;
-
-       if (auth_info->challenge.length) {
-               DEBUG(5, ("auth_get_challenge: returning previous challenge (normal)\n"));
-               return data_blob(auth_info->challenge.data, auth_info->challenge.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_challenge: getting challenge from module %s\n", auth_method->name));
-                       if (challenge_set_by) {
-                               DEBUG(1, ("auth_get_challenge: CONFIGURATION ERROR: authenticaion method %s has already specified a challenge.  Challenge by %s ignored.\n", 
-                                         challenge_set_by, auth_method->name));
-                       } else {
-                               mem_ctx = talloc_init_named("auth_get_challange for module %s", auth_method->name);
-                               if (!mem_ctx) {
-                                       smb_panic("talloc_init_named() failed!");
-                               }
-                               
-                               challenge = auth_method->get_chal(&auth_method->private_data, mem_ctx, auth_info);
-                               if (challenge.length) {
-                                       DEBUG(5, ("auth_get_challenge: sucessfully got challenge from module %s\n", auth_method->name));
-                                       auth_info->challenge = challenge;
-                                       challenge_set_by = auth_method->name;
-                                       auth_info->challenge_set_method = auth_method;
-                               } else {
-                                       DEBUG(3, ("auth_get_challenge: getting challenge from authenticaion method %s FAILED.\n", 
-                                                 auth_method->name));
-                               }
-                               talloc_destroy(mem_ctx);
-                       }
-               } else {
-                       DEBUG(5, ("auth_get_challenge: module %s did not want to specify a challenge\n", auth_method->name));
-               }
-       }
-       
-       if (!challenge_set_by) {
-               uchar chal[8];
-               
-               generate_random_buffer(chal, sizeof(chal), False);
-               auth_info->challenge = data_blob(chal, sizeof(chal));
-               
-               challenge_set_by = "random";
-       } 
-       
-       DEBUG(5, ("auth_info challenge created by %s\n", challenge_set_by));
-       DEBUG(5, ("challenge is: \n"));
-       dump_data(5, auth_info->challenge.data, (auth_info)->challenge.length);
-       
-       SMB_ASSERT(auth_info->challenge.length == 8);
-
-       auth_info->challenge_set_by=challenge_set_by;
-
-       return data_blob(auth_info->challenge.data, auth_info->challenge.length);
-}
-
-
index 1dd97872da0e8d9f8c626b6bc69295c6dc1c7ad3..55ff7aa0604c4a2e12d4e94e497262efb7e06a0c 100644 (file)
@@ -155,10 +155,10 @@ static BOOL check_hosts_equiv(struct passwd *pass)
  Check for a valid .rhosts/hosts.equiv entry for this user
 ****************************************************************************/
 
-static NTSTATUS check_hostsequiv_security(void *my_private_data, 
+static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_context,
+                                         void *my_private_data, 
                                          TALLOC_CTX *mem_ctx,
                                          const auth_usersupplied_info *user_info, 
-                                         const auth_authsupplied_info *auth_info,
                                          auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
@@ -176,15 +176,26 @@ static NTSTATUS check_hostsequiv_security(void *my_private_data,
        return nt_status;
 }
 
+/* module initialisation */
+BOOL auth_init_hostsequiv(struct auth_context *auth_context, auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_context, auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_hostsequiv_security;
+       return True;
+}
+
 
 /****************************************************************************
  Check for a valid .rhosts/hosts.equiv entry for this user
 ****************************************************************************/
 
-static NTSTATUS check_rhosts_security(void *my_private_data, 
+static NTSTATUS check_rhosts_security(const struct auth_context *auth_context,
+                                     void *my_private_data, 
                                      TALLOC_CTX *mem_ctx,
                                      const auth_usersupplied_info *user_info, 
-                                     const auth_authsupplied_info *auth_info,
                                      auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
@@ -209,22 +220,13 @@ static NTSTATUS check_rhosts_security(void *my_private_data,
        return nt_status;
 }
 
-BOOL auth_init_hostsequiv(auth_methods **auth_method) 
+/* module initialisation */
+BOOL auth_init_rhosts(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, 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;
 }
index c8b5386f7af0cfd63b3e7d16d0d81ab067913471..f1bcae461e006621ae72fabf39312e509eadc110 100644 (file)
@@ -27,9 +27,9 @@
 core of smb password checking routine.
 ****************************************************************************/
 static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
-                               const uchar *part_passwd,
-                               DATA_BLOB sec_blob,
-                               uint8 user_sess_key[16])
+                                const uchar *part_passwd,
+                                DATA_BLOB sec_blob,
+                                uint8 user_sess_key[16])
 {
        /* Finish the encryption of part_passwd. */
        uchar p24[24];
@@ -75,10 +75,10 @@ static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response,
 core of smb password checking routine.
 ****************************************************************************/
 static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
-                               const uchar *part_passwd,
-                               const DATA_BLOB sec_blob,
-                               const char *user, const char *domain,
-                               uint8 user_sess_key[16])
+                                const uchar *part_passwd,
+                                const DATA_BLOB sec_blob,
+                                const char *user, const char *domain,
+                                uint8 user_sess_key[16])
 {
        /* Finish the encryption of part_passwd. */
        uchar kr[16];
@@ -132,10 +132,10 @@ 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.
 ****************************************************************************/
-static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
+static NTSTATUS sam_password_ok(const struct auth_context *auth_context,
+                               TALLOC_CTX *mem_ctx,
                                SAM_ACCOUNT *sampass, 
                                const auth_usersupplied_info *user_info, 
-                               const auth_authsupplied_info *auth_info,
                                uint8 user_sess_key[16])
 {
        uint16 acct_ctrl;
@@ -175,7 +175,7 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
                */
                DEBUG(4,("sam_password_ok: Checking NTLMv2 password\n"));
                if (smb_pwd_check_ntlmv2( user_info->nt_resp, 
-                                         nt_pw, auth_info->challenge, 
+                                         nt_pw, auth_context->challenge, 
                                          user_info->smb_name.str, 
                                          user_info->client_domain.str,
                                          user_sess_key))
@@ -192,7 +192,7 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
                        */
                        DEBUG(4,("sam_password_ok: Checking NT MD4 password\n"));
                        if (smb_pwd_check_ntlmv1(user_info->nt_resp, 
-                                                nt_pw, auth_info->challenge,
+                                                nt_pw, auth_context->challenge,
                                                 user_sess_key)) 
                        {
                                return NT_STATUS_OK;
@@ -225,7 +225,7 @@ static NTSTATUS sam_password_ok(TALLOC_CTX *mem_ctx,
                
                DEBUG(4,("sam_password_ok: Checking LM password\n"));
                if (smb_pwd_check_ntlmv1(user_info->lm_resp, 
-                                        lm_pw, auth_info->challenge,
+                                        lm_pw, auth_context->challenge,
                                         user_sess_key)) 
                {
                        return NT_STATUS_OK;
@@ -337,10 +337,10 @@ SMB hash supplied in the user_info structure
 return an NT_STATUS constant.
 ****************************************************************************/
 
-static NTSTATUS check_sam_security(void *my_private_data,
+static NTSTATUS check_sam_security(const struct auth_context *auth_context,
+                                  void *my_private_data, 
                                   TALLOC_CTX *mem_ctx,
                                   const auth_usersupplied_info *user_info, 
-                                  const auth_authsupplied_info *auth_info,
                                   auth_serversupplied_info **server_info)
 {
        SAM_ACCOUNT *sampass=NULL;
@@ -349,8 +349,8 @@ static NTSTATUS check_sam_security(void *my_private_data,
        uint8 user_sess_key[16];
        const uint8* lm_hash;
 
-       if (!user_info || !auth_info) {
-               return NT_STATUS_LOGON_FAILURE;
+       if (!user_info || !auth_context) {
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
        if (!pdb_init_sam(&sampass)) {
@@ -370,7 +370,7 @@ static NTSTATUS check_sam_security(void *my_private_data,
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       nt_status = sam_password_ok(mem_ctx, sampass, user_info, auth_info, user_sess_key);
+       nt_status = sam_password_ok(auth_context, mem_ctx, sampass, user_info, user_sess_key);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                pdb_free_sam(&sampass);
@@ -399,9 +399,10 @@ static NTSTATUS check_sam_security(void *my_private_data,
        return nt_status;
 }
 
-BOOL auth_init_sam(auth_methods **auth_method) 
+/* module initialisation */
+BOOL auth_init_sam(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, auth_method)) {
                return False;
        }
 
@@ -409,20 +410,19 @@ BOOL auth_init_sam(auth_methods **auth_method)
        return True;
 }
 
+
 /****************************************************************************
-check if a username/password is OK assuming the password is a 24 byte
-SMB hash supplied in the user_info structure
-return an NT_STATUS constant.
+Check SAM security (above) but with a few extra checks.
 ****************************************************************************/
 
-static NTSTATUS check_samstrict_security(void *my_private_data,
+static NTSTATUS check_samstrict_security(const struct auth_context *auth_context,
+                                        void *my_private_data, 
                                         TALLOC_CTX *mem_ctx,
                                         const auth_usersupplied_info *user_info, 
-                                        const auth_authsupplied_info *auth_info,
                                         auth_serversupplied_info **server_info)
 {
 
-       if (!user_info || !auth_info) {
+       if (!user_info || !auth_context) {
                return NT_STATUS_LOGON_FAILURE;
        }
 
@@ -434,12 +434,13 @@ static NTSTATUS check_samstrict_security(void *my_private_data,
                return NT_STATUS_NO_SUCH_USER;
        }
        
-       return check_sam_security(my_private_data, mem_ctx, user_info, auth_info, server_info);
+       return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info);
 }
 
-BOOL auth_init_samstrict(auth_methods **auth_method) 
+/* module initialisation */
+BOOL auth_init_samstrict(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, auth_method)) {
                return False;
        }
 
@@ -447,3 +448,4 @@ BOOL auth_init_samstrict(auth_methods **auth_method)
        return True;
 }
 
+
index 7178e3147c4fcfba7302dd3d42bc255dfa08001c..c83230b7167ba1868f4740c83c2b84af6ddde9fe 100644 (file)
@@ -134,9 +134,9 @@ static void send_server_keepalive(void **private_data_pointer)
  Get the challenge out of a password server.
 ****************************************************************************/
 
-static DATA_BLOB auth_get_challenge_server(void **my_private_data, 
-                                          TALLOC_CTX *mem_ctx,
-                                          const struct authsupplied_info *auth_info) 
+static DATA_BLOB auth_get_challenge_server(const struct auth_context *auth_context,
+                                          void **my_private_data, 
+                                          TALLOC_CTX *mem_ctx)
 {
        struct cli_state *cli = server_cryptkey(mem_ctx);
        
@@ -161,8 +161,10 @@ static DATA_BLOB auth_get_challenge_server(void **my_private_data,
                }
 
                *my_private_data = (void *)cli;
-               
-               return data_blob(cli->secblob.data,8);
+
+               /* The return must be allocated on the caller's mem_ctx, as our own will be
+                  destoyed just after the call. */
+               return data_blob_talloc(auth_context->mem_ctx, cli->secblob.data,8);
        } else {
                return data_blob(NULL, 0);
        }
@@ -174,10 +176,10 @@ static DATA_BLOB auth_get_challenge_server(void **my_private_data,
   - Validate a password with the password server.
 ****************************************************************************/
 
-static NTSTATUS check_smbserver_security(void *my_private_data, 
+static NTSTATUS check_smbserver_security(const struct auth_context *auth_context,
+                                        void *my_private_data, 
                                         TALLOC_CTX *mem_ctx,
                                         const auth_usersupplied_info *user_info, 
-                                        const auth_authsupplied_info *auth_info,
                                         auth_serversupplied_info **server_info)
 {
        struct cli_state *cli;
@@ -218,7 +220,7 @@ static NTSTATUS check_smbserver_security(void *my_private_data,
                        return NT_STATUS_LOGON_FAILURE;         
                }
        } else {
-               if (memcmp(cli->secblob.data, auth_info->challenge.data, 8) != 0) {
+               if (memcmp(cli->secblob.data, auth_context->challenge.data, 8) != 0) {
                        DEBUG(1,("the challenge 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;         
                }
@@ -353,9 +355,9 @@ use this machine as the password server.\n"));
        return(nt_status);
 }
 
-BOOL auth_init_smbserver(auth_methods **auth_method) 
+BOOL auth_init_smbserver(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, auth_method)) {
                return False;
        }
        (*auth_method)->auth = check_smbserver_security;
index fa889af5f6ced0e4fa02127164b267a7df163420..69c24b8213d3f0dfdc22039100418ebaf999fcb0 100644 (file)
@@ -83,10 +83,10 @@ static BOOL update_smbpassword_file(char *user, char *password)
  * unless the account has a null password.
  **/
 
-NTSTATUS check_unix_security(void *my_private_data, 
+static NTSTATUS check_unix_security(const struct auth_context *auth_context,
+                            void *my_private_data, 
                             TALLOC_CTX *mem_ctx,
                             const auth_usersupplied_info *user_info, 
-                            const auth_authsupplied_info *auth_info,
                             auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status;
@@ -120,11 +120,13 @@ NTSTATUS check_unix_security(void *my_private_data,
        return nt_status;
 }
 
-BOOL auth_init_unix(auth_methods **auth_method) 
+/* module initialisation */
+BOOL auth_init_unix(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, auth_method)) {
                return False;
        }
+
        (*auth_method)->auth = check_unix_security;
        return True;
 }
index d9f3098e7c6fb10486300ce7aef905e65260b39e..a479f52ab2340068abe972f2ac992a76bbc1f984 100644 (file)
@@ -276,13 +276,13 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
-                                        char *smb_name, 
-                                        char *client_domain, 
-                                        char *wksta_name, 
-                                        uchar chal[8], 
-                                        uchar lm_interactive_pwd[16], 
-                                        uchar nt_interactive_pwd[16], 
-                                        uchar *dc_sess_key)
+                                        const char *smb_name, 
+                                        const char *client_domain, 
+                                        const char *wksta_name, 
+                                        const uchar chal[8], 
+                                        const uchar lm_interactive_pwd[16], 
+                                        const uchar nt_interactive_pwd[16], 
+                                        const uchar *dc_sess_key)
 {
        char lm_pwd[16];
        char nt_pwd[16];
@@ -360,7 +360,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
                              char *smb_name, 
                              char *client_domain,
-                             unsigned char chal[8],
+                             const uint8 chal[8],
                              DATA_BLOB plaintext_password)
 {
 
@@ -383,7 +383,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
                dump_data(100, plaintext_password.data, plaintext_password.length);
 #endif
 
-               SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
+               SMBencrypt( (const uchar *)plaintext_password.data, (const uchar*)chal, local_lm_response);
                local_lm_blob = data_blob(local_lm_response, 24);
                
                /* We can't do an NT hash here, as the password needs to be
@@ -415,8 +415,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
 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)
+                             DATA_BLOB lm_resp, DATA_BLOB nt_resp)
 {
        uint32 ntlmssp_flags = 0;
 
@@ -572,9 +571,17 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info)
  Make an auth_methods struct
 ***************************************************************************/
 
-BOOL make_auth_methods(auth_methods **auth_method) 
+BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       *auth_method = malloc(sizeof(**auth_method));
+       if (!auth_context) {
+               smb_panic("no auth_context supplied to make_auth_methods()!\n");
+       }
+
+       if (!auth_method) {
+               smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");
+       }
+
+       *auth_method = talloc(auth_context->mem_ctx, sizeof(**auth_method));
        if (!*auth_method) {
                DEBUG(0,("make_auth_method: malloc failed!\n"));
                return False;
@@ -623,3 +630,33 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
 
        return token;
 }
+
+/**
+ * Squash an NT_STATUS in line with security requirements.
+ * In an attempt to avoid giving the whole game away when users
+ * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and 
+ * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations 
+ * (session setups in particular).
+ *
+ * @param nt_status NTSTATUS input for squashing.
+ * @return the 'squashed' nt_status
+ **/
+
+NTSTATUS nt_status_squash(NTSTATUS nt_status)
+{
+       if NT_STATUS_IS_OK(nt_status) {
+               return nt_status;               
+       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
+               /* Match WinXP and don't give the game away */
+               return NT_STATUS_LOGON_FAILURE;
+               
+       } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
+               /* Match WinXP and don't give the game away */
+               return NT_STATUS_LOGON_FAILURE;
+       } else {
+               return nt_status;
+       }  
+}
+
+
+
index 74654f8bba2a00282159986394cdbc169043cbea..175e14a9d60fcc0afb1c64a8ca7e9fbbbce31ec0 100644 (file)
@@ -33,10 +33,10 @@ NSS_STATUS winbindd_request(int req_type,
 
 /* Authenticate a user with a challenge/response */
 
-static NTSTATUS check_winbind_security(void *my_private_data,
+static NTSTATUS check_winbind_security(const struct auth_context *auth_context,
+                                      void *my_private_data, 
                                       TALLOC_CTX *mem_ctx,
                                       const auth_usersupplied_info *user_info, 
-                                      const auth_authsupplied_info *auth_info,
                                       auth_serversupplied_info **server_info)
 {
        struct winbindd_request request;
@@ -46,13 +46,13 @@ static NTSTATUS check_winbind_security(void *my_private_data,
        NTSTATUS nt_status;
 
        if (!user_info) {
-               return NT_STATUS_LOGON_FAILURE;
+               return NT_STATUS_UNSUCCESSFUL;
        }
 
-       if (!auth_info) {
+       if (!auth_context) {
                DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n", 
                         user_info->internal_username.str));            
-               return NT_STATUS_LOGON_FAILURE;
+               return NT_STATUS_UNSUCCESSFUL;
        }               
 
        /* Send off request */
@@ -63,7 +63,7 @@ static NTSTATUS check_winbind_security(void *my_private_data,
        snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user),
                 "%s\\%s", user_info->domain.str, user_info->smb_name.str);
 
-       memcpy(request.data.auth_crap.chal, auth_info->challenge.data, sizeof(request.data.auth_crap.chal));
+       memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal));
        
        request.data.auth_crap.lm_resp_len = MIN(user_info->lm_resp.length, 
                                                 sizeof(request.data.auth_crap.lm_resp));
@@ -97,16 +97,13 @@ static NTSTATUS check_winbind_security(void *my_private_data,
         return nt_status;
 }
 
-BOOL auth_init_winbind(auth_methods **auth_method) 
+/* module initialisation */
+BOOL auth_init_winbind(struct auth_context *auth_context, auth_methods **auth_method) 
 {
-       if (!make_auth_methods(auth_method)) {
+       if (!make_auth_methods(auth_context, auth_method)) {
                return False;
        }
 
        (*auth_method)->auth = check_winbind_security;
        return True;
 }
-
-
-
-
index b823e7bf4be39445590b42d95e9eef02c7fc8064..fb486162737fec9bbde332309cc8a8d62e04a624 100644 (file)
@@ -41,7 +41,7 @@ typedef struct interactive_password
        OWF_INFO          nt_owf;              /* NT OWF Password */
 } auth_interactive_password;
 
-typedef struct usersupplied_info
+typedef struct auth_usersupplied_info
 {
        
        DATA_BLOB lm_resp;
@@ -67,7 +67,7 @@ typedef struct usersupplied_info
 #define SAM_FILL_UNIX  0x08
 #define SAM_FILL_ALL (SAM_FILL_NAME | SAM_FILL_INFO3 | SAM_FILL_SAM | SAM_FILL_UNIX)
 
-typedef struct serversupplied_info 
+typedef struct auth_serversupplied_info 
 {
        BOOL guest;
        
@@ -91,7 +91,7 @@ typedef struct serversupplied_info
        
 } auth_serversupplied_info;
 
-typedef struct authsupplied_info {
+struct auth_context {
        DATA_BLOB challenge; 
 
        /* Who set this up in the first place? */ 
@@ -100,22 +100,30 @@ typedef struct authsupplied_info {
        struct auth_methods *challenge_set_method; 
        /* What order are the various methods in?   Try to stop it changing under us */ 
        struct auth_methods *auth_method_list;  
-} auth_authsupplied_info;
+
+       TALLOC_CTX *mem_ctx;
+       const uint8 *(*get_ntlm_challenge)(struct auth_context *auth_context);
+       NTSTATUS (*check_ntlm_password)(const struct auth_context *auth_context,
+                                       const struct auth_usersupplied_info *user_info, 
+                                       struct auth_serversupplied_info **server_info);
+       NTSTATUS (*nt_status_squash)(NTSTATUS nt_status);
+       void (*free)(struct auth_context **auth_context);
+};
 
 typedef struct auth_methods
 {
        struct auth_methods *prev, *next;
        char *name; /* What name got this module */
 
-       NTSTATUS (*auth)(void *my_private_data, 
+       NTSTATUS (*auth)(const struct auth_context *auth_context,
+                        void *my_private_data, 
                         TALLOC_CTX *mem_ctx,
-                        const auth_usersupplied_info *user_info, 
-                        const struct authsupplied_info *auth_info,
+                        const struct auth_usersupplied_info *user_info, 
                         auth_serversupplied_info **server_info);
 
-       DATA_BLOB (*get_chal)(void **my_private_data, 
-                             TALLOC_CTX *mem_ctx
-                             const struct authsupplied_info *auth_info);
+       DATA_BLOB (*get_chal)(const struct auth_context *auth_context,
+                             void **my_private_data
+                             TALLOC_CTX *mem_ctx);
        
        /* Used to keep tabs on things like the cli for SMB server authentication */
        void *private_data;
@@ -128,11 +136,11 @@ typedef struct auth_methods
 
 } auth_methods;
 
-typedef struct auth_init_function {
+struct auth_init_function {
        char *name;
        /* Function to create a member of the authmethods list */
-       BOOL (*init)(struct auth_methods **auth_method);
-} auth_init_function;
+       BOOL (*init)(struct auth_context *auth_context, struct auth_methods **auth_method);
+};
 
 
 #endif /* _SMBAUTH_H_ */
index 634e2540fa6abec271b156471d81d09c84a7b1b6..fbab46022cad79121b37e28c95a2d5034c4bb5de 100644 (file)
@@ -568,19 +568,24 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
        switch (ctr->switch_value) {
        case NET_LOGON_TYPE:
        {
-               auth_authsupplied_info *auth_info = NULL;
-               make_auth_info_fixed(&auth_info, ctr->auth.id2.lm_chal);
+               struct auth_context *auth_context = NULL;
+               if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) {
+                       return status;
+               }
+
                /* Standard challenge/response authenticaion */
-               make_user_info_netlogon_network(&user_info, 
-                                               nt_username, nt_domain, 
-                                               nt_workstation, 
-                                               ctr->auth.id2.lm_chal_resp.buffer,
-                                               ctr->auth.id2.lm_chal_resp.str_str_len,
-                                               ctr->auth.id2.nt_chal_resp.buffer,
-                                               ctr->auth.id2.nt_chal_resp.str_str_len);
-
-               status = check_password(user_info, auth_info, &server_info);
-               free_auth_info(&auth_info);
+               if (!make_user_info_netlogon_network(&user_info, 
+                                                    nt_username, nt_domain, 
+                                                    nt_workstation, 
+                                                    ctr->auth.id2.lm_chal_resp.buffer,
+                                                    ctr->auth.id2.lm_chal_resp.str_str_len,
+                                                    ctr->auth.id2.nt_chal_resp.buffer,
+                                                    ctr->auth.id2.nt_chal_resp.str_str_len)) {
+                       status = NT_STATUS_NO_MEMORY;
+               } else {
+                       status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
+               }
+               auth_context->free(&auth_context);
                        
                break;
        }
@@ -590,23 +595,26 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                   convert this to chellange/responce for the auth
                   subsystem to chew on */
        {
-               auth_authsupplied_info *auth_info = NULL;
-               DATA_BLOB chal;
-               if (!make_auth_info_subsystem(&auth_info)) {
-                       return NT_STATUS_NO_MEMORY;
+               struct auth_context *auth_context = NULL;
+               const uint8 *chal;
+               if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
+                       return status;
                }
                
-               chal = auth_get_challenge(auth_info);
-
-               make_user_info_netlogon_interactive(&user_info, 
-                                                   nt_username, nt_domain, 
-                                                   nt_workstation, chal.data,
-                                                   ctr->auth.id1.lm_owf.data, 
-                                                   ctr->auth.id1.nt_owf.data, 
-                                                   p->dc.sess_key);
-               status = check_password(user_info, auth_info, &server_info);
-               data_blob_free(&chal);
-               free_auth_info(&auth_info);
+               chal = auth_context->get_ntlm_challenge(auth_context);
+
+               if (!make_user_info_netlogon_interactive(&user_info, 
+                                                        nt_username, nt_domain, 
+                                                        nt_workstation, chal,
+                                                        ctr->auth.id1.lm_owf.data, 
+                                                        ctr->auth.id1.nt_owf.data, 
+                                                        p->dc.sess_key)) {
+                       status = NT_STATUS_NO_MEMORY;
+               } else {
+                       status = auth_context->check_ntlm_password(auth_context, user_info, &server_info);
+               }
+
+               auth_context->free(&auth_context);
 
                break;
        }
index c97619c4b6c4085c4a1815a9574724785432ac61..36ca7e0686d480f6a21ffe2e22d88542ebb4134f 100644 (file)
@@ -270,8 +270,8 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
 
        NTSTATUS nt_status;
 
+       struct auth_context *auth_context = NULL;
        auth_usersupplied_info *user_info = NULL;
-       auth_authsupplied_info *auth_info = NULL;
        auth_serversupplied_info *server_info = NULL;
 
        uid_t uid;
@@ -345,7 +345,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
 
        }
        
-       make_auth_info_fixed(&auth_info, (uchar*)p->challenge);
+       make_auth_context_fixed(&auth_context, (uchar*)p->challenge);
 
        if (!make_user_info_netlogon_network(&user_info, 
                                             user_name, domain, wks,
@@ -355,9 +355,9 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
                return False;
        }
        
-       nt_status = check_password(user_info, auth_info, &server_info); 
+       nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); 
        
-       free_auth_info(&auth_info);
+       auth_context->free(&auth_context);
        free_user_info(&user_info);
        
        p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
index d3afa19d00684dfca3845ba139215169209f3014..52ba5e97892e35a46079a719e84eeecf288f4360 100644 (file)
@@ -27,7 +27,28 @@ extern fstring global_myworkgroup;
 extern fstring remote_machine;
 BOOL global_encrypted_passwords_negotiated = False;
 BOOL global_spnego_negotiated = False;
-auth_authsupplied_info *negprot_global_auth_info = NULL;
+struct auth_context *negprot_global_auth_context = NULL;
+
+static void get_challange(char buff[8]) 
+{
+       NTSTATUS nt_status;
+       const uint8 *cryptkey;
+
+       /* We might be called more than once, muliple negprots are premitted */
+       if (negprot_global_auth_context) {
+               DEBUG(3, ("get challange: is this a secondary negprot?  negprot_global_auth_context is non-NULL!\n"));
+               negprot_global_auth_context->free(&negprot_global_auth_context);
+       }
+
+       DEBUG(10, ("get challange: creating negprot_global_auth_context\n"));
+       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&negprot_global_auth_context))) {
+               DEBUG(0, ("make_auth_context_subsystem returned %s", get_nt_error_msg(nt_status)));
+               smb_panic("cannot make_negprot_global_auth_context!\n");
+       }
+       DEBUG(10, ("get challange: getting challange\n"));
+       cryptkey = negprot_global_auth_context->get_ntlm_challenge(negprot_global_auth_context);
+       memcpy(buff, cryptkey, 8);
+}
 
 /****************************************************************************
 reply for the core protocol
@@ -69,7 +90,6 @@ static int reply_lanman1(char *inbuf, char *outbuf)
   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
   int secword=0;
   time_t t = time(NULL);
-  DATA_BLOB cryptkey;
 
   global_encrypted_passwords_negotiated = lp_encrypted_passwords();
 
@@ -80,12 +100,7 @@ static int reply_lanman1(char *inbuf, char *outbuf)
   SSVAL(outbuf,smb_vwv1,secword); 
   /* Create a token value and add it to the outgoing packet. */
   if (global_encrypted_passwords_negotiated) {
-         if (!make_auth_info_subsystem(&negprot_global_auth_info)) {
-                 smb_panic("cannot make_negprot_global_auth_info!\n");
-         }
-         cryptkey = auth_get_challenge(negprot_global_auth_info);
-         memcpy(smb_buf(outbuf), cryptkey.data, 8);
-         data_blob_free(&cryptkey);
+         get_challange(smb_buf(outbuf));
   }
 
   Protocol = PROTOCOL_LANMAN1;
@@ -114,7 +129,6 @@ static int reply_lanman2(char *inbuf, char *outbuf)
   int raw = (lp_readraw()?1:0) | (lp_writeraw()?2:0);
   int secword=0;
   time_t t = time(NULL);
-  DATA_BLOB cryptkey;
 
   global_encrypted_passwords_negotiated = lp_encrypted_passwords();
   
@@ -125,13 +139,9 @@ static int reply_lanman2(char *inbuf, char *outbuf)
   SSVAL(outbuf,smb_vwv1,secword); 
   SIVAL(outbuf,smb_vwv6,sys_getpid());
 
+  /* Create a token value and add it to the outgoing packet. */
   if (global_encrypted_passwords_negotiated) {
-         if (!make_auth_info_subsystem(&negprot_global_auth_info)) {
-                 smb_panic("cannot make_negprot_global_auth_info!\n");
-         }
-         cryptkey = auth_get_challenge(negprot_global_auth_info);
-         memcpy(smb_buf(outbuf), cryptkey.data, 8);
-         data_blob_free(&cryptkey);
+         get_challange(smb_buf(outbuf));
   }
 
   Protocol = PROTOCOL_LANMAN2;
@@ -216,7 +226,6 @@ static int reply_nt1(char *inbuf, char *outbuf)
 
        int secword=0;
        time_t t = time(NULL);
-       DATA_BLOB cryptkey;
        char *p, *q;
        BOOL negotiate_spnego = False;
 
@@ -275,13 +284,9 @@ static int reply_nt1(char *inbuf, char *outbuf)
        
        p = q = smb_buf(outbuf);
        if (!negotiate_spnego) {
-               if (global_encrypted_passwords_negotiated) { 
-                       if (!make_auth_info_subsystem(&negprot_global_auth_info)) {
-                               smb_panic("cannot make_negprot_global_auth_info!\n");
-                       }
-                       cryptkey = auth_get_challenge(negprot_global_auth_info);
-                       memcpy(p, cryptkey.data, 8);
-                       data_blob_free(&cryptkey);
+               /* Create a token value and add it to the outgoing packet. */
+               if (global_encrypted_passwords_negotiated) {
+                       get_challange(p);
                }
                SSVALS(outbuf,smb_vwv16+1,8);
                p += 8;
index af081d5059a1683bdafa74f6cefd463f0b26b2e2..2b31a24ceda6a829799552b68107d63fbcbbaf4f 100644 (file)
@@ -1112,7 +1112,7 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
 
   if (keepalive && (t - last_keepalive_sent_time)>keepalive) 
   {
-         extern auth_authsupplied_info *negprot_global_auth_info;
+         extern struct auth_context *negprot_global_auth_context;
          if (!send_keepalive(smbd_server_fd())) {
                  DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
                  return False;
@@ -1121,11 +1121,11 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
          /* send a keepalive for a password server or the like.
             This is attached to the auth_info created in the
             negprot */
-         if (negprot_global_auth_info 
-             && negprot_global_auth_info->challenge_set_method 
-             && negprot_global_auth_info->challenge_set_method->send_keepalive) {
-                 negprot_global_auth_info->challenge_set_method->send_keepalive
-                         (&negprot_global_auth_info->challenge_set_method->private_data);
+         if (negprot_global_auth_context 
+             && negprot_global_auth_context->challenge_set_method 
+             && negprot_global_auth_context->challenge_set_method->send_keepalive) {
+                 negprot_global_auth_context->challenge_set_method->send_keepalive
+                         (&negprot_global_auth_context->challenge_set_method->private_data);
          }
 
          last_keepalive_sent_time = t;
index 900f5b4846f12338c2991f0c950cafa40ecdfcf9..1fab45048dc53540c39eed5f6173935339c636b1 100644 (file)
@@ -475,7 +475,7 @@ void exit_server(char *reason)
 {
        static int firsttime=1;
        extern char *last_inbuf;
-       extern auth_authsupplied_info *negprot_global_auth_info;
+       extern struct auth_context *negprot_global_auth_context;
 
        if (!firsttime)
                exit(0);
@@ -484,7 +484,9 @@ void exit_server(char *reason)
        change_to_root_user();
        DEBUG(2,("Closing connections\n"));
 
-       free_auth_info(&negprot_global_auth_info);
+       if (negprot_global_auth_context) {
+               negprot_global_auth_context->free(&negprot_global_auth_context);
+       }
 
        conn_close_all();
 
index 41a7a657e2162b37c52706827fa564d2ff895155..737ecade7d7a469f66d1b0d72ddbac9bd47acfeb 100644 (file)
@@ -23,7 +23,7 @@
 #include "includes.h"
 
 uint32 global_client_caps = 0;
-static auth_authsupplied_info *ntlmssp_auth_info;
+static struct auth_context *ntlmssp_auth_context;
 
 /*
   on a logon error possibly map the error to success if "map to guest"
@@ -72,8 +72,7 @@ static void add_signature(char *outbuf)
 ****************************************************************************/
 static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) 
 {
-
-       auth_authsupplied_info *auth_info;
+       struct auth_context *auth_context;
        auth_usersupplied_info *user_info = NULL;
        
        NTSTATUS nt_status;
@@ -83,11 +82,17 @@ static NTSTATUS check_guest_password(auth_serversupplied_info **server_info)
 
        DEBUG(3,("Got anonymous request\n"));
 
-       make_user_info_guest(&user_info);
-       make_auth_info_fixed(&auth_info, chal);
+       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_fixed(&auth_context, chal))) {
+               return nt_status;
+       }
+
+       if (!make_user_info_guest(&user_info)) {
+               auth_context->free(&auth_context);
+               return NT_STATUS_NO_MEMORY;
+       }
        
-       nt_status = check_password(user_info, auth_info, server_info);
-       free_auth_info(&auth_info);
+       nt_status = auth_context->check_ntlm_password(auth_context, user_info, server_info);
+       auth_context->free(&auth_context);
        free_user_info(&user_info);
        return nt_status;
 }
@@ -233,8 +238,9 @@ static int reply_spnego_negotiate(connection_struct *conn,
        int i;
        uint32 ntlmssp_command, neg_flags;
        DATA_BLOB sess_key, chal, spnego_chal;
-       DATA_BLOB cryptkey;
+       const uint8 *cryptkey;
        BOOL got_kerberos = False;
+       NTSTATUS nt_status;
 
        /* parse out the OIDs and the first sec blob */
        if (!parse_negTokenTarg(blob1, OIDs, &secblob)) {
@@ -282,11 +288,15 @@ static int reply_spnego_negotiate(connection_struct *conn,
 
        DEBUG(3,("Got neg_flags=%08x\n", neg_flags));
 
-       if (!make_auth_info_subsystem(&ntlmssp_auth_info)) {
-               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       if (!ntlmssp_auth_context) {
+               ntlmssp_auth_context->free(&ntlmssp_auth_context);
+       }
+
+       if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&ntlmssp_auth_context))) {
+               return ERROR_NT(nt_status);
        }
 
-       cryptkey = auth_get_challenge(ntlmssp_auth_info);
+       cryptkey = ntlmssp_auth_context->get_ntlm_challenge(ntlmssp_auth_context);
 
        /* Give them the challenge. For now, ignore neg_flags and just
           return the flags we want. Obviously this is not correct */
@@ -301,7 +311,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
                  0,
                  0x30, /* ?? */
                  neg_flags,
-                 cryptkey.data, cryptkey.length,
+                 cryptkey, sizeof(cryptkey),
                  0, 0, 0,
                  0x3000); /* ?? */
 
@@ -314,7 +324,6 @@ static int reply_spnego_negotiate(connection_struct *conn,
        reply_sesssetup_blob(conn, outbuf, spnego_chal);
 
        data_blob_free(&chal);
-       data_blob_free(&cryptkey);
        data_blob_free(&spnego_chal);
 
        /* and tell smbd that we have already replied to this packet */
@@ -382,7 +391,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
                return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
 
-       nt_status = check_password(user_info, ntlmssp_auth_info, &server_info); 
+       nt_status = ntlmssp_auth_context->check_ntlm_password(ntlmssp_auth_context, user_info, &server_info); 
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                nt_status = do_map_to_guest(nt_status, &server_info, user, workgroup);
@@ -391,7 +400,7 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
        SAFE_FREE(workgroup);
        SAFE_FREE(machine);
                        
-       free_auth_info(&ntlmssp_auth_info);
+       ntlmssp_auth_context->free(&ntlmssp_auth_context);
 
        free_user_info(&user_info);
        
@@ -544,7 +553,7 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        extern int max_send;
 
        auth_usersupplied_info *user_info = NULL;
-       extern auth_authsupplied_info *negprot_global_auth_info;
+       extern struct auth_context *negprot_global_auth_context;
        auth_serversupplied_info *server_info = NULL;
 
        NTSTATUS nt_status;
@@ -671,13 +680,6 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
 
        DEBUG(3,("sesssetupX:name=[%s]\\[%s]@[%s]\n", domain, user, remote_machine));
 
-       if (*user) {
-               if (global_spnego_negotiated) {
-                       DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
-                       return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
-               }
-       }
-
        if (*user) {
                pstrcpy(sub_user, user);
        } else {
@@ -702,37 +704,46 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        }
        
        if (!*user) {
+               if (global_spnego_negotiated) {
+
+                       /* This has to be here, becouse this is a perfectly valid behaviour for guest logons :-( */
+
+                       DEBUG(0,("reply_sesssetup_and_X:  Rejecting attempt at 'normal' session setup after negotiating spnego.\n"));
+                       return ERROR_NT(NT_STATUS_UNSUCCESSFUL);
+               }
 
                nt_status = check_guest_password(&server_info);
 
        } else if (doencrypt) {
                if (!make_user_info_for_reply_enc(&user_info, 
                                                  user, domain, 
-                                                 lm_resp, nt_resp,
-                                                 plaintext_password)) {
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
+                                                 lm_resp, nt_resp)) {
+                       nt_status = NT_STATUS_NO_MEMORY;
+               } else {
+                       nt_status = negprot_global_auth_context->check_ntlm_password(negprot_global_auth_context, 
+                                                                                    user_info, 
+                                                                                    &server_info);
                }
-               
-               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 ERROR_NT(NT_STATUS_NO_MEMORY);
-               }
-
-               chal = auth_get_challenge(plaintext_auth_info);
-
-               if (!make_user_info_for_reply(&user_info, 
-                                             user, domain, chal.data,
-                                             plaintext_password)) {
-                       return ERROR_NT(NT_STATUS_NO_MEMORY);
-               }
-               
-               nt_status = check_password(user_info, plaintext_auth_info, &server_info); 
+               struct auth_context *plaintext_auth_context = NULL;
+               const uint8 *chal;
+               if (NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) {
+                       chal = plaintext_auth_context->get_ntlm_challenge(plaintext_auth_context);
+                       
+                       if (!make_user_info_for_reply(&user_info, 
+                                                     user, domain, chal,
+                                                     plaintext_password)) {
+                               nt_status = NT_STATUS_NO_MEMORY;
+                       }
                
-               data_blob_free(&chal);
-               free_auth_info(&plaintext_auth_info);
+                       if (NT_STATUS_IS_OK(nt_status)) {
+                               nt_status = plaintext_auth_context->check_ntlm_password(plaintext_auth_context, 
+                                                                                       user_info, 
+                                                                                       &server_info); 
+                               
+                               plaintext_auth_context->free(&plaintext_auth_context);
+                       }
+               }
        }
 
        free_user_info(&user_info);