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

📄 ntlmssp.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    Unix SMB/Netbios implementation.   Version 3.0   handle NLTMSSP, server side   Copyright (C) Andrew Tridgell      2001   Copyright (C) Andrew Bartlett 2001-2003   Copyright (C) Andrew Bartlett 2005 (Updated from gensec).   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"static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, 				       DATA_BLOB reply, DATA_BLOB *next_request);static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,					 const DATA_BLOB in, DATA_BLOB *out);static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, 					 const DATA_BLOB reply, DATA_BLOB *next_request);static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,				    const DATA_BLOB request, DATA_BLOB *reply);/** * Callbacks for NTLMSSP - for both client and server operating modes *  */static const struct ntlmssp_callbacks {	enum NTLMSSP_ROLE role;	enum NTLM_MESSAGE_TYPE ntlmssp_command;	NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, 		       DATA_BLOB in, DATA_BLOB *out);} ntlmssp_callbacks[] = {	{NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial},	{NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate},	{NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge},	{NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth},	{NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL},	{NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL}};/** * Print out the NTLMSSP flags for debugging  * @param neg_flags The flags from the packet */void debug_ntlmssp_flags(uint32 neg_flags){	DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));		if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_OEM) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));	if (neg_flags & NTLMSSP_REQUEST_TARGET) 		DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM_STYLE)		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DATAGRAM_STYLE\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));	if (neg_flags & NTLMSSP_CHAL_ACCEPT_RESPONSE)		DEBUGADD(4, ("  NTLMSSP_CHAL_ACCEPT_RESPONSE\n"));	if (neg_flags & NTLMSSP_CHAL_NON_NT_SESSION_KEY)		DEBUGADD(4, ("  NTLMSSP_CHAL_NON_NT_SESSION_KEY\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));	if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) 		DEBUGADD(4, ("  NTLMSSP_CHAL_TARGET_INFO\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_128) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));	if (neg_flags & NTLMSSP_NEGOTIATE_56)		DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_56\n"));}/** * Default challenge generation code. * */   static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state){	static uchar chal[8];	generate_random_buffer(chal, sizeof(chal));	return chal;}/** * Default 'we can set the challenge to anything we like' implementation * */   static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state){	return True;}/** * Default 'we can set the challenge to anything we like' implementation * * Does not actually do anything, as the value is always in the structure anyway. * */   static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge){	SMB_ASSERT(challenge->length == 8);	return NT_STATUS_OK;}/**  * Set a username on an NTLMSSP context - ensures it is talloc()ed  * */NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) {	ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user ? user : "" );	if (!ntlmssp_state->user) {		return NT_STATUS_NO_MEMORY;	}	return NT_STATUS_OK;}/**  * Set a password on an NTLMSSP context - ensures it is talloc()ed  * */NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) {	if (!password) {		ntlmssp_state->password = NULL;	} else {		ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password);		if (!ntlmssp_state->password) {			return NT_STATUS_NO_MEMORY;		}	}	return NT_STATUS_OK;}/**  * Set a domain on an NTLMSSP context - ensures it is talloc()ed  * */NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) {	ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain ? domain : "" );	if (!ntlmssp_state->domain) {		return NT_STATUS_NO_MEMORY;	}	return NT_STATUS_OK;}/**  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed  * */NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) {	ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation);	if (!ntlmssp_state->workstation) {		return NT_STATUS_NO_MEMORY;	}	return NT_STATUS_OK;}/** *  Store a DATA_BLOB containing an NTLMSSP response, for use later. *  This copies the data blob */NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state,				DATA_BLOB response) {	ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, 							  response.data, response.length);	return NT_STATUS_OK;}/** * Next state function for the NTLMSSP state machine *  * @param ntlmssp_state NTLMSSP State * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB * @param out The reply, as an allocated DATA_BLOB, caller to free. * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK.  */NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, 			const DATA_BLOB in, DATA_BLOB *out) {	DATA_BLOB input;	uint32 ntlmssp_command;	int i;	if (ntlmssp_state->expected_state == NTLMSSP_DONE) {		/* Called update after negotiations finished. */		DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n"));		return NT_STATUS_INVALID_PARAMETER;	}	*out = data_blob(NULL, 0);	if (!in.length && ntlmssp_state->stored_response.length) {		input = ntlmssp_state->stored_response;				/* we only want to read the stored response once - overwrite it */		ntlmssp_state->stored_response = data_blob(NULL, 0);	} else {		input = in;	}	if (!input.length) {		switch (ntlmssp_state->role) {		case NTLMSSP_CLIENT:			ntlmssp_command = NTLMSSP_INITIAL;			break;		case NTLMSSP_SERVER:			/* 'datagram' mode - no neg packet */			ntlmssp_command = NTLMSSP_NEGOTIATE;			break;		}	} else {		if (!msrpc_parse(&input, "Cd",				 "NTLMSSP",				 &ntlmssp_command)) {			DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n"));			dump_data(2, (const char *)input.data, input.length);			return NT_STATUS_INVALID_PARAMETER;		}	}	if (ntlmssp_command != ntlmssp_state->expected_state) {		DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));		return NT_STATUS_INVALID_PARAMETER;	}	for (i=0; ntlmssp_callbacks[i].fn; i++) {		if (ntlmssp_callbacks[i].role == ntlmssp_state->role 		    && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) {			return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out);		}	}	DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", 		  ntlmssp_state->role, ntlmssp_command)); 	return NT_STATUS_INVALID_PARAMETER;}/** * End an NTLMSSP state machine *  * @param ntlmssp_state NTLMSSP State, free()ed by this function */void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state){	TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx;	(*ntlmssp_state)->ref_count--;	if ((*ntlmssp_state)->ref_count == 0) {		data_blob_free(&(*ntlmssp_state)->chal);		data_blob_free(&(*ntlmssp_state)->lm_resp);		data_blob_free(&(*ntlmssp_state)->nt_resp);		talloc_destroy(mem_ctx);	}	*ntlmssp_state = NULL;	return;}/** * Determine correct target name flags for reply, given server role  * and negotiated flags *  * @param ntlmssp_state NTLMSSP State * @param neg_flags The flags from the packet * @param chal_flags The flags to be set in the reply packet * @return The 'target name' string. */static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,				       uint32 neg_flags, uint32 *chal_flags) {	if (neg_flags & NTLMSSP_REQUEST_TARGET) {		*chal_flags |= NTLMSSP_CHAL_TARGET_INFO;		*chal_flags |= NTLMSSP_REQUEST_TARGET;		if (ntlmssp_state->server_role == ROLE_STANDALONE) {			*chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;			return ntlmssp_state->get_global_myname();		} else {			*chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;			return ntlmssp_state->get_domain();		};	} else {		return "";	}}static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state,				      uint32 neg_flags, BOOL allow_lm) {	if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;		ntlmssp_state->unicode = True;	} else {		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;		ntlmssp_state->unicode = False;	}	if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) {		/* other end forcing us to use LM */		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;		ntlmssp_state->use_ntlmv2 = False;	} else {		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;	}	if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) {		ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;	}	if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;	}	if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;		if (neg_flags & NTLMSSP_NEGOTIATE_56) {			ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;		}	}	if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;	}	if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;	}	if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {		ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;	}	}/** Weaken NTLMSSP keys to cope with down-level clients and servers. We probably should have some parameters to control this, but as

⌨️ 快捷键说明

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