sesssetup.c

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

C
526
字号
		set_user_session_key(session, &session_key);				data_blob_free(&session_key);	} else if (session->options.plaintext_auth) {		const char *password = cli_credentials_get_password(io->in.credentials);		state->setup.nt1.in.password1 = data_blob_talloc(state, password, strlen(password));		state->setup.nt1.in.password2 = data_blob(NULL, 0);	} else {		/* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */		return NT_STATUS_INVALID_PARAMETER;	}	*req = smb_raw_sesssetup_send(session, &state->setup);	if (!*req) {		return NT_STATUS_NO_MEMORY;	}	return (*req)->status;}/*  old style session setup (pre NT1 protocol level)*/static NTSTATUS session_setup_old(struct composite_context *c,				  struct smbcli_session *session, 				  struct smb_composite_sesssetup *io,				  struct smbcli_request **req) {	NTSTATUS nt_status;	struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);	const char *password = cli_credentials_get_password(io->in.credentials);	DATA_BLOB names_blob = NTLMv2_generate_names_blob(state, lp_iconv_convenience(global_loadparm), session->transport->socket->hostname, lp_workgroup(global_loadparm));	DATA_BLOB session_key;	int flags = 0;	if (session->options.lanman_auth) {		flags |= CLI_CRED_LANMAN_AUTH;	}	if (session->options.ntlmv2_auth) {		flags |= CLI_CRED_NTLMv2_AUTH;	}	state->setup.old.level      = RAW_SESSSETUP_OLD;	state->setup.old.in.bufsize = session->transport->options.max_xmit;	state->setup.old.in.mpx_max = session->transport->options.max_mux;	state->setup.old.in.vc_num  = 1;	state->setup.old.in.sesskey = io->in.sesskey;	state->setup.old.in.os      = "Unix";	state->setup.old.in.lanman  = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING);	cli_credentials_get_ntlm_username_domain(io->in.credentials, state, 						 &state->setup.old.in.user,						 &state->setup.old.in.domain);		if (session->transport->negotiate.sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {		nt_status = cli_credentials_get_ntlm_response(io->in.credentials, state, 							      &flags, 							      session->transport->negotiate.secblob, 							      names_blob,							      &state->setup.old.in.password,							      NULL,							      NULL, &session_key);		NT_STATUS_NOT_OK_RETURN(nt_status);		set_user_session_key(session, &session_key);				data_blob_free(&session_key);	} else if (session->options.plaintext_auth) {		state->setup.old.in.password = data_blob_talloc(state, password, strlen(password));	} else {		/* could match windows client and return 'cannot logon from this workstation', but it just confuses everybody */		return NT_STATUS_INVALID_PARAMETER;	}		*req = smb_raw_sesssetup_send(session, &state->setup);	if (!*req) {		return NT_STATUS_NO_MEMORY;	}	return (*req)->status;}/*  Modern, all singing, all dancing extended security (and possibly SPNEGO) request*/static NTSTATUS session_setup_spnego(struct composite_context *c,				     struct smbcli_session *session, 				     struct smb_composite_sesssetup *io,				     struct smbcli_request **req) {	struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state);	NTSTATUS status, session_key_err;	DATA_BLOB session_key = data_blob(NULL, 0);	DATA_BLOB null_data_blob = data_blob(NULL, 0);	const char *chosen_oid = NULL;	state->setup.spnego.level           = RAW_SESSSETUP_SPNEGO;	state->setup.spnego.in.bufsize      = session->transport->options.max_xmit;	state->setup.spnego.in.mpx_max      = session->transport->options.max_mux;	state->setup.spnego.in.vc_num       = 1;	state->setup.spnego.in.sesskey      = io->in.sesskey;	state->setup.spnego.in.capabilities = io->in.capabilities;	state->setup.spnego.in.os           = "Unix";	state->setup.spnego.in.lanman       = talloc_asprintf(state, "Samba %s", SAMBA_VERSION_STRING);	state->setup.spnego.in.workgroup    = io->in.workgroup;	smbcli_temp_set_signing(session->transport);	status = gensec_client_start(session, &session->gensec, c->event_ctx,				     global_loadparm);	if (!NT_STATUS_IS_OK(status)) {		DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status)));		return status;	}	gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);	status = gensec_set_credentials(session->gensec, io->in.credentials);	if (!NT_STATUS_IS_OK(status)) {		DEBUG(1, ("Failed to start set GENSEC client credentials: %s\n", 			  nt_errstr(status)));		return status;	}	status = gensec_set_target_hostname(session->gensec, session->transport->socket->hostname);	if (!NT_STATUS_IS_OK(status)) {		DEBUG(1, ("Failed to start set GENSEC target hostname: %s\n", 			  nt_errstr(status)));		return status;	}	status = gensec_set_target_service(session->gensec, "cifs");	if (!NT_STATUS_IS_OK(status)) {		DEBUG(1, ("Failed to start set GENSEC target service: %s\n", 			  nt_errstr(status)));		return status;	}	if (session->transport->negotiate.secblob.length) {		chosen_oid = GENSEC_OID_SPNEGO;		status = gensec_start_mech_by_oid(session->gensec, chosen_oid);		if (!NT_STATUS_IS_OK(status)) {			DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n",				  gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));			chosen_oid = GENSEC_OID_NTLMSSP;			status = gensec_start_mech_by_oid(session->gensec, chosen_oid);			if (!NT_STATUS_IS_OK(status)) {				DEBUG(1, ("Failed to start set (fallback) GENSEC client mechanism %s: %s\n",					  gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));			return status;			}		}	} else {		/* without a sec blob, means raw NTLMSSP */		chosen_oid = GENSEC_OID_NTLMSSP;		status = gensec_start_mech_by_oid(session->gensec, chosen_oid);		if (!NT_STATUS_IS_OK(status)) {			DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n",				  gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));		}	}	if ((const void *)chosen_oid == (const void *)GENSEC_OID_SPNEGO) {		status = gensec_update(session->gensec, state,				       session->transport->negotiate.secblob,				       &state->setup.spnego.in.secblob);	} else {		status = gensec_update(session->gensec, state,				       data_blob(NULL, 0),				       &state->setup.spnego.in.secblob);	}	if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && 	    !NT_STATUS_IS_OK(status)) {		DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n",			  gensec_get_name_by_oid(chosen_oid), nt_errstr(status)));		return status;	}	state->gensec_status = status;	session_key_err = gensec_session_key(session->gensec, &session_key);	if (NT_STATUS_IS_OK(session_key_err)) {		smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);	}	*req = smb_raw_sesssetup_send(session, &state->setup);	if (!*req) {		return NT_STATUS_NO_MEMORY;	}	return (*req)->status;}/*  composite session setup function that hides the details of all the  different session setup varients, including the multi-pass nature of  the spnego varient*/struct composite_context *smb_composite_sesssetup_send(struct smbcli_session *session, 						       struct smb_composite_sesssetup *io){	struct composite_context *c;	struct sesssetup_state *state;	NTSTATUS status;	c = composite_create(session, session->transport->socket->event.ctx);	if (c == NULL) return NULL;	state = talloc_zero(c, struct sesssetup_state);	if (composite_nomem(state, c)) return c;	c->private_data = state;	state->io = io;	talloc_set_destructor(state, sesssetup_state_destructor);	/* no session setup at all in earliest protocol varients */	if (session->transport->negotiate.protocol < PROTOCOL_LANMAN1) {		ZERO_STRUCT(io->out);		composite_done(c);		return c;	}	/* see what session setup interface we will use */	if (session->transport->negotiate.protocol < PROTOCOL_NT1) {		status = session_setup_old(c, session, io, &state->req);	} else if (!session->transport->options.use_spnego ||		   !(io->in.capabilities & CAP_EXTENDED_SECURITY)) {		status = session_setup_nt1(c, session, io, &state->req);	} else {		status = session_setup_spnego(c, session, io, &state->req);	}	if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || 	    NT_STATUS_IS_OK(status)) {		composite_continue_smb(c, state->req, request_handler, c);			return c;	}	composite_error(c, status);	return c;}/*  receive a composite session setup reply*/NTSTATUS smb_composite_sesssetup_recv(struct composite_context *c){	NTSTATUS status;	status = composite_wait(c);	talloc_free(c);	return status;}/*  sync version of smb_composite_sesssetup */NTSTATUS smb_composite_sesssetup(struct smbcli_session *session, struct smb_composite_sesssetup *io){	struct composite_context *c = smb_composite_sesssetup_send(session, io);	return smb_composite_sesssetup_recv(c);}

⌨️ 快捷键说明

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