WHATSNEW: Add release notes for Samba 4.9.17.
[Samba.git] / source3 / winbindd / winbindd_irpc.c
blob1e34fdfc2d0b192dbde5d8c7a4e65a325c179dad
1 /*
2 Unix SMB/CIFS implementation.
3 async implementation of commands submitted over IRPC
4 Copyright (C) Volker Lendecke 2009
5 Copyright (C) Guenther Deschner 2009
6 Copyright (C) Andrew Bartlett 2014
7 Copyright (C) Andrew Tridgell 2009
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "winbindd.h"
25 #include "librpc/gen_ndr/ndr_winbind_c.h"
26 #include "source4/lib/messaging/irpc.h"
27 #include "librpc/gen_ndr/ndr_winbind.h"
28 #include "librpc/gen_ndr/ndr_lsa.h"
29 #include "librpc/gen_ndr/ndr_lsa_c.h"
30 #include "libcli/security/dom_sid.h"
31 #include "passdb/lookup_sid.h" /* only for LOOKUP_NAME_NO_NSS flag */
32 #include "librpc/gen_ndr/ndr_irpc.h"
33 #include "librpc/gen_ndr/ndr_netlogon.h"
35 struct wb_irpc_forward_state {
36 struct irpc_message *msg;
37 struct winbind_DsrUpdateReadOnlyServerDnsRecords *req;
39 const char *opname;
40 struct dcesrv_call_state *dce_call;
44 called when the forwarded rpc request is finished
46 static void wb_irpc_forward_callback(struct tevent_req *subreq)
48 struct wb_irpc_forward_state *st =
49 tevent_req_callback_data(subreq,
50 struct wb_irpc_forward_state);
51 const char *opname = st->opname;
52 NTSTATUS status;
54 status = dcerpc_binding_handle_call_recv(subreq);
55 TALLOC_FREE(subreq);
56 if (!NT_STATUS_IS_OK(status)) {
57 DEBUG(0,("RPC callback failed for %s - %s\n",
58 opname, nt_errstr(status)));
59 irpc_send_reply(st->msg, status);
60 return;
63 irpc_send_reply(st->msg, status);
68 /**
69 * Forward a RPC call using IRPC to another task
72 static NTSTATUS wb_irpc_forward_rpc_call(struct irpc_message *msg, TALLOC_CTX *mem_ctx,
73 struct tevent_context *ev,
74 void *r, uint32_t callid,
75 const char *opname,
76 struct winbindd_domain *domain,
77 uint32_t timeout)
79 struct wb_irpc_forward_state *st;
80 struct dcerpc_binding_handle *binding_handle;
81 struct tevent_req *subreq;
83 st = talloc(mem_ctx, struct wb_irpc_forward_state);
84 if (st == NULL) {
85 return NT_STATUS_NO_MEMORY;
88 st->msg = msg;
89 st->opname = opname;
91 binding_handle = dom_child_handle(domain);
92 if (binding_handle == NULL) {
93 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
94 opname, domain->name));
95 return NT_STATUS_UNSUCCESSFUL;
98 /* reset timeout for the handle */
99 dcerpc_binding_handle_set_timeout(binding_handle, timeout);
101 /* forward the call */
102 subreq = dcerpc_binding_handle_call_send(st, ev,
103 binding_handle,
104 NULL, &ndr_table_winbind,
105 callid,
106 msg, r);
107 if (subreq == NULL) {
108 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
109 opname, domain->name));
110 return NT_STATUS_UNSUCCESSFUL;
113 /* mark the request as replied async */
114 msg->defer_reply = true;
116 /* setup the callback */
117 tevent_req_set_callback(subreq, wb_irpc_forward_callback, st);
118 return NT_STATUS_OK;
121 static NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg,
122 struct winbind_DsrUpdateReadOnlyServerDnsRecords *req)
124 struct winbindd_domain *domain = find_our_domain();
125 if (domain == NULL) {
126 return NT_STATUS_NO_SUCH_DOMAIN;
129 DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n"));
131 return wb_irpc_forward_rpc_call(msg, msg,
132 server_event_context(),
133 req, NDR_WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS,
134 "winbind_DsrUpdateReadOnlyServerDnsRecords",
135 domain, IRPC_CALL_TIMEOUT);
138 static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
139 struct winbind_SamLogon *req)
141 struct winbindd_domain *domain;
142 struct netr_IdentityInfo *identity_info;
143 const char *target_domain_name = NULL;
144 const char *account_name = NULL;
146 switch (req->in.logon_level) {
147 case NetlogonInteractiveInformation:
148 case NetlogonServiceInformation:
149 case NetlogonInteractiveTransitiveInformation:
150 case NetlogonServiceTransitiveInformation:
151 if (req->in.logon.password == NULL) {
152 return NT_STATUS_REQUEST_NOT_ACCEPTED;
154 identity_info = &req->in.logon.password->identity_info;
155 break;
157 case NetlogonNetworkInformation:
158 case NetlogonNetworkTransitiveInformation:
159 if (req->in.logon.network == NULL) {
160 return NT_STATUS_REQUEST_NOT_ACCEPTED;
163 identity_info = &req->in.logon.network->identity_info;
164 break;
166 case NetlogonGenericInformation:
167 if (req->in.logon.generic == NULL) {
168 return NT_STATUS_REQUEST_NOT_ACCEPTED;
171 identity_info = &req->in.logon.generic->identity_info;
172 break;
174 default:
175 return NT_STATUS_REQUEST_NOT_ACCEPTED;
178 target_domain_name = identity_info->domain_name.string;
179 if (target_domain_name == NULL) {
180 target_domain_name = "";
183 account_name = identity_info->account_name.string;
184 if (account_name == NULL) {
185 account_name = "";
188 if (IS_DC && target_domain_name[0] == '\0') {
189 const char *p = NULL;
191 p = strchr_m(account_name, '@');
192 if (p != NULL) {
193 target_domain_name = p + 1;
197 if (IS_DC && target_domain_name[0] == '\0') {
198 DBG_ERR("target_domain[%s] account[%s]\n",
199 target_domain_name, account_name);
200 return NT_STATUS_REQUEST_NOT_ACCEPTED;
203 domain = find_auth_domain(0, target_domain_name);
204 if (domain == NULL) {
205 DBG_INFO("target_domain[%s] for account[%s] not known\n",
206 target_domain_name, account_name);
207 req->out.result = NT_STATUS_NO_SUCH_USER;
208 req->out.authoritative = 0;
209 return NT_STATUS_OK;
212 DEBUG(5, ("wb_irpc_SamLogon called\n"));
214 return wb_irpc_forward_rpc_call(msg, msg,
215 server_event_context(),
216 req, NDR_WINBIND_SAMLOGON,
217 "winbind_SamLogon",
218 domain, IRPC_CALL_TIMEOUT);
221 static NTSTATUS wb_irpc_LogonControl(struct irpc_message *msg,
222 struct winbind_LogonControl *req)
224 TALLOC_CTX *frame = talloc_stackframe();
225 char *domain_name = NULL;
226 struct winbindd_domain *domain = NULL;
228 DEBUG(5, ("wb_irpc_LogonControl called\n"));
230 switch (req->in.function_code) {
231 case NETLOGON_CONTROL_REDISCOVER:
232 case NETLOGON_CONTROL_TC_QUERY:
233 case NETLOGON_CONTROL_CHANGE_PASSWORD:
234 case NETLOGON_CONTROL_TC_VERIFY:
235 if (req->in.data->domain == NULL) {
236 TALLOC_FREE(frame);
237 return NT_STATUS_INVALID_PARAMETER;
240 domain_name = talloc_strdup(frame, req->in.data->domain);
241 if (domain_name == NULL) {
242 req->out.result = WERR_NOT_ENOUGH_MEMORY;
243 TALLOC_FREE(frame);
244 return NT_STATUS_OK;
247 break;
248 default:
249 TALLOC_FREE(frame);
250 return NT_STATUS_NOT_IMPLEMENTED;
253 if (req->in.function_code == NETLOGON_CONTROL_REDISCOVER) {
254 char *p = NULL;
257 * NETLOGON_CONTROL_REDISCOVER
258 * get's an optional \dcname appended to the domain name
260 p = strchr_m(domain_name, '\\');
261 if (p != NULL) {
262 *p = '\0';
266 domain = find_domain_from_name_noinit(domain_name);
267 if (domain == NULL) {
268 req->out.result = WERR_NO_SUCH_DOMAIN;
269 TALLOC_FREE(frame);
270 return NT_STATUS_OK;
273 TALLOC_FREE(frame);
274 return wb_irpc_forward_rpc_call(msg, msg,
275 server_event_context(),
276 req, NDR_WINBIND_LOGONCONTROL,
277 "winbind_LogonControl",
278 domain, 45 /* timeout */);
281 static NTSTATUS wb_irpc_GetForestTrustInformation(struct irpc_message *msg,
282 struct winbind_GetForestTrustInformation *req)
284 struct winbindd_domain *domain = NULL;
286 if (req->in.trusted_domain_name == NULL) {
287 req->out.result = WERR_NO_SUCH_DOMAIN;
288 return NT_STATUS_OK;
291 domain = find_trust_from_name_noinit(req->in.trusted_domain_name);
292 if (domain == NULL) {
293 req->out.result = WERR_NO_SUCH_DOMAIN;
294 return NT_STATUS_OK;
298 * checking for domain->internal and domain->primary
299 * makes sure we only do some work when running as DC.
302 if (domain->internal) {
303 req->out.result = WERR_NO_SUCH_DOMAIN;
304 return NT_STATUS_OK;
307 if (domain->primary) {
308 req->out.result = WERR_NO_SUCH_DOMAIN;
309 return NT_STATUS_OK;
312 DEBUG(5, ("wb_irpc_GetForestTrustInformation called\n"));
314 return wb_irpc_forward_rpc_call(msg, msg,
315 server_event_context(),
316 req, NDR_WINBIND_GETFORESTTRUSTINFORMATION,
317 "winbind_GetForestTrustInformation",
318 domain, 45 /* timeout */);
321 static NTSTATUS wb_irpc_SendToSam(struct irpc_message *msg,
322 struct winbind_SendToSam *req)
324 /* TODO make sure that it is RWDC */
325 struct winbindd_domain *domain = find_our_domain();
326 if (domain == NULL) {
327 return NT_STATUS_NO_SUCH_DOMAIN;
330 DEBUG(5, ("wb_irpc_SendToSam called\n"));
332 return wb_irpc_forward_rpc_call(msg, msg,
333 server_event_context(),
334 req, NDR_WINBIND_SENDTOSAM,
335 "winbind_SendToSam",
336 domain, IRPC_CALL_TIMEOUT);
339 struct wb_irpc_lsa_LookupSids3_state {
340 struct irpc_message *msg;
341 struct lsa_LookupSids3 *req;
344 static void wb_irpc_lsa_LookupSids3_done(struct tevent_req *subreq);
346 static NTSTATUS wb_irpc_lsa_LookupSids3_call(struct irpc_message *msg,
347 struct lsa_LookupSids3 *req)
349 struct wb_irpc_lsa_LookupSids3_state *state = NULL;
350 struct tevent_req *subreq = NULL;
351 struct dom_sid *sids = NULL;
352 uint32_t i;
354 state = talloc_zero(msg, struct wb_irpc_lsa_LookupSids3_state);
355 if (state == NULL) {
356 return NT_STATUS_NO_MEMORY;
359 state->msg = msg;
360 state->req = req;
362 state->req->out.domains = talloc_zero(state->msg,
363 struct lsa_RefDomainList *);
364 if (state->req->out.domains == NULL) {
365 return NT_STATUS_NO_MEMORY;
367 state->req->out.names = talloc_zero(state->msg,
368 struct lsa_TransNameArray2);
369 if (state->req->out.names == NULL) {
370 return NT_STATUS_NO_MEMORY;
372 state->req->out.count = talloc_zero(state->msg, uint32_t);
373 if (state->req->out.count == NULL) {
374 return NT_STATUS_NO_MEMORY;
377 state->req->out.names->names = talloc_zero_array(state->msg,
378 struct lsa_TranslatedName2,
379 req->in.sids->num_sids);
380 if (state->req->out.names->names == NULL) {
381 return NT_STATUS_NO_MEMORY;
384 sids = talloc_zero_array(state, struct dom_sid,
385 req->in.sids->num_sids);
386 if (sids == NULL) {
387 return NT_STATUS_NO_MEMORY;
390 for (i = 0; i < req->in.sids->num_sids; i++) {
391 if (req->in.sids->sids[i].sid == NULL) {
392 return NT_STATUS_REQUEST_NOT_ACCEPTED;
395 sids[i] = *req->in.sids->sids[i].sid;
398 subreq = wb_lookupsids_send(msg,
399 server_event_context(),
400 sids, req->in.sids->num_sids);
401 if (subreq == NULL) {
402 return NT_STATUS_NO_MEMORY;
404 tevent_req_set_callback(subreq, wb_irpc_lsa_LookupSids3_done, state);
405 msg->defer_reply = true;
407 return NT_STATUS_OK;
410 static void wb_irpc_lsa_LookupSids3_done(struct tevent_req *subreq)
412 struct wb_irpc_lsa_LookupSids3_state *state =
413 tevent_req_callback_data(subreq,
414 struct wb_irpc_lsa_LookupSids3_state);
415 struct lsa_RefDomainList *domains = NULL;
416 struct lsa_TransNameArray *names = NULL;
417 NTSTATUS status;
418 uint32_t i;
420 status = wb_lookupsids_recv(subreq, state->msg,
421 &domains, &names);
422 TALLOC_FREE(subreq);
423 if (!NT_STATUS_IS_OK(status)) {
424 DEBUG(0,("RPC callback failed for %s - %s\n",
425 __func__, nt_errstr(status)));
426 irpc_send_reply(state->msg, status);
427 return;
430 if (names->count > state->req->in.sids->num_sids) {
431 status = NT_STATUS_INTERNAL_ERROR;
432 DEBUG(0,("RPC callback failed for %s - %s\n",
433 __func__, nt_errstr(status)));
434 irpc_send_reply(state->msg, status);
435 return;
438 *state->req->out.domains = domains;
439 for (i = 0; i < names->count; i++) {
440 struct lsa_TranslatedName2 *n2 =
441 &state->req->out.names->names[i];
443 n2->sid_type = names->names[i].sid_type;
444 n2->name = names->names[i].name;
445 n2->sid_index = names->names[i].sid_index;
446 n2->unknown = 0;
448 if (n2->sid_type != SID_NAME_UNKNOWN) {
449 (*state->req->out.count)++;
452 state->req->out.names->count = names->count;
454 if (*state->req->out.count == 0) {
455 state->req->out.result = NT_STATUS_NONE_MAPPED;
456 } else if (*state->req->out.count != names->count) {
457 state->req->out.result = NT_STATUS_SOME_NOT_MAPPED;
458 } else {
459 state->req->out.result = NT_STATUS_OK;
462 irpc_send_reply(state->msg, NT_STATUS_OK);
463 return;
466 struct wb_irpc_lsa_LookupNames4_name {
467 void *state;
468 uint32_t idx;
469 const char *namespace;
470 const char *domain;
471 char *name;
472 struct dom_sid sid;
473 enum lsa_SidType type;
474 struct dom_sid *authority_sid;
477 struct wb_irpc_lsa_LookupNames4_state {
478 struct irpc_message *msg;
479 struct lsa_LookupNames4 *req;
480 struct wb_irpc_lsa_LookupNames4_name *names;
481 uint32_t num_pending;
482 uint32_t num_domain_sids;
483 struct dom_sid *domain_sids;
486 static void wb_irpc_lsa_LookupNames4_done(struct tevent_req *subreq);
488 static NTSTATUS wb_irpc_lsa_LookupNames4_call(struct irpc_message *msg,
489 struct lsa_LookupNames4 *req)
491 struct wb_irpc_lsa_LookupNames4_state *state = NULL;
492 struct tevent_req *subreq = NULL;
493 uint32_t i;
496 state = talloc_zero(msg, struct wb_irpc_lsa_LookupNames4_state);
497 if (state == NULL) {
498 return NT_STATUS_NO_MEMORY;
501 state->msg = msg;
502 state->req = req;
504 state->req->out.domains = talloc_zero(state->msg,
505 struct lsa_RefDomainList *);
506 if (state->req->out.domains == NULL) {
507 return NT_STATUS_NO_MEMORY;
509 state->req->out.sids = talloc_zero(state->msg,
510 struct lsa_TransSidArray3);
511 if (state->req->out.sids == NULL) {
512 return NT_STATUS_NO_MEMORY;
514 state->req->out.count = talloc_zero(state->msg, uint32_t);
515 if (state->req->out.count == NULL) {
516 return NT_STATUS_NO_MEMORY;
519 state->req->out.sids->sids = talloc_zero_array(state->msg,
520 struct lsa_TranslatedSid3,
521 req->in.num_names);
522 if (state->req->out.sids->sids == NULL) {
523 return NT_STATUS_NO_MEMORY;
526 state->names = talloc_zero_array(state,
527 struct wb_irpc_lsa_LookupNames4_name,
528 req->in.num_names);
529 if (state->names == NULL) {
530 return NT_STATUS_NO_MEMORY;
533 for (i = 0; i < req->in.num_names; i++) {
534 struct wb_irpc_lsa_LookupNames4_name *nstate =
535 &state->names[i];
536 char *p = NULL;
538 if (req->in.names[i].string == NULL) {
539 DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
540 __location__, req->in.names[i].string);
541 return NT_STATUS_REQUEST_NOT_ACCEPTED;
543 nstate->state = state;
544 nstate->idx = i;
545 nstate->name = talloc_strdup(state->names,
546 req->in.names[i].string);
547 if (nstate->name == NULL) {
548 return NT_STATUS_NO_MEMORY;
550 nstate->type = SID_NAME_UNKNOWN;
552 /* cope with the name being a fully qualified name */
553 p = strchr(nstate->name, '\\');
554 if (p != NULL) {
555 *p = 0;
556 nstate->domain = nstate->name;
557 nstate->namespace = nstate->domain;
558 nstate->name = p+1;
559 } else if ((p = strchr(nstate->name, '@')) != NULL) {
560 /* upn */
561 nstate->domain = "";
562 nstate->namespace = p + 1;
563 } else {
565 * TODO: select the domain based on
566 * req->in.level and req->in.client_revision
568 * For now we don't allow this.
570 DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
571 __location__, nstate->name);
572 return NT_STATUS_REQUEST_NOT_ACCEPTED;
575 subreq = wb_lookupname_send(msg,
576 server_event_context(),
577 nstate->namespace,
578 nstate->domain,
579 nstate->name,
580 LOOKUP_NAME_NO_NSS);
581 if (subreq == NULL) {
582 return NT_STATUS_NO_MEMORY;
584 tevent_req_set_callback(subreq,
585 wb_irpc_lsa_LookupNames4_done,
586 nstate);
587 state->num_pending++;
590 msg->defer_reply = true;
592 return NT_STATUS_OK;
595 static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req *subreq);
597 static void wb_irpc_lsa_LookupNames4_done(struct tevent_req *subreq)
599 struct wb_irpc_lsa_LookupNames4_name *nstate =
600 (struct wb_irpc_lsa_LookupNames4_name *)
601 tevent_req_callback_data_void(subreq);
602 struct wb_irpc_lsa_LookupNames4_state *state =
603 talloc_get_type_abort(nstate->state,
604 struct wb_irpc_lsa_LookupNames4_state);
605 NTSTATUS status;
607 SMB_ASSERT(state->num_pending > 0);
608 state->num_pending--;
609 status = wb_lookupname_recv(subreq, &nstate->sid, &nstate->type);
610 TALLOC_FREE(subreq);
611 if (!NT_STATUS_IS_OK(status)) {
612 DEBUG(0,("RPC callback failed for %s - %s\n",
613 __func__, nt_errstr(status)));
614 irpc_send_reply(state->msg, status);
615 return;
618 status = dom_sid_split_rid(state, &nstate->sid,
619 &nstate->authority_sid, NULL);
620 if (!NT_STATUS_IS_OK(status)) {
621 DBG_ERR("dom_sid_split_rid(%s) failed - %s\n",
622 sid_string_dbg(&nstate->sid), nt_errstr(status));
623 irpc_send_reply(state->msg, status);
624 return;
627 status = add_sid_to_array_unique(state,
628 nstate->authority_sid,
629 &state->domain_sids,
630 &state->num_domain_sids);
631 if (!NT_STATUS_IS_OK(status)) {
632 DBG_ERR("add_sid_to_array_unique(%s) failed - %s\n",
633 sid_string_dbg(nstate->authority_sid), nt_errstr(status));
634 irpc_send_reply(state->msg, status);
635 return;
638 if (state->num_pending > 0) {
640 * wait for more...
642 return;
646 * Now resolve all domains back to a name
647 * to get a good lsa_RefDomainList
649 subreq = wb_lookupsids_send(state,
650 server_event_context(),
651 state->domain_sids,
652 state->num_domain_sids);
653 if (subreq == NULL) {
654 status = NT_STATUS_NO_MEMORY;
655 DBG_ERR("wb_lookupsids_send - %s\n",
656 nt_errstr(status));
657 irpc_send_reply(state->msg, status);
658 return;
660 tevent_req_set_callback(subreq,
661 wb_irpc_lsa_LookupNames4_domains_done,
662 state);
664 return;
667 static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req *subreq)
669 struct wb_irpc_lsa_LookupNames4_state *state =
670 tevent_req_callback_data(subreq,
671 struct wb_irpc_lsa_LookupNames4_state);
672 struct lsa_RefDomainList *domains = NULL;
673 struct lsa_TransNameArray *names = NULL;
674 NTSTATUS status;
675 uint32_t i;
677 status = wb_lookupsids_recv(subreq, state->msg,
678 &domains, &names);
679 TALLOC_FREE(subreq);
680 if (!NT_STATUS_IS_OK(status)) {
681 DEBUG(0,("RPC callback failed for %s - %s\n",
682 __func__, nt_errstr(status)));
683 irpc_send_reply(state->msg, status);
684 return;
687 *state->req->out.domains = domains;
688 for (i = 0; i < state->req->in.num_names; i++) {
689 struct wb_irpc_lsa_LookupNames4_name *nstate =
690 &state->names[i];
691 struct lsa_TranslatedSid3 *s3 =
692 &state->req->out.sids->sids[i];
693 uint32_t di;
695 s3->sid_type = nstate->type;
696 if (s3->sid_type != SID_NAME_UNKNOWN) {
697 s3->sid = &nstate->sid;
698 } else {
699 s3->sid = NULL;
701 s3->sid_index = UINT32_MAX;
702 for (di = 0; di < domains->count; di++) {
703 bool match;
705 if (domains->domains[di].sid == NULL) {
706 continue;
709 match = dom_sid_equal(nstate->authority_sid,
710 domains->domains[di].sid);
711 if (match) {
712 s3->sid_index = di;
713 break;
716 if (s3->sid_type != SID_NAME_UNKNOWN) {
717 (*state->req->out.count)++;
720 state->req->out.sids->count = state->req->in.num_names;
722 if (*state->req->out.count == 0) {
723 state->req->out.result = NT_STATUS_NONE_MAPPED;
724 } else if (*state->req->out.count != state->req->in.num_names) {
725 state->req->out.result = NT_STATUS_SOME_NOT_MAPPED;
726 } else {
727 state->req->out.result = NT_STATUS_OK;
730 irpc_send_reply(state->msg, NT_STATUS_OK);
731 return;
734 struct wb_irpc_GetDCName_state {
735 struct irpc_message *msg;
736 struct wbint_DsGetDcName *req;
739 static void wb_irpc_GetDCName_done(struct tevent_req *subreq);
741 static NTSTATUS wb_irpc_GetDCName(struct irpc_message *msg,
742 struct wbint_DsGetDcName *req)
745 struct tevent_req *subreq = NULL;
746 struct wb_irpc_GetDCName_state *state = NULL;
748 state = talloc_zero(msg, struct wb_irpc_GetDCName_state);
749 if (state == NULL) {
750 return NT_STATUS_NO_MEMORY;
753 state->msg = msg;
754 state->req = req;
756 subreq = wb_dsgetdcname_send(msg,
757 server_event_context(),
758 req->in.domain_name,
759 req->in.domain_guid,
760 req->in.site_name,
761 req->in.flags);
762 if (subreq == NULL) {
763 return NT_STATUS_NO_MEMORY;
766 tevent_req_set_callback(subreq,
767 wb_irpc_GetDCName_done,
768 state);
770 msg->defer_reply = true;
772 return NT_STATUS_OK;
775 static void wb_irpc_GetDCName_done(struct tevent_req *subreq)
777 struct wb_irpc_GetDCName_state *state = tevent_req_callback_data(
778 subreq, struct wb_irpc_GetDCName_state);
779 NTSTATUS status;
781 status = wb_dsgetdcname_recv(subreq, state->msg,
782 state->req->out.dc_info);
783 TALLOC_FREE(subreq);
784 if (!NT_STATUS_IS_OK(status)) {
785 DBG_INFO("RPC callback failed for %s - %s\n", "DSGETDCNAME",
786 nt_errstr(status));
789 state->req->out.result = status;
791 irpc_send_reply(state->msg, NT_STATUS_OK);
794 NTSTATUS wb_irpc_register(void)
796 NTSTATUS status;
798 status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS,
799 wb_irpc_DsrUpdateReadOnlyServerDnsRecords, NULL);
800 if (!NT_STATUS_IS_OK(status)) {
801 return status;
803 status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_SAMLOGON,
804 wb_irpc_SamLogon, NULL);
805 if (!NT_STATUS_IS_OK(status)) {
806 return status;
808 status = IRPC_REGISTER(winbind_imessaging_context(), winbind,
809 WINBIND_LOGONCONTROL,
810 wb_irpc_LogonControl, NULL);
811 if (!NT_STATUS_IS_OK(status)) {
812 return status;
814 status = IRPC_REGISTER(winbind_imessaging_context(), winbind,
815 WINBIND_GETFORESTTRUSTINFORMATION,
816 wb_irpc_GetForestTrustInformation, NULL);
817 if (!NT_STATUS_IS_OK(status)) {
818 return status;
820 status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_SENDTOSAM,
821 wb_irpc_SendToSam, NULL);
822 if (!NT_STATUS_IS_OK(status)) {
823 return status;
825 status = IRPC_REGISTER(winbind_imessaging_context(),
826 lsarpc, LSA_LOOKUPSIDS3,
827 wb_irpc_lsa_LookupSids3_call, NULL);
828 if (!NT_STATUS_IS_OK(status)) {
829 return status;
831 status = IRPC_REGISTER(winbind_imessaging_context(),
832 lsarpc, LSA_LOOKUPNAMES4,
833 wb_irpc_lsa_LookupNames4_call, NULL);
834 if (!NT_STATUS_IS_OK(status)) {
835 return status;
837 status = IRPC_REGISTER(winbind_imessaging_context(),
838 winbind, WBINT_DSGETDCNAME,
839 wb_irpc_GetDCName, NULL);
840 if (!NT_STATUS_IS_OK(status)) {
841 return status;
844 return NT_STATUS_OK;