⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntlm_auth.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/*    Unix SMB/CIFS implementation.   Winbind status program.   Copyright (C) Tim Potter      2000-2003   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2004   Copyright (C) Francesco Chemolli <kinkie@kame.usr.dsi.unimi.it> 2000    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"#include "utils/ntlm_auth.h"#undef DBGC_CLASS#define DBGC_CLASS DBGC_WINBIND#define SQUID_BUFFER_SIZE 2010enum stdio_helper_mode {	SQUID_2_4_BASIC,	SQUID_2_5_BASIC,	SQUID_2_5_NTLMSSP,	NTLMSSP_CLIENT_1,	GSS_SPNEGO,	GSS_SPNEGO_CLIENT,	NTLM_SERVER_1,	NUM_HELPER_MODES};typedef void (*stdio_helper_function)(enum stdio_helper_mode stdio_helper_mode, 				     char *buf, int length);static void manage_squid_basic_request (enum stdio_helper_mode stdio_helper_mode, 					char *buf, int length);static void manage_squid_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, 					  char *buf, int length);static void manage_client_ntlmssp_request (enum stdio_helper_mode stdio_helper_mode, 					   char *buf, int length);static void manage_gss_spnego_request (enum stdio_helper_mode stdio_helper_mode, 				       char *buf, int length);static void manage_gss_spnego_client_request (enum stdio_helper_mode stdio_helper_mode, 					      char *buf, int length);static void manage_ntlm_server_1_request (enum stdio_helper_mode stdio_helper_mode, 					  char *buf, int length);static const struct {	enum stdio_helper_mode mode;	const char *name;	stdio_helper_function fn;} stdio_helper_protocols[] = {	{ SQUID_2_4_BASIC, "squid-2.4-basic", manage_squid_basic_request},	{ SQUID_2_5_BASIC, "squid-2.5-basic", manage_squid_basic_request},	{ SQUID_2_5_NTLMSSP, "squid-2.5-ntlmssp", manage_squid_ntlmssp_request},	{ NTLMSSP_CLIENT_1, "ntlmssp-client-1", manage_client_ntlmssp_request},	{ GSS_SPNEGO, "gss-spnego", manage_gss_spnego_request},	{ GSS_SPNEGO_CLIENT, "gss-spnego-client", manage_gss_spnego_client_request},	{ NTLM_SERVER_1, "ntlm-server-1", manage_ntlm_server_1_request},	{ NUM_HELPER_MODES, NULL, NULL}};extern int winbindd_fd;const char *opt_username;const char *opt_domain;const char *opt_workstation;const char *opt_password;static DATA_BLOB opt_challenge;static DATA_BLOB opt_lm_response;static DATA_BLOB opt_nt_response;static int request_lm_key;static int request_user_session_key;static const char *require_membership_of;static const char *require_membership_of_sid;static char winbind_separator(void){	struct winbindd_response response;	static BOOL got_sep;	static char sep;	if (got_sep)		return sep;	ZERO_STRUCT(response);	/* Send off request */	if (winbindd_request_response(WINBINDD_INFO, NULL, &response) !=	    NSS_STATUS_SUCCESS) {		d_printf("could not obtain winbind separator!\n");		return *lp_winbind_separator();	}	sep = response.data.info.winbind_separator;	got_sep = True;	if (!sep) {		d_printf("winbind separator was NULL!\n");		return *lp_winbind_separator();	}		return sep;}const char *get_winbind_domain(void){	struct winbindd_response response;	static fstring winbind_domain;	if (*winbind_domain) {		return winbind_domain;	}	ZERO_STRUCT(response);	/* Send off request */	if (winbindd_request_response(WINBINDD_DOMAIN_NAME, NULL, &response) !=	    NSS_STATUS_SUCCESS) {		DEBUG(0, ("could not obtain winbind domain name!\n"));		return lp_workgroup();	}	fstrcpy(winbind_domain, response.data.domain_name);	return winbind_domain;}const char *get_winbind_netbios_name(void){	struct winbindd_response response;	static fstring winbind_netbios_name;	if (*winbind_netbios_name) {		return winbind_netbios_name;	}	ZERO_STRUCT(response);	/* Send off request */	if (winbindd_request_response(WINBINDD_NETBIOS_NAME, NULL, &response) !=	    NSS_STATUS_SUCCESS) {		DEBUG(0, ("could not obtain winbind netbios name!\n"));		return global_myname();	}	fstrcpy(winbind_netbios_name, response.data.netbios_name);	return winbind_netbios_name;}DATA_BLOB get_challenge(void) {	static DATA_BLOB chal;	if (opt_challenge.length)		return opt_challenge;		chal = data_blob(NULL, 8);	generate_random_buffer(chal.data, chal.length);	return chal;}/* Copy of parse_domain_user from winbindd_util.c.  Parse a string of the   form DOMAIN/user into a domain and a user */static BOOL parse_ntlm_auth_domain_user(const char *domuser, fstring domain, 				     fstring user){	char *p = strchr(domuser,winbind_separator());	if (!p) {		return False;	}        	fstrcpy(user, p+1);	fstrcpy(domain, domuser);	domain[PTR_DIFF(p, domuser)] = 0;	strupper_m(domain);	return True;}static BOOL get_require_membership_sid(void) {	struct winbindd_request request;	struct winbindd_response response;	if (!require_membership_of) {		return True;	}	if (require_membership_of_sid) {		return True;	}	/* Otherwise, ask winbindd for the name->sid request */	ZERO_STRUCT(request);	ZERO_STRUCT(response);	if (!parse_ntlm_auth_domain_user(require_membership_of, 					 request.data.name.dom_name, 					 request.data.name.name)) {		DEBUG(0, ("Could not parse %s into seperate domain/name parts!\n", 			  require_membership_of));		return False;	}	if (winbindd_request_response(WINBINDD_LOOKUPNAME, &request, &response) !=	    NSS_STATUS_SUCCESS) {		DEBUG(0, ("Winbindd lookupname failed to resolve %s into a SID!\n", 			  require_membership_of));		return False;	}	require_membership_of_sid = SMB_STRDUP(response.data.sid.sid);	if (require_membership_of_sid)		return True;	return False;}/* Authenticate a user with a plaintext password */static BOOL check_plaintext_auth(const char *user, const char *pass, 				 BOOL stdout_diagnostics){	struct winbindd_request request;	struct winbindd_response response;        NSS_STATUS result;	if (!get_require_membership_sid()) {		return False;	}	/* Send off request */	ZERO_STRUCT(request);	ZERO_STRUCT(response);	fstrcpy(request.data.auth.user, user);	fstrcpy(request.data.auth.pass, pass);	if (require_membership_of_sid)		fstrcpy(request.data.auth.require_membership_of_sid, require_membership_of_sid);	result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);	/* Display response */		if (stdout_diagnostics) {		if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {			d_printf("Reading winbind reply failed! (0x01)\n");		}				d_printf("%s: %s (0x%x)\n", 			 response.data.auth.nt_status_string, 			 response.data.auth.error_string, 			 response.data.auth.nt_status);	} else {		if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {			DEBUG(1, ("Reading winbind reply failed! (0x01)\n"));		}				DEBUG(3, ("%s: %s (0x%x)\n", 			  response.data.auth.nt_status_string, 			  response.data.auth.error_string,			  response.data.auth.nt_status));			}		        return (result == NSS_STATUS_SUCCESS);}/* authenticate a user with an encrypted username/password */NTSTATUS contact_winbind_auth_crap(const char *username, 				   const char *domain, 				   const char *workstation,				   const DATA_BLOB *challenge, 				   const DATA_BLOB *lm_response, 				   const DATA_BLOB *nt_response, 				   uint32 flags, 				   uint8 lm_key[8], 				   uint8 user_session_key[16], 				   char **error_string, 				   char **unix_name) {	NTSTATUS nt_status;        NSS_STATUS result;	struct winbindd_request request;	struct winbindd_response response;	if (!get_require_membership_sid()) {		return NT_STATUS_INVALID_PARAMETER;	}	ZERO_STRUCT(request);	ZERO_STRUCT(response);	request.flags = flags;	request.data.auth_crap.logon_parameters = MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT | MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT;	if (require_membership_of_sid)		fstrcpy(request.data.auth_crap.require_membership_of_sid, require_membership_of_sid);        fstrcpy(request.data.auth_crap.user, username);	fstrcpy(request.data.auth_crap.domain, domain);	fstrcpy(request.data.auth_crap.workstation, 		workstation);	memcpy(request.data.auth_crap.chal, challenge->data, MIN(challenge->length, 8));	if (lm_response && lm_response->length) {		memcpy(request.data.auth_crap.lm_resp, 		       lm_response->data, 		       MIN(lm_response->length, sizeof(request.data.auth_crap.lm_resp)));		request.data.auth_crap.lm_resp_len = lm_response->length;	}	if (nt_response && nt_response->length) {		memcpy(request.data.auth_crap.nt_resp, 		       nt_response->data, 		       MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));                request.data.auth_crap.nt_resp_len = nt_response->length;	}		result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);	/* Display response */	if ((result != NSS_STATUS_SUCCESS) && (response.data.auth.nt_status == 0)) {		nt_status = NT_STATUS_UNSUCCESSFUL;		if (error_string)			*error_string = smb_xstrdup("Reading winbind reply failed!");		free_response(&response);		return nt_status;	}		nt_status = (NT_STATUS(response.data.auth.nt_status));	if (!NT_STATUS_IS_OK(nt_status)) {		if (error_string) 			*error_string = smb_xstrdup(response.data.auth.error_string);		free_response(&response);		return nt_status;	}	if ((flags & WBFLAG_PAM_LMKEY) && lm_key) {		memcpy(lm_key, response.data.auth.first_8_lm_hash, 		       sizeof(response.data.auth.first_8_lm_hash));	}	if ((flags & WBFLAG_PAM_USER_SESSION_KEY) && user_session_key) {		memcpy(user_session_key, response.data.auth.user_session_key, 			sizeof(response.data.auth.user_session_key));	}	if (flags & WBFLAG_PAM_UNIX_NAME) {		*unix_name = SMB_STRDUP((char *)response.extra_data);		if (!*unix_name) {			free_response(&response);			return NT_STATUS_NO_MEMORY;		}	}	free_response(&response);	return nt_status;}				   static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) {	static const char zeros[16];	NTSTATUS nt_status;	char *error_string;	uint8 lm_key[8]; 	uint8 user_sess_key[16]; 	char *unix_name;	nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain,					      ntlmssp_state->workstation,					      &ntlmssp_state->chal,					      &ntlmssp_state->lm_resp,					      &ntlmssp_state->nt_resp, 					      WBFLAG_PAM_LMKEY | WBFLAG_PAM_USER_SESSION_KEY | WBFLAG_PAM_UNIX_NAME,					      lm_key, user_sess_key, 					      &error_string, &unix_name);	if (NT_STATUS_IS_OK(nt_status)) {		if (memcmp(lm_key, zeros, 8) != 0) {			*lm_session_key = data_blob(NULL, 16);			memcpy(lm_session_key->data, lm_key, 8);			memset(lm_session_key->data+8, '\0', 8);		}				if (memcmp(user_sess_key, zeros, 16) != 0) {			*user_session_key = data_blob(user_sess_key, 16);		}		ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state->mem_ctx, unix_name);		SAFE_FREE(unix_name);	} else {		DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3, 		      ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 		       ntlmssp_state->domain, ntlmssp_state->user, 		       ntlmssp_state->workstation, 		       error_string ? error_string : "unknown error (NULL)"));		ntlmssp_state->auth_context = NULL;	}	return nt_status;}static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) {	NTSTATUS nt_status;	uint8 lm_pw[16], nt_pw[16];	nt_lm_owf_gen (opt_password, nt_pw, lm_pw);		nt_status = ntlm_password_check(ntlmssp_state->mem_ctx, 					&ntlmssp_state->chal,					&ntlmssp_state->lm_resp,					&ntlmssp_state->nt_resp, 					NULL, NULL,					ntlmssp_state->user, 					ntlmssp_state->user, 					ntlmssp_state->domain,					lm_pw, nt_pw, user_session_key, lm_session_key);		if (NT_STATUS_IS_OK(nt_status)) {		ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state->mem_ctx, 							      "%s%c%s", ntlmssp_state->domain, 							      *lp_winbind_separator(), 							      ntlmssp_state->user);	} else {		DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 			  ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, 			  nt_errstr(nt_status)));		ntlmssp_state->auth_context = NULL;	}	return nt_status;}static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_state) {	NTSTATUS status;	if ( (opt_username == NULL) || (opt_domain == NULL) ) {		status = NT_STATUS_UNSUCCESSFUL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -