This is another rather major change to the samba authenticaion
authorAndrew Bartlett <abartlet@samba.org>
Sat, 24 Nov 2001 12:12:38 +0000 (12:12 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 24 Nov 2001 12:12:38 +0000 (12:12 +0000)
subystem.

The particular aim is to modularized the interface - so that we
can have arbitrary password back-ends.

This code adds one such back-end, a 'winbind' module to authenticate
against the winbind_auth_crap functionality.  While fully-functional
this code is mainly useful as a demonstration, because we don't get
back the info3 as we would for direct ntdomain authentication.

This commit introduced the new 'auth methods' parameter, in the
spirit of the 'auth order' discussed on the lists.  It is renamed
because not all the methods may be consulted, even if previous
methods fail - they may not have a suitable challenge for example.

Also, we have a 'local' authentication method, for old-style
'unix if plaintext, sam if encrypted' authentication and a
'guest' module to handle guest logins in a single place.

While this current design is not ideal, I feel that it does
provide a better infrastructure than the current design, and can
be built upon.

The following parameters have changed:
 - use rhosts =

  This has been replaced by the 'rhosts' authentication method,
 and can be specified like 'auth methods = guest rhosts'

 - hosts equiv =

  This needs both this parameter and an 'auth methods' entry
  to be effective.  (auth methods = guest hostsequiv ....)

 - plaintext to smbpasswd =

  This is replaced by specifying 'sam' rather than 'local'
  in the auth methods.

The security = parameter is unchanged, and now provides defaults
for the 'auth methods' parameter.

The available auth methods are:

guest
rhosts
hostsequiv
sam (passdb direct hash access)
unix (PAM, crypt() etc)
local (the combination of the above, based on encryption)
smbserver (old security=server)
ntdomain (old security=domain)
winbind (use winbind to cache DC connections)

Assistance in testing, or the production of new and interesting
authentication modules is always appreciated.

Andrew Bartlett

33 files changed:
source/Makefile.in
source/auth/auth.c
source/auth/auth_builtin.c [new file with mode: 0644]
source/auth/auth_domain.c
source/auth/auth_info.c [new file with mode: 0644]
source/auth/auth_rhosts.c
source/auth/auth_sam.c
source/auth/auth_server.c
source/auth/auth_unix.c
source/auth/auth_util.c
source/include/auth.h
source/libsmb/cliconnect.c
source/libsmb/domain_client_validate.c
source/nsswitch/winbindd_pam.c
source/param/loadparm.c
source/passdb/pdb_smbpasswd.c
source/rpc_client/cli_login.c
source/rpc_server/srv_netlog_nt.c
source/rpc_server/srv_pipe.c
source/smbd/auth.c
source/smbd/auth_builtin.c [new file with mode: 0644]
source/smbd/auth_domain.c
source/smbd/auth_info.c [new file with mode: 0644]
source/smbd/auth_rhosts.c
source/smbd/auth_server.c
source/smbd/auth_smbpasswd.c
source/smbd/auth_unix.c
source/smbd/auth_util.c
source/smbd/negprot.c
source/smbd/process.c
source/smbd/server.c
source/smbd/sesssetup.c
source/utils/testparm.c

index d69941bed386153491d9f84bf37a82972b748140..6b3b337a120205c467b1762ee9708bd5d3e1c508 100644 (file)
@@ -197,7 +197,8 @@ NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o
 PLAINTEXT_AUTH_OBJ = passdb/pampass.o passdb/pass_check.o
 
 AUTH_OBJ = smbd/auth.o smbd/auth_smbpasswd.o smbd/auth_server.o smbd/auth_domain.o \
-          smbd/auth_rhosts.o smbd/auth_unix.o smbd/auth_util.o $(PLAINTEXT_AUTH_OBJ) \
+          smbd/auth_rhosts.o smbd/auth_unix.o smbd/auth_util.o smbd/auth_winbind.o \
+          smbd/auth_info.o smbd/auth_builtin.o $(PLAINTEXT_AUTH_OBJ) \
           libsmb/domain_client_validate.o 
 
 
index 95c97182b852ce5963ebcc7a78e5a1c144d602eb..c62e2ed5a07ca7d7c4d707f4b03a6d1bccfee2da 100644 (file)
@@ -58,27 +58,50 @@ static BOOL check_domain_match(char *user, char *domain)
 ****************************************************************************/
 
 NTSTATUS check_password(const auth_usersupplied_info *user_info, 
+                       const auth_authsupplied_info *auth_info,
                        auth_serversupplied_info **server_info)
 {
        
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-       BOOL done_pam = False;
        const char *pdb_username;
+       auth_methods *auth_method;
+
+       if (!user_info || !auth_info || !server_info) {
+               return NT_STATUS_LOGON_FAILURE;
+       }
 
        DEBUG(3, ("check_password:  Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", 
                  user_info->client_domain.str, user_info->smb_name.str, user_info->wksta_name.str));
 
        DEBUG(3, ("check_password:  mapped user is: [%s]\\[%s]@[%s]\n", 
                  user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str));
-
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_guest_security(user_info, server_info);
+       DEBUG(10, ("auth_info challange created by %s\n", auth_info->challange_set_by));
+       DEBUG(10, ("challange is: \n"));
+       dump_data(5, (auth_info)->challange.data, (auth_info)->challange.length);
+
+#ifdef DEBUG_PASSWORD
+       DEBUG(100, ("user_info has passwords of length %d and %d\n", 
+                   user_info->lm_resp.length, user_info->nt_resp.length));
+       DEBUG(100, ("lm:\n"));
+       dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
+       DEBUG(100, ("nt:\n"));
+       dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length);
+#endif
+
+       for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next)
+       {
+               nt_status = auth_method->auth(auth_method->private_data, user_info, auth_info, server_info);
                if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(5, ("check_password:  checking guest-account for user [%s] suceeded\n", user_info->smb_name.str));
+                       DEBUG(3, ("check_password: %s authentication for user [%s] suceeded\n", 
+                                 auth_method->name, user_info->smb_name.str));
                } else {
-                       DEBUG(10, ("check_password:  checking gusst-account for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
+                       DEBUG(5, ("check_password: %s authentication for user [%s] FAILED with error %s\n", 
+                                 auth_method->name, user_info->smb_name.str, get_nt_error_msg(nt_status)));
+               }
+               
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       break;
+               }
        }
 
        /* This needs to be sorted:  If it doesn't match, what should we do? */
@@ -86,83 +109,47 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
                return NT_STATUS_LOGON_FAILURE;
        }
 
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_rhosts_security(user_info, server_info);
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(3, ("check_password:  Password (rhosts) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(10, ("check_password:  Password (rhosts) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
-       
-       if ((lp_security() == SEC_DOMAIN) && !NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_domain_security(user_info, server_info);
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(7, ("check_password:  Password (domain) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(5, ("check_password:  Password (domain) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
-       
-       if ((lp_security() == SEC_SERVER) && !NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_server_security(user_info, server_info);
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(7, ("check_password:  Password (server) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(5, ("check_password:  Password (server) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
 
+       /* This is one of the few places the *relies* (rather than just sets defaults
+          on the value of lp_security().  This needs to change.  A new paramater 
+          perhaps? */
        if (lp_security() >= SEC_SERVER) {
                smb_user_control(user_info, *server_info, nt_status);
        }
 
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               if (user_info->encrypted || lp_plaintext_to_smbpasswd()) { 
-                       nt_status = check_smbpasswd_security(user_info, server_info);
-               } else {
-                       nt_status = check_unix_security(user_info, server_info);
-                       done_pam = True;
-               }
-               
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(7, ("check_password:  Password (unix/smbpasswd) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(5, ("check_password:  Password (unix/smbpasswd) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
-
        if (NT_STATUS_IS_OK(nt_status)) {
                pdb_username = pdb_get_username((*server_info)->sam_account);
-               if (!done_pam && !(*server_info)->guest) {
+               if (!(*server_info)->guest) {
                        /* We might not be root if we are an RPC call */
                        become_root();
                        nt_status = smb_pam_accountcheck(pdb_username);
                        unbecome_root();
                        
                        if (NT_STATUS_IS_OK(nt_status)) {
-                               DEBUG(5, ("check_password:  PAM Account for user [%s] suceeded\n", pdb_username));
+                               DEBUG(5, ("check_password:  PAM Account for user [%s] suceeded\n", 
+                                         pdb_username));
                        } else {
-                               DEBUG(3, ("check_password:  PAM Account for user [%s] FAILED with error %s\n", pdb_username, get_nt_error_msg(nt_status)));
+                               DEBUG(3, ("check_password:  PAM Account for user [%s] FAILED with error %s\n", 
+                                         pdb_username, get_nt_error_msg(nt_status)));
                        } 
                }
+               
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       DEBUG((*server_info)->guest ? 5 : 2, 
+                             ("check_password:  %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", 
+                              (*server_info)->guest ? "guest " : "", 
+                              user_info->smb_name.str, 
+                              user_info->internal_username.str, 
+                              pdb_username));
+               }
        }
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               DEBUG(3, ("check_password:  %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", 
-                         (*server_info)->guest ? "guest " : "", 
-                         user_info->smb_name.str, 
-                         user_info->internal_username.str, 
-                         pdb_username));
-       } else {
-               DEBUG(3, ("check_password:  Authenticaion for user [%s] -> [%s] FAILED with error %s\n", user_info->smb_name.str, user_info->internal_username.str, get_nt_error_msg(nt_status)));
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(2, ("check_password:  Authenticaion for user [%s] -> [%s] FAILED with error %s\n", 
+                         user_info->smb_name.str, user_info->internal_username.str, 
+                         get_nt_error_msg(nt_status)));
                ZERO_STRUCTP(server_info);
-       }               
-
+       }
        return nt_status;
 
 }
@@ -210,16 +197,35 @@ static NTSTATUS pass_check_smb(char *smb_name,
 {
        NTSTATUS nt_status;
        auth_usersupplied_info *user_info = NULL;
+       extern auth_authsupplied_info *negprot_global_auth_info;
        auth_serversupplied_info *server_info = NULL;
+       if (encrypted) {                
+               make_user_info_for_reply_enc(&user_info, smb_name, 
+                                            domain,
+                                            lm_pwd, 
+                                            nt_pwd, 
+                                            plaintext_password);
+               nt_status = check_password(user_info, negprot_global_auth_info, &server_info);
+       } else {
+               auth_authsupplied_info *plaintext_auth_info = NULL;
+               DATA_BLOB chal;
+               if (!make_auth_info_subsystem(&plaintext_auth_info)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
 
-       make_user_info_for_reply(&user_info, smb_name, 
-                                domain, 
-                                lm_pwd, 
-                                nt_pwd, 
-                                plaintext_password, 
-                                encrypted);
-       
-       nt_status = check_password(user_info, &server_info);
+               chal = auth_get_challange(plaintext_auth_info);
+
+               if (!make_user_info_for_reply(&user_info, 
+                                             smb_name, domain, chal.data,
+                                             plaintext_password)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               
+               nt_status = check_password(user_info, plaintext_auth_info, &server_info); 
+               
+               data_blob_free(&chal);
+               free_auth_info(&plaintext_auth_info);
+       }               
        free_user_info(&user_info);
        free_server_info(&server_info);
        return nt_status;
@@ -235,22 +241,23 @@ BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
 
        DATA_BLOB null_password = data_blob(NULL, 0);
        extern BOOL global_encrypted_passwords_negotiated;
-
-       if (global_encrypted_passwords_negotiated) {
+       BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
+       
+       if (encrypted) {
                /* 
                 * The password could be either NTLM or plain LM.  Try NTLM first, 
                 * but fall-through as required.
                 * NTLMv2 makes no sense here.
                 */
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, global_encrypted_passwords_negotiated))) {
+               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
                        return True;
                }
                
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, global_encrypted_passwords_negotiated))) {
+               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
                        return True;
                }
        } else {
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, global_encrypted_passwords_negotiated))) {
+               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
                        return True;
                }
        }
diff --git a/source/auth/auth_builtin.c b/source/auth/auth_builtin.c
new file mode 100644 (file)
index 0000000..6ea6d0b
--- /dev/null
@@ -0,0 +1,87 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0.
+   Generic authenticaion types
+   Copyright (C) Andrew Bartlett              2001
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+ Check for a guest logon (username = "") and if so create the required 
+ structure.
+****************************************************************************/
+
+static NTSTATUS check_guest_security(void *my_private_data, 
+                             const auth_usersupplied_info *user_info, 
+                             const auth_authsupplied_info *auth_info,
+                             auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+
+       if (!(user_info->internal_username.str 
+             && *user_info->internal_username.str)) { 
+               if (make_server_info_guest(server_info)) {
+                       nt_status = NT_STATUS_OK;
+               } else {
+                       nt_status = NT_STATUS_NO_SUCH_USER;
+               }
+       }
+
+       return nt_status;
+}
+
+BOOL auth_init_guest(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_guest_security;
+       return True;
+}
+
+/****************************************************************************
+ Check against either sam or unix, depending on encryption.
+****************************************************************************/
+
+static NTSTATUS check_local_security(void *my_private_data,
+                             const auth_usersupplied_info *user_info, 
+                             const auth_authsupplied_info *auth_info,
+                             auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+
+       if (user_info->encrypted) {
+               nt_status = check_sam_security(my_private_data, user_info, auth_info, server_info);
+       } else {
+               nt_status = check_unix_security(my_private_data, user_info, auth_info, server_info);
+       }
+       
+       return nt_status;
+}
+
+BOOL auth_init_local(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_local_security;
+       return True;
+}
+
index 4ada7d4a56ecaf65e5890dbc205860086900fc88..ef0e5b2f10a4d4152f564d03d830dfb80ff417ad 100644 (file)
@@ -28,8 +28,10 @@ BOOL global_machine_password_needs_changing = False;
  Check for a valid username and password in security=domain mode.
 ****************************************************************************/
 
-NTSTATUS check_domain_security(const auth_usersupplied_info *user_info, 
-                              auth_serversupplied_info **server_info)
+static NTSTATUS check_ntdomain_security(void *my_private_data,
+                                       const auth_usersupplied_info *user_info, 
+                                       const auth_authsupplied_info *auth_info,
+                                       auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
        char *p, *pserver;
@@ -66,8 +68,18 @@ NTSTATUS check_domain_security(const auth_usersupplied_info *user_info,
        if (! *pserver) pserver = "*";
        p = pserver;
 
-       nt_status = domain_client_validate(user_info, server_info, 
+       nt_status = domain_client_validate(user_info, (uchar *)auth_info->challange.data,server_info, 
                                           p, trust_passwd, last_change_time);
 
        return nt_status;
 }
+
+BOOL auth_init_ntdomain(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_ntdomain_security;
+       return True;
+}
diff --git a/source/auth/auth_info.c b/source/auth/auth_info.c
new file mode 100644 (file)
index 0000000..12b843d
--- /dev/null
@@ -0,0 +1,279 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0.
+   Authentication utility functions
+   Copyright (C) Andrew Bartlett 2001
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+const struct auth_init_function builtin_auth_init_functions[] = {
+       { "guest", auth_init_guest },
+       { "rhosts", auth_init_rhosts },
+       { "hostsequiv", auth_init_hostsequiv },
+       { "sam", auth_init_sam },
+       { "unix", auth_init_unix },
+       { "local", auth_init_local },
+       { "smbserver", auth_init_smbserver },
+       { "ntdomain", auth_init_ntdomain },
+       { "winbind", auth_init_winbind },
+       { NULL, NULL}
+};
+
+/***************************************************************************
+ Make a auth_info struct
+***************************************************************************/
+
+static BOOL make_auth_info(auth_authsupplied_info **auth_info) 
+{
+       *auth_info = malloc(sizeof(**auth_info));
+       if (!*auth_info) {
+               DEBUG(0,("make_auth_info: malloc failed!\n"));
+               return False;
+       }
+       ZERO_STRUCTP(*auth_info);
+       
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a specified list.
+***************************************************************************/
+
+BOOL make_auth_info_list(auth_authsupplied_info **auth_info, auth_methods *list) 
+{
+       if (!make_auth_info(auth_info)) {
+               return False;
+       }
+       
+       (*auth_info)->auth_method_list = list;
+       
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **text_list) 
+{
+       auth_methods *list = NULL;
+       auth_methods *t = NULL;
+       auth_methods *tmp;
+       int i;
+       
+       for (;*text_list; text_list++)
+       { 
+               DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list));
+               for (i = 0; builtin_auth_init_functions[i].name; i++)
+               {
+                       if (strequal(builtin_auth_init_functions[i].name, *text_list))
+                       {
+                               DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i));
+                               /* Malloc entry,  fill it,  link it */
+                               t = (auth_methods *)malloc(sizeof(*t));
+                               if (!t) {
+                                       DEBUG(0,("make_pw_chat: malloc failed!\n"));
+                                       return False;
+                               }
+                               
+                               ZERO_STRUCTP(t);
+                               
+                               if (builtin_auth_init_functions[i].init(&t)) {
+                                       DEBUG(5,("auth method %s has a valid init\n", *text_list));
+                                       t->name = builtin_auth_init_functions[i].name;
+                                       DLIST_ADD_END(list, t, tmp);
+                               } else {
+                                       DEBUG(5,("auth method %s DOES NOT have a valid init\n", *text_list));
+                               }
+                               break;
+                       }
+               }
+       }
+       
+       make_auth_info_list(auth_info, list);
+       
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+BOOL make_auth_info_subsystem(auth_authsupplied_info **auth_info) 
+{
+       char **auth_method_list = NULL; 
+       
+       if (!make_auth_info(auth_info)) {
+               return False;
+       }
+       
+       if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
+               return False;
+       }
+
+       if (auth_method_list == NULL) {
+               switch (lp_security()) 
+               {
+               case SEC_DOMAIN:
+                       DEBUG(5,("Making default auth method list for security=domain\n"));
+                       auth_method_list = lp_list_make("guest ntdomain local");
+                       break;
+               case SEC_SERVER:
+                       DEBUG(5,("Making default auth method list for security=server\n"));
+                       auth_method_list = lp_list_make("guest smbserver local");
+                       break;
+               case SEC_USER:
+                       DEBUG(5,("Making default auth method list for security=user\n"));
+                       auth_method_list = lp_list_make("guest local");
+                       break;
+               case SEC_SHARE:
+                       DEBUG(5,("Making default auth method list for security=share\n"));
+                       auth_method_list = lp_list_make("guest local");
+                       break;
+               }
+       } else {
+               DEBUG(5,("Using specified auth order\n"));
+       }
+       
+       if (!make_auth_info_text_list(auth_info, auth_method_list)) {
+               lp_list_free(&auth_method_list);
+               return False;
+       }
+       
+       lp_list_free(&auth_method_list);
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a random challange
+***************************************************************************/
+
+BOOL make_auth_info_random(auth_authsupplied_info **auth_info) 
+{
+       uchar chal[8];
+       if (!make_auth_info_subsystem(auth_info)) {
+               return False;
+       }
+       
+       generate_random_buffer(chal, sizeof(chal), False);
+       (*auth_info)->challange = data_blob(chal, sizeof(chal));
+
+       (*auth_info)->challange_set_by = "random";
+
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a fixed challange
+***************************************************************************/
+
+BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8]) 
+{
+       if (!make_auth_info_subsystem(auth_info)) {
+               return False;
+       }
+       
+       (*auth_info)->challange = data_blob(chal, 8);
+       return True;
+}
+
+/***************************************************************************
+ Clear out a auth_info struct that has been allocated
+***************************************************************************/
+
+void free_auth_info(auth_authsupplied_info **auth_info)
+{
+       auth_methods *list;
+       if (*auth_info != NULL) {
+               list = (*auth_info)->auth_method_list;  
+               while (list) {
+                       auth_methods *old_head = list;
+                       if (list->free_private_data) {
+                               list->free_private_data(&(list->private_data));
+                       }
+                       DLIST_REMOVE(list, list);                       
+                       SAFE_FREE(old_head);
+               }
+               
+               data_blob_free(&(*auth_info)->challange);
+               ZERO_STRUCT(**auth_info);
+       }
+       SAFE_FREE(*auth_info);
+}
+
+/****************************************************************************
+ Try to get a challange out of the various authenticaion modules.
+ It is up to the caller to free it.
+****************************************************************************/
+
+DATA_BLOB auth_get_challange(auth_authsupplied_info *auth_info) 
+{
+       DATA_BLOB challange = data_blob(NULL, 0);
+       char *challange_set_by = NULL;
+       auth_methods *auth_method;
+
+       if (auth_info->challange.length) {
+               DEBUG(5, ("auth_get_challange: returning previous challange (normal)\n"));
+               return data_blob(auth_info->challange.data, auth_info->challange.length);
+       }
+
+       for (auth_method = auth_info->auth_method_list; auth_method; auth_method = auth_method->next)
+       {
+               if (auth_method->get_chal) {
+                       DEBUG(5, ("auth_get_challange: getting challange from module %s\n", auth_method->name));
+                       if (challange_set_by) {
+                               DEBUG(1, ("auth_get_challange: CONFIGURATION ERROR: authenticaion method %s has already specified a challange.  Challange by %s ignored.\n", 
+                                         challange_set_by, auth_method->name));
+                       } else {
+                               challange = auth_method->get_chal(&auth_method->private_data, auth_info);
+                               if (challange.length) {
+                                       DEBUG(5, ("auth_get_challange: sucessfully got challange from module %s\n", auth_method->name));
+                                       auth_info->challange = challange;
+                                       challange_set_by = auth_method->name;
+                                       auth_info->challange_set_method = auth_method;
+                               } else {
+                                       DEBUG(3, ("auth_get_challange: getting challange from authenticaion method %s FAILED.\n", 
+                                                 auth_method->name));
+                               }
+                       }
+               } else {
+                       DEBUG(5, ("auth_get_challange: module %s did not want to specify a challange\n", auth_method->name));
+               }
+       }
+       
+       if (!challange_set_by) {
+               uchar chal[8];
+               
+               generate_random_buffer(chal, sizeof(chal), False);
+               auth_info->challange = data_blob(chal, sizeof(chal));
+               
+               challange_set_by = "random";
+       } 
+       
+       DEBUG(5, ("auth_info challange created by %s\n", challange_set_by));
+       DEBUG(5, ("challange is: \n"));
+       dump_data(5, auth_info->challange.data, (auth_info)->challange.length);
+       
+       SMB_ASSERT(auth_info->challange.length == 8);
+
+       auth_info->challange_set_by=challange_set_by;
+
+       return data_blob(auth_info->challange.data, auth_info->challange.length);
+}
+
+
index 9c07e48a9b673d6ebc0748a575612c58461b3b61..2605f0770a225d5077fa828700efc9072a288477 100644 (file)
@@ -135,7 +135,6 @@ check for a possible hosts equiv or rhosts entry for the user
 static BOOL check_hosts_equiv(struct passwd *pass)
 {
   char *fname = NULL;
-  pstring rhostsfile;
 
   if (!pass) 
     return(False);
@@ -148,39 +147,82 @@ static BOOL check_hosts_equiv(struct passwd *pass)
                  return(True);
   }
   
-  if (lp_use_rhosts())
-  {
-         char *home = pass->pw_dir;
-         if (home) {
-                 slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
-                 if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
-                         return(True);
-         }
-  }
-  
   return(False);
 }
 
+
 /****************************************************************************
  Check for a valid .rhosts/hosts.equiv entry for this user
 ****************************************************************************/
 
-NTSTATUS check_rhosts_security(const auth_usersupplied_info *user_info, 
-                            auth_serversupplied_info **server_info)
+static NTSTATUS check_hostsequiv_security(void *my_private_data, 
+                                         const auth_usersupplied_info *user_info, 
+                                         const auth_authsupplied_info *auth_info,
+                                         auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
        struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
        
        if (pass) {
-               become_root();
                if (check_hosts_equiv(pass)) {
                        nt_status = NT_STATUS_OK;
                        make_server_info_pw(server_info, pass);
                }
-               unbecome_root();
        } else {
                nt_status = NT_STATUS_NO_SUCH_USER;
        }
 
        return nt_status;
 }
+
+
+/****************************************************************************
+ Check for a valid .rhosts/hosts.equiv entry for this user
+****************************************************************************/
+
+static NTSTATUS check_rhosts_security(void *my_private_data, 
+                                     const auth_usersupplied_info *user_info, 
+                                     const auth_authsupplied_info *auth_info,
+                                     auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
+       pstring rhostsfile;
+       
+       if (pass) {
+               char *home = pass->pw_dir;
+               if (home) {
+                       slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
+                       become_root();
+                       if (check_user_equiv(pass->pw_name,client_name(),rhostsfile)) {
+                               nt_status = NT_STATUS_OK;
+                               make_server_info_pw(server_info, pass);
+                       }
+                       unbecome_root();
+               } 
+       } else {
+               nt_status = NT_STATUS_NO_SUCH_USER;
+       }
+
+       return nt_status;
+}
+
+BOOL auth_init_hostsequiv(auth_methods **auth_method) 
+{
+
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_hostsequiv_security;
+       return True;
+}
+
+BOOL auth_init_rhosts(auth_methods **auth_method) 
+{
+
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_rhosts_security;
+       return True;
+}
index 70632fb5dfb46b9bb2fee081a497f07b745f9840..24a4d4e4e427ad1dbf6973811ce68da487cbdb3c 100644 (file)
@@ -96,7 +96,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
        if (ntv2_response.length < 16) {
                /* We MUST have more than 16 bytes, or the stuff below will go
                   crazy... */
-               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", 
+               DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n", 
                          ntv2_response.length));
                return False;
        }
@@ -132,15 +132,16 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
  Do a specific test for an smb password being correct, given a smb_password and
  the lanman and NT responses.
 ****************************************************************************/
-NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, uint8 user_sess_key[16])
+static NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, 
+                               const auth_usersupplied_info *user_info, 
+                               const auth_authsupplied_info *auth_info,
+                               uint8 user_sess_key[16])
 {
+       uint16 acct_ctrl;
        const uint8 *nt_pw, *lm_pw;
-       uint16  acct_ctrl = pdb_get_acct_ctrl(sampass);
        uint32 ntlmssp_flags;
 
-       if (!user_info || !sampass) 
-               return NT_STATUS_LOGON_FAILURE;
-
+       acct_ctrl = pdb_get_acct_ctrl(sampass);
        if (acct_ctrl & ACB_PWNOTREQ) 
        {
                if (lp_null_passwords()) 
@@ -173,8 +174,8 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
                */
                DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n"));
                if (smb_pwd_check_ntlmv2( user_info->nt_resp, 
-                                         nt_pw, 
-                                         user_info->sec_blob, user_info->smb_name.str, 
+                                         nt_pw, auth_info->challange, 
+                                         user_info->smb_name.str, 
                                          user_info->client_domain.str,
                                          user_sess_key))
                {
@@ -190,7 +191,7 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
                        */
                        DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
                        if (smb_pwd_check_ntlmv1(user_info->nt_resp, 
-                                                nt_pw, user_info->sec_blob,
+                                                nt_pw, auth_info->challange,
                                                 user_sess_key)) 
                        {
                                return NT_STATUS_OK;
@@ -223,7 +224,7 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
                
                DEBUG(4,("smb_password_ok: Checking LM password\n"));
                if (smb_pwd_check_ntlmv1(user_info->lm_resp, 
-                                        lm_pw, user_info->sec_blob,
+                                        lm_pw, auth_info->challange,
                                         user_sess_key)) 
                {
                        return NT_STATUS_OK;
@@ -265,6 +266,24 @@ static NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_inf
                return NT_STATUS_ACCOUNT_EXPIRED;
        }
 
+       if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) {
+               time_t must_change_time = pdb_get_pass_must_change_time(sampass);
+               time_t last_set_time = pdb_get_pass_last_set_time(sampass);
+
+               /* check for immediate expiry "must change at next logon" */
+               if (must_change_time == 0 && last_set_time != 0) {
+                       DEBUG(1,("Account for user '%s' password must change!.\n", pdb_get_username(sampass)));
+                       return NT_STATUS_PASSWORD_MUST_CHANGE;
+               }
+
+               /* check for expired password */
+               if (must_change_time < time(NULL) && must_change_time != 0) {
+                       DEBUG(1,("Account for user '%s' password expired!.\n", pdb_get_username(sampass)));
+                       DEBUG(1,("Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time));
+                       return NT_STATUS_PASSWORD_EXPIRED;
+               }
+       }
+
        /* Test workstation. Workstation list is comma separated. */
 
        workstation_list = strdup(pdb_get_workstations(sampass));
@@ -293,24 +312,6 @@ static NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_inf
                SAFE_FREE(workstation_list);
        }
 
-       if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) {
-               time_t must_change_time = pdb_get_pass_must_change_time(sampass);
-               time_t last_set_time = pdb_get_pass_last_set_time(sampass);
-
-               /* check for immediate expiry "must change at next logon" */
-               if (must_change_time == 0 && last_set_time != 0) {
-                       DEBUG(1,("Account for user '%s' password must change!.\n", pdb_get_username(sampass)));
-                       return NT_STATUS_PASSWORD_MUST_CHANGE;
-               }
-
-               /* check for expired password */
-               if (must_change_time < time(NULL) && must_change_time != 0) {
-                       DEBUG(1,("Account for user '%s' password expired!.\n", pdb_get_username(sampass)));
-                       DEBUG(1,("Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time));
-                       return NT_STATUS_PASSWORD_EXPIRED;
-               }
-       }
-
        if (acct_ctrl & ACB_DOMTRUST) {
                DEBUG(2,("session_trust_account: Domain trust account %s denied by server\n", pdb_get_username(sampass)));
                return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
@@ -336,7 +337,10 @@ SMB hash supplied in the user_info structure
 return an NT_STATUS constant.
 ****************************************************************************/
 
-NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+NTSTATUS check_sam_security(void *my_private_dat,
+                           const auth_usersupplied_info *user_info, 
+                           const auth_authsupplied_info *auth_info,
+                           auth_serversupplied_info **server_info)
 {
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret;
@@ -344,7 +348,7 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
        uint8 user_sess_key[16];
        const uint8* lm_hash;
 
-       if (!user_info) {
+       if (!user_info || !auth_info) {
                return NT_STATUS_LOGON_FAILURE;
        }
 
@@ -365,7 +369,7 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       nt_status = sam_password_ok(sampass, user_info, user_sess_key);
+       nt_status = sam_password_ok(sampass, user_info, auth_info, user_sess_key);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                pdb_free_sam(&sampass);
@@ -394,6 +398,15 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
        return nt_status;
 }
 
+BOOL auth_init_sam(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_sam_security;
+       return True;
+}
 
 
 
index ddbc284d50ce02bd79795edc83dfab197c364e79..067b5b2997bc4bc8051cf5f20a6da6ca64a908d8 100644 (file)
 
 extern pstring global_myname;
 
-/****************************************************************************
- Return the client state structure.
-****************************************************************************/
-
-struct cli_state *server_client(void)
-{
-       static struct cli_state pw_cli;
-       return &pw_cli;
-}
-
 /****************************************************************************
  Support for server level security.
 ****************************************************************************/
 
-struct cli_state *server_cryptkey(void)
+static struct cli_state *server_cryptkey(void)
 {
-       struct cli_state *cli;
+       struct cli_state *cli = NULL;
        fstring desthost;
        struct in_addr dest_ip;
        char *p, *pserver;
        BOOL connected_ok = False;
 
-       cli = server_client();
-
-       if (!cli_initialise(cli))
+       if (!(cli = cli_initialise(cli)))
                return NULL;
 
        /* security = server just can't function with spnego */
@@ -88,7 +76,11 @@ struct cli_state *server_cryptkey(void)
 
        if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip))
                return NULL;
-
+       
+       if (strequal(desthost,myhostname())) {
+               exit_server("Password server loop!");
+       }
+       
        DEBUG(3,("got session\n"));
 
        if (!cli_negprot(cli)) {
@@ -109,13 +101,82 @@ struct cli_state *server_cryptkey(void)
        return cli;
 }
 
+/****************************************************************************
+ Clean up our allocated cli.
+****************************************************************************/
+
+static void free_server_private_data(void **private_data_pointer) 
+{
+       struct cli_state **cli = (struct cli_state **)private_data_pointer;
+       if (*cli && (*cli)->initialised) {
+               cli_shutdown(*cli);
+               
+               SAFE_FREE(*cli);
+       }
+}
+
+/****************************************************************************
+ Send a 'keepalive' packet down the cli pipe.
+****************************************************************************/
+
+static void send_server_keepalive(void **private_data_pointer) 
+{
+       struct cli_state **cli = (struct cli_state **)private_data_pointer;
+       
+       /* also send a keepalive to the password server if its still
+          connected */
+       if (cli && *cli && (*cli)->initialised) {
+               if (!send_keepalive((*cli)->fd)) {
+                       DEBUG( 2, ( "password server keepalive failed.\n"));
+                       cli_shutdown(*cli);
+                       SAFE_FREE(*cli);
+               }
+       }
+}
+
+/****************************************************************************
+ Get the challange out of a password server.
+****************************************************************************/
+
+static DATA_BLOB auth_get_challange_server(void **my_private_data, const struct authsupplied_info *auth_info) 
+{
+       struct cli_state *cli = server_cryptkey();
+       
+       if (cli) {
+               DEBUG(3,("using password server validation\n"));
+               if ((cli->sec_mode & 2) == 0) {
+                       /* We can't work with unencrypted password servers
+                          unless 'encrypt passwords = no' */
+                       DEBUG(5,("make_auth_info_server: Server is unencrypted, no challange available..\n"));
+
+                       *my_private_data = (void *)cli;
+                       return data_blob(NULL, 0);
+                       
+               } else if (cli->secblob.length < 8) {
+                       /* We can't do much if we don't get a full challange */
+                       DEBUG(2,("make_auth_info_server: Didn't receive a full challange from server\n"));
+                       cli_shutdown(cli);
+                       return data_blob(NULL, 0);
+               }
+
+               *my_private_data = (void *)cli;
+               
+               return data_blob(cli->secblob.data,8);
+       } else {
+               return data_blob(NULL, 0);
+       }
+}
+
 
 /****************************************************************************
  Check for a valid username and password in security=server mode.
   - Validate a password with the password server.
 ****************************************************************************/
 
-NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+static NTSTATUS check_smbserver_security(void *my_private_data, 
+                                 const auth_usersupplied_info *user_info, 
+                                 const auth_authsupplied_info *auth_info,
+                                 auth_serversupplied_info **server_info)
 {
        struct cli_state *cli;
        static unsigned char badpass[24];
@@ -123,13 +184,32 @@ NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_ser
        static BOOL tested_password_server = False;
        static BOOL bad_password_server = False;
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       BOOL locally_made_cli = False;
 
-       cli = server_client();
+       cli = my_private_data;
+       
+       if (cli) {
+       } else {
+               cli = server_cryptkey();
+               locally_made_cli = True;
+       }
 
-       if (!cli->initialised) {
+       if (!cli || !cli->initialised) {
                DEBUG(1,("password server %s is not connected\n", cli->desthost));
-               return(NT_STATUS_LOGON_FAILURE);
+               return NT_STATUS_LOGON_FAILURE;
        }  
+       
+       if ((cli->sec_mode & 2) == 0) {
+               if (user_info->encrypted) {
+                       DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost));
+                       return NT_STATUS_LOGON_FAILURE;         
+               }
+       } else {
+               if (memcmp(cli->secblob.data, auth_info->challange.data, 8) != 0) {
+                       DEBUG(1,("the challange that the password server (%s) supplied us is not the one we gave our client. This just can't work :-(\n", cli->desthost));
+                       return NT_STATUS_LOGON_FAILURE;         
+               }
+       }
 
        if(badpass[0] == 0)
                memset(badpass, 0x1f, sizeof(badpass));
@@ -206,17 +286,32 @@ use this machine as the password server.\n"));
         * not guest enabled, we can try with the real password.
         */
 
-       if (!cli_session_setup(cli, user_info->smb_name.str, 
-                              (char *)user_info->lm_resp.data, 
-                              user_info->lm_resp.length, 
-                              (char *)user_info->nt_resp.data, 
-                              user_info->nt_resp.length, 
-                              user_info->domain.str)) {
-               DEBUG(1,("password server %s rejected the password\n", cli->desthost));
-               /* Make this cli_nt_error() when the conversion is in */
-               nt_status = cli_nt_error(cli);
+       if (!user_info->encrypted) {
+               /* Plaintext available */
+               if (!cli_session_setup(cli, user_info->smb_name.str, 
+                                      (char *)user_info->plaintext_password.data, 
+                                      user_info->plaintext_password.length, 
+                                      NULL, 0,
+                                      user_info->domain.str)) {
+                       DEBUG(1,("password server %s rejected the password\n", cli->desthost));
+                       /* Make this cli_nt_error() when the conversion is in */
+                       nt_status = cli_nt_error(cli);
+               } else {
+                       nt_status = NT_STATUS_OK;
+               }
        } else {
-               nt_status = NT_STATUS_OK;
+               if (!cli_session_setup(cli, user_info->smb_name.str, 
+                                      (char *)user_info->lm_resp.data, 
+                                      user_info->lm_resp.length, 
+                                      (char *)user_info->nt_resp.data, 
+                                      user_info->nt_resp.length, 
+                                      user_info->domain.str)) {
+                       DEBUG(1,("password server %s rejected the password\n", cli->desthost));
+                       /* Make this cli_nt_error() when the conversion is in */
+                       nt_status = cli_nt_error(cli);
+               } else {
+                       nt_status = NT_STATUS_OK;
+               }
        }
 
        /* if logged in as guest then reject */
@@ -238,5 +333,22 @@ use this machine as the password server.\n"));
                }
        }
 
+       if (locally_made_cli) {
+               cli_shutdown(cli);
+               SAFE_FREE(cli);
+       }
+
        return(nt_status);
 }
+
+BOOL auth_init_smbserver(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_smbserver_security;
+       (*auth_method)->get_chal = auth_get_challange_server;
+       (*auth_method)->send_keepalive = send_server_keepalive;
+       (*auth_method)->free_private_data = free_server_private_data;
+       return True;
+}
index 8c4a520350bdcd135379d87f08ee5a7e57f92953..d134ce6909cd45c6eccbbe24a4523563ae72d7f2 100644 (file)
@@ -82,7 +82,10 @@ check if a username/password is OK assuming the password
 in PLAIN TEXT
 ****************************************************************************/
 
-NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+NTSTATUS check_unix_security(void *my_private_data,
+                            const auth_usersupplied_info *user_info, 
+                            const auth_authsupplied_info *auth_info,
+                            auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status;
        struct passwd *pass = NULL;
@@ -104,9 +107,19 @@ NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serve
                if (pass) {
                        make_server_info_pw(server_info, pass);
                } else {
+                       /* we need to do somthing more useful here */
                        nt_status = NT_STATUS_NO_SUCH_USER;
                }
        }
 
        return nt_status;
 }
+
+BOOL auth_init_unix(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_unix_security;
+       return True;
+}
index 25e0830fc77414ebc78c76ac7170388300929cce..d1b2cc92e52e954ffc5aac9972bc51d33084d3c7 100644 (file)
 
 #include "includes.h"
 
-/* Data to do lanman1/2 password challenge. */
-static unsigned char saved_challenge[8];
-static BOOL challenge_sent=False;
 extern fstring remote_machine;
 extern pstring global_myname;
 
-/*******************************************************************
- Get the next challenge value - no repeats.
-********************************************************************/
-
-void generate_next_challenge(char *challenge)
-{
-       unsigned char buf[8];
-
-       generate_random_buffer(buf,8,False);
-       memcpy(saved_challenge, buf, 8);
-       memcpy(challenge,buf,8);
-       challenge_sent = True;
-}
-
-/*******************************************************************
- Set the last challenge sent, usually from a password server.
-********************************************************************/
-
-BOOL set_challenge(unsigned char *challenge)
-{
-       memcpy(saved_challenge,challenge,8);
-       challenge_sent = True;
-       return(True);
-}
-
-/*******************************************************************
- Get the last challenge sent.
-********************************************************************/
-
-BOOL last_challenge(unsigned char *challenge)
-{
-       if (!challenge_sent)
-               return(False);
-       memcpy(challenge,saved_challenge,8);
-       return(True);
-}
-
 /****************************************************************************
  Create a UNIX user on demand.
 ****************************************************************************/
@@ -166,7 +126,6 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
                           const char *client_domain, 
                           const char *domain,
                           const char *wksta_name, 
-                          DATA_BLOB sec_blob, 
                           DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
                           DATA_BLOB plaintext, 
                           uint32 ntlmssp_flags, BOOL encrypted)
@@ -226,7 +185,6 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
 
        DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
 
-       (*user_info)->sec_blob = data_blob(sec_blob.data, sec_blob.length);
        (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
        (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
        (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
@@ -246,7 +204,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
 BOOL make_user_info_map(auth_usersupplied_info **user_info, 
                        const char *smb_name, 
                        const char *client_domain, 
-                       const char *wksta_name, DATA_BLOB sec_blob, 
+                       const char *wksta_name, 
                        DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
                        DATA_BLOB plaintext, 
                        uint32 ntlmssp_flags, BOOL encrypted)
@@ -265,7 +223,7 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
        return make_user_info(user_info, 
                              smb_name, internal_username,
                              client_domain, domain,
-                             wksta_name, sec_blob,
+                             wksta_name, 
                              lm_pwd, nt_pwd,
                              plaintext, 
                              ntlmssp_flags, encrypted);
@@ -280,12 +238,11 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
                                     char *smb_name, 
                                     char *client_domain, 
-                                    char *wksta_name, uchar chal[8],
+                                    char *wksta_name, 
                                     uchar *lm_network_pwd, int lm_pwd_len,
                                     uchar *nt_network_pwd, int nt_pwd_len)
 {
        BOOL ret;
-       DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
        DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
        DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -301,8 +258,8 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
 
        ret = make_user_info_map(user_info, 
                                 smb_name, client_domain, 
-                                wksta_name, sec_blob, 
-                                nt_blob, lm_blob,
+                                wksta_name, 
+                                lm_blob, nt_blob,
                                 plaintext_blob, 
                                 ntlmssp_flags, True);
                
@@ -320,6 +277,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
                                         char *smb_name, 
                                         char *client_domain, 
                                         char *wksta_name, 
+                                        char chal[8], 
                                         uchar lm_interactive_pwd[16], 
                                         uchar nt_interactive_pwd[16], 
                                         uchar *dc_sess_key)
@@ -329,11 +287,8 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
        unsigned char local_lm_response[24];
        unsigned char local_nt_response[24];
        unsigned char key[16];
-       uint8 chal[8];
        uint32 ntlmssp_flags = 0;
        
-       generate_random_buffer(chal, 8, False);
-
        ZERO_STRUCT(key);
        memcpy(key, dc_sess_key, 8);
        
@@ -362,7 +317,6 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
        dump_data(100, nt_pwd, sizeof(nt_pwd));
 #endif
        
-       generate_random_buffer(chal, 8, False);
        SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
        SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
        
@@ -373,7 +327,6 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
 
        {
                BOOL ret;
-               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
                DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
                DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
                DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -385,7 +338,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
 
                ret = make_user_info_map(user_info, 
                                         smb_name, client_domain, 
-                                        wksta_name, sec_blob, 
+                                        wksta_name, 
                                         local_lm_blob,
                                         local_nt_blob,
                                         plaintext_blob, 
@@ -402,13 +355,14 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_winbind(auth_usersupplied_info **user_info, 
-                            char *username,
-                            char *domain, 
-                            char *password)
+                            const char *username,
+                            const char *domain, 
+                            const char *password,
+                           char chal[8] /* Give winbind back the challange we used */
+       )
 {
        unsigned char local_lm_response[24];
        unsigned char local_nt_response[24];
-       char chal[8];
        DATA_BLOB local_lm_blob;
        DATA_BLOB local_nt_blob;
        DATA_BLOB plaintext_blob;
@@ -453,16 +407,11 @@ BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
 
        {
                BOOL ret;
-               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
-               
-               if (!sec_blob.data) {
-                       return False;
-               }
 
                ret = make_user_info(user_info, 
                                     username, username,
                                     domain, domain, 
-                                    global_myname, sec_blob, 
+                                    global_myname, 
                                     local_nt_blob,
                                     local_lm_blob,
                                     plaintext_blob, 
@@ -483,12 +432,10 @@ BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
 BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, 
                                 char *smb_name, 
                                 char *client_domain, 
-                                uchar chal[8],
                                 uchar *lm_network_pwd, int lm_pwd_len,
                                 uchar *nt_network_pwd, int nt_pwd_len)
 {
        BOOL ret;
-       DATA_BLOB sec_blob = data_blob(chal, 8);
        DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
        DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -502,7 +449,7 @@ BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
        ret = make_user_info(user_info, 
                             smb_name, smb_name, 
                             client_domain, client_domain, 
-                            global_myname, sec_blob, 
+                            global_myname, 
                             nt_blob, lm_blob,
                             plaintext_blob, 
                             ntlmssp_flags, True);
@@ -517,59 +464,30 @@ BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
-                             char *smb_name,
-                             char *client_domain, 
-                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
-                             DATA_BLOB plaintext_password,
-                             BOOL encrypted)
+                             char *smb_name, 
+                             char *client_domain,
+                             char chal[8],
+                             DATA_BLOB plaintext_password)
 {
-       uchar chal[8];
 
        DATA_BLOB local_lm_blob;
        DATA_BLOB local_nt_blob;
-       DATA_BLOB sec_blob;
        BOOL ret = False;
        uint32 ntlmssp_flags = 0;
                        
-       if (encrypted) {
-               DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
-               if (!last_challenge(chal)) {
-                       DEBUG(0,("Encrypted login but no challange set!\n"));
-                       return False;
-               }
-               sec_blob = data_blob(chal, 8);
-               
-               if (lm_resp.length == 24) {
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
-               }
-               if (nt_resp.length == 0) {
-               } else if (nt_resp.length == 24) {
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
-               } else {
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
-               }
-
-               return make_user_info_map(user_info, smb_name, 
-                                         client_domain, 
-                                         remote_machine, sec_blob,
-                                         lm_resp, 
-                                         nt_resp, 
-                                         no_plaintext_blob, 
-                                         ntlmssp_flags, encrypted);
-       }
-
-       generate_random_buffer(chal, 8, False);
-
-       sec_blob = data_blob(chal, 8);
-       
        /*
         * Not encrypted - do so.
         */
        
-       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
+       DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
        
        if (plaintext_password.data) {
                unsigned char local_lm_response[24];
+               
+#ifdef DEBUG_PASSWORD
+               DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
+               dump_data(100, plaintext_password.data, plaintext_password.length);
+#endif
 
                SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
                local_lm_blob = data_blob(local_lm_response, 24);
@@ -587,23 +505,54 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
        ret = make_user_info_map(user_info, smb_name,
                                 client_domain, 
                                 remote_machine,
-                                sec_blob,
                                 local_lm_blob,
                                 local_nt_blob,
                                 plaintext_password, 
-                                ntlmssp_flags, encrypted);
+                                ntlmssp_flags, False);
        
        data_blob_free(&local_lm_blob);
        return ret;
 }
 
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
+                             char *smb_name,
+                             char *client_domain, 
+                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
+                             DATA_BLOB plaintext_password)
+{
+       uint32 ntlmssp_flags = 0;
+
+       DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
+       
+       if (lm_resp.length == 24) {
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+       }
+       if (nt_resp.length == 0) {
+       } else if (nt_resp.length == 24) {
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
+       } else {
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+       }
+
+       return make_user_info_map(user_info, smb_name, 
+                                client_domain, 
+                                remote_machine, 
+                                lm_resp, 
+                                nt_resp, 
+                                no_plaintext_blob, 
+                                ntlmssp_flags, True);
+}
+
 /****************************************************************************
  Create a guest user_info blob, for anonymous authenticaion.
 ****************************************************************************/
 
 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
 {
-       DATA_BLOB sec_blob = data_blob(NULL, 0);
        DATA_BLOB lm_blob = data_blob(NULL, 0);
        DATA_BLOB nt_blob = data_blob(NULL, 0);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -612,7 +561,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info)
        return make_user_info(user_info, 
                              "","", 
                              "","", 
-                             "", sec_blob,
+                             "", 
                              nt_blob, lm_blob,
                              plaintext_blob, 
                              ntlmssp_flags, True);
@@ -680,7 +629,6 @@ void free_user_info(auth_usersupplied_info **user_info)
                SAFE_FREE((*user_info)->internal_username.str);
                SAFE_FREE((*user_info)->client_domain.str);
                SAFE_FREE((*user_info)->domain.str);
-               data_blob_free(&(*user_info)->sec_blob);
                data_blob_free(&(*user_info)->lm_resp);
                data_blob_free(&(*user_info)->nt_resp);
                SAFE_FREE((*user_info)->interactive_password);
@@ -725,6 +673,22 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info)
        return False;
 }
 
+/***************************************************************************
+ Make an auth_methods struct
+***************************************************************************/
+
+BOOL make_auth_methods(auth_methods **auth_method) 
+{
+       *auth_method = malloc(sizeof(**auth_method));
+       if (!*auth_method) {
+               DEBUG(0,("make_auth_method: malloc failed!\n"));
+               return False;
+       }
+       ZERO_STRUCTP(*auth_method);
+       
+       return True;
+}
+
 /****************************************************************************
  Delete a SID token.
 ****************************************************************************/
@@ -764,25 +728,3 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
 
        return token;
 }
-
-/****************************************************************************
- Check for a guest logon (username = "") and if so create the required 
- structure.
-****************************************************************************/
-
-NTSTATUS check_guest_security(const auth_usersupplied_info *user_info, 
-                             auth_serversupplied_info **server_info)
-{
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-
-       if (!(user_info->internal_username.str 
-             && *user_info->internal_username.str)) { 
-               if (make_server_info_guest(server_info)) {
-                       nt_status = NT_STATUS_OK;
-               } else {
-                       nt_status = NT_STATUS_NO_SUCH_USER;
-               }
-       }
-
-       return nt_status;
-}
index 04c5aa55e525095a4372aeb31c17fc96a41a1f2d..e33ccc2e24b7d500e958fda491070e9213347ee4 100644 (file)
@@ -53,8 +53,6 @@ typedef struct usersupplied_info
        
        uint32 ntlmssp_flags;
 
-       DATA_BLOB sec_blob;
-
        AUTH_STR           client_domain;          /* domain name string */
        AUTH_STR           domain;               /* domain name after mapping */
        AUTH_STR           internal_username;    /* username after mapping */
@@ -69,16 +67,16 @@ 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 serversupplied_info 
 {
        BOOL guest;
        
        /* This groups info is needed for when we become_user() for this uid */
        int n_groups;
        gid_t *groups;
-
+       
        /* NT group information taken from the info3 structure */
-
+       
        NT_USER_TOKEN *ptok;
        
        uchar session_key[16];
@@ -86,8 +84,52 @@ typedef struct serversupplied_info
        uint8 first_8_lm_hash[8];
 
        uint32 sam_fill_level;  /* How far is this structure filled? */
-
+       
        SAM_ACCOUNT *sam_account;
+       
+       void *pam_handle;
+       
 } auth_serversupplied_info;
 
+typedef struct authsupplied_info {
+       DATA_BLOB challange; 
+
+       /* Who set this up in the first place? */ 
+       char *challange_set_by; \
+
+       struct auth_methods *challange_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;
+
+typedef struct auth_methods
+{
+       struct auth_methods *prev, *next;
+       char *name; /* What name got this module */
+
+       NTSTATUS (*auth)(void *my_private_data, 
+                        const auth_usersupplied_info *user_info, 
+                        const struct authsupplied_info *auth_info,
+                        auth_serversupplied_info **server_info);
+
+       DATA_BLOB (*get_chal)(void **my_private_data, const struct authsupplied_info *auth_info);
+       
+       /* Used to keep tabs on things like the cli for SMB server authentication */
+       void *private_data;
+       
+       /* Function to clean up the above arbitary structure */
+       void (*free_private_data)(void **private_data);
+
+       /* Function to send a keepalive message on the above structure */
+       void (*send_keepalive)(void **private_data);
+
+} auth_methods;
+
+typedef 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;
+
+
 #endif /* _SMBAUTH_H_ */
index f5d6c5a7f4adb6ff30345a3e85469af3ef8a07b1..4ea19db9ec61fa53f6f319334352900414748600 100644 (file)
@@ -197,7 +197,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
        int passlen;
        char *p;
 
-       passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE);
+       passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII);
 
        set_message(cli->outbuf,13,0,True);
        CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
index 2fd17e1fa4abecad437fa018f3695b952562ea36..df263e7ae974304fd27a70a5c778e3801b1b8d57 100644 (file)
@@ -271,9 +271,10 @@ static BOOL find_connect_pdc(struct cli_state *pcli,
 ************************************************************************/
 
 NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, 
-                             auth_serversupplied_info **server_info, 
-                             char *server, unsigned char *trust_passwd,
-                             time_t last_change_time)
+                               uchar chal[8],
+                               auth_serversupplied_info **server_info, 
+                               char *server, unsigned char *trust_passwd,
+                               time_t last_change_time)
 {
        fstring remote_machine;
        NET_ID_INFO_CTR ctr;
@@ -330,7 +331,7 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info,
          * in the info3 structure.  
          */
 
-       status = cli_nt_login_network(&cli, user_info, smb_uid_low, 
+       status = cli_nt_login_network(&cli, user_info, chal, smb_uid_low, 
                                      &ctr, &info3);
         
        if (!NT_STATUS_IS_OK(status)) {
index 9138583096177fc3fb71bbce2c52ce33a83c5160..2ea0692fe92cb40470509b3ac8f23050ab4b1da5 100644 (file)
@@ -40,6 +40,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
         NET_USER_INFO_3 info3;
        NET_ID_INFO_CTR ctr;
         struct cli_state *cli;
+       uchar chal[8];
 
        DEBUG(3, ("[%5d]: pam auth %s\n", state->pid,
                  state->request.data.auth.user));
@@ -59,7 +60,8 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
        if (state->request.data.auth.pass[0])
                make_user_info_winbind(&user_info, 
                                        name_user, name_domain,
-                                       state->request.data.auth.pass);
+                                       state->request.data.auth.pass,
+                                      chal);
        else
                return WINBINDD_ERROR;
        
@@ -87,7 +89,7 @@ enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state)
                 goto done;
         }
 
-       result = cli_nt_login_network(cli, user_info, smb_uid_low, 
+       result = cli_nt_login_network(cli, user_info, chal, smb_uid_low, 
                                      &ctr, &info3);
 
         free_user_info(&user_info);
@@ -123,7 +125,7 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
 
                make_user_info_winbind_crap(
                 &user_info, name_user, 
-                name_domain, state->request.data.auth_crap.chal,
+                name_domain, 
                 (uchar *)state->request.data.auth_crap.lm_resp,
                 state->request.data.auth_crap.lm_resp_len,
                 (uchar *)state->request.data.auth_crap.nt_resp,
@@ -153,8 +155,8 @@ enum winbindd_result winbindd_pam_auth_crap(struct winbindd_cli_state *state)
                 goto done;
         }
 
-       result = cli_nt_login_network(cli, user_info, smb_uid_low, 
-                                     &ctr, &info3);
+       result = cli_nt_login_network(cli, user_info, state->request.data.auth_crap.chal,
+                                     smb_uid_low, &ctr, &info3);
 
         free_user_info(&user_info);
 
index 3f781be67f0043094e4594a78b8eb34d54abfc6a..ab17f90a6ef8b352d847f284920d4fd0b4c2ec24 100644 (file)
@@ -179,6 +179,7 @@ typedef struct
        int maxprotocol;
        int minprotocol;
        int security;
+       char **AuthMethods;
        BOOL paranoid_server_security;
        int maxdisksize;
        int lpqcachetime;
@@ -238,7 +239,6 @@ typedef struct
        BOOL bNullPasswords;
        BOOL bObeyPamRestrictions;
        BOOL bLoadPrinters;
-       BOOL bUseRhosts;
        BOOL bLargeReadwrite;
        BOOL bReadRaw;
        BOOL bWriteRaw;
@@ -261,7 +261,6 @@ typedef struct
        BOOL bRestrictAnonymous;
        BOOL bLanmanAuth;
        BOOL bNTLMAuth;
-       BOOL bPlaintextToSmbpasswd;
        BOOL bDebugHiresTimestamp;
        BOOL bDebugPid;
        BOOL bDebugUid;
@@ -661,6 +660,7 @@ static struct parm_struct parm_table[] = {
        {"Security Options", P_SEP, P_SEPARATOR},
        
        {"security", P_ENUM, P_GLOBAL, &Globals.security, NULL, enum_security, FLAG_BASIC},
+       {"auth methods", P_LIST, P_GLOBAL, &Globals.AuthMethods, NULL, NULL, FLAG_BASIC},
        {"encrypt passwords", P_BOOL, P_GLOBAL, &Globals.bEncryptPasswords, NULL, NULL, FLAG_BASIC},
        {"update encrypted", P_BOOL, P_GLOBAL, &Globals.bUpdateEncrypt, NULL, NULL, FLAG_BASIC},
        {"allow trusted domains", P_BOOL, P_GLOBAL, &Globals.bAllowTrustedDomains, NULL, NULL, 0},
@@ -691,8 +691,6 @@ static struct parm_struct parm_table[] = {
        {"restrict anonymous", P_BOOL, P_GLOBAL, &Globals.bRestrictAnonymous, NULL, NULL, 0},
        {"lanman auth", P_BOOL, P_GLOBAL, &Globals.bLanmanAuth, NULL, NULL, 0},
        {"ntlm auth", P_BOOL, P_GLOBAL, &Globals.bNTLMAuth, NULL, NULL, 0},
-       {"plaintext to smbpasswd", P_BOOL, P_GLOBAL, &Globals.bPlaintextToSmbpasswd, NULL, NULL, 0},
-       {"use rhosts", P_BOOL, P_GLOBAL, &Globals.bUseRhosts, NULL, NULL, 0},
        
        {"username", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, FLAG_GLOBAL | FLAG_SHARE},
        {"user", P_STRING, P_LOCAL, &sDefault.szUsername, NULL, NULL, 0},
@@ -1191,7 +1189,7 @@ static void init_globals(void)
        string_set(&Globals.szPassdbModulePath, "");
 
        string_set(&Globals.szGuestaccount, GUEST_ACCOUNT);
-       
+
        /*
         * Allow the default PASSWD_CHAT to be overridden in local.h.
         */
@@ -1218,7 +1216,6 @@ static void init_globals(void)
        string_set(&Globals.szNameResolveOrder, "lmhosts wins host bcast");
 
        Globals.bLoadPrinters = True;
-       Globals.bUseRhosts = False;
        Globals.max_packet = 65535;
        Globals.mangled_stack = 50;
        Globals.max_xmit = 65535;
@@ -1281,7 +1278,6 @@ static void init_globals(void)
        Globals.bRestrictAnonymous = False;
        Globals.bLanmanAuth = True;     /* Do use the LanMan hash if it is available */
        Globals.bNTLMAuth = True;       /* Do use NTLMv1 if it is available (otherwise NTLMv2) */
-       Globals.bPlaintextToSmbpasswd = False;  /* Check the passwords with smbpasswd, even if in plaintext */
        Globals.map_to_guest = 0;       /* By Default, "Never" */
        Globals.min_passwd_length = MINPASSWDLENGTH;    /* By Default, 5. */
        Globals.oplock_break_wait_time = 0;     /* By Default, 0 msecs. */
@@ -1543,7 +1539,6 @@ FN_GLOBAL_BOOL(lp_wins_proxy, &Globals.bWINSproxy)
 FN_GLOBAL_BOOL(lp_local_master, &Globals.bLocalMaster)
 FN_GLOBAL_BOOL(lp_domain_logons, &Globals.bDomainLogons)
 FN_GLOBAL_BOOL(lp_load_printers, &Globals.bLoadPrinters)
-FN_GLOBAL_BOOL(lp_use_rhosts, &Globals.bUseRhosts)
 FN_GLOBAL_BOOL(lp_readprediction, &Globals.bReadPrediction)
 FN_GLOBAL_BOOL(lp_readbmpx, &Globals.bReadbmpx)
 FN_GLOBAL_BOOL(lp_readraw, &Globals.bReadRaw)
@@ -1573,7 +1568,6 @@ FN_GLOBAL_BOOL(lp_allow_trusted_domains, &Globals.bAllowTrustedDomains)
 FN_GLOBAL_BOOL(lp_restrict_anonymous, &Globals.bRestrictAnonymous)
 FN_GLOBAL_BOOL(lp_lanman_auth, &Globals.bLanmanAuth)
 FN_GLOBAL_BOOL(lp_ntlm_auth, &Globals.bNTLMAuth)
-FN_GLOBAL_BOOL(lp_plaintext_to_smbpasswd, &Globals.bPlaintextToSmbpasswd)
 FN_GLOBAL_BOOL(lp_host_msdfs, &Globals.bHostMSDfs)
 FN_GLOBAL_BOOL(lp_kernel_oplocks, &Globals.bKernelOplocks)
 FN_GLOBAL_BOOL(lp_enhanced_browsing, &Globals.enhanced_browsing)
@@ -1594,6 +1588,7 @@ FN_GLOBAL_INTEGER(lp_deadtime, &Globals.deadtime)
 FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
 FN_GLOBAL_INTEGER(lp_minprotocol, &Globals.minprotocol)
 FN_GLOBAL_INTEGER(lp_security, &Globals.security)
+FN_GLOBAL_LIST(lp_auth_methods, &Globals.AuthMethods)
 FN_GLOBAL_BOOL(lp_paranoid_server_security, &Globals.paranoid_server_security)
 FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
 FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
index e190be99a56ef15fc093c5f372a253b65709e38b..ce79be1666271ebac17d129f4355ab12f29c2175 100644 (file)
@@ -1408,7 +1408,7 @@ BOOL pdb_getsampwuid (SAM_ACCOUNT *sam_acct, uid_t uid)
        struct smb_passwd *smb_pw;
        void *fp = NULL;
 
-       DEBUG(10, ("pdb_getsampwuid: search by uid: %d\n", uid));
+       DEBUG(10, ("pdb_getsampwuid: search by uid: %d\n", (int)uid));
 
        /* Open the sam password file - not for update. */
        fp = startsmbfilepwent(lp_smb_passwd_file(), PWF_READ, &pw_file_lock_depth);
index eaedb1613a527f83807f78d4505e08036025b77e..e5c221690dd156a53a3230227fab3205731e6d53 100644 (file)
@@ -159,9 +159,10 @@ password equivalents over the network. JRA.
 ****************************************************************************/
 
 NTSTATUS cli_nt_login_network(struct cli_state *cli, 
-                            const auth_usersupplied_info *user_info, 
-                            uint32 smb_userid_low, NET_ID_INFO_CTR *ctr, 
-                            NET_USER_INFO_3 *user_info3)
+                             const auth_usersupplied_info *user_info, 
+                             uchar chal[8],
+                             uint32 smb_userid_low, NET_ID_INFO_CTR *ctr, 
+                             NET_USER_INFO_3 *user_info3)
 {
   DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
   /* indicate a "network" login */
@@ -174,7 +175,7 @@ NTSTATUS cli_nt_login_network(struct cli_state *cli,
                ((user_info->wksta_name.len > 0) ?
                 user_info->wksta_name.str :
                 cli->clnt_name_slash),
-               user_info->sec_blob.data
+               chal
                user_info->lm_resp.data, user_info->lm_resp.length,
                user_info->nt_resp.data, user_info->nt_resp.length);
 
index 1aa58f52745fbb9ea45fb1f986b8045d3fe5288e..6f0d2384d555e3d779353b3a27f271b7767835b4 100644 (file)
@@ -566,26 +566,46 @@ 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);
                /* Standard challange/response authenticaion */
                make_user_info_netlogon_network(&user_info, 
                                                nt_username, nt_domain, 
-                                               nt_workstation, ctr->auth.id2.lm_chal, 
+                                               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);
+                       
                break;
+       }
        case INTERACTIVE_LOGON_TYPE:
                /* 'Interactive' autheticaion, supplies the password in its MD4 form, encrypted
                   with the session key.  We will convert this to challange/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;
+               }
+               
+               chal = auth_get_challange(auth_info);
+
                make_user_info_netlogon_interactive(&user_info, 
                                                    nt_username, nt_domain, 
-                                                   nt_workstation, 
+                                                   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);
+
                break;
        }
        default:
@@ -593,8 +613,6 @@ NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *
                return NT_STATUS_INVALID_INFO_CLASS;
        } /* end switch */
        
-       status = check_password(user_info, &server_info);
-
        free_user_info(&user_info);
        
        DEBUG(5, ("_net_sam_logon: check_password returned status %s\n", 
index b9c40e719b4631dbbe5abf942d83478aef9cb0f9..4b3140b35040aab67b12c8987d2755c03bd76597 100644 (file)
@@ -271,6 +271,7 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
        NTSTATUS nt_status;
 
        auth_usersupplied_info *user_info = NULL;
+       auth_authsupplied_info *auth_info = NULL;
        auth_serversupplied_info *server_info = NULL;
 
        uid_t *puid;
@@ -343,17 +344,20 @@ static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlm
                        return False;
 
        }
+       
+       make_auth_info_fixed(&auth_info, (uchar*)p->challenge);
 
        if (!make_user_info_netlogon_network(&user_info, 
-                                            user_name, domain, wks,  (uchar*)p->challenge, 
+                                            user_name, domain, wks,
                                             lm_owf, lm_pw_len, 
                                             nt_owf, nt_pw_len)) {
                DEBUG(0,("make_user_info_netlogon_network failed!  Failing authenticaion.\n"));
                return False;
        }
        
-       nt_status = check_password(user_info, &server_info); 
+       nt_status = check_password(user_info, auth_info, &server_info); 
        
+       free_auth_info(&auth_info);
        free_user_info(&user_info);
        
        p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
index 95c97182b852ce5963ebcc7a78e5a1c144d602eb..c62e2ed5a07ca7d7c4d707f4b03a6d1bccfee2da 100644 (file)
@@ -58,27 +58,50 @@ static BOOL check_domain_match(char *user, char *domain)
 ****************************************************************************/
 
 NTSTATUS check_password(const auth_usersupplied_info *user_info, 
+                       const auth_authsupplied_info *auth_info,
                        auth_serversupplied_info **server_info)
 {
        
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-       BOOL done_pam = False;
        const char *pdb_username;
+       auth_methods *auth_method;
+
+       if (!user_info || !auth_info || !server_info) {
+               return NT_STATUS_LOGON_FAILURE;
+       }
 
        DEBUG(3, ("check_password:  Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", 
                  user_info->client_domain.str, user_info->smb_name.str, user_info->wksta_name.str));
 
        DEBUG(3, ("check_password:  mapped user is: [%s]\\[%s]@[%s]\n", 
                  user_info->domain.str, user_info->internal_username.str, user_info->wksta_name.str));
-
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_guest_security(user_info, server_info);
+       DEBUG(10, ("auth_info challange created by %s\n", auth_info->challange_set_by));
+       DEBUG(10, ("challange is: \n"));
+       dump_data(5, (auth_info)->challange.data, (auth_info)->challange.length);
+
+#ifdef DEBUG_PASSWORD
+       DEBUG(100, ("user_info has passwords of length %d and %d\n", 
+                   user_info->lm_resp.length, user_info->nt_resp.length));
+       DEBUG(100, ("lm:\n"));
+       dump_data(100, user_info->lm_resp.data, user_info->lm_resp.length);
+       DEBUG(100, ("nt:\n"));
+       dump_data(100, user_info->nt_resp.data, user_info->nt_resp.length);
+#endif
+
+       for (auth_method = auth_info->auth_method_list;auth_method; auth_method = auth_method->next)
+       {
+               nt_status = auth_method->auth(auth_method->private_data, user_info, auth_info, server_info);
                if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(5, ("check_password:  checking guest-account for user [%s] suceeded\n", user_info->smb_name.str));
+                       DEBUG(3, ("check_password: %s authentication for user [%s] suceeded\n", 
+                                 auth_method->name, user_info->smb_name.str));
                } else {
-                       DEBUG(10, ("check_password:  checking gusst-account for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
+                       DEBUG(5, ("check_password: %s authentication for user [%s] FAILED with error %s\n", 
+                                 auth_method->name, user_info->smb_name.str, get_nt_error_msg(nt_status)));
+               }
+               
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       break;
+               }
        }
 
        /* This needs to be sorted:  If it doesn't match, what should we do? */
@@ -86,83 +109,47 @@ NTSTATUS check_password(const auth_usersupplied_info *user_info,
                return NT_STATUS_LOGON_FAILURE;
        }
 
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_rhosts_security(user_info, server_info);
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(3, ("check_password:  Password (rhosts) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(10, ("check_password:  Password (rhosts) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
-       
-       if ((lp_security() == SEC_DOMAIN) && !NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_domain_security(user_info, server_info);
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(7, ("check_password:  Password (domain) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(5, ("check_password:  Password (domain) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
-       
-       if ((lp_security() == SEC_SERVER) && !NT_STATUS_IS_OK(nt_status)) {
-               nt_status = check_server_security(user_info, server_info);
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(7, ("check_password:  Password (server) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(5, ("check_password:  Password (server) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
 
+       /* This is one of the few places the *relies* (rather than just sets defaults
+          on the value of lp_security().  This needs to change.  A new paramater 
+          perhaps? */
        if (lp_security() >= SEC_SERVER) {
                smb_user_control(user_info, *server_info, nt_status);
        }
 
-       if (!NT_STATUS_IS_OK(nt_status)) {
-               if (user_info->encrypted || lp_plaintext_to_smbpasswd()) { 
-                       nt_status = check_smbpasswd_security(user_info, server_info);
-               } else {
-                       nt_status = check_unix_security(user_info, server_info);
-                       done_pam = True;
-               }
-               
-               if (NT_STATUS_IS_OK(nt_status)) {
-                       DEBUG(7, ("check_password:  Password (unix/smbpasswd) for user [%s] suceeded\n", user_info->smb_name.str));
-               } else {
-                       DEBUG(5, ("check_password:  Password (unix/smbpasswd) for user [%s] FAILED with error %s\n", user_info->smb_name.str, get_nt_error_msg(nt_status)));
-                       
-               }               
-       }
-
        if (NT_STATUS_IS_OK(nt_status)) {
                pdb_username = pdb_get_username((*server_info)->sam_account);
-               if (!done_pam && !(*server_info)->guest) {
+               if (!(*server_info)->guest) {
                        /* We might not be root if we are an RPC call */
                        become_root();
                        nt_status = smb_pam_accountcheck(pdb_username);
                        unbecome_root();
                        
                        if (NT_STATUS_IS_OK(nt_status)) {
-                               DEBUG(5, ("check_password:  PAM Account for user [%s] suceeded\n", pdb_username));
+                               DEBUG(5, ("check_password:  PAM Account for user [%s] suceeded\n", 
+                                         pdb_username));
                        } else {
-                               DEBUG(3, ("check_password:  PAM Account for user [%s] FAILED with error %s\n", pdb_username, get_nt_error_msg(nt_status)));
+                               DEBUG(3, ("check_password:  PAM Account for user [%s] FAILED with error %s\n", 
+                                         pdb_username, get_nt_error_msg(nt_status)));
                        } 
                }
+               
+               if (NT_STATUS_IS_OK(nt_status)) {
+                       DEBUG((*server_info)->guest ? 5 : 2, 
+                             ("check_password:  %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", 
+                              (*server_info)->guest ? "guest " : "", 
+                              user_info->smb_name.str, 
+                              user_info->internal_username.str, 
+                              pdb_username));
+               }
        }
 
-       if (NT_STATUS_IS_OK(nt_status)) {
-               DEBUG(3, ("check_password:  %sauthenticaion for user [%s] -> [%s] -> [%s] suceeded\n", 
-                         (*server_info)->guest ? "guest " : "", 
-                         user_info->smb_name.str, 
-                         user_info->internal_username.str, 
-                         pdb_username));
-       } else {
-               DEBUG(3, ("check_password:  Authenticaion for user [%s] -> [%s] FAILED with error %s\n", user_info->smb_name.str, user_info->internal_username.str, get_nt_error_msg(nt_status)));
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(2, ("check_password:  Authenticaion for user [%s] -> [%s] FAILED with error %s\n", 
+                         user_info->smb_name.str, user_info->internal_username.str, 
+                         get_nt_error_msg(nt_status)));
                ZERO_STRUCTP(server_info);
-       }               
-
+       }
        return nt_status;
 
 }
@@ -210,16 +197,35 @@ static NTSTATUS pass_check_smb(char *smb_name,
 {
        NTSTATUS nt_status;
        auth_usersupplied_info *user_info = NULL;
+       extern auth_authsupplied_info *negprot_global_auth_info;
        auth_serversupplied_info *server_info = NULL;
+       if (encrypted) {                
+               make_user_info_for_reply_enc(&user_info, smb_name, 
+                                            domain,
+                                            lm_pwd, 
+                                            nt_pwd, 
+                                            plaintext_password);
+               nt_status = check_password(user_info, negprot_global_auth_info, &server_info);
+       } else {
+               auth_authsupplied_info *plaintext_auth_info = NULL;
+               DATA_BLOB chal;
+               if (!make_auth_info_subsystem(&plaintext_auth_info)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
 
-       make_user_info_for_reply(&user_info, smb_name, 
-                                domain, 
-                                lm_pwd, 
-                                nt_pwd, 
-                                plaintext_password, 
-                                encrypted);
-       
-       nt_status = check_password(user_info, &server_info);
+               chal = auth_get_challange(plaintext_auth_info);
+
+               if (!make_user_info_for_reply(&user_info, 
+                                             smb_name, domain, chal.data,
+                                             plaintext_password)) {
+                       return NT_STATUS_NO_MEMORY;
+               }
+               
+               nt_status = check_password(user_info, plaintext_auth_info, &server_info); 
+               
+               data_blob_free(&chal);
+               free_auth_info(&plaintext_auth_info);
+       }               
        free_user_info(&user_info);
        free_server_info(&server_info);
        return nt_status;
@@ -235,22 +241,23 @@ BOOL password_ok(char *smb_name, DATA_BLOB password_blob)
 
        DATA_BLOB null_password = data_blob(NULL, 0);
        extern BOOL global_encrypted_passwords_negotiated;
-
-       if (global_encrypted_passwords_negotiated) {
+       BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24);
+       
+       if (encrypted) {
                /* 
                 * The password could be either NTLM or plain LM.  Try NTLM first, 
                 * but fall-through as required.
                 * NTLMv2 makes no sense here.
                 */
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, global_encrypted_passwords_negotiated))) {
+               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) {
                        return True;
                }
                
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, global_encrypted_passwords_negotiated))) {
+               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) {
                        return True;
                }
        } else {
-               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, global_encrypted_passwords_negotiated))) {
+               if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) {
                        return True;
                }
        }
diff --git a/source/smbd/auth_builtin.c b/source/smbd/auth_builtin.c
new file mode 100644 (file)
index 0000000..6ea6d0b
--- /dev/null
@@ -0,0 +1,87 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0.
+   Generic authenticaion types
+   Copyright (C) Andrew Bartlett              2001
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/****************************************************************************
+ Check for a guest logon (username = "") and if so create the required 
+ structure.
+****************************************************************************/
+
+static NTSTATUS check_guest_security(void *my_private_data, 
+                             const auth_usersupplied_info *user_info, 
+                             const auth_authsupplied_info *auth_info,
+                             auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+
+       if (!(user_info->internal_username.str 
+             && *user_info->internal_username.str)) { 
+               if (make_server_info_guest(server_info)) {
+                       nt_status = NT_STATUS_OK;
+               } else {
+                       nt_status = NT_STATUS_NO_SUCH_USER;
+               }
+       }
+
+       return nt_status;
+}
+
+BOOL auth_init_guest(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_guest_security;
+       return True;
+}
+
+/****************************************************************************
+ Check against either sam or unix, depending on encryption.
+****************************************************************************/
+
+static NTSTATUS check_local_security(void *my_private_data,
+                             const auth_usersupplied_info *user_info, 
+                             const auth_authsupplied_info *auth_info,
+                             auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+
+       if (user_info->encrypted) {
+               nt_status = check_sam_security(my_private_data, user_info, auth_info, server_info);
+       } else {
+               nt_status = check_unix_security(my_private_data, user_info, auth_info, server_info);
+       }
+       
+       return nt_status;
+}
+
+BOOL auth_init_local(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_local_security;
+       return True;
+}
+
index 4ada7d4a56ecaf65e5890dbc205860086900fc88..ef0e5b2f10a4d4152f564d03d830dfb80ff417ad 100644 (file)
@@ -28,8 +28,10 @@ BOOL global_machine_password_needs_changing = False;
  Check for a valid username and password in security=domain mode.
 ****************************************************************************/
 
-NTSTATUS check_domain_security(const auth_usersupplied_info *user_info, 
-                              auth_serversupplied_info **server_info)
+static NTSTATUS check_ntdomain_security(void *my_private_data,
+                                       const auth_usersupplied_info *user_info, 
+                                       const auth_authsupplied_info *auth_info,
+                                       auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
        char *p, *pserver;
@@ -66,8 +68,18 @@ NTSTATUS check_domain_security(const auth_usersupplied_info *user_info,
        if (! *pserver) pserver = "*";
        p = pserver;
 
-       nt_status = domain_client_validate(user_info, server_info, 
+       nt_status = domain_client_validate(user_info, (uchar *)auth_info->challange.data,server_info, 
                                           p, trust_passwd, last_change_time);
 
        return nt_status;
 }
+
+BOOL auth_init_ntdomain(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_ntdomain_security;
+       return True;
+}
diff --git a/source/smbd/auth_info.c b/source/smbd/auth_info.c
new file mode 100644 (file)
index 0000000..12b843d
--- /dev/null
@@ -0,0 +1,279 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0.
+   Authentication utility functions
+   Copyright (C) Andrew Bartlett 2001
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+const struct auth_init_function builtin_auth_init_functions[] = {
+       { "guest", auth_init_guest },
+       { "rhosts", auth_init_rhosts },
+       { "hostsequiv", auth_init_hostsequiv },
+       { "sam", auth_init_sam },
+       { "unix", auth_init_unix },
+       { "local", auth_init_local },
+       { "smbserver", auth_init_smbserver },
+       { "ntdomain", auth_init_ntdomain },
+       { "winbind", auth_init_winbind },
+       { NULL, NULL}
+};
+
+/***************************************************************************
+ Make a auth_info struct
+***************************************************************************/
+
+static BOOL make_auth_info(auth_authsupplied_info **auth_info) 
+{
+       *auth_info = malloc(sizeof(**auth_info));
+       if (!*auth_info) {
+               DEBUG(0,("make_auth_info: malloc failed!\n"));
+               return False;
+       }
+       ZERO_STRUCTP(*auth_info);
+       
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a specified list.
+***************************************************************************/
+
+BOOL make_auth_info_list(auth_authsupplied_info **auth_info, auth_methods *list) 
+{
+       if (!make_auth_info(auth_info)) {
+               return False;
+       }
+       
+       (*auth_info)->auth_method_list = list;
+       
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **text_list) 
+{
+       auth_methods *list = NULL;
+       auth_methods *t = NULL;
+       auth_methods *tmp;
+       int i;
+       
+       for (;*text_list; text_list++)
+       { 
+               DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list));
+               for (i = 0; builtin_auth_init_functions[i].name; i++)
+               {
+                       if (strequal(builtin_auth_init_functions[i].name, *text_list))
+                       {
+                               DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i));
+                               /* Malloc entry,  fill it,  link it */
+                               t = (auth_methods *)malloc(sizeof(*t));
+                               if (!t) {
+                                       DEBUG(0,("make_pw_chat: malloc failed!\n"));
+                                       return False;
+                               }
+                               
+                               ZERO_STRUCTP(t);
+                               
+                               if (builtin_auth_init_functions[i].init(&t)) {
+                                       DEBUG(5,("auth method %s has a valid init\n", *text_list));
+                                       t->name = builtin_auth_init_functions[i].name;
+                                       DLIST_ADD_END(list, t, tmp);
+                               } else {
+                                       DEBUG(5,("auth method %s DOES NOT have a valid init\n", *text_list));
+                               }
+                               break;
+                       }
+               }
+       }
+       
+       make_auth_info_list(auth_info, list);
+       
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct for the auth subsystem
+***************************************************************************/
+
+BOOL make_auth_info_subsystem(auth_authsupplied_info **auth_info) 
+{
+       char **auth_method_list = NULL; 
+       
+       if (!make_auth_info(auth_info)) {
+               return False;
+       }
+       
+       if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) {
+               return False;
+       }
+
+       if (auth_method_list == NULL) {
+               switch (lp_security()) 
+               {
+               case SEC_DOMAIN:
+                       DEBUG(5,("Making default auth method list for security=domain\n"));
+                       auth_method_list = lp_list_make("guest ntdomain local");
+                       break;
+               case SEC_SERVER:
+                       DEBUG(5,("Making default auth method list for security=server\n"));
+                       auth_method_list = lp_list_make("guest smbserver local");
+                       break;
+               case SEC_USER:
+                       DEBUG(5,("Making default auth method list for security=user\n"));
+                       auth_method_list = lp_list_make("guest local");
+                       break;
+               case SEC_SHARE:
+                       DEBUG(5,("Making default auth method list for security=share\n"));
+                       auth_method_list = lp_list_make("guest local");
+                       break;
+               }
+       } else {
+               DEBUG(5,("Using specified auth order\n"));
+       }
+       
+       if (!make_auth_info_text_list(auth_info, auth_method_list)) {
+               lp_list_free(&auth_method_list);
+               return False;
+       }
+       
+       lp_list_free(&auth_method_list);
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a random challange
+***************************************************************************/
+
+BOOL make_auth_info_random(auth_authsupplied_info **auth_info) 
+{
+       uchar chal[8];
+       if (!make_auth_info_subsystem(auth_info)) {
+               return False;
+       }
+       
+       generate_random_buffer(chal, sizeof(chal), False);
+       (*auth_info)->challange = data_blob(chal, sizeof(chal));
+
+       (*auth_info)->challange_set_by = "random";
+
+       return True;
+}
+
+/***************************************************************************
+ Make a auth_info struct with a fixed challange
+***************************************************************************/
+
+BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8]) 
+{
+       if (!make_auth_info_subsystem(auth_info)) {
+               return False;
+       }
+       
+       (*auth_info)->challange = data_blob(chal, 8);
+       return True;
+}
+
+/***************************************************************************
+ Clear out a auth_info struct that has been allocated
+***************************************************************************/
+
+void free_auth_info(auth_authsupplied_info **auth_info)
+{
+       auth_methods *list;
+       if (*auth_info != NULL) {
+               list = (*auth_info)->auth_method_list;  
+               while (list) {
+                       auth_methods *old_head = list;
+                       if (list->free_private_data) {
+                               list->free_private_data(&(list->private_data));
+                       }
+                       DLIST_REMOVE(list, list);                       
+                       SAFE_FREE(old_head);
+               }
+               
+               data_blob_free(&(*auth_info)->challange);
+               ZERO_STRUCT(**auth_info);
+       }
+       SAFE_FREE(*auth_info);
+}
+
+/****************************************************************************
+ Try to get a challange out of the various authenticaion modules.
+ It is up to the caller to free it.
+****************************************************************************/
+
+DATA_BLOB auth_get_challange(auth_authsupplied_info *auth_info) 
+{
+       DATA_BLOB challange = data_blob(NULL, 0);
+       char *challange_set_by = NULL;
+       auth_methods *auth_method;
+
+       if (auth_info->challange.length) {
+               DEBUG(5, ("auth_get_challange: returning previous challange (normal)\n"));
+               return data_blob(auth_info->challange.data, auth_info->challange.length);
+       }
+
+       for (auth_method = auth_info->auth_method_list; auth_method; auth_method = auth_method->next)
+       {
+               if (auth_method->get_chal) {
+                       DEBUG(5, ("auth_get_challange: getting challange from module %s\n", auth_method->name));
+                       if (challange_set_by) {
+                               DEBUG(1, ("auth_get_challange: CONFIGURATION ERROR: authenticaion method %s has already specified a challange.  Challange by %s ignored.\n", 
+                                         challange_set_by, auth_method->name));
+                       } else {
+                               challange = auth_method->get_chal(&auth_method->private_data, auth_info);
+                               if (challange.length) {
+                                       DEBUG(5, ("auth_get_challange: sucessfully got challange from module %s\n", auth_method->name));
+                                       auth_info->challange = challange;
+                                       challange_set_by = auth_method->name;
+                                       auth_info->challange_set_method = auth_method;
+                               } else {
+                                       DEBUG(3, ("auth_get_challange: getting challange from authenticaion method %s FAILED.\n", 
+                                                 auth_method->name));
+                               }
+                       }
+               } else {
+                       DEBUG(5, ("auth_get_challange: module %s did not want to specify a challange\n", auth_method->name));
+               }
+       }
+       
+       if (!challange_set_by) {
+               uchar chal[8];
+               
+               generate_random_buffer(chal, sizeof(chal), False);
+               auth_info->challange = data_blob(chal, sizeof(chal));
+               
+               challange_set_by = "random";
+       } 
+       
+       DEBUG(5, ("auth_info challange created by %s\n", challange_set_by));
+       DEBUG(5, ("challange is: \n"));
+       dump_data(5, auth_info->challange.data, (auth_info)->challange.length);
+       
+       SMB_ASSERT(auth_info->challange.length == 8);
+
+       auth_info->challange_set_by=challange_set_by;
+
+       return data_blob(auth_info->challange.data, auth_info->challange.length);
+}
+
+
index 9c07e48a9b673d6ebc0748a575612c58461b3b61..2605f0770a225d5077fa828700efc9072a288477 100644 (file)
@@ -135,7 +135,6 @@ check for a possible hosts equiv or rhosts entry for the user
 static BOOL check_hosts_equiv(struct passwd *pass)
 {
   char *fname = NULL;
-  pstring rhostsfile;
 
   if (!pass) 
     return(False);
@@ -148,39 +147,82 @@ static BOOL check_hosts_equiv(struct passwd *pass)
                  return(True);
   }
   
-  if (lp_use_rhosts())
-  {
-         char *home = pass->pw_dir;
-         if (home) {
-                 slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
-                 if (check_user_equiv(pass->pw_name,client_name(),rhostsfile))
-                         return(True);
-         }
-  }
-  
   return(False);
 }
 
+
 /****************************************************************************
  Check for a valid .rhosts/hosts.equiv entry for this user
 ****************************************************************************/
 
-NTSTATUS check_rhosts_security(const auth_usersupplied_info *user_info, 
-                            auth_serversupplied_info **server_info)
+static NTSTATUS check_hostsequiv_security(void *my_private_data, 
+                                         const auth_usersupplied_info *user_info, 
+                                         const auth_authsupplied_info *auth_info,
+                                         auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
        struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
        
        if (pass) {
-               become_root();
                if (check_hosts_equiv(pass)) {
                        nt_status = NT_STATUS_OK;
                        make_server_info_pw(server_info, pass);
                }
-               unbecome_root();
        } else {
                nt_status = NT_STATUS_NO_SUCH_USER;
        }
 
        return nt_status;
 }
+
+
+/****************************************************************************
+ Check for a valid .rhosts/hosts.equiv entry for this user
+****************************************************************************/
+
+static NTSTATUS check_rhosts_security(void *my_private_data, 
+                                     const auth_usersupplied_info *user_info, 
+                                     const auth_authsupplied_info *auth_info,
+                                     auth_serversupplied_info **server_info)
+{
+       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       struct passwd *pass = Get_Pwnam(user_info->internal_username.str);
+       pstring rhostsfile;
+       
+       if (pass) {
+               char *home = pass->pw_dir;
+               if (home) {
+                       slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home);
+                       become_root();
+                       if (check_user_equiv(pass->pw_name,client_name(),rhostsfile)) {
+                               nt_status = NT_STATUS_OK;
+                               make_server_info_pw(server_info, pass);
+                       }
+                       unbecome_root();
+               } 
+       } else {
+               nt_status = NT_STATUS_NO_SUCH_USER;
+       }
+
+       return nt_status;
+}
+
+BOOL auth_init_hostsequiv(auth_methods **auth_method) 
+{
+
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_hostsequiv_security;
+       return True;
+}
+
+BOOL auth_init_rhosts(auth_methods **auth_method) 
+{
+
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_rhosts_security;
+       return True;
+}
index ddbc284d50ce02bd79795edc83dfab197c364e79..067b5b2997bc4bc8051cf5f20a6da6ca64a908d8 100644 (file)
 
 extern pstring global_myname;
 
-/****************************************************************************
- Return the client state structure.
-****************************************************************************/
-
-struct cli_state *server_client(void)
-{
-       static struct cli_state pw_cli;
-       return &pw_cli;
-}
-
 /****************************************************************************
  Support for server level security.
 ****************************************************************************/
 
-struct cli_state *server_cryptkey(void)
+static struct cli_state *server_cryptkey(void)
 {
-       struct cli_state *cli;
+       struct cli_state *cli = NULL;
        fstring desthost;
        struct in_addr dest_ip;
        char *p, *pserver;
        BOOL connected_ok = False;
 
-       cli = server_client();
-
-       if (!cli_initialise(cli))
+       if (!(cli = cli_initialise(cli)))
                return NULL;
 
        /* security = server just can't function with spnego */
@@ -88,7 +76,11 @@ struct cli_state *server_cryptkey(void)
 
        if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip))
                return NULL;
-
+       
+       if (strequal(desthost,myhostname())) {
+               exit_server("Password server loop!");
+       }
+       
        DEBUG(3,("got session\n"));
 
        if (!cli_negprot(cli)) {
@@ -109,13 +101,82 @@ struct cli_state *server_cryptkey(void)
        return cli;
 }
 
+/****************************************************************************
+ Clean up our allocated cli.
+****************************************************************************/
+
+static void free_server_private_data(void **private_data_pointer) 
+{
+       struct cli_state **cli = (struct cli_state **)private_data_pointer;
+       if (*cli && (*cli)->initialised) {
+               cli_shutdown(*cli);
+               
+               SAFE_FREE(*cli);
+       }
+}
+
+/****************************************************************************
+ Send a 'keepalive' packet down the cli pipe.
+****************************************************************************/
+
+static void send_server_keepalive(void **private_data_pointer) 
+{
+       struct cli_state **cli = (struct cli_state **)private_data_pointer;
+       
+       /* also send a keepalive to the password server if its still
+          connected */
+       if (cli && *cli && (*cli)->initialised) {
+               if (!send_keepalive((*cli)->fd)) {
+                       DEBUG( 2, ( "password server keepalive failed.\n"));
+                       cli_shutdown(*cli);
+                       SAFE_FREE(*cli);
+               }
+       }
+}
+
+/****************************************************************************
+ Get the challange out of a password server.
+****************************************************************************/
+
+static DATA_BLOB auth_get_challange_server(void **my_private_data, const struct authsupplied_info *auth_info) 
+{
+       struct cli_state *cli = server_cryptkey();
+       
+       if (cli) {
+               DEBUG(3,("using password server validation\n"));
+               if ((cli->sec_mode & 2) == 0) {
+                       /* We can't work with unencrypted password servers
+                          unless 'encrypt passwords = no' */
+                       DEBUG(5,("make_auth_info_server: Server is unencrypted, no challange available..\n"));
+
+                       *my_private_data = (void *)cli;
+                       return data_blob(NULL, 0);
+                       
+               } else if (cli->secblob.length < 8) {
+                       /* We can't do much if we don't get a full challange */
+                       DEBUG(2,("make_auth_info_server: Didn't receive a full challange from server\n"));
+                       cli_shutdown(cli);
+                       return data_blob(NULL, 0);
+               }
+
+               *my_private_data = (void *)cli;
+               
+               return data_blob(cli->secblob.data,8);
+       } else {
+               return data_blob(NULL, 0);
+       }
+}
+
 
 /****************************************************************************
  Check for a valid username and password in security=server mode.
   - Validate a password with the password server.
 ****************************************************************************/
 
-NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+static NTSTATUS check_smbserver_security(void *my_private_data, 
+                                 const auth_usersupplied_info *user_info, 
+                                 const auth_authsupplied_info *auth_info,
+                                 auth_serversupplied_info **server_info)
 {
        struct cli_state *cli;
        static unsigned char badpass[24];
@@ -123,13 +184,32 @@ NTSTATUS check_server_security(const auth_usersupplied_info *user_info, auth_ser
        static BOOL tested_password_server = False;
        static BOOL bad_password_server = False;
        NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
+       BOOL locally_made_cli = False;
 
-       cli = server_client();
+       cli = my_private_data;
+       
+       if (cli) {
+       } else {
+               cli = server_cryptkey();
+               locally_made_cli = True;
+       }
 
-       if (!cli->initialised) {
+       if (!cli || !cli->initialised) {
                DEBUG(1,("password server %s is not connected\n", cli->desthost));
-               return(NT_STATUS_LOGON_FAILURE);
+               return NT_STATUS_LOGON_FAILURE;
        }  
+       
+       if ((cli->sec_mode & 2) == 0) {
+               if (user_info->encrypted) {
+                       DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost));
+                       return NT_STATUS_LOGON_FAILURE;         
+               }
+       } else {
+               if (memcmp(cli->secblob.data, auth_info->challange.data, 8) != 0) {
+                       DEBUG(1,("the challange that the password server (%s) supplied us is not the one we gave our client. This just can't work :-(\n", cli->desthost));
+                       return NT_STATUS_LOGON_FAILURE;         
+               }
+       }
 
        if(badpass[0] == 0)
                memset(badpass, 0x1f, sizeof(badpass));
@@ -206,17 +286,32 @@ use this machine as the password server.\n"));
         * not guest enabled, we can try with the real password.
         */
 
-       if (!cli_session_setup(cli, user_info->smb_name.str, 
-                              (char *)user_info->lm_resp.data, 
-                              user_info->lm_resp.length, 
-                              (char *)user_info->nt_resp.data, 
-                              user_info->nt_resp.length, 
-                              user_info->domain.str)) {
-               DEBUG(1,("password server %s rejected the password\n", cli->desthost));
-               /* Make this cli_nt_error() when the conversion is in */
-               nt_status = cli_nt_error(cli);
+       if (!user_info->encrypted) {
+               /* Plaintext available */
+               if (!cli_session_setup(cli, user_info->smb_name.str, 
+                                      (char *)user_info->plaintext_password.data, 
+                                      user_info->plaintext_password.length, 
+                                      NULL, 0,
+                                      user_info->domain.str)) {
+                       DEBUG(1,("password server %s rejected the password\n", cli->desthost));
+                       /* Make this cli_nt_error() when the conversion is in */
+                       nt_status = cli_nt_error(cli);
+               } else {
+                       nt_status = NT_STATUS_OK;
+               }
        } else {
-               nt_status = NT_STATUS_OK;
+               if (!cli_session_setup(cli, user_info->smb_name.str, 
+                                      (char *)user_info->lm_resp.data, 
+                                      user_info->lm_resp.length, 
+                                      (char *)user_info->nt_resp.data, 
+                                      user_info->nt_resp.length, 
+                                      user_info->domain.str)) {
+                       DEBUG(1,("password server %s rejected the password\n", cli->desthost));
+                       /* Make this cli_nt_error() when the conversion is in */
+                       nt_status = cli_nt_error(cli);
+               } else {
+                       nt_status = NT_STATUS_OK;
+               }
        }
 
        /* if logged in as guest then reject */
@@ -238,5 +333,22 @@ use this machine as the password server.\n"));
                }
        }
 
+       if (locally_made_cli) {
+               cli_shutdown(cli);
+               SAFE_FREE(cli);
+       }
+
        return(nt_status);
 }
+
+BOOL auth_init_smbserver(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_smbserver_security;
+       (*auth_method)->get_chal = auth_get_challange_server;
+       (*auth_method)->send_keepalive = send_server_keepalive;
+       (*auth_method)->free_private_data = free_server_private_data;
+       return True;
+}
index 70632fb5dfb46b9bb2fee081a497f07b745f9840..24a4d4e4e427ad1dbf6973811ce68da487cbdb3c 100644 (file)
@@ -96,7 +96,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
        if (ntv2_response.length < 16) {
                /* We MUST have more than 16 bytes, or the stuff below will go
                   crazy... */
-               DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", 
+               DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n", 
                          ntv2_response.length));
                return False;
        }
@@ -132,15 +132,16 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response,
  Do a specific test for an smb password being correct, given a smb_password and
  the lanman and NT responses.
 ****************************************************************************/
-NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info, uint8 user_sess_key[16])
+static NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, 
+                               const auth_usersupplied_info *user_info, 
+                               const auth_authsupplied_info *auth_info,
+                               uint8 user_sess_key[16])
 {
+       uint16 acct_ctrl;
        const uint8 *nt_pw, *lm_pw;
-       uint16  acct_ctrl = pdb_get_acct_ctrl(sampass);
        uint32 ntlmssp_flags;
 
-       if (!user_info || !sampass) 
-               return NT_STATUS_LOGON_FAILURE;
-
+       acct_ctrl = pdb_get_acct_ctrl(sampass);
        if (acct_ctrl & ACB_PWNOTREQ) 
        {
                if (lp_null_passwords()) 
@@ -173,8 +174,8 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
                */
                DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n"));
                if (smb_pwd_check_ntlmv2( user_info->nt_resp, 
-                                         nt_pw, 
-                                         user_info->sec_blob, user_info->smb_name.str, 
+                                         nt_pw, auth_info->challange, 
+                                         user_info->smb_name.str, 
                                          user_info->client_domain.str,
                                          user_sess_key))
                {
@@ -190,7 +191,7 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
                        */
                        DEBUG(4,("smb_password_ok: Checking NT MD4 password\n"));
                        if (smb_pwd_check_ntlmv1(user_info->nt_resp, 
-                                                nt_pw, user_info->sec_blob,
+                                                nt_pw, auth_info->challange,
                                                 user_sess_key)) 
                        {
                                return NT_STATUS_OK;
@@ -223,7 +224,7 @@ NTSTATUS sam_password_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *use
                
                DEBUG(4,("smb_password_ok: Checking LM password\n"));
                if (smb_pwd_check_ntlmv1(user_info->lm_resp, 
-                                        lm_pw, user_info->sec_blob,
+                                        lm_pw, auth_info->challange,
                                         user_sess_key)) 
                {
                        return NT_STATUS_OK;
@@ -265,6 +266,24 @@ static NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_inf
                return NT_STATUS_ACCOUNT_EXPIRED;
        }
 
+       if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) {
+               time_t must_change_time = pdb_get_pass_must_change_time(sampass);
+               time_t last_set_time = pdb_get_pass_last_set_time(sampass);
+
+               /* check for immediate expiry "must change at next logon" */
+               if (must_change_time == 0 && last_set_time != 0) {
+                       DEBUG(1,("Account for user '%s' password must change!.\n", pdb_get_username(sampass)));
+                       return NT_STATUS_PASSWORD_MUST_CHANGE;
+               }
+
+               /* check for expired password */
+               if (must_change_time < time(NULL) && must_change_time != 0) {
+                       DEBUG(1,("Account for user '%s' password expired!.\n", pdb_get_username(sampass)));
+                       DEBUG(1,("Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time));
+                       return NT_STATUS_PASSWORD_EXPIRED;
+               }
+       }
+
        /* Test workstation. Workstation list is comma separated. */
 
        workstation_list = strdup(pdb_get_workstations(sampass));
@@ -293,24 +312,6 @@ static NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_inf
                SAFE_FREE(workstation_list);
        }
 
-       if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP)) {
-               time_t must_change_time = pdb_get_pass_must_change_time(sampass);
-               time_t last_set_time = pdb_get_pass_last_set_time(sampass);
-
-               /* check for immediate expiry "must change at next logon" */
-               if (must_change_time == 0 && last_set_time != 0) {
-                       DEBUG(1,("Account for user '%s' password must change!.\n", pdb_get_username(sampass)));
-                       return NT_STATUS_PASSWORD_MUST_CHANGE;
-               }
-
-               /* check for expired password */
-               if (must_change_time < time(NULL) && must_change_time != 0) {
-                       DEBUG(1,("Account for user '%s' password expired!.\n", pdb_get_username(sampass)));
-                       DEBUG(1,("Password expired at '%s' (%ld) unix time.\n", http_timestring(must_change_time), (long)must_change_time));
-                       return NT_STATUS_PASSWORD_EXPIRED;
-               }
-       }
-
        if (acct_ctrl & ACB_DOMTRUST) {
                DEBUG(2,("session_trust_account: Domain trust account %s denied by server\n", pdb_get_username(sampass)));
                return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;
@@ -336,7 +337,10 @@ SMB hash supplied in the user_info structure
 return an NT_STATUS constant.
 ****************************************************************************/
 
-NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+NTSTATUS check_sam_security(void *my_private_dat,
+                           const auth_usersupplied_info *user_info, 
+                           const auth_authsupplied_info *auth_info,
+                           auth_serversupplied_info **server_info)
 {
        SAM_ACCOUNT *sampass=NULL;
        BOOL ret;
@@ -344,7 +348,7 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
        uint8 user_sess_key[16];
        const uint8* lm_hash;
 
-       if (!user_info) {
+       if (!user_info || !auth_info) {
                return NT_STATUS_LOGON_FAILURE;
        }
 
@@ -365,7 +369,7 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
                return NT_STATUS_NO_SUCH_USER;
        }
 
-       nt_status = sam_password_ok(sampass, user_info, user_sess_key);
+       nt_status = sam_password_ok(sampass, user_info, auth_info, user_sess_key);
 
        if (!NT_STATUS_IS_OK(nt_status)) {
                pdb_free_sam(&sampass);
@@ -394,6 +398,15 @@ NTSTATUS check_smbpasswd_security(const auth_usersupplied_info *user_info, auth_
        return nt_status;
 }
 
+BOOL auth_init_sam(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+
+       (*auth_method)->auth = check_sam_security;
+       return True;
+}
 
 
 
index 8c4a520350bdcd135379d87f08ee5a7e57f92953..d134ce6909cd45c6eccbbe24a4523563ae72d7f2 100644 (file)
@@ -82,7 +82,10 @@ check if a username/password is OK assuming the password
 in PLAIN TEXT
 ****************************************************************************/
 
-NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serversupplied_info **server_info)
+NTSTATUS check_unix_security(void *my_private_data,
+                            const auth_usersupplied_info *user_info, 
+                            const auth_authsupplied_info *auth_info,
+                            auth_serversupplied_info **server_info)
 {
        NTSTATUS nt_status;
        struct passwd *pass = NULL;
@@ -104,9 +107,19 @@ NTSTATUS check_unix_security(const auth_usersupplied_info *user_info, auth_serve
                if (pass) {
                        make_server_info_pw(server_info, pass);
                } else {
+                       /* we need to do somthing more useful here */
                        nt_status = NT_STATUS_NO_SUCH_USER;
                }
        }
 
        return nt_status;
 }
+
+BOOL auth_init_unix(auth_methods **auth_method) 
+{
+       if (!make_auth_methods(auth_method)) {
+               return False;
+       }
+       (*auth_method)->auth = check_unix_security;
+       return True;
+}
index 25e0830fc77414ebc78c76ac7170388300929cce..d1b2cc92e52e954ffc5aac9972bc51d33084d3c7 100644 (file)
 
 #include "includes.h"
 
-/* Data to do lanman1/2 password challenge. */
-static unsigned char saved_challenge[8];
-static BOOL challenge_sent=False;
 extern fstring remote_machine;
 extern pstring global_myname;
 
-/*******************************************************************
- Get the next challenge value - no repeats.
-********************************************************************/
-
-void generate_next_challenge(char *challenge)
-{
-       unsigned char buf[8];
-
-       generate_random_buffer(buf,8,False);
-       memcpy(saved_challenge, buf, 8);
-       memcpy(challenge,buf,8);
-       challenge_sent = True;
-}
-
-/*******************************************************************
- Set the last challenge sent, usually from a password server.
-********************************************************************/
-
-BOOL set_challenge(unsigned char *challenge)
-{
-       memcpy(saved_challenge,challenge,8);
-       challenge_sent = True;
-       return(True);
-}
-
-/*******************************************************************
- Get the last challenge sent.
-********************************************************************/
-
-BOOL last_challenge(unsigned char *challenge)
-{
-       if (!challenge_sent)
-               return(False);
-       memcpy(challenge,saved_challenge,8);
-       return(True);
-}
-
 /****************************************************************************
  Create a UNIX user on demand.
 ****************************************************************************/
@@ -166,7 +126,6 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
                           const char *client_domain, 
                           const char *domain,
                           const char *wksta_name, 
-                          DATA_BLOB sec_blob, 
                           DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
                           DATA_BLOB plaintext, 
                           uint32 ntlmssp_flags, BOOL encrypted)
@@ -226,7 +185,6 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
 
        DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username));
 
-       (*user_info)->sec_blob = data_blob(sec_blob.data, sec_blob.length);
        (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length);
        (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length);
        (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length);
@@ -246,7 +204,7 @@ static BOOL make_user_info(auth_usersupplied_info **user_info,
 BOOL make_user_info_map(auth_usersupplied_info **user_info, 
                        const char *smb_name, 
                        const char *client_domain, 
-                       const char *wksta_name, DATA_BLOB sec_blob, 
+                       const char *wksta_name, 
                        DATA_BLOB lm_pwd, DATA_BLOB nt_pwd,
                        DATA_BLOB plaintext, 
                        uint32 ntlmssp_flags, BOOL encrypted)
@@ -265,7 +223,7 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
        return make_user_info(user_info, 
                              smb_name, internal_username,
                              client_domain, domain,
-                             wksta_name, sec_blob,
+                             wksta_name, 
                              lm_pwd, nt_pwd,
                              plaintext, 
                              ntlmssp_flags, encrypted);
@@ -280,12 +238,11 @@ BOOL make_user_info_map(auth_usersupplied_info **user_info,
 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
                                     char *smb_name, 
                                     char *client_domain, 
-                                    char *wksta_name, uchar chal[8],
+                                    char *wksta_name, 
                                     uchar *lm_network_pwd, int lm_pwd_len,
                                     uchar *nt_network_pwd, int nt_pwd_len)
 {
        BOOL ret;
-       DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
        DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
        DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -301,8 +258,8 @@ BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info,
 
        ret = make_user_info_map(user_info, 
                                 smb_name, client_domain, 
-                                wksta_name, sec_blob, 
-                                nt_blob, lm_blob,
+                                wksta_name, 
+                                lm_blob, nt_blob,
                                 plaintext_blob, 
                                 ntlmssp_flags, True);
                
@@ -320,6 +277,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
                                         char *smb_name, 
                                         char *client_domain, 
                                         char *wksta_name, 
+                                        char chal[8], 
                                         uchar lm_interactive_pwd[16], 
                                         uchar nt_interactive_pwd[16], 
                                         uchar *dc_sess_key)
@@ -329,11 +287,8 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
        unsigned char local_lm_response[24];
        unsigned char local_nt_response[24];
        unsigned char key[16];
-       uint8 chal[8];
        uint32 ntlmssp_flags = 0;
        
-       generate_random_buffer(chal, 8, False);
-
        ZERO_STRUCT(key);
        memcpy(key, dc_sess_key, 8);
        
@@ -362,7 +317,6 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
        dump_data(100, nt_pwd, sizeof(nt_pwd));
 #endif
        
-       generate_random_buffer(chal, 8, False);
        SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response);
        SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response);
        
@@ -373,7 +327,6 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
 
        {
                BOOL ret;
-               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
                DATA_BLOB local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response));
                DATA_BLOB local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response));
                DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -385,7 +338,7 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
 
                ret = make_user_info_map(user_info, 
                                         smb_name, client_domain, 
-                                        wksta_name, sec_blob, 
+                                        wksta_name, 
                                         local_lm_blob,
                                         local_nt_blob,
                                         plaintext_blob, 
@@ -402,13 +355,14 @@ BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_winbind(auth_usersupplied_info **user_info, 
-                            char *username,
-                            char *domain, 
-                            char *password)
+                            const char *username,
+                            const char *domain, 
+                            const char *password,
+                           char chal[8] /* Give winbind back the challange we used */
+       )
 {
        unsigned char local_lm_response[24];
        unsigned char local_nt_response[24];
-       char chal[8];
        DATA_BLOB local_lm_blob;
        DATA_BLOB local_nt_blob;
        DATA_BLOB plaintext_blob;
@@ -453,16 +407,11 @@ BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
 
        {
                BOOL ret;
-               DATA_BLOB sec_blob = data_blob(chal, sizeof(chal));
-               
-               if (!sec_blob.data) {
-                       return False;
-               }
 
                ret = make_user_info(user_info, 
                                     username, username,
                                     domain, domain, 
-                                    global_myname, sec_blob, 
+                                    global_myname, 
                                     local_nt_blob,
                                     local_lm_blob,
                                     plaintext_blob, 
@@ -483,12 +432,10 @@ BOOL make_user_info_winbind(auth_usersupplied_info **user_info,
 BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, 
                                 char *smb_name, 
                                 char *client_domain, 
-                                uchar chal[8],
                                 uchar *lm_network_pwd, int lm_pwd_len,
                                 uchar *nt_network_pwd, int nt_pwd_len)
 {
        BOOL ret;
-       DATA_BLOB sec_blob = data_blob(chal, 8);
        DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
        DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -502,7 +449,7 @@ BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
        ret = make_user_info(user_info, 
                             smb_name, smb_name, 
                             client_domain, client_domain, 
-                            global_myname, sec_blob, 
+                            global_myname, 
                             nt_blob, lm_blob,
                             plaintext_blob, 
                             ntlmssp_flags, True);
@@ -517,59 +464,30 @@ BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info,
 ****************************************************************************/
 
 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
-                             char *smb_name,
-                             char *client_domain, 
-                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
-                             DATA_BLOB plaintext_password,
-                             BOOL encrypted)
+                             char *smb_name, 
+                             char *client_domain,
+                             char chal[8],
+                             DATA_BLOB plaintext_password)
 {
-       uchar chal[8];
 
        DATA_BLOB local_lm_blob;
        DATA_BLOB local_nt_blob;
-       DATA_BLOB sec_blob;
        BOOL ret = False;
        uint32 ntlmssp_flags = 0;
                        
-       if (encrypted) {
-               DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
-               if (!last_challenge(chal)) {
-                       DEBUG(0,("Encrypted login but no challange set!\n"));
-                       return False;
-               }
-               sec_blob = data_blob(chal, 8);
-               
-               if (lm_resp.length == 24) {
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
-               }
-               if (nt_resp.length == 0) {
-               } else if (nt_resp.length == 24) {
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
-               } else {
-                       ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
-               }
-
-               return make_user_info_map(user_info, smb_name, 
-                                         client_domain, 
-                                         remote_machine, sec_blob,
-                                         lm_resp, 
-                                         nt_resp, 
-                                         no_plaintext_blob, 
-                                         ntlmssp_flags, encrypted);
-       }
-
-       generate_random_buffer(chal, 8, False);
-
-       sec_blob = data_blob(chal, 8);
-       
        /*
         * Not encrypted - do so.
         */
        
-       DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n"));
+       DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted format.\n"));
        
        if (plaintext_password.data) {
                unsigned char local_lm_response[24];
+               
+#ifdef DEBUG_PASSWORD
+               DEBUG(10,("Unencrypted password (len %d):\n",plaintext_password.length));
+               dump_data(100, plaintext_password.data, plaintext_password.length);
+#endif
 
                SMBencrypt( (const uchar *)plaintext_password.data, chal, local_lm_response);
                local_lm_blob = data_blob(local_lm_response, 24);
@@ -587,23 +505,54 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info,
        ret = make_user_info_map(user_info, smb_name,
                                 client_domain, 
                                 remote_machine,
-                                sec_blob,
                                 local_lm_blob,
                                 local_nt_blob,
                                 plaintext_password, 
-                                ntlmssp_flags, encrypted);
+                                ntlmssp_flags, False);
        
        data_blob_free(&local_lm_blob);
        return ret;
 }
 
+/****************************************************************************
+ Create an auth_usersupplied_data structure
+****************************************************************************/
+
+BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
+                             char *smb_name,
+                             char *client_domain, 
+                             DATA_BLOB lm_resp, DATA_BLOB nt_resp,
+                             DATA_BLOB plaintext_password)
+{
+       uint32 ntlmssp_flags = 0;
+
+       DATA_BLOB no_plaintext_blob = data_blob(NULL, 0); 
+       
+       if (lm_resp.length == 24) {
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM;
+       }
+       if (nt_resp.length == 0) {
+       } else if (nt_resp.length == 24) {
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM;
+       } else {
+               ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2;
+       }
+
+       return make_user_info_map(user_info, smb_name, 
+                                client_domain, 
+                                remote_machine, 
+                                lm_resp, 
+                                nt_resp, 
+                                no_plaintext_blob, 
+                                ntlmssp_flags, True);
+}
+
 /****************************************************************************
  Create a guest user_info blob, for anonymous authenticaion.
 ****************************************************************************/
 
 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
 {
-       DATA_BLOB sec_blob = data_blob(NULL, 0);
        DATA_BLOB lm_blob = data_blob(NULL, 0);
        DATA_BLOB nt_blob = data_blob(NULL, 0);
        DATA_BLOB plaintext_blob = data_blob(NULL, 0);
@@ -612,7 +561,7 @@ BOOL make_user_info_guest(auth_usersupplied_info **user_info)
        return make_user_info(user_info, 
                              "","", 
                              "","", 
-                             "", sec_blob,
+                             "", 
                              nt_blob, lm_blob,
                              plaintext_blob, 
                              ntlmssp_flags, True);
@@ -680,7 +629,6 @@ void free_user_info(auth_usersupplied_info **user_info)
                SAFE_FREE((*user_info)->internal_username.str);
                SAFE_FREE((*user_info)->client_domain.str);
                SAFE_FREE((*user_info)->domain.str);
-               data_blob_free(&(*user_info)->sec_blob);
                data_blob_free(&(*user_info)->lm_resp);
                data_blob_free(&(*user_info)->nt_resp);
                SAFE_FREE((*user_info)->interactive_password);
@@ -725,6 +673,22 @@ BOOL make_server_info_guest(auth_serversupplied_info **server_info)
        return False;
 }
 
+/***************************************************************************
+ Make an auth_methods struct
+***************************************************************************/
+
+BOOL make_auth_methods(auth_methods **auth_method) 
+{
+       *auth_method = malloc(sizeof(**auth_method));
+       if (!*auth_method) {
+               DEBUG(0,("make_auth_method: malloc failed!\n"));
+               return False;
+       }
+       ZERO_STRUCTP(*auth_method);
+       
+       return True;
+}
+
 /****************************************************************************
  Delete a SID token.
 ****************************************************************************/
@@ -764,25 +728,3 @@ NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken)
 
        return token;
 }
-
-/****************************************************************************
- Check for a guest logon (username = "") and if so create the required 
- structure.
-****************************************************************************/
-
-NTSTATUS check_guest_security(const auth_usersupplied_info *user_info, 
-                             auth_serversupplied_info **server_info)
-{
-       NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
-
-       if (!(user_info->internal_username.str 
-             && *user_info->internal_username.str)) { 
-               if (make_server_info_guest(server_info)) {
-                       nt_status = NT_STATUS_OK;
-               } else {
-                       nt_status = NT_STATUS_NO_SUCH_USER;
-               }
-       }
-
-       return nt_status;
-}
index 045e16a9bbe85b36fd388e2b28a55cda8d8016a7..d080c23332c022a523c86082e70b6edcee37ef3b 100644 (file)
@@ -27,6 +27,7 @@ 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;
 
 /****************************************************************************
 reply for the core protocol
@@ -68,6 +69,7 @@ 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();
 
@@ -77,8 +79,14 @@ static int reply_lanman1(char *inbuf, char *outbuf)
   set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
   SSVAL(outbuf,smb_vwv1,secword); 
   /* Create a token value and add it to the outgoing packet. */
-  if (global_encrypted_passwords_negotiated) 
-    generate_next_challenge(smb_buf(outbuf));
+  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_challange(negprot_global_auth_info);
+         memcpy(smb_buf(outbuf), cryptkey.data, 8);
+         data_blob_free(&cryptkey);
+  }
 
   Protocol = PROTOCOL_LANMAN1;
 
@@ -106,40 +114,26 @@ 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);
-  struct cli_state *cli = NULL;
-  char cryptkey[8];
-  char crypt_len = 0;
+  DATA_BLOB cryptkey;
 
   global_encrypted_passwords_negotiated = lp_encrypted_passwords();
-
-  if (lp_security() == SEC_SERVER) {
-         cli = server_cryptkey();
-  }
-
-  if (cli) {
-         DEBUG(3,("using password server validation\n"));
-         global_encrypted_passwords_negotiated = ((cli->sec_mode & 2) != 0);
-  }
-
+  
   if (lp_security()>=SEC_USER) secword |= 1;
   if (global_encrypted_passwords_negotiated) secword |= 2;
 
+  set_message(outbuf,13,global_encrypted_passwords_negotiated?8:0,True);
+  SSVAL(outbuf,smb_vwv1,secword); 
+  SIVAL(outbuf,smb_vwv6,sys_getpid());
+
   if (global_encrypted_passwords_negotiated) {
-         crypt_len = 8;
-         if (!cli) {
-                 generate_next_challenge(cryptkey);
-         } else {
-                 memcpy(cryptkey, cli->secblob.data, 8);
-                 set_challenge((unsigned char *)cryptkey);
+         if (!make_auth_info_subsystem(&negprot_global_auth_info)) {
+                 smb_panic("cannot make_negprot_global_auth_info!\n");
          }
+         cryptkey = auth_get_challange(negprot_global_auth_info);
+         memcpy(smb_buf(outbuf), cryptkey.data, 8);
+         data_blob_free(&cryptkey);
   }
 
-  set_message(outbuf,13,crypt_len,True);
-  SSVAL(outbuf,smb_vwv1,secword); 
-  SIVAL(outbuf,smb_vwv6,sys_getpid());
-  if (global_encrypted_passwords_negotiated) 
-         memcpy(smb_buf(outbuf), cryptkey, 8);
-
   Protocol = PROTOCOL_LANMAN2;
 
   /* Reply, SMBlockread, SMBwritelock supported. */
@@ -202,45 +196,22 @@ static int reply_nt1(char *inbuf, char *outbuf)
 
        int secword=0;
        time_t t = time(NULL);
-       struct cli_state *cli = NULL;
-       uint8 cryptkey[8];
+       DATA_BLOB cryptkey;
        char *p, *q;
        BOOL negotiate_spnego = False;
 
        global_encrypted_passwords_negotiated = lp_encrypted_passwords();
 
-       if (lp_security() == SEC_SERVER) {
-               DEBUG(5,("attempting password server validation\n"));
-               cli = server_cryptkey();
-       } else {
-               DEBUG(5,("not attempting password server validation\n"));
-               /* do spnego in user level security if the client
-                  supports it and we can do encrypted passwords */
-               if (global_encrypted_passwords_negotiated && 
-                   (lp_security() == SEC_USER ||
-                    lp_security() == SEC_DOMAIN) &&
-                   (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
-                       negotiate_spnego = True;
-                       capabilities |= CAP_EXTENDED_SECURITY;
-               }
-       }
+       /* do spnego in user level security if the client
+          supports it and we can do encrypted passwords */
        
-       if (cli) {
-               DEBUG(3,("using password server validation\n"));
-               global_encrypted_passwords_negotiated = ((cli->sec_mode & 2) != 0);
-       } else {
-               DEBUG(3,("not using password server validation\n"));
+       if (global_encrypted_passwords_negotiated && 
+           (lp_security() != SEC_SHARE) &&
+           (SVAL(inbuf, smb_flg2) & FLAGS2_EXTENDED_SECURITY)) {
+               negotiate_spnego = True;
+               capabilities |= CAP_EXTENDED_SECURITY;
        }
        
-       if (global_encrypted_passwords_negotiated) {
-               if (!cli) {
-                       generate_next_challenge((char *)cryptkey);
-               } else {
-                       memcpy(cryptkey, cli->secblob.data, 8);
-                       set_challenge(cryptkey);
-               }
-       }
-
        capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS;
        
        if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64)) {
@@ -283,7 +254,14 @@ static int reply_nt1(char *inbuf, char *outbuf)
        
        p = q = smb_buf(outbuf);
        if (!negotiate_spnego) {
-               if (global_encrypted_passwords_negotiated) memcpy(p, cryptkey, 8);
+               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_challange(negprot_global_auth_info);
+                       memcpy(p, cryptkey.data, 8);
+                       data_blob_free(&cryptkey);
+               }
                SSVALS(outbuf,smb_vwv16+1,8);
                p += 8;
                DEBUG(3,("not using SPNEGO\n"));
@@ -467,11 +445,6 @@ int reply_negprot(connection_struct *conn,
   /* possibly reload - change of architecture */
   reload_services(True);      
     
-  /* a special case to stop password server loops */
-  if (Index == 1 && strequal(remote_machine,myhostname()) && 
-      (lp_security()==SEC_SERVER || lp_security()==SEC_DOMAIN))
-    exit_server("Password server loop!");
-  
   /* Check for protocols, most desirable first */
   for (protocol = 0; supported_protocols[protocol].proto_name; protocol++)
     {
@@ -508,3 +481,4 @@ int reply_negprot(connection_struct *conn,
   END_PROFILE(SMBnegprot);
   return(outsize);
 }
+
index b020cdd5d7282e8e142ecb666716a51e63469093..d9322ae26c4d8b7515cc2f5afb1e6e6108e6908f 100644 (file)
@@ -1112,19 +1112,23 @@ static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_t
 
   if (keepalive && (t - last_keepalive_sent_time)>keepalive) 
   {
-    struct cli_state *cli = server_client();
-    if (!send_keepalive(smbd_server_fd())) {
-      DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
-      return False;
-    }      
-    /* also send a keepalive to the password server if its still
-       connected */
-    if (cli && cli->initialised)
-      if (!send_keepalive(cli->fd)) {
-        DEBUG( 2, ( "password server keepalive failed.\n"));
-        cli_shutdown(cli);
-      }
-    last_keepalive_sent_time = t;
+         extern auth_authsupplied_info *negprot_global_auth_info;
+         if (!send_keepalive(smbd_server_fd())) {
+                 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
+                 return False;
+         }
+         
+         /* 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->challange_set_method 
+             && negprot_global_auth_info->challange_set_method->send_keepalive) {
+                 negprot_global_auth_info->challange_set_method->send_keepalive
+                         (&negprot_global_auth_info->challange_set_method->private_data);
+         }
+
+         last_keepalive_sent_time = t;
   }
 
   /* check for connection timeouts */
index b08c8e8bda28c436b44ea570a846318c37f0be5c..2f374e48aae9af6afd3ac9d7698fb3d871c33151 100644 (file)
@@ -476,7 +476,7 @@ void exit_server(char *reason)
 {
        static int firsttime=1;
        extern char *last_inbuf;
-
+       extern auth_authsupplied_info *negprot_global_auth_info;
 
        if (!firsttime)
                exit(0);
@@ -485,6 +485,8 @@ void exit_server(char *reason)
        change_to_root_user();
        DEBUG(2,("Closing connections\n"));
 
+       free_auth_info(&negprot_global_auth_info);
+
        conn_close_all();
 
        invalidate_all_vuids();
index b3e9b7be8f0d07b5fdde8d068ba397c940ddd3f4..c9db35956992646578abe152f3c3a33b4e04f500 100644 (file)
@@ -23,6 +23,7 @@
 #include "includes.h"
 
 uint32 global_client_caps = 0;
+static auth_authsupplied_info *ntlmssp_auth_info;
 
 /****************************************************************************
  Add the standard 'Samba' signature to the end of the session setup.
@@ -37,6 +38,31 @@ static void add_signature(char *outbuf)
        set_message_end(outbuf,p);
 }
 
+/****************************************************************************
+ Do a 'guest' logon, getting back the 
+****************************************************************************/
+static NTSTATUS check_guest_password(auth_serversupplied_info **server_info) 
+{
+
+       auth_authsupplied_info *auth_info;
+       auth_usersupplied_info *user_info = NULL;
+       
+       NTSTATUS nt_status;
+       char chal[8];
+
+       ZERO_STRUCT(chal);
+
+       DEBUG(3,("Got anonymous request\n"));
+
+       make_user_info_guest(&user_info);
+       make_auth_info_fixed(&auth_info, chal);
+       
+       nt_status = check_password(user_info, auth_info, server_info);
+       free_auth_info(&auth_info);
+       return nt_status;
+}
+
+
 #if HAVE_KRB5
 /****************************************************************************
 reply to a session setup spnego negotiate packet for kerberos
@@ -189,7 +215,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
        int i;
        uint32 ntlmssp_command, neg_flags;
        DATA_BLOB sess_key, chal, spnego_chal;
-       uint8 cryptkey[8];
+       DATA_BLOB cryptkey;
        BOOL got_kerberos = False;
 
        /* parse out the OIDs and the first sec blob */
@@ -238,10 +264,12 @@ static int reply_spnego_negotiate(connection_struct *conn,
 
        DEBUG(3,("Got neg_flags=%08x\n", neg_flags));
 
-       if (!last_challenge(cryptkey)) {
-               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
+       if (!make_auth_info_subsystem(&ntlmssp_auth_info)) {
+               return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
 
+       cryptkey = auth_get_challange(ntlmssp_auth_info);
+
        /* Give them the challenge. For now, ignore neg_flags and just
           return the flags we want. Obviously this is not correct */
        
@@ -255,7 +283,7 @@ static int reply_spnego_negotiate(connection_struct *conn,
                  0,
                  0x30, /* ?? */
                  neg_flags,
-                 cryptkey, 8,
+                 cryptkey.data, cryptkey.length,
                  0, 0, 0,
                  0x3000); /* ?? */
 
@@ -268,6 +296,7 @@ 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 */
@@ -286,11 +315,9 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
        char *workgroup, *user, *machine;
        DATA_BLOB lmhash, nthash, sess_key;
        DATA_BLOB plaintext_password = data_blob(NULL, 0);
-       DATA_BLOB sec_blob;
        uint32 ntlmssp_command, neg_flags;
        NTSTATUS nt_status;
        int sess_vuid;
-       char chal[8];
 
        auth_usersupplied_info *user_info = NULL;
        auth_serversupplied_info *server_info = NULL;
@@ -327,26 +354,19 @@ static int reply_spnego_auth(connection_struct *conn, char *inbuf, char *outbuf,
        file_save("lmhash1.dat", lmhash.data, lmhash.length);
 #endif
 
-       if (!last_challenge(chal)) {
-               DEBUG(0,("Encrypted login but no challange set!\n"));
-               return ERROR_NT(NT_STATUS_LOGON_FAILURE);
-       }
-       sec_blob = data_blob(chal, 8);
-       if (!sec_blob.data) {
-               return ERROR_NT(NT_STATUS_NO_MEMORY);
-       }
-       
        if (!make_user_info_map(&user_info, 
                                user, workgroup, 
-                               machine, sec_blob,
+                               machine, 
                                lmhash, nthash,
                                plaintext_password, 
                                neg_flags, True)) {
                return ERROR_NT(NT_STATUS_NO_MEMORY);
        }
        
-       nt_status = check_password(user_info, &server_info); 
+       nt_status = check_password(user_info, ntlmssp_auth_info, &server_info); 
        
+       free_auth_info(&ntlmssp_auth_info);
+
        free_user_info(&user_info);
        
        data_blob_free(&lmhash);
@@ -383,18 +403,17 @@ static int reply_spnego_anonymous(connection_struct *conn, char *inbuf, char *ou
                                  int length, int bufsize)
 {
        int sess_vuid;
-       auth_usersupplied_info *user_info = NULL;
        auth_serversupplied_info *server_info = NULL;
-
        NTSTATUS nt_status;
 
-       DEBUG(3,("Got anonymous request\n"));
-
-       make_user_info_guest(&user_info);
+       nt_status = check_guest_password(&server_info);
 
-       nt_status = check_password(user_info, &server_info);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               return ERROR_NT(nt_status_squash(nt_status));
+       }
 
        sess_vuid = register_vuid(server_info, lp_guestaccount());
+
        free_server_info(&server_info);
   
        if (sess_vuid == -1) {
@@ -490,6 +509,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;
        auth_serversupplied_info *server_info = NULL;
 
        NTSTATUS nt_status;
@@ -523,16 +543,12 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                        lm_resp = data_blob(smb_buf(inbuf), passlen1);
                } else {
                        plaintext_password = data_blob(smb_buf(inbuf), passlen1+1);
-                       if (!plaintext_password.data) {
-                               DEBUG(0,("reply_sesssetup_and_X: malloc failed for plaintext_password!\n"));
-                               return ERROR_NT(NT_STATUS_NO_MEMORY);
-                       } else {
-                               /* Ensure null termination */
-                               plaintext_password.data[passlen1] = 0;
-                       }
+                       /* Ensure null termination */
+                       plaintext_password.data[passlen1] = 0;
                }
 
                srvstr_pull(inbuf, user, smb_buf(inbuf)+passlen1, sizeof(user), -1, STR_TERMINATE);
+               *domain = 0;
   
        } else {
                uint16 passlen1 = SVAL(inbuf,smb_vwv7);
@@ -645,15 +661,41 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
                *user = 0;
        }
        
-       if (!make_user_info_for_reply(&user_info, 
-                                     user, domain, 
-                                     lm_resp, nt_resp,
-                                     plaintext_password, doencrypt)) {
-               return ERROR_NT(NT_STATUS_NO_MEMORY);
+       if (!*user) {
+
+               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);
+               }
+               
+               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_challange(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); 
+               
+               data_blob_free(&chal);
+               free_auth_info(&plaintext_auth_info);
        }
-       
-       nt_status = check_password(user_info, &server_info); 
-       
+
        free_user_info(&user_info);
        
        data_blob_free(&lm_resp);
@@ -726,3 +768,8 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,
        END_PROFILE(SMBsesssetupX);
        return chain_reply(inbuf,outbuf,length,bufsize);
 }
+
+
+
+
+
index c1b8b10a84afac87e67c030487a6b8f7075bfec6..97dc0c014a2f549621fc353544369040435be08f 100644 (file)
@@ -92,12 +92,6 @@ to a valid password server.\n", sec_setting );
                ret = 1;
        }
 
-       if(lp_use_rhosts() && !lp_hostname_lookups()) {
-               printf("ERROR: The setting 'use rhosts = yes' requires the 'hostname lookups = yes'.\n");
-               ret = 1;
-       }
-
-
        /*
         * Password chat sanity checks.
         */