1/* 2 Unix SMB/CIFS implementation. 3 Password and authentication handling 4 Copyright (C) Andrew Bartlett 2001 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18*/ 19 20#include "includes.h" 21 22#undef DBGC_CLASS 23#define DBGC_CLASS DBGC_AUTH 24 25/** 26 * update the encrypted smbpasswd file from the plaintext username and password 27 * 28 * this ugly hack needs to die, but not quite yet, I think people still use it... 29 **/ 30static bool update_smbpassword_file(const char *user, const char *password) 31{ 32 struct samu *sampass; 33 bool ret; 34 35 if ( !(sampass = samu_new( NULL )) ) { 36 return False; 37 } 38 39 become_root(); 40 ret = pdb_getsampwnam(sampass, user); 41 unbecome_root(); 42 43 if(ret == False) { 44 DEBUG(0,("pdb_getsampwnam returned NULL\n")); 45 TALLOC_FREE(sampass); 46 return False; 47 } 48 49 /* 50 * Remove the account disabled flag - we are updating the 51 * users password from a login. 52 */ 53 if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED, PDB_CHANGED)) { 54 TALLOC_FREE(sampass); 55 return False; 56 } 57 58 if (!pdb_set_plaintext_passwd (sampass, password)) { 59 TALLOC_FREE(sampass); 60 return False; 61 } 62 63 /* Now write it into the file. */ 64 become_root(); 65 66 ret = NT_STATUS_IS_OK(pdb_update_sam_account (sampass)); 67 68 unbecome_root(); 69 70 if (ret) { 71 DEBUG(3,("pdb_update_sam_account returned %d\n",ret)); 72 } 73 74 TALLOC_FREE(sampass); 75 return ret; 76} 77 78 79/** Check a plaintext username/password 80 * 81 * Cannot deal with an encrupted password in any manner whatsoever, 82 * unless the account has a null password. 83 **/ 84 85static NTSTATUS check_unix_security(const struct auth_context *auth_context, 86 void *my_private_data, 87 TALLOC_CTX *mem_ctx, 88 const auth_usersupplied_info *user_info, 89 auth_serversupplied_info **server_info) 90{ 91 NTSTATUS nt_status; 92 struct passwd *pass = NULL; 93 94 become_root(); 95 pass = Get_Pwnam_alloc(talloc_tos(), user_info->internal_username); 96 97 98 /** @todo This call assumes a ASCII password, no charset transformation is 99 done. We may need to revisit this **/ 100 nt_status = pass_check(pass, 101 pass ? pass->pw_name : user_info->internal_username, 102 (char *)user_info->plaintext_password.data, 103 user_info->plaintext_password.length-1, 104 lp_update_encrypted() ? 105 update_smbpassword_file : NULL, 106 True); 107 108 unbecome_root(); 109 110 if (NT_STATUS_IS_OK(nt_status)) { 111 if (pass) { 112 /* if a real user check pam account restrictions */ 113 /* only really perfomed if "obey pam restriction" is true */ 114 nt_status = smb_pam_accountcheck(pass->pw_name); 115 if ( !NT_STATUS_IS_OK(nt_status)) { 116 DEBUG(1, ("PAM account restriction prevents user login\n")); 117 } else { 118 make_server_info_pw(server_info, pass->pw_name, pass); 119 } 120 } else { 121 /* we need to do somthing more useful here */ 122 nt_status = NT_STATUS_NO_SUCH_USER; 123 } 124 } 125 126 TALLOC_FREE(pass); 127 return nt_status; 128} 129 130/* module initialisation */ 131static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) 132{ 133 if (!make_auth_methods(auth_context, auth_method)) { 134 return NT_STATUS_NO_MEMORY; 135 } 136 137 (*auth_method)->name = "unix"; 138 (*auth_method)->auth = check_unix_security; 139 return NT_STATUS_OK; 140} 141 142NTSTATUS auth_unix_init(void) 143{ 144 return smb_register_auth(AUTH_INTERFACE_VERSION, "unix", auth_init_unix); 145} 146