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

📄 ntlm_auth.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
				user = SMB_STRDUP(principal);				data_blob_free(&ap_rep);				SAFE_FREE(principal);			}		}#endif	} else {		if ( (request.negTokenTarg.supportedMech == NULL) ||		     ( strcmp(request.negTokenTarg.supportedMech, OID_NTLMSSP) != 0 ) ) {			/* Kerberos should never send a negTokenTarg, OID_NTLMSSP			   is the only one we support that sends this stuff */			DEBUG(1, ("Got a negTokenTarg for something non-NTLMSSP: %s\n",				  request.negTokenTarg.supportedMech));			x_fprintf(x_stdout, "BH\n");			return;		}		if (request.negTokenTarg.responseToken.data == NULL) {			DEBUG(1, ("Got a negTokenTarg without a responseToken!\n"));			x_fprintf(x_stdout, "BH\n");			return;		}		status = ntlmssp_update(ntlmssp_state,					       request.negTokenTarg.responseToken,					       &response.negTokenTarg.responseToken);		response.type = SPNEGO_NEG_TOKEN_TARG;		response.negTokenTarg.supportedMech = SMB_STRDUP(OID_NTLMSSP);		response.negTokenTarg.mechListMIC = data_blob(NULL, 0);		if (NT_STATUS_IS_OK(status)) {			user = SMB_STRDUP(ntlmssp_state->user);			domain = SMB_STRDUP(ntlmssp_state->domain);			ntlmssp_end(&ntlmssp_state);		}	}	free_spnego_data(&request);	if (NT_STATUS_IS_OK(status)) {		response.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;		reply_code = "AF";		pstr_sprintf(reply_argument, "%s\\%s", domain, user);	} else if (NT_STATUS_EQUAL(status,				   NT_STATUS_MORE_PROCESSING_REQUIRED)) {		response.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;		reply_code = "TT";		pstr_sprintf(reply_argument, "*");	} else {		response.negTokenTarg.negResult = SPNEGO_REJECT;		reply_code = "NA";		pstrcpy(reply_argument, nt_errstr(status));	}	SAFE_FREE(user);	SAFE_FREE(domain);	len = write_spnego_data(&token, &response);	free_spnego_data(&response);	if (len == -1) {		DEBUG(1, ("Could not write SPNEGO data blob\n"));		x_fprintf(x_stdout, "BH\n");		return;	}	reply_base64 = base64_encode_data_blob(token);	x_fprintf(x_stdout, "%s %s %s\n",		  reply_code, reply_base64, reply_argument);	SAFE_FREE(reply_base64);	data_blob_free(&token);	return;}static NTLMSSP_STATE *client_ntlmssp_state = NULL;static BOOL manage_client_ntlmssp_init(SPNEGO_DATA spnego){	NTSTATUS status;	DATA_BLOB null_blob = data_blob(NULL, 0);	DATA_BLOB to_server;	char *to_server_base64;	const char *my_mechs[] = {OID_NTLMSSP, NULL};	DEBUG(10, ("Got spnego negTokenInit with NTLMSSP\n"));	if (client_ntlmssp_state != NULL) {		DEBUG(1, ("Request for initial SPNEGO request where "			  "we already have a state\n"));		return False;	}	if (!client_ntlmssp_state) {		if (!NT_STATUS_IS_OK(status = ntlm_auth_start_ntlmssp_client(&client_ntlmssp_state))) {			x_fprintf(x_stdout, "BH %s\n", nt_errstr(status));			return False;		}	}	if (opt_password == NULL) {		/* Request a password from the calling process.  After		   sending it, the calling process should retry with		   the negTokenInit. */		DEBUG(10, ("Requesting password\n"));		x_fprintf(x_stdout, "PW\n");		return True;	}	spnego.type = SPNEGO_NEG_TOKEN_INIT;	spnego.negTokenInit.mechTypes = my_mechs;	spnego.negTokenInit.reqFlags = 0;	spnego.negTokenInit.mechListMIC = null_blob;	status = ntlmssp_update(client_ntlmssp_state, null_blob,				       &spnego.negTokenInit.mechToken);	if ( !(NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) ||			NT_STATUS_IS_OK(status)) ) {		DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n",			  nt_errstr(status)));		ntlmssp_end(&client_ntlmssp_state);		return False;	}	write_spnego_data(&to_server, &spnego);	data_blob_free(&spnego.negTokenInit.mechToken);	to_server_base64 = base64_encode_data_blob(to_server);	data_blob_free(&to_server);	x_fprintf(x_stdout, "KK %s\n", to_server_base64);	SAFE_FREE(to_server_base64);	return True;}static void manage_client_ntlmssp_targ(SPNEGO_DATA spnego){	NTSTATUS status;	DATA_BLOB null_blob = data_blob(NULL, 0);	DATA_BLOB request;	DATA_BLOB to_server;	char *to_server_base64;	DEBUG(10, ("Got spnego negTokenTarg with NTLMSSP\n"));	if (client_ntlmssp_state == NULL) {		DEBUG(1, ("Got NTLMSSP tArg without a client state\n"));		x_fprintf(x_stdout, "BH\n");		ntlmssp_end(&client_ntlmssp_state);		return;	}	if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {		x_fprintf(x_stdout, "NA\n");		ntlmssp_end(&client_ntlmssp_state);		return;	}	if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {		x_fprintf(x_stdout, "AF\n");		ntlmssp_end(&client_ntlmssp_state);		return;	}	status = ntlmssp_update(client_ntlmssp_state,				       spnego.negTokenTarg.responseToken,				       &request);			if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {		DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "			  "ntlmssp_client_update, got: %s\n",			  nt_errstr(status)));		x_fprintf(x_stdout, "BH\n");		data_blob_free(&request);		ntlmssp_end(&client_ntlmssp_state);		return;	}	spnego.type = SPNEGO_NEG_TOKEN_TARG;	spnego.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;	spnego.negTokenTarg.supportedMech = (char *)OID_NTLMSSP;	spnego.negTokenTarg.responseToken = request;	spnego.negTokenTarg.mechListMIC = null_blob;		write_spnego_data(&to_server, &spnego);	data_blob_free(&request);	to_server_base64 = base64_encode_data_blob(to_server);	data_blob_free(&to_server);	x_fprintf(x_stdout, "KK %s\n", to_server_base64);	SAFE_FREE(to_server_base64);	return;}#ifdef HAVE_KRB5static BOOL manage_client_krb5_init(SPNEGO_DATA spnego){	char *principal;	DATA_BLOB tkt, to_server;	DATA_BLOB session_key_krb5 = data_blob(NULL, 0);	SPNEGO_DATA reply;	char *reply_base64;	int retval;		const char *my_mechs[] = {OID_KERBEROS5_OLD, NULL};	ssize_t len;	if ( (spnego.negTokenInit.mechListMIC.data == NULL) ||	     (spnego.negTokenInit.mechListMIC.length == 0) ) {		DEBUG(1, ("Did not get a principal for krb5\n"));		return False;	}	principal = SMB_MALLOC(spnego.negTokenInit.mechListMIC.length+1);	if (principal == NULL) {		DEBUG(1, ("Could not malloc principal\n"));		return False;	}	memcpy(principal, spnego.negTokenInit.mechListMIC.data,	       spnego.negTokenInit.mechListMIC.length);	principal[spnego.negTokenInit.mechListMIC.length] = '\0';	retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0);	if (retval) {		pstring user;		/* Let's try to first get the TGT, for that we need a                   password. */		if (opt_password == NULL) {			DEBUG(10, ("Requesting password\n"));			x_fprintf(x_stdout, "PW\n");			return True;		}		pstr_sprintf(user, "%s@%s", opt_username, opt_domain);		if ((retval = kerberos_kinit_password(user, opt_password, 						      0, NULL, NULL))) {			DEBUG(10, ("Requesting TGT failed: %s\n", error_message(retval)));			return False;		}		retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0);		if (retval) {			DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));			return False;		}	}	data_blob_free(&session_key_krb5);	ZERO_STRUCT(reply);	reply.type = SPNEGO_NEG_TOKEN_INIT;	reply.negTokenInit.mechTypes = my_mechs;	reply.negTokenInit.reqFlags = 0;	reply.negTokenInit.mechToken = tkt;	reply.negTokenInit.mechListMIC = data_blob(NULL, 0);	len = write_spnego_data(&to_server, &reply);	data_blob_free(&tkt);	if (len == -1) {		DEBUG(1, ("Could not write SPNEGO data blob\n"));		return False;	}	reply_base64 = base64_encode_data_blob(to_server);	x_fprintf(x_stdout, "KK %s *\n", reply_base64);	SAFE_FREE(reply_base64);	data_blob_free(&to_server);	DEBUG(10, ("sent GSS-SPNEGO KERBEROS5 negTokenInit\n"));	return True;}static void manage_client_krb5_targ(SPNEGO_DATA spnego){	switch (spnego.negTokenTarg.negResult) {	case SPNEGO_ACCEPT_INCOMPLETE:		DEBUG(1, ("Got a Kerberos negTokenTarg with ACCEPT_INCOMPLETE\n"));		x_fprintf(x_stdout, "BH\n");		break;	case SPNEGO_ACCEPT_COMPLETED:		DEBUG(10, ("Accept completed\n"));		x_fprintf(x_stdout, "AF\n");		break;	case SPNEGO_REJECT:		DEBUG(10, ("Rejected\n"));		x_fprintf(x_stdout, "NA\n");		break;	default:		DEBUG(1, ("Got an invalid negTokenTarg\n"));		x_fprintf(x_stdout, "AF\n");	}}#endifstatic void manage_gss_spnego_client_request(enum stdio_helper_mode stdio_helper_mode, 					     char *buf, int length) {	DATA_BLOB request;	SPNEGO_DATA spnego;	ssize_t len;	if (strlen(buf) <= 3) {		DEBUG(1, ("SPNEGO query [%s] too short\n", buf));		x_fprintf(x_stdout, "BH\n");		return;	}	request = base64_decode_data_blob(buf+3);	if (strncmp(buf, "PW ", 3) == 0) {		/* We asked for a password and obviously got it :-) */		opt_password = SMB_STRNDUP((const char *)request.data, request.length);				if (opt_password == NULL) {			DEBUG(1, ("Out of memory\n"));			x_fprintf(x_stdout, "BH\n");			data_blob_free(&request);			return;		}		x_fprintf(x_stdout, "OK\n");		data_blob_free(&request);		return;	}	if ( (strncmp(buf, "TT ", 3) != 0) &&	     (strncmp(buf, "AF ", 3) != 0) &&	     (strncmp(buf, "NA ", 3) != 0) ) {		DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));		x_fprintf(x_stdout, "BH\n");		data_blob_free(&request);		return;	}	/* So we got a server challenge to generate a SPNEGO           client-to-server request... */	len = read_spnego_data(request, &spnego);	data_blob_free(&request);	if (len == -1) {		DEBUG(1, ("Could not read SPNEGO data for [%s]\n", buf));		x_fprintf(x_stdout, "BH\n");		return;	}	if (spnego.type == SPNEGO_NEG_TOKEN_INIT) {		/* The server offers a list of mechanisms */		const char **mechType = (const char **)spnego.negTokenInit.mechTypes;		while (*mechType != NULL) {#ifdef HAVE_KRB5			if ( (strcmp(*mechType, OID_KERBEROS5_OLD) == 0) ||			     (strcmp(*mechType, OID_KERBEROS5) == 0) ) {				if (manage_client_krb5_init(spnego))					goto out;			}#endif			if (strcmp(*mechType, OID_NTLMSSP) == 0) {				if (manage_client_ntlmssp_init(spnego))					goto out;			}			mechType++;		}		DEBUG(1, ("Server offered no compatible mechanism\n"));		x_fprintf(x_stdout, "BH\n");		return;	}	if (spnego.type == SPNEGO_NEG_TOKEN_TARG) {		if (spnego.negTokenTarg.supportedMech == NULL) {			/* On accept/reject Windows does not send the                           mechanism anymore. Handle that here and                           shut down the mechanisms. */			switch (spnego.negTokenTarg.negResult) {			case SPNEGO_ACCEPT_COMPLETED:				x_fprintf(x_stdout, "AF\n");				break;			case SPNEGO_REJECT:				x_fprintf(x_stdout, "NA\n");				break;			default:				DEBUG(1, ("Got a negTokenTarg with no mech and an "					  "unknown negResult: %d\n",					  spnego.negTokenTarg.negResult));				x_fprintf(x_stdout, "BH\n");			}			ntlmssp_end(&client_ntlmssp_state);			goto out;		}		if (strcmp(spnego.negTokenTarg.supportedMech,			   OID_NTLMSSP) == 0) {			manage_client_ntlmssp_targ(spnego);			goto out;		}#if HAVE_KRB5		if (strcmp(spnego.negTokenTarg.supportedMech,			   OID_KERBEROS5_OLD) == 0) {			manage_client_krb5_targ(spnego);			goto out;		}#endif	}	DEBUG(1, ("Got an SPNEGO token I could not handle [%s]!\n", buf));	x_fprintf(x_stdout, "BH\n");	return; out:	free_spnego_data(&spnego);	return;}static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, 					 char *buf, int length) {	char *request, *parameter;		static DATA_BLOB challenge;	static DATA_BLOB lm_response;	static DATA_BLOB nt_response;	static char *full_username;	static char *username;	static char *domain;	static char *plaintext_password;	static BOOL ntlm_server_1_user_session_key;	static BOOL ntlm_server_1_lm_session_key;		if (strequal(buf, ".")) {		if (!full_username && !username) {				x_fprintf(x_stdout, "Error: No username supplied!\n");		} else if (plaintext_password) {			/* handle this request as plaintext */			if (!full_username) {				if (asprintf(&full_username, "%s%c%s", domain, winbind_separator(), username) == -1) {

⌨️ 快捷键说明

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