ntlm_auth.c

来自「samba最新软件」· C语言 代码 · 共 1,160 行 · 第 1/3 页

C
1,160
字号
	char *out_base64 = NULL;	const char *reply_arg = NULL;	struct gensec_ntlm_state {		struct gensec_security *gensec_state;		const char *set_password;	};	struct gensec_ntlm_state *state;	struct event_context *ev;	struct messaging_context *msg;	NTSTATUS nt_status;	bool first = false;	const char *reply_code;	struct cli_credentials *creds;	static char *want_feature_list = NULL;	static DATA_BLOB session_key;	TALLOC_CTX *mem_ctx;	if (*private) {		state = (struct gensec_ntlm_state *)*private;	} else {		state = talloc_zero(NULL, struct gensec_ntlm_state);		if (!state) {			mux_printf(mux_id, "BH No Memory\n");			exit(1);		}		*private = state;		if (opt_password) {			state->set_password = opt_password;		}	}		if (strlen(buf) < 2) {		DEBUG(1, ("query [%s] invalid", buf));		mux_printf(mux_id, "BH Query invalid\n");		return;	}	if (strlen(buf) > 3) {		if(strncmp(buf, "SF ", 3) == 0) {			DEBUG(10, ("Setting flags to negotiate\n"));			talloc_free(want_feature_list);			want_feature_list = talloc_strndup(state, buf+3, strlen(buf)-3);			mux_printf(mux_id, "OK\n");			return;		}		in = base64_decode_data_blob(NULL, buf + 3);	} else {		in = data_blob(NULL, 0);	}	if (strncmp(buf, "YR", 2) == 0) {		if (state->gensec_state) {			talloc_free(state->gensec_state);			state->gensec_state = NULL;		}	} else if ( (strncmp(buf, "OK", 2) == 0)) {		/* Just return BH, like ntlm_auth from Samba 3 does. */		mux_printf(mux_id, "BH Command expected\n");		data_blob_free(&in);		return;	} else if ( (strncmp(buf, "TT ", 3) != 0) &&		    (strncmp(buf, "KK ", 3) != 0) &&		    (strncmp(buf, "AF ", 3) != 0) &&		    (strncmp(buf, "NA ", 3) != 0) && 		    (strncmp(buf, "UG", 2) != 0) && 		    (strncmp(buf, "PW ", 3) != 0) &&		    (strncmp(buf, "GK", 2) != 0) &&		    (strncmp(buf, "GF", 2) != 0)) {		DEBUG(1, ("SPNEGO request [%s] invalid\n", buf));		mux_printf(mux_id, "BH SPNEGO request invalid\n");		data_blob_free(&in);		return;	}	ev = event_context_init(state);	if (!ev) {		exit(1);	}	/* setup gensec */	if (!(state->gensec_state)) {		switch (stdio_helper_mode) {		case GSS_SPNEGO_CLIENT:		case NTLMSSP_CLIENT_1:			/* setup the client side */			nt_status = gensec_client_start(NULL, &state->gensec_state, ev, lp_ctx);			if (!NT_STATUS_IS_OK(nt_status)) {				exit(1);			}			break;		case GSS_SPNEGO_SERVER:		case SQUID_2_5_NTLMSSP:			msg = messaging_client_init(state, lp_messaging_path(state, lp_ctx), 						    lp_iconv_convenience(lp_ctx), ev);			if (!msg) {				exit(1);			}			if (!NT_STATUS_IS_OK(gensec_server_start(state, ev, lp_ctx, msg, &state->gensec_state))) {				exit(1);			}			break;		default:			abort();		}		creds = cli_credentials_init(state->gensec_state);		cli_credentials_set_conf(creds, lp_ctx);		if (opt_username) {			cli_credentials_set_username(creds, opt_username, CRED_SPECIFIED);		}		if (opt_domain) {			cli_credentials_set_domain(creds, opt_domain, CRED_SPECIFIED);		}		if (state->set_password) {			cli_credentials_set_password(creds, state->set_password, CRED_SPECIFIED);		} else {			cli_credentials_set_password_callback(creds, get_password);			creds->priv_data = (void*)mux_id;		}		if (opt_workstation) {			cli_credentials_set_workstation(creds, opt_workstation, CRED_SPECIFIED);		}				switch (stdio_helper_mode) {		case GSS_SPNEGO_SERVER:		case SQUID_2_5_NTLMSSP:			cli_credentials_set_machine_account(creds, lp_ctx);			break;		default:			break;		}		gensec_set_credentials(state->gensec_state, creds);		gensec_want_feature_list(state->gensec_state, want_feature_list);		switch (stdio_helper_mode) {		case GSS_SPNEGO_CLIENT:		case GSS_SPNEGO_SERVER:			nt_status = gensec_start_mech_by_oid(state->gensec_state, GENSEC_OID_SPNEGO);			if (!in.length) {				first = true;			}			break;		case NTLMSSP_CLIENT_1:			if (!in.length) {				first = true;			}			/* fall through */		case SQUID_2_5_NTLMSSP:			nt_status = gensec_start_mech_by_oid(state->gensec_state, GENSEC_OID_NTLMSSP);			break;		default:			abort();		}		if (!NT_STATUS_IS_OK(nt_status)) {			DEBUG(1, ("GENSEC mech failed to start: %s\n", nt_errstr(nt_status)));			mux_printf(mux_id, "BH GENSEC mech failed to start\n");			return;		}	}	/* update */	mem_ctx = talloc_named(NULL, 0, "manage_gensec_request internal mem_ctx");		if (strncmp(buf, "PW ", 3) == 0) {		state->set_password = talloc_strndup(state,						     (const char *)in.data, 						     in.length);				cli_credentials_set_password(gensec_get_credentials(state->gensec_state),					     state->set_password,					     CRED_SPECIFIED);		mux_printf(mux_id, "OK\n");		data_blob_free(&in);		talloc_free(mem_ctx);		return;	}	if (strncmp(buf, "UG", 2) == 0) {		int i;		char *grouplist = NULL;		struct auth_session_info *session_info;		nt_status = gensec_session_info(state->gensec_state, &session_info); 		if (!NT_STATUS_IS_OK(nt_status)) {			DEBUG(1, ("gensec_session_info failed: %s\n", nt_errstr(nt_status)));			mux_printf(mux_id, "BH %s\n", nt_errstr(nt_status));			data_blob_free(&in);			talloc_free(mem_ctx);			return;		}				/* get the string onto the context */		grouplist = talloc_strdup(mem_ctx, "");				for (i=0; i<session_info->security_token->num_sids; i++) {			struct security_token *token = session_info->security_token; 			const char *sidstr = dom_sid_string(session_info, 							    token->sids[i]);			grouplist = talloc_asprintf_append_buffer(grouplist, "%s,", sidstr);		}		mux_printf(mux_id, "GL %s\n", grouplist);		talloc_free(session_info);		data_blob_free(&in);		talloc_free(mem_ctx);		return;	}	if (strncmp(buf, "GK", 2) == 0) {		char *base64_key;		DEBUG(10, ("Requested session key\n"));		nt_status = gensec_session_key(state->gensec_state, &session_key);		if(!NT_STATUS_IS_OK(nt_status)) {			DEBUG(1, ("gensec_session_key failed: %s\n", nt_errstr(nt_status)));			mux_printf(mux_id, "BH No session key\n");			talloc_free(mem_ctx);			return;		} else {			base64_key = base64_encode_data_blob(state, session_key);			mux_printf(mux_id, "GK %s\n", base64_key);			talloc_free(base64_key);		}		talloc_free(mem_ctx);		return;	}	if (strncmp(buf, "GF", 2) == 0) {		struct gensec_ntlmssp_state *gensec_ntlmssp_state;		uint32_t neg_flags;		gensec_ntlmssp_state = talloc_get_type(state->gensec_state->private_data, 				struct gensec_ntlmssp_state);		neg_flags = gensec_ntlmssp_state->neg_flags;		DEBUG(10, ("Requested negotiated feature flags\n"));		mux_printf(mux_id, "GF 0x%08x\n", neg_flags);		return;	}	nt_status = gensec_update(state->gensec_state, mem_ctx, in, &out);		/* don't leak 'bad password'/'no such user' info to the network client */	nt_status = auth_nt_status_squash(nt_status);	if (out.length) {		out_base64 = base64_encode_data_blob(mem_ctx, out);	} else {		out_base64 = NULL;	}	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {		reply_arg = "*";		if (first) {			reply_code = "YR";		} else if (state->gensec_state->gensec_role == GENSEC_CLIENT) { 			reply_code = "KK";		} else if (state->gensec_state->gensec_role == GENSEC_SERVER) { 			reply_code = "TT";		} else {			abort();		}	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) {		reply_code = "BH NT_STATUS_ACCESS_DENIED";		reply_arg = nt_errstr(nt_status);		DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));	} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_UNSUCCESSFUL)) {		reply_code = "BH NT_STATUS_UNSUCCESSFUL";		reply_arg = nt_errstr(nt_status);		DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));	} else if (!NT_STATUS_IS_OK(nt_status)) {		reply_code = "NA";		reply_arg = nt_errstr(nt_status);		DEBUG(1, ("GENSEC login failed: %s\n", nt_errstr(nt_status)));	} else if /* OK */ (state->gensec_state->gensec_role == GENSEC_SERVER) {		struct auth_session_info *session_info;		nt_status = gensec_session_info(state->gensec_state, &session_info);		if (!NT_STATUS_IS_OK(nt_status)) {			reply_code = "BH Failed to retrive session info";			reply_arg = nt_errstr(nt_status);			DEBUG(1, ("GENSEC failed to retreive the session info: %s\n", nt_errstr(nt_status)));		} else {			reply_code = "AF";			reply_arg = talloc_asprintf(state->gensec_state, 						    "%s%s%s", session_info->server_info->domain_name, 						    lp_winbind_separator(lp_ctx), session_info->server_info->account_name);			talloc_free(session_info);		}	} else if (state->gensec_state->gensec_role == GENSEC_CLIENT) {		reply_code = "AF";		reply_arg = out_base64;	} else {		abort();	}	switch (stdio_helper_mode) {	case GSS_SPNEGO_SERVER:		mux_printf(mux_id, "%s %s %s\n", reply_code, 			  out_base64 ? out_base64 : "*", 			  reply_arg ? reply_arg : "*");		break;	default:		if (out_base64) {			mux_printf(mux_id, "%s %s\n", reply_code, out_base64);		} else if (reply_arg) {			mux_printf(mux_id, "%s %s\n", reply_code, reply_arg);		} else {			mux_printf(mux_id, "%s\n", reply_code);		}	}	talloc_free(mem_ctx);	return;}static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mode, 					 struct loadparm_context *lp_ctx,					 char *buf, int length, void **private,					 unsigned int mux_id, void **private2) {	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) {				mux_printf(mux_id, "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, *lp_winbind_separator(lp_ctx), username) == -1) {					mux_printf(mux_id, "Error: Out of memory in asprintf!\n.\n");					return;				}			}			if (check_plaintext_auth(full_username, plaintext_password, false)) {				mux_printf(mux_id, "Authenticated: Yes\n");			} else {				mux_printf(mux_id, "Authenticated: No\n");			}		} else if (!lm_response.data && !nt_response.data) {			mux_printf(mux_id, "Error: No password supplied!\n");		} else if (!challenge.data) {				mux_printf(mux_id, "Error: No lanman-challenge supplied!\n");		} else {			char *error_string = NULL;			DATA_BLOB lm_key;			DATA_BLOB user_session_key;			uint32_t flags = 0;			if (full_username && !username) {				fstring fstr_user;				fstring fstr_domain;								if (!parse_ntlm_auth_domain_user(full_username, fstr_user, fstr_domain, 								 *lp_winbind_separator(lp_ctx))) {					/* username might be 'tainted', don't print into our new-line deleimianted stream */					mux_printf(mux_id, "Error: Could not parse into domain and username\n");				}				SAFE_FREE(username);				SAFE_FREE(domain);				username = smb_xstrdup(fstr_user);				domain = smb_xstrdup(fstr_domain);			}			if (!domain) {				domain = smb_xstrdup(lp_workgroup(lp_ctx));			}			if (ntlm_server_1_lm_session_key) 

⌨️ 快捷键说明

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