📄 wb_init_domain.c
字号:
state->domain->libnet_ctx->cred, state->domain->libnet_ctx->lp_ctx ); composite_continue(state->ctx, ctx, init_domain_recv_lsa_pipe, state);}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; state->ctx->status = NT_STATUS_OK; if (state->domain->netlogon_binding->flags & DCERPC_SCHANNEL && !(binding->flags & 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 */ binding->flags |= DCERPC_SCHANNEL; /* 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; }}/* 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_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_steal(state->domain->libnet_ctx->lsa.pipe, state->domain->lsa_binding); 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; req = dcerpc_lsa_OpenPolicy2_send(state->domain->libnet_ctx->lsa.pipe, state, &state->lsa_openpolicy); composite_continue_rpc(state->ctx, req, init_domain_recv_lsa_policy, state);}/* Receive a policy handle (or not, and retry the authentication) and * obtain some basic information about the domain */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, &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->queryinfo.in.handle = &state->domain->libnet_ctx->lsa.handle; state->queryinfo.in.level = LSA_POLICY_INFO_ACCOUNT_DOMAIN; req = dcerpc_lsa_QueryInfoPolicy_send(state->domain->libnet_ctx->lsa.pipe, state, &state->queryinfo); composite_continue_rpc(state->ctx, req, init_domain_recv_queryinfo, state);}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->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) */ state->domain->samr_binding->flags = state->domain->lsa_binding->flags; state->domain->libnet_ctx->samr.pipe = 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->libnet_ctx->samr.pipe, &state->domain->libnet_ctx->samr.handle, &state->domain->libnet_ctx->samr.handle); if (!composite_is_ok(state->ctx)) return; talloc_steal(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 = state->domain->info->sid; state->domain->ldap_conn = ldap4_new_connection(state->domain, state->domain->libnet_ctx->lp_ctx, 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);}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->libnet_ctx->cred, state->domain->libnet_ctx->lp_ctx); DEBUG(0, ("ldap_bind returned %s\n", nt_errstr(state->ctx->status))); } composite_done(state->ctx);}NTSTATUS wb_init_domain_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, struct wbsrv_domain **result){ NTSTATUS status = composite_wait(c); if (NT_STATUS_IS_OK(status)) { struct init_domain_state *state = talloc_get_type(c->private_data, struct init_domain_state); *result = talloc_steal(mem_ctx, state->domain); } talloc_free(c); return status;}NTSTATUS wb_init_domain(TALLOC_CTX *mem_ctx, struct wbsrv_service *service, struct wb_dom_info *dom_info, struct wbsrv_domain **result){ struct composite_context *c = wb_init_domain_send(mem_ctx, service, dom_info); return wb_init_domain_recv(c, mem_ctx, result);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -