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 + -
显示快捷键?