/* * Test activating the IWbemLevel1Login interface asynchronously. */ static void torture_wbem_login_async_cont(struct composite_context *ctx) { struct composite_context *c = NULL; BOOL *pRet = NULL; struct IUnknown **mqi = NULL; NTSTATUS status; /* retrieve the parent composite context */ c = talloc_get_type(ctx->async.private_data, struct composite_context); if (!composite_is_ok(c)) return; pRet = (BOOL *)c->private_data; status = dcom_activate_recv(ctx, c, &mqi); *pRet = NT_STATUS_IS_OK(status); talloc_report_full(c, stdout); if (*pRet) { /* * Clean up by releasing the IUnknown interface on the remote server * and also by releasing our allocated interface pointer. */ IUnknown_Release(mqi[0], c); /* really synchronous but eh */ talloc_free(mqi); } composite_done(c); }
/* Receive a bind reply from the transport */ static void dcerpc_bind_recv_handler(struct rpc_request *req, DATA_BLOB *raw_packet, struct ncacn_packet *pkt) { struct composite_context *c; struct dcerpc_connection *conn; c = talloc_get_type(req->async.private_data, struct composite_context); if (pkt->ptype == DCERPC_PKT_BIND_NAK) { DEBUG(2,("dcerpc: bind_nak reason %d\n", pkt->u.bind_nak.reject_reason)); composite_error(c, dcerpc_map_reason(pkt->u.bind_nak. reject_reason)); return; } if ((pkt->ptype != DCERPC_PKT_BIND_ACK) || (pkt->u.bind_ack.num_results == 0) || (pkt->u.bind_ack.ctx_list[0].result != 0)) { composite_error(c, NT_STATUS_NET_WRITE_FAULT); return; } conn = req->p->conn; conn->srv_max_xmit_frag = pkt->u.bind_ack.max_xmit_frag; conn->srv_max_recv_frag = pkt->u.bind_ack.max_recv_frag; if ((req->p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) && (pkt->pfc_flags & DCERPC_PFC_FLAG_CONC_MPX)) { conn->flags |= DCERPC_CONCURRENT_MULTIPLEX; } if ((req->p->binding->flags & DCERPC_HEADER_SIGNING) && (pkt->pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN)) { conn->flags |= DCERPC_HEADER_SIGNING; } /* the bind_ack might contain a reply set of credentials */ if (conn->security_state.auth_info && pkt->u.bind_ack.auth_info.length) { enum ndr_err_code ndr_err; ndr_err = ndr_pull_struct_blob( &pkt->u.bind_ack.auth_info, conn, NULL, conn->security_state.auth_info, (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { c->status = ndr_map_error2ntstatus(ndr_err); if (!composite_is_ok(c)) return; } } req->p->assoc_group_id = pkt->u.bind_ack.assoc_group_id; composite_done(c); }
static struct composite_context *wreplsrv_pull_table_send(TALLOC_CTX *mem_ctx, struct wreplsrv_pull_table_io *io) { struct composite_context *c = NULL; struct wreplsrv_service *service = io->in.partner->service; struct wreplsrv_pull_table_state *state = NULL; c = talloc_zero(mem_ctx, struct composite_context); if (!c) goto failed; state = talloc_zero(c, struct wreplsrv_pull_table_state); if (!state) goto failed; state->c = c; state->io = io; c->state = COMPOSITE_STATE_IN_PROGRESS; c->event_ctx = service->task->event_ctx; c->private_data = state; if (io->in.num_owners) { struct wrepl_wins_owner *partners; uint32_t i; partners = talloc_array(state, struct wrepl_wins_owner, io->in.num_owners); if (composite_nomem(partners, c)) goto failed; for (i=0; i < io->in.num_owners; i++) { partners[i] = io->in.owners[i]; partners[i].address = talloc_strdup(partners, io->in.owners[i].address); if (composite_nomem(partners[i].address, c)) goto failed; } state->table_io.out.num_partners = io->in.num_owners; state->table_io.out.partners = partners; state->stage = WREPLSRV_PULL_TABLE_STAGE_DONE; composite_done(c); return c; } state->stage = WREPLSRV_PULL_TABLE_STAGE_WAIT_CONNECTION; state->creq = wreplsrv_out_connect_send(io->in.partner, WINSREPL_PARTNER_PULL, NULL); if (!state->creq) goto failed; state->creq->async.fn = wreplsrv_pull_table_handler_creq; state->creq->async.private_data = state; return c; failed: talloc_free(c); return NULL; }
_PUBLIC_ void composite_error(struct composite_context *ctx, NTSTATUS status) { /* you are allowed to pass NT_STATUS_OK to composite_error(), in which case it is equivalent to composite_done() */ if (NT_STATUS_IS_OK(status)) { composite_done(ctx); return; } if (!ctx->used_wait && !ctx->async.fn) { tevent_add_timer(ctx->event_ctx, ctx, timeval_zero(), composite_trigger, ctx); } ctx->status = status; ctx->state = COMPOSITE_STATE_ERROR; if (ctx->async.fn != NULL) { ctx->async.fn(ctx); } }
/* 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->ev); 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 an alter reply from the transport */ static void dcerpc_alter_recv_handler(struct rpc_request *req, DATA_BLOB *raw_packet, struct ncacn_packet *pkt) { struct composite_context *c; struct dcerpc_pipe *recv_pipe; c = talloc_get_type(req->async.private_data, struct composite_context); recv_pipe = talloc_get_type(c->private_data, struct dcerpc_pipe); if (pkt->ptype == DCERPC_PKT_ALTER_RESP && pkt->u.alter_resp.num_results == 1 && pkt->u.alter_resp.ctx_list[0].result != 0) { DEBUG(2,("dcerpc: alter_resp failed - reason %d\n", pkt->u.alter_resp.ctx_list[0].reason)); composite_error(c, dcerpc_map_reason(pkt->u.alter_resp.ctx_list[0].reason)); return; } if (pkt->ptype != DCERPC_PKT_ALTER_RESP || pkt->u.alter_resp.num_results == 0 || pkt->u.alter_resp.ctx_list[0].result != 0) { composite_error(c, NT_STATUS_NET_WRITE_FAULT); return; } /* the alter_resp might contain a reply set of credentials */ if (recv_pipe->conn->security_state.auth_info && pkt->u.alter_resp.auth_info.length) { enum ndr_err_code ndr_err; ndr_err = ndr_pull_struct_blob( &pkt->u.alter_resp.auth_info, recv_pipe, NULL, recv_pipe->conn->security_state.auth_info, (ndr_pull_flags_fn_t)ndr_pull_dcerpc_auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { c->status = ndr_map_error2ntstatus(ndr_err); if (!composite_is_ok(c)) return; } } composite_done(c); }
static void init_domain_recv_ldapconn(struct composite_context *ctx) { struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); state->ctx->status = ldap_connect_recv(ctx); if (NT_STATUS_IS_OK(state->ctx->status)) { state->domain->ldap_conn->host = talloc_strdup(state->domain->ldap_conn, state->domain->dc_name); state->ctx->status = ldap_bind_sasl(state->domain->ldap_conn, state->domain->schannel_creds); DEBUG(0, ("ldap_bind returned %s\n", nt_errstr(state->ctx->status))); } composite_done(state->ctx); }
static void unbecomeDC_drsuapi_remove_ds_server_recv(struct rpc_request *req) { struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data, struct libnet_UnbecomeDC_state); struct composite_context *c = s->creq; struct drsuapi_DsRemoveDSServer *r = &s->drsuapi.rm_ds_srv_r; c->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(c)) return; if (!W_ERROR_IS_OK(r->out.result)) { composite_error(c, werror_to_ntstatus(r->out.result)); return; } if (*r->out.level_out != 1) { composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } composite_done(c); }
/* Recv the SAMR details (SamrConnect and SamrOpenDomain handle) and * open an LDAP connection */ static void init_domain_recv_samr(struct composite_context *ctx) { struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); state->ctx->status = wb_connect_samr_recv( ctx, state->domain, &state->domain->libnet_ctx->samr.pipe, &state->domain->libnet_ctx->samr.connect_handle, &state->domain->libnet_ctx->samr.handle); if (!composite_is_ok(state->ctx)) return; talloc_reparent(state, state->domain->libnet_ctx->samr.pipe, state->domain->samr_binding); state->domain->libnet_ctx->samr.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; state->domain->libnet_ctx->samr.name = state->domain->info->name; state->domain->libnet_ctx->samr.sid = dom_sid_dup( state->domain->libnet_ctx, state->domain->info->sid); composite_done(state->ctx); }
static void unbecomeDC_drsuapi_remove_ds_server_recv(struct tevent_req *subreq) { struct libnet_UnbecomeDC_state *s = tevent_req_callback_data(subreq, struct libnet_UnbecomeDC_state); struct composite_context *c = s->creq; struct drsuapi_DsRemoveDSServer *r = &s->drsuapi.rm_ds_srv_r; c->status = dcerpc_drsuapi_DsRemoveDSServer_r_recv(subreq, s); TALLOC_FREE(subreq); if (!composite_is_ok(c)) return; if (!W_ERROR_IS_OK(r->out.result)) { composite_error(c, werror_to_ntstatus(r->out.result)); return; } if (*r->out.level_out != 1) { composite_error(c, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } composite_done(c); }
static struct composite_context *wreplsrv_out_connect_send(struct wreplsrv_partner *partner, enum winsrepl_partner_type type, struct wreplsrv_out_connection *wreplconn) { struct composite_context *c = NULL; struct wreplsrv_service *service = partner->service; struct wreplsrv_out_connect_state *state = NULL; struct wreplsrv_out_connection **wreplconnp = &wreplconn; bool cached_connection = false; c = talloc_zero(partner, struct composite_context); if (!c) goto failed; state = talloc_zero(c, struct wreplsrv_out_connect_state); if (!state) goto failed; state->c = c; state->type = type; c->state = COMPOSITE_STATE_IN_PROGRESS; c->event_ctx = service->task->event_ctx; c->private_data = state; if (type == WINSREPL_PARTNER_PUSH) { cached_connection = true; wreplconn = partner->push.wreplconn; wreplconnp = &partner->push.wreplconn; } else if (type == WINSREPL_PARTNER_PULL) { cached_connection = true; wreplconn = partner->pull.wreplconn; wreplconnp = &partner->pull.wreplconn; } /* we have a connection already, so use it */ if (wreplconn) { if (wrepl_socket_is_connected(wreplconn->sock)) { state->stage = WREPLSRV_OUT_CONNECT_STAGE_DONE; state->wreplconn= wreplconn; composite_done(c); return c; } else if (!cached_connection) { state->stage = WREPLSRV_OUT_CONNECT_STAGE_DONE; state->wreplconn= NULL; composite_done(c); return c; } else { talloc_free(wreplconn); *wreplconnp = NULL; } } wreplconn = talloc_zero(state, struct wreplsrv_out_connection); if (!wreplconn) goto failed; wreplconn->service = service; wreplconn->partner = partner; wreplconn->sock = wrepl_socket_init(wreplconn, service->task->event_ctx); if (!wreplconn->sock) goto failed; state->stage = WREPLSRV_OUT_CONNECT_STAGE_WAIT_SOCKET; state->wreplconn= wreplconn; state->subreq = wrepl_connect_send(state, service->task->event_ctx, wreplconn->sock, partner->our_address?partner->our_address:wrepl_best_ip(service->task->lp_ctx, partner->address), partner->address); if (!state->subreq) goto failed; tevent_req_set_callback(state->subreq, wreplsrv_out_connect_handler_treq, state); return c; failed: talloc_free(c); return NULL; }
/* handler for completion of a smbcli_request sub-request */ static void request_handler(struct smbcli_request *req) { struct composite_context *c = (struct composite_context *)req->async.private_data; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); struct smbcli_session *session = req->session; DATA_BLOB null_data_blob = data_blob(NULL, 0); NTSTATUS session_key_err, nt_status; struct smbcli_request *check_req = NULL; const char *os = NULL; const char *lanman = NULL; if (req->sign_caller_checks) { req->do_not_free = true; check_req = req; } state->remote_status = smb_raw_sesssetup_recv(req, state, &state->setup); c->status = state->remote_status; state->req = NULL; /* * we only need to check the signature if the * NT_STATUS_OK is returned */ if (!NT_STATUS_IS_OK(state->remote_status)) { talloc_free(check_req); check_req = NULL; } switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: state->io->out.vuid = state->setup.old.out.vuid; /* This doesn't work, as this only happens on old * protocols, where this comparison won't match. */ if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { /* we neet to reset the vuid for a new try */ session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_old(c, session, state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; } } } os = state->setup.old.out.os; lanman = state->setup.old.out.lanman; break; case RAW_SESSSETUP_NT1: state->io->out.vuid = state->setup.nt1.out.vuid; if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { /* we need to reset the vuid for a new try */ session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_nt1(c, session, state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; } } } os = state->setup.nt1.out.os; lanman = state->setup.nt1.out.lanman; break; case RAW_SESSSETUP_SPNEGO: state->io->out.vuid = state->setup.spnego.out.vuid; if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { const char *principal; /* we need to reset the vuid for a new try */ session->vuid = 0; principal = gensec_get_target_principal(session->gensec); if (principal == NULL) { const char *hostname = gensec_get_target_hostname(session->gensec); const char *service = gensec_get_target_service(session->gensec); if (hostname != NULL && service != NULL) { principal = talloc_asprintf(state, "%s/%s", service, hostname); } } if (cli_credentials_failed_kerberos_login(state->io->in.credentials, principal, &state->logon_retries) || cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_spnego(c, session, state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; } } } if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(c->status)) { break; } if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* The status value here, from the earlier pass at GENSEC is * vital to the security of the system. Even if the other end * accepts, if GENSEC claims 'MORE_PROCESSING_REQUIRED' then * you must keep feeding it blobs, or else the remote * host/attacker might avoid mutal authentication * requirements */ state->gensec_status = gensec_update(session->gensec, state, c->event_ctx, state->setup.spnego.out.secblob, &state->setup.spnego.in.secblob); c->status = state->gensec_status; if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(c->status)) { break; } } else { state->setup.spnego.in.secblob = data_blob(NULL, 0); } if (NT_STATUS_IS_OK(state->remote_status)) { DATA_BLOB session_key; if (state->setup.spnego.in.secblob.length) { c->status = NT_STATUS_INTERNAL_ERROR; break; } session_key_err = gensec_session_key(session->gensec, session, &session_key); if (NT_STATUS_IS_OK(session_key_err)) { smb1cli_conn_activate_signing(session->transport->conn, session_key, null_data_blob); } c->status = smb1cli_session_set_session_key(session->smbXcli, session_key); data_blob_free(&session_key); if (!NT_STATUS_IS_OK(c->status)) { break; } } if (state->setup.spnego.in.secblob.length) { /* * set the session->vuid value only for calling * smb_raw_sesssetup_send() */ uint16_t vuid = session->vuid; session->vuid = state->io->out.vuid; state->req = smb_raw_sesssetup_send(session, &state->setup); session->vuid = vuid; if (state->req && !smb1cli_conn_signing_is_active(state->req->transport->conn)) { state->req->sign_caller_checks = true; } composite_continue_smb(c, state->req, request_handler, c); return; } os = state->setup.spnego.out.os; lanman = state->setup.spnego.out.lanman; break; case RAW_SESSSETUP_SMB2: c->status = NT_STATUS_INTERNAL_ERROR; break; } if (check_req) { bool ok; check_req->sign_caller_checks = false; ok = smb1cli_conn_check_signing(check_req->transport->conn, check_req->in.buffer, 1); if (!ok) { c->status = NT_STATUS_ACCESS_DENIED; } talloc_free(check_req); check_req = NULL; } if (!NT_STATUS_IS_OK(c->status)) { composite_error(c, c->status); return; } if (os) { session->os = talloc_strdup(session, os); if (composite_nomem(session->os, c)) return; } else { session->os = NULL; } if (lanman) { session->lanman = talloc_strdup(session, lanman); if (composite_nomem(session->lanman, c)) return; } else { session->lanman = NULL; } composite_done(c); }
/* handler for completion of a smbcli_request sub-request */ static void request_handler(struct smbcli_request *req) { struct composite_context *c = (struct composite_context *)req->async.private_data; struct sesssetup_state *state = talloc_get_type(c->private_data, struct sesssetup_state); struct smbcli_session *session = req->session; DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB null_data_blob = data_blob(NULL, 0); NTSTATUS session_key_err, nt_status; struct smbcli_request *check_req = NULL; const char *os = NULL; const char *lanman = NULL; if (req->sign_caller_checks) { req->do_not_free = true; check_req = req; } state->remote_status = smb_raw_sesssetup_recv(req, state, &state->setup); c->status = state->remote_status; state->req = NULL; /* * we only need to check the signature if the * NT_STATUS_OK is returned */ if (!NT_STATUS_IS_OK(state->remote_status)) { talloc_free(check_req); check_req = NULL; } switch (state->setup.old.level) { case RAW_SESSSETUP_OLD: state->io->out.vuid = state->setup.old.out.vuid; /* This doesn't work, as this only happens on old * protocols, where this comparison won't match. */ if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { /* we neet to reset the vuid for a new try */ session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_old(c, session, state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; } } } os = state->setup.old.out.os; lanman = state->setup.old.out.lanman; break; case RAW_SESSSETUP_NT1: state->io->out.vuid = state->setup.nt1.out.vuid; if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { /* we neet to reset the vuid for a new try */ session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_nt1(c, session, state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; } } } os = state->setup.nt1.out.os; lanman = state->setup.nt1.out.lanman; break; case RAW_SESSSETUP_SPNEGO: state->io->out.vuid = state->setup.spnego.out.vuid; if (NT_STATUS_EQUAL(c->status, NT_STATUS_LOGON_FAILURE)) { /* we need to reset the vuid for a new try */ session->vuid = 0; if (cli_credentials_wrong_password(state->io->in.credentials)) { nt_status = session_setup_spnego(c, session, state->io, &state->req); if (NT_STATUS_IS_OK(nt_status)) { talloc_free(check_req); c->status = nt_status; composite_continue_smb(c, state->req, request_handler, c); return; } } } if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(c->status)) { break; } if (NT_STATUS_EQUAL(state->gensec_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { /* The status value here, from the earlier pass at GENSEC is * vital to the security of the system. Even if the other end * accepts, if GENSEC claims 'MORE_PROCESSING_REQUIRED' then * you must keep feeding it blobs, or else the remote * host/attacker might avoid mutal authentication * requirements */ state->gensec_status = gensec_update(session->gensec, state, state->setup.spnego.out.secblob, &state->setup.spnego.in.secblob); c->status = state->gensec_status; if (!NT_STATUS_EQUAL(c->status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(c->status)) { break; } } else { state->setup.spnego.in.secblob = data_blob(NULL, 0); } if (NT_STATUS_IS_OK(state->remote_status)) { if (state->setup.spnego.in.secblob.length) { c->status = NT_STATUS_INTERNAL_ERROR; break; } session_key_err = gensec_session_key(session->gensec, session, &session->user_session_key); if (NT_STATUS_IS_OK(session_key_err)) { smbcli_transport_simple_set_signing(session->transport, session->user_session_key, null_data_blob); } } if (state->setup.spnego.in.secblob.length) { /* * set the session->vuid value only for calling * smb_raw_sesssetup_send() */ uint16_t vuid = session->vuid; session->vuid = state->io->out.vuid; state->req = smb_raw_sesssetup_send(session, &state->setup); session->vuid = vuid; if (state->req) { state->req->sign_caller_checks = true; } composite_continue_smb(c, state->req, request_handler, c); return; } os = state->setup.spnego.out.os; lanman = state->setup.spnego.out.lanman; break; case RAW_SESSSETUP_SMB2: c->status = NT_STATUS_INTERNAL_ERROR; break; } if (check_req) { check_req->sign_caller_checks = false; if (!smbcli_request_check_sign_mac(check_req)) { c->status = NT_STATUS_ACCESS_DENIED; } talloc_free(check_req); check_req = NULL; } /* enforce the local signing required flag */ if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) { if (!session->transport->negotiate.sign_info.doing_signing && session->transport->negotiate.sign_info.mandatory_signing) { DEBUG(0, ("SMB signing required, but server does not support it\n")); c->status = NT_STATUS_ACCESS_DENIED; } } if (!NT_STATUS_IS_OK(c->status)) { composite_error(c, c->status); return; } if (os) { session->os = talloc_strdup(session, os); if (composite_nomem(session->os, c)) return; } else { session->os = NULL; } if (lanman) { session->lanman = talloc_strdup(session, lanman); if (composite_nomem(session->lanman, c)) return; } else { session->lanman = NULL; } composite_done(c); }