auth_util.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,706 行 · 第 1/4 页
C
1,706 行
/* Unix SMB/CIFS implementation. Authentication utility functions Copyright (C) Andrew Tridgell 1992-1998 Copyright (C) Andrew Bartlett 2001 Copyright (C) Jeremy Allison 2000-2001 Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_AUTH/**************************************************************************** Create a UNIX user on demand.****************************************************************************/static int smb_create_user(const char *domain, const char *unix_username, 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_username, sizeof(pstring)); if (domain) all_string_sub(add_script, "%D", domain, sizeof(pstring)); if (homedir) all_string_sub(add_script, "%H", homedir, sizeof(pstring)); ret = smbrun(add_script,NULL); flush_pwnam_cache(); DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret)); return ret;}/**************************************************************************** Create an auth_usersupplied_data structure****************************************************************************/static NTSTATUS 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 *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd, DATA_BLOB *plaintext, BOOL encrypted){ DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name)); *user_info = SMB_MALLOC_P(auth_usersupplied_info); if (!user_info) { DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info))); return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(*user_info); DEBUG(5,("making strings for %s's user_info struct\n", internal_username)); (*user_info)->smb_name.str = SMB_STRDUP(smb_name); if ((*user_info)->smb_name.str) { (*user_info)->smb_name.len = strlen(smb_name); } else { free_user_info(user_info); return NT_STATUS_NO_MEMORY; } (*user_info)->internal_username.str = SMB_STRDUP(internal_username); if ((*user_info)->internal_username.str) { (*user_info)->internal_username.len = strlen(internal_username); } else { free_user_info(user_info); return NT_STATUS_NO_MEMORY; } (*user_info)->domain.str = SMB_STRDUP(domain); if ((*user_info)->domain.str) { (*user_info)->domain.len = strlen(domain); } else { free_user_info(user_info); return NT_STATUS_NO_MEMORY; } (*user_info)->client_domain.str = SMB_STRDUP(client_domain); if ((*user_info)->client_domain.str) { (*user_info)->client_domain.len = strlen(client_domain); } else { free_user_info(user_info); return NT_STATUS_NO_MEMORY; } (*user_info)->wksta_name.str = SMB_STRDUP(wksta_name); if ((*user_info)->wksta_name.str) { (*user_info)->wksta_name.len = strlen(wksta_name); } else { free_user_info(user_info); return NT_STATUS_NO_MEMORY; } DEBUG(5,("making blobs for %s's user_info struct\n", internal_username)); if (lm_pwd) (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length); if (nt_pwd) (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length); if (lm_interactive_pwd) (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length); if (nt_interactive_pwd) (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length); if (plaintext) (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length); (*user_info)->encrypted = encrypted; (*user_info)->logon_parameters = 0; DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name)); return NT_STATUS_OK;}/**************************************************************************** Create an auth_usersupplied_data structure after appropriate mapping.****************************************************************************/NTSTATUS 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 *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd, DATA_BLOB *plaintext, BOOL encrypted){ const char *domain; fstring internal_username; fstrcpy(internal_username, smb_name); map_username(internal_username); DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n", client_domain, smb_name, wksta_name)); /* don't allow "" as a domain, fixes a Win9X bug where it doens't supply a domain for logon script 'net use' commands. */ if ( *client_domain ) domain = client_domain; else domain = lp_workgroup(); /* do what win2k does. Always map unknown domains to our own and let the "passdb backend" handle unknown users. */ if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) domain = get_default_sam_name(); /* we know that it is a trusted domain (and we are allowing them) or it is our domain */ return make_user_info(user_info, smb_name, internal_username, client_domain, domain, wksta_name, lm_pwd, nt_pwd, lm_interactive_pwd, nt_interactive_pwd, plaintext, 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, const char *smb_name, const char *client_domain, const char *wksta_name, uint32 logon_parameters, const uchar *lm_network_pwd, int lm_pwd_len, const uchar *nt_network_pwd, int nt_pwd_len){ BOOL ret; NTSTATUS nt_status; DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len); DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len); nt_status = make_user_info_map(user_info, smb_name, client_domain, wksta_name, lm_pwd_len ? &lm_blob : NULL, nt_pwd_len ? &nt_blob : NULL, NULL, NULL, NULL, True); if (NT_STATUS_IS_OK(nt_status)) { (*user_info)->logon_parameters = logon_parameters; } ret = NT_STATUS_IS_OK(nt_status) ? True : False; 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, const char *smb_name, const char *client_domain, const char *wksta_name, uint32 logon_parameters, const uchar chal[8], const uchar lm_interactive_pwd[16], const uchar nt_interactive_pwd[16], const uchar *dc_sess_key){ char lm_pwd[16]; char nt_pwd[16]; unsigned char local_lm_response[24]; unsigned char local_nt_response[24]; unsigned char key[16]; 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 if (lm_interactive_pwd) SamOEMhash((uchar *)lm_pwd, key, sizeof(lm_pwd)); if (nt_interactive_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 if (lm_interactive_pwd) SMBOWFencrypt((const unsigned char *)lm_pwd, chal, local_lm_response); if (nt_interactive_pwd) SMBOWFencrypt((const unsigned char *)nt_pwd, chal, local_nt_response); /* Password info paranoia */ ZERO_STRUCT(key); { BOOL ret; NTSTATUS nt_status; DATA_BLOB local_lm_blob; DATA_BLOB local_nt_blob; DATA_BLOB lm_interactive_blob; DATA_BLOB nt_interactive_blob; if (lm_interactive_pwd) { local_lm_blob = data_blob(local_lm_response, sizeof(local_lm_response)); lm_interactive_blob = data_blob(lm_pwd, sizeof(lm_pwd)); ZERO_STRUCT(lm_pwd); } if (nt_interactive_pwd) { local_nt_blob = data_blob(local_nt_response, sizeof(local_nt_response)); nt_interactive_blob = data_blob(nt_pwd, sizeof(nt_pwd)); ZERO_STRUCT(nt_pwd); } nt_status = make_user_info_map(user_info, smb_name, client_domain, wksta_name, lm_interactive_pwd ? &local_lm_blob : NULL, nt_interactive_pwd ? &local_nt_blob : NULL, lm_interactive_pwd ? &lm_interactive_blob : NULL, nt_interactive_pwd ? &nt_interactive_blob : NULL, NULL, True); if (NT_STATUS_IS_OK(nt_status)) { (*user_info)->logon_parameters = logon_parameters; } ret = NT_STATUS_IS_OK(nt_status) ? True : False; data_blob_free(&local_lm_blob); data_blob_free(&local_nt_blob); data_blob_free(&lm_interactive_blob); data_blob_free(&nt_interactive_blob); return ret; }}/**************************************************************************** Create an auth_usersupplied_data structure****************************************************************************/BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, const char *smb_name, const char *client_domain, const uint8 chal[8], DATA_BLOB plaintext_password){ DATA_BLOB local_lm_blob; DATA_BLOB local_nt_blob; NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; /* * 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",(int)plaintext_password.length)); dump_data(100, (const char *)plaintext_password.data, plaintext_password.length);#endif SMBencrypt( (const char *)plaintext_password.data, (const uchar*)chal, local_lm_response); local_lm_blob = data_blob(local_lm_response, 24); /* We can't do an NT hash here, as the password needs to be case insensitive */ local_nt_blob = data_blob(NULL, 0); } 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, get_remote_machine_name(), local_lm_blob.data ? &local_lm_blob : NULL, local_nt_blob.data ? &local_nt_blob : NULL, NULL, NULL, plaintext_password.data ? &plaintext_password : NULL, False); data_blob_free(&local_lm_blob); return NT_STATUS_IS_OK(ret) ? True : False;}/**************************************************************************** Create an auth_usersupplied_data structure****************************************************************************/NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, const char *smb_name, const char *client_domain, DATA_BLOB lm_resp, DATA_BLOB nt_resp){ return make_user_info_map(user_info, smb_name, client_domain, get_remote_machine_name(), lm_resp.data ? &lm_resp : NULL, nt_resp.data ? &nt_resp : NULL, NULL, NULL, NULL, True);}/**************************************************************************** Create a guest user_info blob, for anonymous authenticaion.****************************************************************************/BOOL make_user_info_guest(auth_usersupplied_info **user_info) { NTSTATUS nt_status; nt_status = make_user_info(user_info, "","", "","", "", NULL, NULL, NULL, NULL, NULL, True); return NT_STATUS_IS_OK(nt_status) ? True : False;}/**************************************************************************** prints a NT_USER_TOKEN to debug output.****************************************************************************/void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?