diff options
-rw-r--r-- | source3/Makefile.in | 11 | ||||
-rw-r--r-- | source3/auth/auth_domain.c | 411 | ||||
-rw-r--r-- | source3/smbd/auth.c | 268 | ||||
-rw-r--r-- | source3/smbd/auth_builtin.c | 120 | ||||
-rw-r--r-- | source3/smbd/auth_domain.c | 85 | ||||
-rw-r--r-- | source3/smbd/auth_info.c | 282 | ||||
-rw-r--r-- | source3/smbd/auth_rhosts.c | 228 | ||||
-rw-r--r-- | source3/smbd/auth_server.c | 354 | ||||
-rw-r--r-- | source3/smbd/auth_smbpasswd.c | 412 | ||||
-rw-r--r-- | source3/smbd/auth_unix.c | 125 | ||||
-rw-r--r-- | source3/smbd/auth_util.c | 730 | ||||
-rw-r--r-- | source3/smbd/auth_winbind.c | 111 |
12 files changed, 415 insertions, 2722 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 3642e7eb2e..ba94499de8 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -194,12 +194,11 @@ OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o NOTIFY_OBJ = smbd/notify.o smbd/notify_hash.o smbd/notify_kernel.o -PLAINTEXT_AUTH_OBJ = passdb/pampass.o passdb/pass_check.o +PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/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 smbd/auth_winbind.o \ - smbd/auth_info.o smbd/auth_builtin.o $(PLAINTEXT_AUTH_OBJ) \ - libsmb/domain_client_validate.o +AUTH_OBJ = auth/auth.o auth/auth_sam.o auth/auth_server.o auth/auth_domain.o \ + auth/auth_rhosts.o auth/auth_unix.o auth/auth_util.o auth/auth_winbind.o \ + auth/auth_info.o auth/auth_builtin.o $(PLAINTEXT_AUTH_OBJ) SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ @@ -416,7 +415,7 @@ WINBINDD_OBJ1 = \ NECESSARY_BECAUSE_SAMBA_DEPENDENCIES_ARE_SO_BROKEN_OBJ = \ rpc_client/cli_netlogon.o rpc_client/cli_login.o \ - smbd/auth_util.o + auth/auth_util.o WINBINDD_OBJ = \ $(WINBINDD_OBJ1) $(NOPROTO_OBJ) $(PASSDB_OBJ) \ diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index ef0e5b2f10..fa6093a592 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -1,6 +1,6 @@ /* Unix SMB/Netbios implementation. - Version 1.9. + Version 3.0. Authenticate against a remote domain Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Andrew Bartlett 2001 @@ -24,6 +24,415 @@ BOOL global_machine_password_needs_changing = False; +extern struct in_addr ipzero; + +extern pstring global_myname; + +/*********************************************************************** + Connect to a remote machine for domain security authentication + given a name or IP address. + ***********************************************************************/ + +static BOOL connect_to_domain_password_server(struct cli_state *pcli, + char *server, unsigned char *trust_passwd) +{ + struct in_addr dest_ip; + fstring remote_machine; + NTSTATUS result; + + if(cli_initialise(pcli) == NULL) { + DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); + return False; + } + + if (is_ipaddress(server)) { + struct in_addr to_ip; + + /* we shouldn't have 255.255.255.255 forthe IP address of + a password server anyways */ + if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) { + DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server)); + return False; + } + + if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) { + DEBUG(0, ("connect_to_domain_password_server: Can't " + "resolve name for IP %s\n", server)); + return False; + } + } else { + fstrcpy(remote_machine, server); + } + + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if(!resolve_name( remote_machine, &dest_ip, 0x20)) { + DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (ismyip(dest_ip)) { + DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (!cli_connect(pcli, remote_machine, &dest_ip)) { + DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) { + DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \ +session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + return False; + } + + pcli->protocol = PROTOCOL_NT1; + + if (!cli_negprot(pcli)) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (pcli->protocol != PROTOCOL_NT1) { + DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + /* + * Do an anonymous session setup. + */ + + if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (!(pcli->sec_mode & 1)) { + DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + /* + * We now have an anonymous connection to IPC$ on the domain password server. + */ + + /* + * Even if the connect succeeds we need to setup the netlogon + * pipe here. We do this as we may just have changed the domain + * account password on the PDC and yet we may be talking to + * a BDC that doesn't have this replicated yet. In this case + * a successful connect to a DC needs to take the netlogon connect + * into account also. This patch from "Bjart Kvarme" <bjart.kvarme@usit.uio.no>. + */ + + if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) { + DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); + cli_nt_session_close(pcli); + cli_ulogoff(pcli); + cli_shutdown(pcli); + return False; + } + + result = cli_nt_setup_creds(pcli, trust_passwd); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ +%s. Error was : %s.\n", remote_machine, get_nt_error_msg(result))); + cli_nt_session_close(pcli); + cli_ulogoff(pcli); + cli_shutdown(pcli); + return(False); + } + + return True; +} + +/*********************************************************************** + Utility function to attempt a connection to an IP address of a DC. +************************************************************************/ + +static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, + unsigned char *trust_passwd) +{ + fstring dc_name; + + /* + * Ignore addresses we have already tried. + */ + + if (ip_equal(ipzero, *ip)) + return False; + + if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) + return False; + + return connect_to_domain_password_server(pcli, dc_name, trust_passwd); +} + +/*********************************************************************** + We have been asked to dynamcially determine the IP addresses of + the PDC and BDC's for this DOMAIN, and query them in turn. +************************************************************************/ +static BOOL find_connect_pdc(struct cli_state *pcli, + unsigned char *trust_passwd, + time_t last_change_time) +{ + struct in_addr *ip_list = NULL; + int count = 0; + int i; + BOOL connected_ok = False; + time_t time_now = time(NULL); + BOOL use_pdc_only = False; + + /* + * If the time the machine password has changed + * was less than an hour ago then we need to contact + * the PDC only, as we cannot be sure domain replication + * has yet taken place. Bug found by Gerald (way to go + * Gerald !). JRA. + */ + + if (time_now - last_change_time < 3600) + use_pdc_only = True; + + if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count)) + return False; + + /* + * Firstly try and contact a PDC/BDC who has the same + * network address as any of our interfaces. + */ + for(i = 0; i < count; i++) { + if(!is_local_net(ip_list[i])) + continue; + + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Secondly try and contact a random PDC/BDC. + */ + if(!connected_ok) { + i = (sys_random() % count); + + if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Finally go through the IP list in turn, ignoring any addresses + * we have already tried. + */ + if(!connected_ok) { + /* + * Try and connect to any of the other IP addresses in the PDC/BDC list. + * Note that from a WINS server the #1 IP address is the PDC. + */ + for(i = 0; i < count; i++) { + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + } + } + + SAFE_FREE(ip_list); + + + return connected_ok; +} + +/*********************************************************************** + Do the same as security=server, but using NT Domain calls and a session + key from the machine password. If the server parameter is specified + use it, otherwise figure out a server from the 'password server' param. +************************************************************************/ + +static NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, + 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; + NET_USER_INFO_3 info3; + struct cli_state cli; + uint32 smb_uid_low; + BOOL connected_ok = False; + NTSTATUS status; + struct passwd *pass; + + /* + * Check that the requested domain is not our own machine name. + * If it is, we should never check the PDC here, we use our own local + * password file. + */ + + if(strequal(user_info->domain.str, global_myname)) { + DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); + return NT_STATUS_LOGON_FAILURE; + } + + /* + * At this point, smb_apasswd points to the lanman response to + * the challenge in local_challenge, and smb_ntpasswd points to + * the NT response to the challenge in local_challenge. Ship + * these over the secure channel to a domain controller and + * see if they were valid. + */ + + ZERO_STRUCT(cli); + + while (!connected_ok && + next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) { + if(strequal(remote_machine, "*")) { + connected_ok = find_connect_pdc(&cli, trust_passwd, last_change_time); + } else { + connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); + } + } + + if (!connected_ok) { + DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + cli_shutdown(&cli); + return NT_STATUS_LOGON_FAILURE; + } + + /* We really don't care what LUID we give the user. */ + generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); + + ZERO_STRUCT(info3); + + /* + * If this call succeeds, we now have lots of info about the user + * in the info3 structure. + */ + + status = cli_nt_login_network(&cli, user_info, chal, smb_uid_low, + &ctr, &info3); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("domain_client_validate: unable to validate password " + "for user %s in domain %s to Domain controller %s. " + "Error was %s.\n", user_info->smb_name.str, + user_info->domain.str, cli.srv_name_slash, + get_nt_error_msg(status))); + } else { + char *dom_user; + + /* Check DOMAIN\username first to catch winbind users, then + just the username for local users. */ + + asprintf(&dom_user, "%s%s%s", user_info->domain.str, + lp_winbind_separator(), + user_info->internal_username.str); + + if (!(pass = Get_Pwnam(dom_user))) + pass = Get_Pwnam(user_info->internal_username.str); + + free(dom_user); + + if (pass) { + make_server_info_pw(server_info, pass); + if (!server_info) { + status = NT_STATUS_NO_MEMORY; + } + } else { + status = NT_STATUS_NO_SUCH_USER; + } + } + + /* Store the user group information in the server_info returned to the caller. */ + + if (NT_STATUS_IS_OK(status) && (info3.num_groups2 != 0)) { + DOM_SID domain_sid; + int i; + NT_USER_TOKEN *ptok; + auth_serversupplied_info *pserver_info = *server_info; + + if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { + DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + ptok = pserver_info->ptok; + ptok->num_sids = (size_t)info3.num_groups2; + + if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { + DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + for (i = 0; i < ptok->num_sids; i++) { + sid_copy(&ptok->user_sids[i], &domain_sid); + sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid); + } + } + +#if 0 + /* + * We don't actually need to do this - plus it fails currently with + * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to + * send here. JRA. + */ + + if (NT_STATUS_IS_OK(status)) { + if(cli_nt_logoff(&cli, &ctr) == False) { + DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ +%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); + status = NT_STATUS_LOGON_FAILURE; + } + } +#endif /* 0 */ + + done: + + /* Note - once the cli stream is shutdown the mem_ctx used + to allocate the other_sids and gids structures has been deleted - so + these pointers are no longer valid..... */ + + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return status; +} + /**************************************************************************** Check for a valid username and password in security=domain mode. ****************************************************************************/ diff --git a/source3/smbd/auth.c b/source3/smbd/auth.c deleted file mode 100644 index c62e2ed5a0..0000000000 --- a/source3/smbd/auth.c +++ /dev/null @@ -1,268 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Password and authentication handling - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - 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 user is in correct domain if required -****************************************************************************/ - -static BOOL check_domain_match(char *user, char *domain) -{ - /* - * If we aren't serving to trusted domains, we must make sure that - * the validation request comes from an account in the same domain - * as the Samba server - */ - - if (!lp_allow_trusted_domains() && - (!strequal(lp_workgroup(), domain) || strequal("", domain))) { - DEBUG(1, ("check_domain_match: Attempt to connect as user %s from domain %s denied.\n", user, domain)); - return False; - } else { - return True; - } -} - -/**************************************************************************** - Check a users password, as given in the user-info struct and return various - interesting details in the server_info struct. - - This functions does NOT need to be in a become_root()/unbecome_root() pair - as it makes the calls itself when needed. - - The return value takes precedence over the contents of the server_info - struct. When the return is other than NT_STATUS_NOPROBLEMO the contents - of that structure is undefined. - -****************************************************************************/ - -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; - 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)); - 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(3, ("check_password: %s authentication for user [%s] suceeded\n", - auth_method->name, user_info->smb_name.str)); - } else { - 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? */ - if (!check_domain_match(user_info->smb_name.str, user_info->domain.str)) { - return NT_STATUS_LOGON_FAILURE; - } - - - /* 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)) { - pdb_username = pdb_get_username((*server_info)->sam_account); - 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)); - } else { - 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(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; - -} - -/**************************************************************************** - Squash an NT_STATUS return in line with requirements for unauthenticated - connections. (session setups in particular) -****************************************************************************/ - -NTSTATUS nt_status_squash(NTSTATUS nt_status) -{ - if NT_STATUS_IS_OK(nt_status) { - return nt_status; - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { - /* Match WinXP and don't give the game away */ - return NT_STATUS_LOGON_FAILURE; - - } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { - /* Match WinXP and don't give the game away */ - return NT_STATUS_LOGON_FAILURE; - } else { - return nt_status; - } -} - - - -/**************************************************************************** - COMPATABILITY INTERFACES: - ***************************************************************************/ - -/**************************************************************************** -check if a username/password is OK assuming the password is a 24 byte -SMB hash -return True if the password is correct, False otherwise -****************************************************************************/ - -static NTSTATUS pass_check_smb(char *smb_name, - char *domain, - DATA_BLOB lm_pwd, - DATA_BLOB nt_pwd, - DATA_BLOB plaintext_password, - BOOL encrypted) - -{ - NTSTATUS nt_status; - auth_usersupplied_info *user_info = NULL; - extern auth_authsupplied_info *negprot_global_auth_info; - auth_serversupplied_info *server_info = NULL; - if (encrypted) { - make_user_info_for_reply_enc(&user_info, smb_name, - domain, - lm_pwd, - nt_pwd, - plaintext_password); - nt_status = check_password(user_info, negprot_global_auth_info, &server_info); - } else { - auth_authsupplied_info *plaintext_auth_info = NULL; - DATA_BLOB chal; - if (!make_auth_info_subsystem(&plaintext_auth_info)) { - return NT_STATUS_NO_MEMORY; - } - - chal = auth_get_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; -} - -/**************************************************************************** -check if a username/password pair is OK either via the system password -database or the encrypted SMB password database -return True if the password is correct, False otherwise -****************************************************************************/ -BOOL password_ok(char *smb_name, DATA_BLOB password_blob) -{ - - DATA_BLOB null_password = data_blob(NULL, 0); - extern BOOL global_encrypted_passwords_negotiated; - BOOL encrypted = (global_encrypted_passwords_negotiated && password_blob.length == 24); - - if (encrypted) { - /* - * The password could be either NTLM or plain LM. Try NTLM first, - * but fall-through as required. - * NTLMv2 makes no sense here. - */ - if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, password_blob, null_password, encrypted))) { - return True; - } - - if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), password_blob, null_password, null_password, encrypted))) { - return True; - } - } else { - if (NT_STATUS_IS_OK(pass_check_smb(smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) { - return True; - } - } - - return False; -} - - diff --git a/source3/smbd/auth_builtin.c b/source3/smbd/auth_builtin.c deleted file mode 100644 index 482ae6dee1..0000000000 --- a/source3/smbd/auth_builtin.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - 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; -} - -/**************************************************************************** - Return an error based on username -****************************************************************************/ - -static NTSTATUS check_name_to_ntstatus_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; - fstring user; - long error_num; - fstrcpy(user, user_info->smb_name.str); - strlower(user); - error_num = strtoul(user, NULL, 16); - - DEBUG(5,("Error for user %s was %lx\n", user, error_num)); - - nt_status = NT_STATUS(error_num); - - return nt_status; -} - -BOOL auth_init_name_to_ntstatus(auth_methods **auth_method) -{ - if (!make_auth_methods(auth_method)) { - return False; - } - - (*auth_method)->auth = check_name_to_ntstatus_security; - return True; -} - diff --git a/source3/smbd/auth_domain.c b/source3/smbd/auth_domain.c deleted file mode 100644 index ef0e5b2f10..0000000000 --- a/source3/smbd/auth_domain.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Authenticate against a remote domain - Copyright (C) Andrew Tridgell 1992-1998 - 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" - -BOOL global_machine_password_needs_changing = False; - -/**************************************************************************** - Check for a valid username and password in security=domain mode. -****************************************************************************/ - -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; - unsigned char trust_passwd[16]; - time_t last_change_time; - - become_root(); - - /* - * Get the machine account password for our primary domain - */ - - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time)) - { - DEBUG(0, ("check_domain_security: could not fetch trust account password for domain %s\n", lp_workgroup())); - unbecome_root(); - return NT_STATUS_LOGON_FAILURE; - } - - unbecome_root(); - - /* Test if machine password is expired and need to be changed */ - if (time(NULL) > last_change_time + lp_machine_password_timeout()) - { - global_machine_password_needs_changing = True; - } - - /* - * Treat each name in the 'password server =' line as a potential - * PDC/BDC. Contact each in turn and try and authenticate. - */ - - pserver = lp_passwordserver(); - if (! *pserver) pserver = "*"; - p = pserver; - - nt_status = domain_client_validate(user_info, (uchar *)auth_info->challange.data,server_info, - p, trust_passwd, last_change_time); - - return nt_status; -} - -BOOL auth_init_ntdomain(auth_methods **auth_method) -{ - if (!make_auth_methods(auth_method)) { - return False; - } - - (*auth_method)->auth = check_ntdomain_security; - return True; -} diff --git a/source3/smbd/auth_info.c b/source3/smbd/auth_info.c deleted file mode 100644 index b1c994d54f..0000000000 --- a/source3/smbd/auth_info.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 3.0. - Authentication utility functions - Copyright (C) Andrew Bartlett 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -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 }, -#ifdef DEVELOPER - { "name_to_ntstatus", auth_init_name_to_ntstatus }, -#endif - { NULL, NULL} -}; - -/*************************************************************************** - Make a auth_info struct -***************************************************************************/ - -static BOOL make_auth_info(auth_authsupplied_info **auth_info) -{ - *auth_info = malloc(sizeof(**auth_info)); - if (!*auth_info) { - DEBUG(0,("make_auth_info: malloc failed!\n")); - return False; - } - ZERO_STRUCTP(*auth_info); - - return True; -} - -/*************************************************************************** - Make a auth_info struct with a specified list. -***************************************************************************/ - -BOOL make_auth_info_list(auth_authsupplied_info **auth_info, auth_methods *list) -{ - if (!make_auth_info(auth_info)) { - return False; - } - - (*auth_info)->auth_method_list = list; - - return True; -} - -/*************************************************************************** - Make a auth_info struct for the auth subsystem -***************************************************************************/ - -static BOOL make_auth_info_text_list(auth_authsupplied_info **auth_info, char **text_list) -{ - auth_methods *list = NULL; - auth_methods *t = NULL; - auth_methods *tmp; - int i; - - for (;*text_list; text_list++) - { - DEBUG(5,("Attempting to find an auth method to match %s\n", *text_list)); - for (i = 0; builtin_auth_init_functions[i].name; i++) - { - if (strequal(builtin_auth_init_functions[i].name, *text_list)) - { - DEBUG(5,("Found auth method %s (at pos %d)\n", *text_list, i)); - /* Malloc entry, fill it, link it */ - t = (auth_methods *)malloc(sizeof(*t)); - if (!t) { - DEBUG(0,("make_pw_chat: malloc failed!\n")); - return False; - } - - ZERO_STRUCTP(t); - - if (builtin_auth_init_functions[i].init(&t)) { - DEBUG(5,("auth method %s has a valid init\n", *text_list)); - t->name = builtin_auth_init_functions[i].name; - DLIST_ADD_END(list, t, tmp); - } else { - DEBUG(5,("auth method %s DOES NOT have a valid init\n", *text_list)); - } - break; - } - } - } - - make_auth_info_list(auth_info, list); - - return True; -} - -/*************************************************************************** - Make a auth_info struct for the auth subsystem -***************************************************************************/ - -BOOL make_auth_info_subsystem(auth_authsupplied_info **auth_info) -{ - char **auth_method_list = NULL; - - if (!make_auth_info(auth_info)) { - return False; - } - - if (lp_auth_methods() && !lp_list_copy(&auth_method_list, lp_auth_methods())) { - return False; - } - - if (auth_method_list == NULL) { - switch (lp_security()) - { - case SEC_DOMAIN: - DEBUG(5,("Making default auth method list for security=domain\n")); - auth_method_list = lp_list_make("guest ntdomain local"); - break; - case SEC_SERVER: - DEBUG(5,("Making default auth method list for security=server\n")); - auth_method_list = lp_list_make("guest smbserver local"); - break; - case SEC_USER: - DEBUG(5,("Making default auth method list for security=user\n")); - auth_method_list = lp_list_make("guest local"); - break; - case SEC_SHARE: - DEBUG(5,("Making default auth method list for security=share\n")); - auth_method_list = lp_list_make("guest local"); - break; - } - } else { - DEBUG(5,("Using specified auth order\n")); - } - - if (!make_auth_info_text_list(auth_info, auth_method_list)) { - lp_list_free(&auth_method_list); - return False; - } - - lp_list_free(&auth_method_list); - return True; -} - -/*************************************************************************** - Make a auth_info struct with a random challange -***************************************************************************/ - -BOOL make_auth_info_random(auth_authsupplied_info **auth_info) -{ - uchar chal[8]; - if (!make_auth_info_subsystem(auth_info)) { - return False; - } - - generate_random_buffer(chal, sizeof(chal), False); - (*auth_info)->challange = data_blob(chal, sizeof(chal)); - - (*auth_info)->challange_set_by = "random"; - - return True; -} - -/*************************************************************************** - Make a auth_info struct with a fixed challange -***************************************************************************/ - -BOOL make_auth_info_fixed(auth_authsupplied_info **auth_info, uchar chal[8]) -{ - if (!make_auth_info_subsystem(auth_info)) { - return False; - } - - (*auth_info)->challange = data_blob(chal, 8); - return True; -} - -/*************************************************************************** - Clear out a auth_info struct that has been allocated -***************************************************************************/ - -void free_auth_info(auth_authsupplied_info **auth_info) -{ - auth_methods *list; - if (*auth_info != NULL) { - list = (*auth_info)->auth_method_list; - while (list) { - auth_methods *old_head = list; - if (list->free_private_data) { - list->free_private_data(&(list->private_data)); - } - DLIST_REMOVE(list, list); - SAFE_FREE(old_head); - } - - data_blob_free(&(*auth_info)->challange); - ZERO_STRUCT(**auth_info); - } - SAFE_FREE(*auth_info); -} - -/**************************************************************************** - Try to get a challange out of the various authenticaion modules. - It is up to the caller to free it. -****************************************************************************/ - -DATA_BLOB auth_get_challange(auth_authsupplied_info *auth_info) -{ - DATA_BLOB challange = data_blob(NULL, 0); - char *challange_set_by = NULL; - auth_methods *auth_method; - - if (auth_info->challange.length) { - DEBUG(5, ("auth_get_challange: returning previous challange (normal)\n")); - return data_blob(auth_info->challange.data, auth_info->challange.length); - } - - for (auth_method = auth_info->auth_method_list; auth_method; auth_method = auth_method->next) - { - if (auth_method->get_chal) { - DEBUG(5, ("auth_get_challange: getting challange from module %s\n", auth_method->name)); - if (challange_set_by) { - DEBUG(1, ("auth_get_challange: CONFIGURATION ERROR: authenticaion method %s has already specified a challange. Challange by %s ignored.\n", - challange_set_by, auth_method->name)); - } else { - challange = auth_method->get_chal(&auth_method->private_data, auth_info); - if (challange.length) { - DEBUG(5, ("auth_get_challange: sucessfully got challange from module %s\n", auth_method->name)); - auth_info->challange = challange; - challange_set_by = auth_method->name; - auth_info->challange_set_method = auth_method; - } else { - DEBUG(3, ("auth_get_challange: getting challange from authenticaion method %s FAILED.\n", - auth_method->name)); - } - } - } else { - DEBUG(5, ("auth_get_challange: module %s did not want to specify a challange\n", auth_method->name)); - } - } - - if (!challange_set_by) { - uchar chal[8]; - - generate_random_buffer(chal, sizeof(chal), False); - auth_info->challange = data_blob(chal, sizeof(chal)); - - challange_set_by = "random"; - } - - DEBUG(5, ("auth_info challange created by %s\n", challange_set_by)); - DEBUG(5, ("challange is: \n")); - dump_data(5, auth_info->challange.data, (auth_info)->challange.length); - - SMB_ASSERT(auth_info->challange.length == 8); - - auth_info->challange_set_by=challange_set_by; - - return data_blob(auth_info->challange.data, auth_info->challange.length); -} - - diff --git a/source3/smbd/auth_rhosts.c b/source3/smbd/auth_rhosts.c deleted file mode 100644 index 2605f0770a..0000000000 --- a/source3/smbd/auth_rhosts.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Main SMB reply routines - Copyright (C) Andrew Tridgell 1992-1998 - - 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" - -/**************************************************************************** - Read the a hosts.equiv or .rhosts file and check if it - allows this user from this machine. -****************************************************************************/ - -static BOOL check_user_equiv(const char *user, const char *remote, const char *equiv_file) -{ - int plus_allowed = 1; - char *file_host; - char *file_user; - char **lines = file_lines_load(equiv_file, NULL); - int i; - - DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file)); - if (! lines) return False; - for (i=0; lines[i]; i++) { - char *buf = lines[i]; - trim_string(buf," "," "); - - if (buf[0] != '#' && buf[0] != '\n') - { - BOOL is_group = False; - int plus = 1; - char *bp = buf; - if (strcmp(buf, "NO_PLUS\n") == 0) - { - DEBUG(6, ("check_user_equiv NO_PLUS\n")); - plus_allowed = 0; - } - else { - if (buf[0] == '+') - { - bp++; - if (*bp == '\n' && plus_allowed) - { - /* a bare plus means everbody allowed */ - DEBUG(6, ("check_user_equiv everybody allowed\n")); - file_lines_free(lines); - return True; - } - } - else if (buf[0] == '-') - { - bp++; - plus = 0; - } - if (*bp == '@') - { - is_group = True; - bp++; - } - file_host = strtok(bp, " \t\n"); - file_user = strtok(NULL, " \t\n"); - DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)", - file_user ? file_user : "(null)" )); - if (file_host && *file_host) - { - BOOL host_ok = False; - -#if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN) - if (is_group) - { - static char *mydomain = NULL; - if (!mydomain) - yp_get_default_domain(&mydomain); - if (mydomain && innetgr(file_host,remote,user,mydomain)) - host_ok = True; - } -#else - if (is_group) - { - DEBUG(1,("Netgroups not configured\n")); - continue; - } -#endif - - /* is it this host */ - /* the fact that remote has come from a call of gethostbyaddr - * means that it may have the fully qualified domain name - * so we could look up the file version to get it into - * a canonical form, but I would rather just type it - * in full in the equiv file - */ - if (!host_ok && !is_group && strequal(remote, file_host)) - host_ok = True; - - if (!host_ok) - continue; - - /* is it this user */ - if (file_user == 0 || strequal(user, file_user)) - { - DEBUG(5, ("check_user_equiv matched %s%s %s\n", - (plus ? "+" : "-"), file_host, - (file_user ? file_user : ""))); - file_lines_free(lines); - return (plus ? True : False); - } - } - } - } - } - file_lines_free(lines); - return False; -} - - -/**************************************************************************** -check for a possible hosts equiv or rhosts entry for the user -****************************************************************************/ - -static BOOL check_hosts_equiv(struct passwd *pass) -{ - char *fname = NULL; - - if (!pass) - return(False); - - fname = lp_hosts_equiv(); - - /* note: don't allow hosts.equiv on root */ - if (fname && *fname && (pass->pw_uid != 0)) { - if (check_user_equiv(pass->pw_name,client_name(),fname)) - return(True); - } - - return(False); -} - - -/**************************************************************************** - Check for a valid .rhosts/hosts.equiv entry for this user -****************************************************************************/ - -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) { - if (check_hosts_equiv(pass)) { - nt_status = NT_STATUS_OK; - make_server_info_pw(server_info, pass); - } - } else { - nt_status = NT_STATUS_NO_SUCH_USER; - } - - return nt_status; -} - - -/**************************************************************************** - Check for a valid .rhosts/hosts.equiv entry for this user -****************************************************************************/ - -static NTSTATUS check_rhosts_security(void *my_private_data, - const auth_usersupplied_info *user_info, - const auth_authsupplied_info *auth_info, - auth_serversupplied_info **server_info) -{ - NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; - struct passwd *pass = Get_Pwnam(user_info->internal_username.str); - pstring rhostsfile; - - if (pass) { - char *home = pass->pw_dir; - if (home) { - slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); - become_root(); - if (check_user_equiv(pass->pw_name,client_name(),rhostsfile)) { - nt_status = NT_STATUS_OK; - make_server_info_pw(server_info, pass); - } - unbecome_root(); - } - } else { - nt_status = NT_STATUS_NO_SUCH_USER; - } - - return nt_status; -} - -BOOL auth_init_hostsequiv(auth_methods **auth_method) -{ - - if (!make_auth_methods(auth_method)) { - return False; - } - (*auth_method)->auth = check_hostsequiv_security; - return True; -} - -BOOL auth_init_rhosts(auth_methods **auth_method) -{ - - if (!make_auth_methods(auth_method)) { - return False; - } - (*auth_method)->auth = check_rhosts_security; - return True; -} diff --git a/source3/smbd/auth_server.c b/source3/smbd/auth_server.c deleted file mode 100644 index 067b5b2997..0000000000 --- a/source3/smbd/auth_server.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Authenticate to a remote server - Copyright (C) Andrew Tridgell 1992-1998 - 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" - -extern pstring global_myname; - -/**************************************************************************** - Support for server level security. -****************************************************************************/ - -static struct cli_state *server_cryptkey(void) -{ - struct cli_state *cli = NULL; - fstring desthost; - struct in_addr dest_ip; - char *p, *pserver; - BOOL connected_ok = False; - - if (!(cli = cli_initialise(cli))) - return NULL; - - /* security = server just can't function with spnego */ - cli->use_spnego = False; - - pserver = strdup(lp_passwordserver()); - p = pserver; - - while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { - standard_sub_basic(desthost); - strupper(desthost); - - if(!resolve_name( desthost, &dest_ip, 0x20)) { - DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); - continue; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",desthost)); - continue; - } - - if (cli_connect(cli, desthost, &dest_ip)) { - DEBUG(3,("connected to password server %s\n",desthost)); - connected_ok = True; - break; - } - } - - SAFE_FREE(pserver); - - if (!connected_ok) { - DEBUG(0,("password server not available\n")); - cli_shutdown(cli); - return NULL; - } - - 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)) { - DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(cli); - return NULL; - } - - if (cli->protocol < PROTOCOL_LANMAN2 || - !(cli->sec_mode & 1)) { - DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(cli); - return NULL; - } - - DEBUG(3,("password server OK\n")); - - 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. -****************************************************************************/ - -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]; - static fstring baduser; - 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 = my_private_data; - - if (cli) { - } else { - cli = server_cryptkey(); - locally_made_cli = True; - } - - if (!cli || !cli->initialised) { - DEBUG(1,("password server %s is not connected\n", cli->desthost)); - 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)); - - if((user_info->nt_resp.length == sizeof(badpass)) && - !memcmp(badpass, user_info->nt_resp.data, sizeof(badpass))) { - /* - * Very unlikely, our random bad password is the same as the users - * password. - */ - memset(badpass, badpass[0]+1, sizeof(badpass)); - } - - if(baduser[0] == 0) { - fstrcpy(baduser, INVALID_USER_PREFIX); - fstrcat(baduser, global_myname); - } - - /* - * Attempt a session setup with a totally incorrect password. - * If this succeeds with the guest bit *NOT* set then the password - * server is broken and is not correctly setting the guest bit. We - * need to detect this as some versions of NT4.x are broken. JRA. - */ - - /* I sure as hell hope that there arn't servers out there that take - * NTLMv2 and have this bug, as we don't test for that... - * - abartlet@samba.org - */ - - if ((!tested_password_server) && (lp_paranoid_server_security())) { - if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass), - (char *)badpass, sizeof(badpass), user_info->domain.str)) { - - /* - * We connected to the password server so we - * can say we've tested it. - */ - tested_password_server = True; - - if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { - DEBUG(0,("server_validate: password server %s allows users as non-guest \ -with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ -use this machine as the password server.\n")); - cli_ulogoff(cli); - - /* - * Password server has the bug. - */ - bad_password_server = True; - return NT_STATUS_LOGON_FAILURE; - } - cli_ulogoff(cli); - } - } else { - - /* - * We have already tested the password server. - * Fail immediately if it has the bug. - */ - - if(bad_password_server) { - DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \ -with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \ -use this machine as the password server.\n")); - return NT_STATUS_LOGON_FAILURE; - } - } - - /* - * Now we know the password server will correctly set the guest bit, or is - * not guest enabled, we can try with the real password. - */ - - 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 { - 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 */ - if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); - nt_status = NT_STATUS_LOGON_FAILURE; - } - - cli_ulogoff(cli); - - if NT_STATUS_IS_OK(nt_status) { - struct passwd *pass = Get_Pwnam(user_info->internal_username.str); - if (pass) { - if (!make_server_info_pw(server_info, pass)) { - nt_status = NT_STATUS_NO_MEMORY; - } - } else { - nt_status = NT_STATUS_NO_SUCH_USER; - } - } - - if (locally_made_cli) { - cli_shutdown(cli); - SAFE_FREE(cli); - } - - return(nt_status); -} - -BOOL auth_init_smbserver(auth_methods **auth_method) -{ - if (!make_auth_methods(auth_method)) { - return False; - } - (*auth_method)->auth = check_smbserver_security; - (*auth_method)->get_chal = auth_get_challange_server; - (*auth_method)->send_keepalive = send_server_keepalive; - (*auth_method)->free_private_data = free_server_private_data; - return True; -} diff --git a/source3/smbd/auth_smbpasswd.c b/source3/smbd/auth_smbpasswd.c deleted file mode 100644 index 24a4d4e4e4..0000000000 --- a/source3/smbd/auth_smbpasswd.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Password and authentication handling - Copyright (C) Andrew Tridgell 1992-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - 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" - -/**************************************************************************** -core of smb password checking routine. -****************************************************************************/ -static BOOL smb_pwd_check_ntlmv1(DATA_BLOB nt_response, - const uchar *part_passwd, - DATA_BLOB sec_blob, - uint8 user_sess_key[16]) -{ - /* Finish the encryption of part_passwd. */ - uchar p24[24]; - - if (part_passwd == NULL) { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always false ! */ - return False; - } - - if (sec_blob.length != 8) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challange size (%d)\n", sec_blob.length)); - return False; - } - - if (nt_response.length != 24) { - DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%d)\n", nt_response.length)); - return False; - } - - SMBOWFencrypt(part_passwd, sec_blob.data, p24); - if (user_sess_key != NULL) - { - SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key); - } - - - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |")); - dump_data(100, part_passwd, 16); - DEBUG(100,("Password from client was |")); - dump_data(100, nt_response.data, nt_response.length); - DEBUG(100,("Given challenge was |")); - dump_data(100, sec_blob.data, sec_blob.length); - DEBUG(100,("Value from encryption was |")); - dump_data(100, p24, 24); -#endif - return (memcmp(p24, nt_response.data, 24) == 0); -} - -/**************************************************************************** -core of smb password checking routine. -****************************************************************************/ -static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response, - const uchar *part_passwd, - const DATA_BLOB sec_blob, - const char *user, const char *domain, - uint8 user_sess_key[16]) -{ - /* Finish the encryption of part_passwd. */ - uchar kr[16]; - uchar value_from_encryption[16]; - uchar client_response[16]; - DATA_BLOB client_key_data; - - if (part_passwd == NULL) - { - DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always False */ - return False; - } - - if (ntv2_response.length < 16) { - /* We MUST have more than 16 bytes, or the stuff below will go - crazy... */ - DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%d)\n", - ntv2_response.length)); - return False; - } - - client_key_data = data_blob(ntv2_response.data+16, ntv2_response.length-16); - memcpy(client_response, ntv2_response.data, sizeof(client_response)); - - ntv2_owf_gen(part_passwd, user, domain, kr); - SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption); - if (user_sess_key != NULL) - { - SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key); - } - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |")); - dump_data(100, part_passwd, 16); - DEBUG(100,("Password from client was |")); - dump_data(100, ntv2_response.data, ntv2_response.length); - DEBUG(100,("Variable data from client was |")); - dump_data(100, client_key_data.data, client_key_data.length); - DEBUG(100,("Given challenge was |")); - dump_data(100, sec_blob.data, sec_blob.length); - DEBUG(100,("Value from encryption was |")); - dump_data(100, value_from_encryption, 16); -#endif - data_blob_clear_free(&client_key_data); - return (memcmp(value_from_encryption, client_response, 16) == 0); -} - - -/**************************************************************************** - Do a specific test for an smb password being correct, given a smb_password and - the lanman and NT responses. -****************************************************************************/ -static NTSTATUS sam_password_ok(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; - uint32 ntlmssp_flags; - - acct_ctrl = pdb_get_acct_ctrl(sampass); - if (acct_ctrl & ACB_PWNOTREQ) - { - if (lp_null_passwords()) - { - DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", pdb_get_username(sampass))); - return(NT_STATUS_OK); - } - else - { - DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", pdb_get_username(sampass))); - return(NT_STATUS_LOGON_FAILURE); - } - } - - nt_pw = pdb_get_nt_passwd(sampass); - lm_pw = pdb_get_lanman_passwd(sampass); - - ntlmssp_flags = user_info->ntlmssp_flags; - - if (nt_pw == NULL) { - DEBUG(3,("smb_password_ok: NO NT password stored for user %s.\n", - pdb_get_username(sampass))); - /* No return, we want to check the LM hash below in this case */ - ntlmssp_flags &= (~(NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2)); - } - - if (ntlmssp_flags & NTLMSSP_NEGOTIATE_NTLM2) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NTLMv2 password\n")); - if (smb_pwd_check_ntlmv2( user_info->nt_resp, - nt_pw, auth_info->challange, - user_info->smb_name.str, - user_info->client_domain.str, - user_sess_key)) - { - return NT_STATUS_OK; - } else { - DEBUG(3,("smb_password_ok: NTLMv2 password check failed\n")); - return NT_STATUS_WRONG_PASSWORD; - } - } else if (ntlmssp_flags & NTLMSSP_NEGOTIATE_NTLM) { - if (lp_ntlm_auth()) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_pwd_check_ntlmv1(user_info->nt_resp, - nt_pw, auth_info->challange, - user_sess_key)) - { - return NT_STATUS_OK; - } else { - DEBUG(3,("smb_password_ok: NT MD4 password check failed for user %s\n",pdb_get_username(sampass))); - return NT_STATUS_WRONG_PASSWORD; - } - } else { - DEBUG(2,("smb_password_ok: NTLMv1 passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass))); - /* No return, we want to check the LM hash below in this case */ - } - } - - if (lm_pw == NULL) { - DEBUG(3,("smb_password_ok: NO LanMan password set for user %s (and no NT password supplied)\n",pdb_get_username(sampass))); - ntlmssp_flags &= (~NTLMSSP_NEGOTIATE_OEM); - } - - if (ntlmssp_flags & NTLMSSP_NEGOTIATE_OEM) { - - if (user_info->lm_resp.length != 24) { - DEBUG(2,("smb_password_ok: invalid LanMan password length (%d) for user %s\n", - user_info->nt_resp.length, pdb_get_username(sampass))); - } - - if (!lp_lanman_auth()) { - DEBUG(3,("smb_password_ok: Lanman passwords NOT PERMITTED for user %s\n",pdb_get_username(sampass))); - return NT_STATUS_LOGON_FAILURE; - } - - DEBUG(4,("smb_password_ok: Checking LM password\n")); - if (smb_pwd_check_ntlmv1(user_info->lm_resp, - lm_pw, auth_info->challange, - user_sess_key)) - { - return NT_STATUS_OK; - } else { - DEBUG(4,("smb_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass))); - return NT_STATUS_WRONG_PASSWORD; - } - } - - /* Should not be reached, but if they send nothing... */ - DEBUG(3,("smb_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass))); - return NT_STATUS_WRONG_PASSWORD; -} - -/**************************************************************************** - Do a specific test for a SAM_ACCOUNT being vaild for this connection - (ie not disabled, expired and the like). -****************************************************************************/ -static NTSTATUS sam_account_ok(SAM_ACCOUNT *sampass, const auth_usersupplied_info *user_info) -{ - uint16 acct_ctrl = pdb_get_acct_ctrl(sampass); - char *workstation_list; - time_t kickoff_time; - - DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",pdb_get_username(sampass))); - - /* Quit if the account was disabled. */ - if (acct_ctrl & ACB_DISABLED) { - DEBUG(1,("Account for user '%s' was disabled.\n", pdb_get_username(sampass))); - return NT_STATUS_ACCOUNT_DISABLED; - } - - /* Test account expire time */ - - kickoff_time = pdb_get_kickoff_time(sampass); - if (kickoff_time != 0 && time(NULL) > kickoff_time) { - DEBUG(1,("Account for user '%s' has expried.\n", pdb_get_username(sampass))); - DEBUG(3,("Account expired at '%ld' unix time.\n", (long)kickoff_time)); - 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)); - - if (!workstation_list) return NT_STATUS_NO_MEMORY; - - if (*workstation_list) { - BOOL invalid_ws = True; - char *s = workstation_list; - - fstring tok; - - while (next_token(&s, tok, ",", sizeof(tok))) { - DEBUG(10,("checking for workstation match %s and %s (len=%d)\n", - tok, user_info->wksta_name.str, user_info->wksta_name.len)); - if(strequal(tok, user_info->wksta_name.str)) { - invalid_ws = False; - break; - } - } - - SAFE_FREE(workstation_list); - if (invalid_ws) - return NT_STATUS_INVALID_WORKSTATION; - } else { - SAFE_FREE(workstation_list); - } - - 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; - } - - if (acct_ctrl & ACB_SVRTRUST) { - DEBUG(2,("session_trust_account: Server trust account %s denied by server\n", pdb_get_username(sampass))); - return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT; - } - - if (acct_ctrl & ACB_WSTRUST) { - DEBUG(4,("session_trust_account: Wksta trust account %s denied by server\n", pdb_get_username(sampass))); - return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT; - } - - return NT_STATUS_OK; -} - - -/**************************************************************************** -check if a username/password is OK assuming the password is a 24 byte -SMB hash supplied in the user_info structure -return an NT_STATUS constant. -****************************************************************************/ - -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; - NTSTATUS nt_status; - uint8 user_sess_key[16]; - const uint8* lm_hash; - - if (!user_info || !auth_info) { - return NT_STATUS_LOGON_FAILURE; - } - - if (!pdb_init_sam(&sampass)) { - return NT_STATUS_NO_MEMORY; - } - - /* get the account information */ - - become_root(); - ret = pdb_getsampwnam(sampass, user_info->internal_username.str); - unbecome_root(); - - if (ret == False) - { - DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user_info->internal_username.str)); - pdb_free_sam(&sampass); - return NT_STATUS_NO_SUCH_USER; - } - - nt_status = sam_password_ok(sampass, user_info, auth_info, user_sess_key); - - if (!NT_STATUS_IS_OK(nt_status)) { - pdb_free_sam(&sampass); - return nt_status; - } - - nt_status = sam_account_ok(sampass, user_info); - - if (!NT_STATUS_IS_OK(nt_status)) { - pdb_free_sam(&sampass); - return nt_status; - } - - if (!make_server_info_sam(server_info, sampass)) { - DEBUG(0,("failed to malloc memory for server_info\n")); - return NT_STATUS_NO_MEMORY; - } - - lm_hash = pdb_get_lanman_passwd((*server_info)->sam_account); - if (lm_hash) { - memcpy((*server_info)->first_8_lm_hash, lm_hash, 8); - } - - memcpy((*server_info)->session_key, user_sess_key, sizeof(user_sess_key)); - - return nt_status; -} - -BOOL auth_init_sam(auth_methods **auth_method) -{ - if (!make_auth_methods(auth_method)) { - return False; - } - - (*auth_method)->auth = check_sam_security; - return True; -} - - - diff --git a/source3/smbd/auth_unix.c b/source3/smbd/auth_unix.c deleted file mode 100644 index d134ce6909..0000000000 --- a/source3/smbd/auth_unix.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 2.2 - Password and authentication handling - 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" - -/**************************************************************************** -update the encrypted smbpasswd file from the plaintext username and password - -this ugly hack needs to die, but not quite yet... -*****************************************************************************/ -static BOOL update_smbpassword_file(char *user, char *password) -{ - SAM_ACCOUNT *sampass = NULL; - BOOL ret; - - pdb_init_sam(&sampass); - - become_root(); - ret = pdb_getsampwnam(sampass, user); - unbecome_root(); - - if(ret == False) { - DEBUG(0,("pdb_getsampwnam returned NULL\n")); - pdb_free_sam(&sampass); - return False; - } - - /* - * Remove the account disabled flag - we are updating the - * users password from a login. - */ - if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED)) { - pdb_free_sam(&sampass); - return False; - } - - if (!pdb_set_plaintext_passwd (sampass, password)) { - pdb_free_sam(&sampass); - return False; - } - - /* Now write it into the file. */ - become_root(); - - /* Here, the override flag is True, because we want to ignore the - XXXXXXX'd out password */ - ret = pdb_update_sam_account (sampass, True); - - unbecome_root(); - - if (ret) { - DEBUG(3,("pdb_update_sam_account returned %d\n",ret)); - } - - memset(password, '\0', strlen(password)); - - pdb_free_sam(&sampass); - return ret; -} - - -/**************************************************************************** -check if a username/password is OK assuming the password -in PLAIN TEXT -****************************************************************************/ - -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; - - become_root(); - pass = Get_Pwnam(user_info->internal_username.str); - - nt_status = pass_check(pass, - pass ? pass->pw_name : user_info->internal_username.str, - (char *)user_info->plaintext_password.data, - user_info->plaintext_password.length-1, - lp_update_encrypted() ? - update_smbpassword_file : NULL, - True); - - unbecome_root(); - - if NT_STATUS_IS_OK(nt_status) { - if (pass) { - make_server_info_pw(server_info, pass); - } else { - /* we need to do somthing more useful here */ - nt_status = NT_STATUS_NO_SUCH_USER; - } - } - - return nt_status; -} - -BOOL auth_init_unix(auth_methods **auth_method) -{ - if (!make_auth_methods(auth_method)) { - return False; - } - (*auth_method)->auth = check_unix_security; - return True; -} diff --git a/source3/smbd/auth_util.c b/source3/smbd/auth_util.c deleted file mode 100644 index d1b2cc92e5..0000000000 --- a/source3/smbd/auth_util.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Authentication utility functions - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Andrew Bartlett 2001 - Copyright (C) Jeremy Allison 2000-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" - -extern fstring remote_machine; -extern pstring global_myname; - -/**************************************************************************** - Create a UNIX user on demand. -****************************************************************************/ - -static int smb_create_user(const char *unix_user, const char *homedir) -{ - pstring add_script; - int ret; - - pstrcpy(add_script, lp_adduser_script()); - if (! *add_script) - return -1; - all_string_sub(add_script, "%u", unix_user, sizeof(pstring)); - if (homedir) - all_string_sub(add_script, "%H", homedir, sizeof(pstring)); - ret = smbrun(add_script,NULL); - DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret)); - return ret; -} - -/**************************************************************************** - Delete a UNIX user on demand. -****************************************************************************/ - -static int smb_delete_user(char *unix_user) -{ - pstring del_script; - int ret; - - pstrcpy(del_script, lp_deluser_script()); - if (! *del_script) - return -1; - all_string_sub(del_script, "%u", unix_user, sizeof(pstring)); - ret = smbrun(del_script,NULL); - DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret)); - return ret; -} - -/**************************************************************************** - Add and Delete UNIX users on demand, based on NTSTATUS codes. -****************************************************************************/ - -void smb_user_control(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, NTSTATUS nt_status) -{ - struct passwd *pwd=NULL; - - if (NT_STATUS_IS_OK(nt_status)) { - - if (!(server_info->sam_fill_level & SAM_FILL_UNIX)) { - - /* - * User validated ok against Domain controller. - * If the admin wants us to try and create a UNIX - * user on the fly, do so. - */ - - if(lp_adduser_script() && !(pwd = Get_Pwnam(user_info->internal_username.str))) { - smb_create_user(user_info->internal_username.str, NULL); - } - } else { - if(lp_adduser_script()) { - SMB_STRUCT_STAT st; - const char *home_dir = pdb_get_homedir(server_info->sam_account); - /* - * Also call smb_create_user if the users - * home directory doesn't exist. Used with - * winbindd to allow the script to create - * the home directory for a user mapped - * with winbindd. - */ - - if (home_dir && - (sys_stat(home_dir, &st) == -1) && (errno == ENOENT)) { - smb_create_user(user_info->internal_username.str, home_dir); - } - } - } - } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) { - /* - * User failed to validate ok against Domain controller. - * If the failure was "user doesn't exist" and admin - * wants us to try and delete that UNIX user on the fly, - * do so. - */ - if (lp_deluser_script()) { - smb_delete_user(user_info->internal_username.str); - } - } -} - -/**************************************************************************** - Create an auth_usersupplied_data structure -****************************************************************************/ - -static BOOL make_user_info(auth_usersupplied_info **user_info, - const char *smb_name, - const char *internal_username, - const char *client_domain, - const char *domain, - const char *wksta_name, - DATA_BLOB lm_pwd, DATA_BLOB nt_pwd, - DATA_BLOB plaintext, - uint32 ntlmssp_flags, BOOL encrypted) -{ - - DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name)); - - *user_info = malloc(sizeof(**user_info)); - if (!user_info) { - DEBUG(0,("malloc failed for user_info (size %d)\n", sizeof(*user_info))); - return False; - } - - ZERO_STRUCTP(*user_info); - - DEBUG(5,("makeing strings for %s's user_info struct\n", internal_username)); - - (*user_info)->smb_name.str = strdup(smb_name); - if ((*user_info)->smb_name.str) { - (*user_info)->smb_name.len = strlen(smb_name); - } else { - free_user_info(user_info); - return False; - } - - (*user_info)->internal_username.str = strdup(internal_username); - if ((*user_info)->internal_username.str) { - (*user_info)->internal_username.len = strlen(internal_username); - } else { - free_user_info(user_info); - return False; - } - - (*user_info)->domain.str = strdup(domain); - if ((*user_info)->domain.str) { - (*user_info)->domain.len = strlen(domain); - } else { - free_user_info(user_info); - return False; - } - - (*user_info)->client_domain.str = strdup(client_domain); - if ((*user_info)->client_domain.str) { - (*user_info)->client_domain.len = strlen(client_domain); - } else { - free_user_info(user_info); - return False; - } - - (*user_info)->wksta_name.str = strdup(wksta_name); - if ((*user_info)->wksta_name.str) { - (*user_info)->wksta_name.len = strlen(wksta_name); - } else { - free_user_info(user_info); - return False; - } - - DEBUG(5,("makeing blobs for %s's user_info struct\n", internal_username)); - - (*user_info)->lm_resp = data_blob(lm_pwd.data, lm_pwd.length); - (*user_info)->nt_resp = data_blob(nt_pwd.data, nt_pwd.length); - (*user_info)->plaintext_password = data_blob(plaintext.data, plaintext.length); - - (*user_info)->encrypted = encrypted; - (*user_info)->ntlmssp_flags = ntlmssp_flags; - - DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name)); - - return True; -} - -/**************************************************************************** - Create an auth_usersupplied_data structure after appropriate mapping. -****************************************************************************/ - -BOOL make_user_info_map(auth_usersupplied_info **user_info, - const char *smb_name, - const char *client_domain, - const char *wksta_name, - DATA_BLOB lm_pwd, DATA_BLOB nt_pwd, - DATA_BLOB plaintext, - uint32 ntlmssp_flags, BOOL encrypted) -{ - const char *domain; - fstring internal_username; - fstrcpy(internal_username, smb_name); - map_username(internal_username); - - if (lp_allow_trusted_domains()) { - domain = client_domain; - } else { - domain = lp_workgroup(); - } - - return make_user_info(user_info, - smb_name, internal_username, - client_domain, domain, - wksta_name, - lm_pwd, nt_pwd, - plaintext, - ntlmssp_flags, encrypted); - -} - -/**************************************************************************** - Create an auth_usersupplied_data, making the DATA_BLOBs here. - Decrypt and encrypt the passwords. -****************************************************************************/ - -BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, - char *smb_name, - char *client_domain, - char *wksta_name, - uchar *lm_network_pwd, int lm_pwd_len, - uchar *nt_network_pwd, int nt_pwd_len) -{ - BOOL ret; - 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); - uint32 ntlmssp_flags = 0; - - if (lm_pwd_len) - ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM; - if (nt_pwd_len == 24) { - ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; - } else if (nt_pwd_len != 0) { - ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM2; - } - - ret = make_user_info_map(user_info, - smb_name, client_domain, - wksta_name, - lm_blob, nt_blob, - plaintext_blob, - ntlmssp_flags, True); - - data_blob_free(&lm_blob); - data_blob_free(&nt_blob); - return ret; -} - -/**************************************************************************** - Create an auth_usersupplied_data, making the DATA_BLOBs here. - Decrypt and encrypt the passwords. -****************************************************************************/ - -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) -{ - char lm_pwd[16]; - char nt_pwd[16]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; - unsigned char key[16]; - uint32 ntlmssp_flags = 0; - - ZERO_STRUCT(key); - memcpy(key, dc_sess_key, 8); - - if (lm_interactive_pwd) memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd)); - if (nt_interactive_pwd) memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd)); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("key:")); - dump_data(100, (char *)key, sizeof(key)); - - DEBUG(100,("lm owf password:")); - dump_data(100, lm_pwd, sizeof(lm_pwd)); - - DEBUG(100,("nt owf password:")); - dump_data(100, nt_pwd, sizeof(nt_pwd)); -#endif - - SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd)); - SamOEMhash((uchar *)nt_pwd, key, sizeof(nt_pwd)); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("decrypt of lm owf password:")); - dump_data(100, lm_pwd, sizeof(lm_pwd)); - - DEBUG(100,("decrypt of nt owf password:")); - dump_data(100, nt_pwd, sizeof(nt_pwd)); -#endif - - SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response); - SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response); - - /* Password info parinoia */ - ZERO_STRUCT(lm_pwd); - ZERO_STRUCT(nt_pwd); - ZERO_STRUCT(key); - - { - BOOL ret; - 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); - - if (lm_interactive_pwd) - ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM; - if (nt_interactive_pwd) - ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; - - ret = make_user_info_map(user_info, - smb_name, client_domain, - wksta_name, - local_lm_blob, - local_nt_blob, - plaintext_blob, - ntlmssp_flags, True); - - data_blob_free(&local_lm_blob); - data_blob_free(&local_nt_blob); - return ret; - } -} - -/**************************************************************************** - Create an auth_usersupplied_data structure -****************************************************************************/ - -BOOL make_user_info_winbind(auth_usersupplied_info **user_info, - 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]; - DATA_BLOB local_lm_blob; - DATA_BLOB local_nt_blob; - DATA_BLOB plaintext_blob; - uint32 ntlmssp_flags = 0; - - /* - * Not encrypted - do so. - */ - - DEBUG(5,("pass_check_smb: User passwords not in encrypted format.\n")); - - generate_random_buffer(chal, 8, False); - - if (*password) { - SMBencrypt( (const uchar *)password, chal, local_lm_response); - - /* This encrypts the lm_pwd field, which actually contains - the password rather than the nt_pwd field because that - contains nothing */ - - /* WATCH OUT. This doesn't work if the incoming password is - incorrectly cased. We might want to add a check here - and only do an LM in that case */ - - SMBNTencrypt((const uchar *)password, chal, local_nt_response); - - local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response)); - local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response)); - plaintext_blob = data_blob(password, strlen(password)+1); - if ((!local_lm_blob.data) || (!local_nt_blob.data)|| (!plaintext_blob.data)) { - data_blob_free(&local_lm_blob); - data_blob_free(&local_nt_blob); - data_blob_clear_free(&plaintext_blob); - return False; - } - ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM; - } else { - local_lm_blob = data_blob(NULL, 0); - local_nt_blob = data_blob(NULL, 0); - plaintext_blob = data_blob(NULL, 0); - } - - { - BOOL ret; - - ret = make_user_info(user_info, - username, username, - domain, domain, - global_myname, - local_nt_blob, - local_lm_blob, - plaintext_blob, - ntlmssp_flags, False); - - data_blob_free(&local_lm_blob); - data_blob_free(&local_nt_blob); - data_blob_clear_free(&plaintext_blob); - return ret; - } -} - -/**************************************************************************** - Create an auth_usersupplied_data, making the DATA_BLOBs here. - Decrypt and encrypt the passwords. -****************************************************************************/ - -BOOL make_user_info_winbind_crap(auth_usersupplied_info **user_info, - char *smb_name, - char *client_domain, - uchar *lm_network_pwd, int lm_pwd_len, - uchar *nt_network_pwd, int nt_pwd_len) -{ - BOOL ret; - 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); - uint32 ntlmssp_flags = 0; - - if (lm_pwd_len) - ntlmssp_flags |= NTLMSSP_NEGOTIATE_OEM; - if (nt_pwd_len) - ntlmssp_flags |= NTLMSSP_NEGOTIATE_NTLM; - - ret = make_user_info(user_info, - smb_name, smb_name, - client_domain, client_domain, - global_myname, - nt_blob, lm_blob, - plaintext_blob, - ntlmssp_flags, True); - - data_blob_free(&lm_blob); - data_blob_free(&nt_blob); - return ret; -} - -/**************************************************************************** - Create an auth_usersupplied_data structure -****************************************************************************/ - -BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, - char *smb_name, - char *client_domain, - char chal[8], - DATA_BLOB plaintext_password) -{ - - DATA_BLOB local_lm_blob; - DATA_BLOB local_nt_blob; - BOOL ret = False; - uint32 ntlmssp_flags = 0; - - /* - * Not encrypted - do so. - */ - - 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); - - /* We can't do an NT hash here, as the password needs to be - case insensitive */ - local_nt_blob = data_blob(NULL, 0); - - ntlmssp_flags = NTLMSSP_NEGOTIATE_OEM; - } else { - local_lm_blob = data_blob(NULL, 0); - local_nt_blob = data_blob(NULL, 0); - } - - ret = make_user_info_map(user_info, smb_name, - client_domain, - remote_machine, - local_lm_blob, - local_nt_blob, - plaintext_password, - 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 lm_blob = data_blob(NULL, 0); - DATA_BLOB nt_blob = data_blob(NULL, 0); - DATA_BLOB plaintext_blob = data_blob(NULL, 0); - uint32 ntlmssp_flags = 0; - - return make_user_info(user_info, - "","", - "","", - "", - nt_blob, lm_blob, - plaintext_blob, - ntlmssp_flags, True); -} - -/*************************************************************************** - Make a user_info struct -***************************************************************************/ - -BOOL make_server_info(auth_serversupplied_info **server_info) -{ - *server_info = malloc(sizeof(**server_info)); - if (!*server_info) { - DEBUG(0,("make_server_info: malloc failed!\n")); - return False; - } - ZERO_STRUCTP(*server_info); - return True; -} - -/*************************************************************************** - Make (and fill) a user_info struct from a SAM_ACCOUNT -***************************************************************************/ - -BOOL make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass) -{ - if (!make_server_info(server_info)) { - return False; - } - - (*server_info)->sam_fill_level = SAM_FILL_ALL; - (*server_info)->sam_account = sampass; - - DEBUG(5,("make_server_info_sam: made server info for user %s\n", - pdb_get_username((*server_info)->sam_account))); - return True; -} - -/*************************************************************************** - Make (and fill) a user_info struct from a 'struct passwd' by conversion - to a SAM_ACCOUNT -***************************************************************************/ - -BOOL make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd) -{ - SAM_ACCOUNT *sampass = NULL; - if (!pdb_init_sam_pw(&sampass, pwd)) { - return False; - } - return make_server_info_sam(server_info, sampass); -} - -/*************************************************************************** - Free a user_info struct -***************************************************************************/ - -void free_user_info(auth_usersupplied_info **user_info) -{ - DEBUG(5,("attempting to free (and zero) a user_info structure\n")); - if (*user_info != NULL) { - if ((*user_info)->smb_name.str) { - DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str)); - } - SAFE_FREE((*user_info)->smb_name.str); - 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)->lm_resp); - data_blob_free(&(*user_info)->nt_resp); - SAFE_FREE((*user_info)->interactive_password); - data_blob_clear_free(&(*user_info)->plaintext_password); - ZERO_STRUCT(**user_info); - } - SAFE_FREE(*user_info); -} - -/*************************************************************************** - Clear out a server_info struct that has been allocated -***************************************************************************/ - -void free_server_info(auth_serversupplied_info **server_info) -{ - if (*server_info != NULL) { - pdb_free_sam(&(*server_info)->sam_account); - - /* call pam_end here, unless we know we are keeping it */ - delete_nt_token( &(*server_info)->ptok ); - ZERO_STRUCT(**server_info); - } - SAFE_FREE(*server_info); -} - -/*************************************************************************** - Make a server_info struct for a guest user -***************************************************************************/ - -BOOL make_server_info_guest(auth_serversupplied_info **server_info) -{ - struct passwd *pass = sys_getpwnam(lp_guestaccount()); - - if (pass) { - if (!make_server_info_pw(server_info, pass)) { - return False; - } - (*server_info)->guest = True; - return True; - } - DEBUG(0,("make_server_info_guest: sys_getpwnam() failed on guest account!\n")); - 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. -****************************************************************************/ - -void delete_nt_token(NT_USER_TOKEN **pptoken) -{ - if (*pptoken) { - NT_USER_TOKEN *ptoken = *pptoken; - SAFE_FREE( ptoken->user_sids ); - ZERO_STRUCTP(ptoken); - } - SAFE_FREE(*pptoken); -} - -/**************************************************************************** - Duplicate a SID token. -****************************************************************************/ - -NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken) -{ - NT_USER_TOKEN *token; - - if (!ptoken) - return NULL; - - if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) - return NULL; - - ZERO_STRUCTP(token); - - if ((token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids )) == NULL) { - SAFE_FREE(token); - return NULL; - } - - token->num_sids = ptoken->num_sids; - - return token; -} diff --git a/source3/smbd/auth_winbind.c b/source3/smbd/auth_winbind.c deleted file mode 100644 index c29d008f4a..0000000000 --- a/source3/smbd/auth_winbind.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 2.0 - - Winbind authentication mechnism - - Copyright (C) Tim Potter 2000 - 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" - -/* Prototypes from common.h */ - -NSS_STATUS winbindd_request(int req_type, - struct winbindd_request *request, - struct winbindd_response *response); - - -/* Authenticate a user with a challenge/response */ - -static NTSTATUS check_winbind_security(void *my_private_data, - const auth_usersupplied_info *user_info, - const auth_authsupplied_info *auth_info, - auth_serversupplied_info **server_info) -{ - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS result; - struct passwd *pw; - NTSTATUS nt_status; - - if (!user_info) { - return NT_STATUS_LOGON_FAILURE; - } - - if (!auth_info) { - DEBUG(3,("Password for user %s cannot be checked becouse we have no auth_info to get the challange from.\n", - user_info->internal_username.str)); - return NT_STATUS_LOGON_FAILURE; - } - - /* Send off request */ - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user), - "%s\\%s", user_info->domain.str, user_info->smb_name.str); - - memcpy(request.data.auth_crap.chal, auth_info->challange.data, sizeof(request.data.auth_crap.chal)); - - request.data.auth_crap.lm_resp_len = MIN(user_info->lm_resp.length, - sizeof(request.data.auth_crap.lm_resp)); - request.data.auth_crap.nt_resp_len = MIN(user_info->nt_resp.length, - sizeof(request.data.auth_crap.nt_resp)); - - memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data, - sizeof(request.data.auth_crap.lm_resp_len)); - memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, - request.data.auth_crap.lm_resp_len); - - result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response); - - if (result == NSS_STATUS_SUCCESS) { - - pw = Get_Pwnam(user_info->internal_username.str); - - if (pw) { - if (make_server_info_pw(server_info, pw)) { - nt_status = NT_STATUS_OK; - } else { - nt_status = NT_STATUS_NO_MEMORY; - } - } else { - nt_status = NT_STATUS_NO_SUCH_USER; - } - } else { - nt_status = NT_STATUS_LOGON_FAILURE; - } - - return nt_status; -} - -BOOL auth_init_winbind(auth_methods **auth_method) -{ - if (!make_auth_methods(auth_method)) { - return False; - } - - (*auth_method)->auth = check_winbind_security; - return True; -} - - - - |