static void init_domain_recv_lsa_policy(struct rpc_request *req) { struct init_domain_state *state = talloc_get_type(req->async.private_data, struct init_domain_state); state->ctx->status = dcerpc_ndr_request_recv(req); if ((!NT_STATUS_IS_OK(state->ctx->status) || !NT_STATUS_IS_OK(state->lsa_openpolicy.out.result))) { if (retry_with_schannel(state, state->domain->lsa_binding, init_domain_recv_lsa_pipe)) { return; } } if (!composite_is_ok(state->ctx)) return; state->ctx->status = state->lsa_openpolicy.out.result; if (!composite_is_ok(state->ctx)) return; state->queryinfo.in.handle = state->domain->lsa_policy_handle; state->queryinfo.in.level = LSA_POLICY_INFO_ACCOUNT_DOMAIN; req = dcerpc_lsa_QueryInfoPolicy_send(state->domain->lsa_pipe, state, &state->queryinfo); composite_continue_rpc(state->ctx, req, init_domain_recv_queryinfo, state); }
static void init_domain_recv_lsa_policy(struct tevent_req *subreq) { struct init_domain_state *state = tevent_req_callback_data(subreq, struct init_domain_state); state->ctx->status = dcerpc_lsa_OpenPolicy2_r_recv(subreq, state); TALLOC_FREE(subreq); if ((!NT_STATUS_IS_OK(state->ctx->status) || !NT_STATUS_IS_OK(state->lsa_openpolicy.out.result))) { if (retry_with_schannel(state, state->domain->lsa_binding, &ndr_table_lsarpc, init_domain_recv_lsa_pipe)) { return; } } if (!composite_is_ok(state->ctx)) return; state->ctx->status = state->lsa_openpolicy.out.result; if (!composite_is_ok(state->ctx)) return; state->info = talloc_zero(state->ctx, union lsa_PolicyInformation); if (composite_nomem(state->info, state->ctx)) return; state->queryinfo.in.handle = &state->domain->libnet_ctx->lsa.handle; state->queryinfo.in.level = LSA_POLICY_INFO_ACCOUNT_DOMAIN; state->queryinfo.out.info = &state->info; subreq = dcerpc_lsa_QueryInfoPolicy_r_send(state, state->ctx->event_ctx, state->domain->libnet_ctx->lsa.pipe->binding_handle, &state->queryinfo); if (composite_nomem(subreq, state->ctx)) return; tevent_req_set_callback(subreq, init_domain_recv_queryinfo, state); }
static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s) { struct composite_context *c = s->creq; struct tevent_req *req; struct tsocket_address *dest_address; int ret; s->cldap.io.in.dest_address = NULL; s->cldap.io.in.dest_port = 0; s->cldap.io.in.realm = s->domain.dns_name; s->cldap.io.in.host = s->dest_dsa.netbios_name; s->cldap.io.in.user = NULL; s->cldap.io.in.domain_guid = NULL; s->cldap.io.in.domain_sid = NULL; s->cldap.io.in.acct_control = -1; s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; s->cldap.io.in.map_response = true; ret = tsocket_address_inet_from_strings(s, "ip", s->source_dsa.address, lpcfg_cldap_port(s->libnet->lp_ctx), &dest_address); if (ret != 0) { c->status = map_nt_error_from_unix_common(errno); if (!composite_is_ok(c)) return; } c->status = cldap_socket_init(s, NULL, dest_address, &s->cldap.sock); if (!composite_is_ok(c)) return; req = cldap_netlogon_send(s, s->libnet->event_ctx, s->cldap.sock, &s->cldap.io); if (composite_nomem(req, c)) return; tevent_req_set_callback(req, unbecomeDC_recv_cldap, s); }
static void unbecomeDC_drsuapi_connect_send(struct libnet_UnbecomeDC_state *s) { struct composite_context *c = s->creq; struct composite_context *creq; char *binding_str; binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[seal,target_hostname=%s]", s->source_dsa.address, s->source_dsa.dns_name); if (composite_nomem(binding_str, c)) return; c->status = dcerpc_parse_binding(s, binding_str, &s->drsuapi.binding); talloc_free(binding_str); if (!composite_is_ok(c)) return; if (DEBUGLEVEL >= 10) { c->status = dcerpc_binding_set_flags(s->drsuapi.binding, DCERPC_DEBUG_PRINT_BOTH, 0); if (!composite_is_ok(c)) return; } creq = dcerpc_pipe_connect_b_send(s, s->drsuapi.binding, &ndr_table_drsuapi, s->libnet->cred, s->libnet->event_ctx, s->libnet->lp_ctx); composite_continue(c, creq, unbecomeDC_drsuapi_connect_recv, s); }
static void init_domain_recv_queryinfo(struct tevent_req *subreq) { struct init_domain_state *state = tevent_req_callback_data(subreq, struct init_domain_state); struct lsa_DomainInfo *dominfo; struct composite_context *ctx; uint32_t lflags; state->ctx->status = dcerpc_lsa_QueryInfoPolicy_r_recv(subreq, state); TALLOC_FREE(subreq); if (!composite_is_ok(state->ctx)) return; state->ctx->status = state->queryinfo.out.result; if (!composite_is_ok(state->ctx)) return; if (!dom_sid_equal(state->domain->info->sid, &global_sid_Builtin)) { dominfo = &(*state->queryinfo.out.info)->account_domain; if (strcasecmp(state->domain->info->name, dominfo->name.string) != 0) { DEBUG(2, ("Expected domain name %s, DC %s said %s\n", state->domain->info->name, dcerpc_server_name(state->domain->libnet_ctx->lsa.pipe), dominfo->name.string)); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } if (!dom_sid_equal(state->domain->info->sid, dominfo->sid)) { DEBUG(2, ("Expected domain sid %s, DC %s said %s\n", dom_sid_string(state, state->domain->info->sid), dcerpc_server_name(state->domain->libnet_ctx->lsa.pipe), dom_sid_string(state, dominfo->sid))); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } } state->domain->samr_binding = init_domain_binding(state, &ndr_table_samr); /* We want to use the same flags as the LSA pipe did (so, if * it needed schannel, then we need that here too) */ lflags = dcerpc_binding_get_flags(state->domain->lsa_binding); state->ctx->status = dcerpc_binding_set_flags(state->domain->samr_binding, lflags, 0); if (!composite_is_ok(state->ctx)) return; state->domain->libnet_ctx->samr.pipe = NULL; state->domain->libnet_ctx->samr.samr_handle = NULL; ctx = wb_connect_samr_send(state, state->domain); composite_continue(state->ctx, ctx, init_domain_recv_samr, state); }
/* Recv the SAMR details (SamrConnect and SamrOpenDomain handle) and * open an LDAP connection */ static void init_domain_recv_samr(struct composite_context *ctx) { const char *ldap_url; 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->samr_pipe, &state->domain->samr_handle, &state->domain->domain_handle); if (!composite_is_ok(state->ctx)) return; talloc_steal(state->domain->samr_pipe, state->domain->samr_binding); state->domain->ldap_conn = ldap4_new_connection(state->domain, state->ctx->event_ctx); composite_nomem(state->domain->ldap_conn, state->ctx); ldap_url = talloc_asprintf(state, "ldap://%s/", state->domain->dc_address); composite_nomem(ldap_url, state->ctx); ctx = ldap_connect_send(state->domain->ldap_conn, ldap_url); composite_continue(state->ctx, ctx, init_domain_recv_ldapconn, state); }
/* Having make a netlogon connection (possibly secured with schannel), * make an LSA connection to the same DC, on the same IPC$ share */ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) { struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); state->ctx->status = dcerpc_pipe_connect_b_recv(ctx, state, &state->domain->netlogon_pipe); if (!composite_is_ok(state->ctx)) { talloc_free(state->domain->netlogon_binding); return; } talloc_steal(state->domain->netlogon_pipe, state->domain->netlogon_binding); state->domain->lsa_binding = init_domain_binding(state, &dcerpc_table_lsarpc); /* For debugging, it can be a real pain if all the traffic is encrypted */ if (lp_winbind_sealed_pipes()) { state->domain->lsa_binding->flags |= (DCERPC_SIGN | DCERPC_SEAL ); } else { state->domain->lsa_binding->flags |= (DCERPC_SIGN); } state->domain->lsa_pipe = NULL; /* this will make the secondary connection on the same IPC$ share, secured with SPNEGO or NTLMSSP */ ctx = dcerpc_secondary_connection_send(state->domain->netlogon_pipe, state->domain->lsa_binding); composite_continue(state->ctx, ctx, init_domain_recv_lsa_pipe, state); }
/* * 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); }
static void unbecomeDC_recv_cldap(struct tevent_req *req) { struct libnet_UnbecomeDC_state *s = tevent_req_callback_data(req, struct libnet_UnbecomeDC_state); struct composite_context *c = s->creq; c->status = cldap_netlogon_recv(req, lp_iconv_convenience(s->libnet->lp_ctx), s, &s->cldap.io); talloc_free(req); if (!composite_is_ok(c)) return; s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex; s->domain.dns_name = s->cldap.netlogon.dns_domain; s->domain.netbios_name = s->cldap.netlogon.domain; s->domain.guid = s->cldap.netlogon.domain_uuid; s->source_dsa.dns_name = s->cldap.netlogon.pdc_dns_name; s->source_dsa.netbios_name = s->cldap.netlogon.pdc_name; s->source_dsa.site_name = s->cldap.netlogon.server_site; s->dest_dsa.site_name = s->cldap.netlogon.client_site; unbecomeDC_connect_ldap(s); }
/* Having make a netlogon connection (possibly secured with schannel), * make an LSA connection to the same DC, on the same IPC$ share */ static void init_domain_recv_netlogonpipe(struct composite_context *ctx) { struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); uint32_t flags; state->ctx->status = dcerpc_pipe_connect_b_recv(ctx, state->domain, &state->domain->netlogon_pipe); if (!composite_is_ok(state->ctx)) { return; } talloc_reparent(state, state->domain->netlogon_pipe, state->domain->netlogon_binding); /* the netlogon connection is ready */ tevent_queue_start(state->domain->netlogon_queue); state->domain->lsa_binding = init_domain_binding(state, &ndr_table_lsarpc); /* For debugging, it can be a real pain if all the traffic is encrypted */ if (lpcfg_winbind_sealed_pipes(state->service->task->lp_ctx)) { flags = DCERPC_SIGN | DCERPC_SEAL; } else { flags = DCERPC_SIGN; } state->ctx->status = dcerpc_binding_set_flags(state->domain->lsa_binding, flags, 0); if (!composite_is_ok(state->ctx)) { return; } state->domain->libnet_ctx->lsa.pipe = NULL; state->domain->libnet_ctx->lsa.lsa_handle = NULL; /* this will make the secondary connection on the same IPC$ share, secured with SPNEGO or NTLMSSP */ ctx = dcerpc_secondary_auth_connection_send(state->domain->netlogon_pipe, state->domain->lsa_binding, &ndr_table_lsarpc, state->domain->libnet_ctx->cred, state->domain->libnet_ctx->lp_ctx ); composite_continue(state->ctx, ctx, init_domain_recv_lsa_pipe, state); }
/* 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 void init_domain_recv_queryinfo(struct rpc_request *req) { struct init_domain_state *state = talloc_get_type(req->async.private_data, struct init_domain_state); struct lsa_DomainInfo *dominfo; struct composite_context *ctx; state->ctx->status = dcerpc_ndr_request_recv(req); if (!composite_is_ok(state->ctx)) return; state->ctx->status = state->queryinfo.out.result; if (!composite_is_ok(state->ctx)) return; dominfo = &state->queryinfo.out.info->account_domain; if (strcasecmp(state->domain->info->name, dominfo->name.string) != 0) { DEBUG(2, ("Expected domain name %s, DC %s said %s\n", state->domain->info->name, dcerpc_server_name(state->domain->lsa_pipe), dominfo->name.string)); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } if (!dom_sid_equal(state->domain->info->sid, dominfo->sid)) { DEBUG(2, ("Expected domain sid %s, DC %s said %s\n", dom_sid_string(state, state->domain->info->sid), dcerpc_server_name(state->domain->lsa_pipe), dom_sid_string(state, dominfo->sid))); composite_error(state->ctx, NT_STATUS_INVALID_DOMAIN_STATE); return; } state->domain->samr_binding = init_domain_binding(state, &dcerpc_table_samr); /* We want to use the same flags as the LSA pipe did (so, if * it needed schannel, then we need that here too) */ state->domain->samr_binding->flags = state->domain->lsa_binding->flags; state->domain->samr_pipe = NULL; ctx = wb_connect_samr_send(state, state->domain); composite_continue(state->ctx, ctx, init_domain_recv_samr, state); }
static void unbecomeDC_drsuapi_connect_recv(struct composite_context *req) { struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data, struct libnet_UnbecomeDC_state); struct composite_context *c = s->creq; c->status = dcerpc_pipe_connect_b_recv(req, s, &s->drsuapi.pipe); if (!composite_is_ok(c)) return; unbecomeDC_drsuapi_bind_send(s); }
static void unbecomeDC_connect_ldap(struct libnet_UnbecomeDC_state *s) { struct composite_context *c = s->creq; c->status = unbecomeDC_ldap_connect(s); if (!composite_is_ok(c)) return; c->status = unbecomeDC_ldap_rootdse(s); if (!composite_is_ok(c)) return; c->status = unbecomeDC_ldap_computer_object(s); if (!composite_is_ok(c)) return; c->status = unbecomeDC_ldap_modify_computer(s); if (!composite_is_ok(c)) return; c->status = unbecomeDC_ldap_move_computer(s); if (!composite_is_ok(c)) return; unbecomeDC_drsuapi_connect_send(s); }
static void unbecomeDC_drsuapi_connect_send(struct libnet_UnbecomeDC_state *s) { struct composite_context *c = s->creq; struct composite_context *creq; char *binding_str; binding_str = talloc_asprintf(s, "ncacn_ip_tcp:%s[seal]", s->source_dsa.dns_name); if (composite_nomem(binding_str, c)) return; c->status = dcerpc_parse_binding(s, binding_str, &s->drsuapi.binding); talloc_free(binding_str); if (!composite_is_ok(c)) return; creq = dcerpc_pipe_connect_b_send(s, s->drsuapi.binding, &ndr_table_drsuapi, s->libnet->cred, s->libnet->event_ctx, s->libnet->lp_ctx); composite_continue(c, creq, unbecomeDC_drsuapi_connect_recv, s); }
static void unbecomeDC_drsuapi_bind_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; c->status = dcerpc_drsuapi_DsBind_r_recv(subreq, s); TALLOC_FREE(subreq); if (!composite_is_ok(c)) return; if (!W_ERROR_IS_OK(s->drsuapi.bind_r.out.result)) { composite_error(c, werror_to_ntstatus(s->drsuapi.bind_r.out.result)); return; } ZERO_STRUCT(s->drsuapi.remote_info28); if (s->drsuapi.bind_r.out.bind_info) { switch (s->drsuapi.bind_r.out.bind_info->length) { case 24: { struct drsuapi_DsBindInfo24 *info24; info24 = &s->drsuapi.bind_r.out.bind_info->info.info24; s->drsuapi.remote_info28.supported_extensions = info24->supported_extensions; s->drsuapi.remote_info28.site_guid = info24->site_guid; s->drsuapi.remote_info28.pid = info24->pid; s->drsuapi.remote_info28.repl_epoch = 0; break; } case 48: { struct drsuapi_DsBindInfo48 *info48; info48 = &s->drsuapi.bind_r.out.bind_info->info.info48; s->drsuapi.remote_info28.supported_extensions = info48->supported_extensions; s->drsuapi.remote_info28.site_guid = info48->site_guid; s->drsuapi.remote_info28.pid = info48->pid; s->drsuapi.remote_info28.repl_epoch = info48->repl_epoch; break; } case 28: s->drsuapi.remote_info28 = s->drsuapi.bind_r.out.bind_info->info.info28; break; } } unbecomeDC_drsuapi_remove_ds_server_send(s); }
/* 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); }
/* We should now have either an authenticated LSA pipe, or an error. * On success, open a policy handle */ static void init_domain_recv_lsa_pipe(struct composite_context *ctx) { struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); struct tevent_req *subreq; state->ctx->status = dcerpc_secondary_auth_connection_recv(ctx, state->domain, &state->domain->libnet_ctx->lsa.pipe); if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_LOGON_FAILURE)) { if (retry_with_schannel(state, state->domain->lsa_binding, &ndr_table_lsarpc, init_domain_recv_lsa_pipe)) { return; } } if (!composite_is_ok(state->ctx)) return; talloc_steal(state->domain->libnet_ctx, state->domain->libnet_ctx->lsa.pipe); talloc_reparent(state, state->domain->libnet_ctx->lsa.pipe, state->domain->lsa_binding); state->domain->libnet_ctx->lsa.lsa_handle = state->domain->libnet_ctx->lsa.pipe->binding_handle; state->domain->libnet_ctx->lsa.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; state->domain->libnet_ctx->lsa.name = state->domain->info->name; ZERO_STRUCT(state->domain->libnet_ctx->lsa.handle); state->lsa_openpolicy.in.system_name = talloc_asprintf(state, "\\\\%s", dcerpc_server_name(state->domain->libnet_ctx->lsa.pipe)); ZERO_STRUCT(state->objectattr); state->lsa_openpolicy.in.attr = &state->objectattr; state->lsa_openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; state->lsa_openpolicy.out.handle = &state->domain->libnet_ctx->lsa.handle; subreq = dcerpc_lsa_OpenPolicy2_r_send(state, state->ctx->event_ctx, state->domain->libnet_ctx->lsa.pipe->binding_handle, &state->lsa_openpolicy); if (composite_nomem(subreq, state->ctx)) return; tevent_req_set_callback(subreq, init_domain_recv_lsa_policy, state); }
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 bool retry_with_schannel(struct init_domain_state *state, struct dcerpc_binding *binding, const struct ndr_interface_table *table, void (*continuation)(struct composite_context *)) { struct composite_context *ctx; uint32_t nflags; uint32_t bflags; state->ctx->status = NT_STATUS_OK; nflags = dcerpc_binding_get_flags(state->domain->netlogon_binding); bflags = dcerpc_binding_get_flags(binding); if ((nflags & DCERPC_SCHANNEL) && !(bflags & DCERPC_SCHANNEL)) { /* Opening a policy handle failed, perhaps it was * because we don't get a 'wrong password' error on * NTLMSSP binds */ /* Try again with schannel */ bflags |= DCERPC_SCHANNEL | DCERPC_SCHANNEL_AUTO; state->ctx->status = dcerpc_binding_set_flags(binding, bflags, 0); if (!composite_is_ok(state->ctx)) return true; /* Try again, likewise on the same IPC$ share, secured with SCHANNEL */ ctx = dcerpc_secondary_auth_connection_send(state->domain->netlogon_pipe, binding, table, state->domain->libnet_ctx->cred, state->domain->libnet_ctx->lp_ctx); composite_continue(state->ctx, ctx, continuation, state); return true; } else { return false; } }
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); }
/* We should now have either an authenticated LSA pipe, or an error. * On success, open a policy handle */ static void init_domain_recv_lsa_pipe(struct composite_context *ctx) { struct rpc_request *req; struct init_domain_state *state = talloc_get_type(ctx->async.private_data, struct init_domain_state); state->ctx->status = dcerpc_secondary_connection_recv(ctx, &state->domain->lsa_pipe); if (NT_STATUS_EQUAL(state->ctx->status, NT_STATUS_LOGON_FAILURE)) { if (retry_with_schannel(state, state->domain->lsa_binding, init_domain_recv_lsa_pipe)) { return; } } if (!composite_is_ok(state->ctx)) return; talloc_steal(state->domain, state->domain->lsa_pipe); talloc_steal(state->domain->lsa_pipe, state->domain->lsa_binding); state->domain->lsa_policy_handle = talloc(state, struct policy_handle); if (composite_nomem(state->domain->lsa_policy_handle, state->ctx)) return; state->lsa_openpolicy.in.system_name = talloc_asprintf(state, "\\\\%s", dcerpc_server_name(state->domain->lsa_pipe)); ZERO_STRUCT(state->objectattr); state->lsa_openpolicy.in.attr = &state->objectattr; state->lsa_openpolicy.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; state->lsa_openpolicy.out.handle = state->domain->lsa_policy_handle; req = dcerpc_lsa_OpenPolicy2_send(state->domain->lsa_pipe, state, &state->lsa_openpolicy); composite_continue_rpc(state->ctx, req, init_domain_recv_lsa_policy, state); }
static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s) { struct composite_context *c = s->creq; struct tevent_req *req; s->cldap.io.in.dest_address = s->source_dsa.address; s->cldap.io.in.dest_port = lp_cldap_port(s->libnet->lp_ctx); s->cldap.io.in.realm = s->domain.dns_name; s->cldap.io.in.host = s->dest_dsa.netbios_name; s->cldap.io.in.user = NULL; s->cldap.io.in.domain_guid = NULL; s->cldap.io.in.domain_sid = NULL; s->cldap.io.in.acct_control = -1; s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; s->cldap.io.in.map_response = true; c->status = cldap_socket_init(s, s->libnet->event_ctx, NULL, NULL, &s->cldap.sock);//TODO if (!composite_is_ok(c)) return; req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io); if (composite_nomem(req, c)) return; tevent_req_set_callback(req, unbecomeDC_recv_cldap, s); }
/* send a async dcerpc bind request */ struct composite_context *dcerpc_bind_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, const struct ndr_syntax_id *syntax, const struct ndr_syntax_id *transfer_syntax) { struct composite_context *c; struct ncacn_packet pkt; DATA_BLOB blob; struct rpc_request *req; c = composite_create(mem_ctx,p->conn->event_ctx); if (c == NULL) return NULL; c->private_data = p; p->syntax = *syntax; p->transfer_syntax = *transfer_syntax; init_ncacn_hdr(p->conn, &pkt); pkt.ptype = DCERPC_PKT_BIND; pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; pkt.call_id = p->conn->call_id; pkt.auth_length = 0; if (p->binding->flags & DCERPC_CONCURRENT_MULTIPLEX) { pkt.pfc_flags |= DCERPC_PFC_FLAG_CONC_MPX; } if (p->binding->flags & DCERPC_HEADER_SIGNING) { pkt.pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; } pkt.u.bind.max_xmit_frag = 5840; pkt.u.bind.max_recv_frag = 5840; pkt.u.bind.assoc_group_id = p->binding->assoc_group_id; pkt.u.bind.num_contexts = 1; pkt.u.bind.ctx_list = talloc_array(mem_ctx, struct dcerpc_ctx_list, 1); if (composite_nomem(pkt.u.bind.ctx_list, c)) return c; pkt.u.bind.ctx_list[0].context_id = p->context_id; pkt.u.bind.ctx_list[0].num_transfer_syntaxes = 1; pkt.u.bind.ctx_list[0].abstract_syntax = p->syntax; pkt.u.bind.ctx_list[0].transfer_syntaxes = &p->transfer_syntax; pkt.u.bind.auth_info = data_blob(NULL, 0); /* construct the NDR form of the packet */ c->status = ncacn_push_auth(&blob, c, p->conn->iconv_convenience, &pkt, p->conn->security_state.auth_info); if (!composite_is_ok(c)) return c; p->conn->transport.recv_data = dcerpc_recv_data; /* * we allocate a dcerpc_request so we can be in the same * request queue as normal requests */ req = talloc_zero(c, struct rpc_request); if (composite_nomem(req, c)) return c; req->state = RPC_REQUEST_PENDING; req->call_id = pkt.call_id; req->async.private_data = c; req->async.callback = dcerpc_composite_fail; req->p = p; req->recv_handler = dcerpc_bind_recv_handler; DLIST_ADD_END(p->conn->pending, req, struct rpc_request *); talloc_set_destructor(req, dcerpc_req_dequeue); c->status = p->conn->transport.send_request(p->conn, &blob, true); if (!composite_is_ok(c)) return c; event_add_timed(c->event_ctx, req, timeval_current_ofs(DCERPC_REQUEST_TIMEOUT, 0), dcerpc_timeout_handler, req); return c; }