gpo: Add CSE for applying smb.conf
[Samba.git] / source3 / winbindd / winbindd_irpc.c
blobfda29c7e7022a9e1da6da750b0b5f65806cb46c4
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 const char *opname;
38 struct dcesrv_call_state *dce_call;
42 called when the forwarded rpc request is finished
44 static void wb_irpc_forward_callback(struct tevent_req *subreq)
46 struct wb_irpc_forward_state *st =
47 tevent_req_callback_data(subreq,
48 struct wb_irpc_forward_state);
49 const char *opname = st->opname;
50 NTSTATUS status;
52 status = dcerpc_binding_handle_call_recv(subreq);
53 TALLOC_FREE(subreq);
54 if (!NT_STATUS_IS_OK(status)) {
55 DEBUG(0,("RPC callback failed for %s - %s\n",
56 opname, nt_errstr(status)));
57 irpc_send_reply(st->msg, status);
58 return;
61 irpc_send_reply(st->msg, status);
66 /**
67 * Forward a RPC call using IRPC to another task
70 static NTSTATUS wb_irpc_forward_rpc_call(struct irpc_message *msg, TALLOC_CTX *mem_ctx,
71 struct tevent_context *ev,
72 void *r, uint32_t callid,
73 const char *opname,
74 struct winbindd_domain *domain,
75 uint32_t timeout)
77 struct wb_irpc_forward_state *st;
78 struct dcerpc_binding_handle *binding_handle;
79 struct tevent_req *subreq;
81 st = talloc(mem_ctx, struct wb_irpc_forward_state);
82 if (st == NULL) {
83 return NT_STATUS_NO_MEMORY;
86 st->msg = msg;
87 st->opname = opname;
89 binding_handle = dom_child_handle(domain);
90 if (binding_handle == NULL) {
91 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
92 opname, domain->name));
93 return NT_STATUS_UNSUCCESSFUL;
96 /* reset timeout for the handle */
97 dcerpc_binding_handle_set_timeout(binding_handle, timeout);
99 /* forward the call */
100 subreq = dcerpc_binding_handle_call_send(st, ev,
101 binding_handle,
102 NULL, &ndr_table_winbind,
103 callid,
104 msg, r);
105 if (subreq == NULL) {
106 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
107 opname, domain->name));
108 return NT_STATUS_UNSUCCESSFUL;
111 /* mark the request as replied async */
112 msg->defer_reply = true;
114 /* setup the callback */
115 tevent_req_set_callback(subreq, wb_irpc_forward_callback, st);
116 return NT_STATUS_OK;
119 static NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg,
120 struct winbind_DsrUpdateReadOnlyServerDnsRecords *req)
122 struct winbindd_domain *domain = find_our_domain();
123 if (domain == NULL) {
124 return NT_STATUS_NO_SUCH_DOMAIN;
127 DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n"));
129 return wb_irpc_forward_rpc_call(msg, msg,
130 global_event_context(),
131 req, NDR_WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS,
132 "winbind_DsrUpdateReadOnlyServerDnsRecords",
133 domain, IRPC_CALL_TIMEOUT);
136 static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
137 struct winbind_SamLogon *req)
139 struct winbindd_domain *domain;
140 struct netr_IdentityInfo *identity_info;
141 const char *target_domain_name = NULL;
142 const char *account_name = NULL;
144 switch (req->in.logon_level) {
145 case NetlogonInteractiveInformation:
146 case NetlogonServiceInformation:
147 case NetlogonInteractiveTransitiveInformation:
148 case NetlogonServiceTransitiveInformation:
149 if (req->in.logon.password == NULL) {
150 return NT_STATUS_REQUEST_NOT_ACCEPTED;
152 identity_info = &req->in.logon.password->identity_info;
153 break;
155 case NetlogonNetworkInformation:
156 case NetlogonNetworkTransitiveInformation:
157 if (req->in.logon.network == NULL) {
158 return NT_STATUS_REQUEST_NOT_ACCEPTED;
161 identity_info = &req->in.logon.network->identity_info;
162 break;
164 case NetlogonGenericInformation:
165 if (req->in.logon.generic == NULL) {
166 return NT_STATUS_REQUEST_NOT_ACCEPTED;
169 identity_info = &req->in.logon.generic->identity_info;
170 break;
172 default:
173 return NT_STATUS_REQUEST_NOT_ACCEPTED;
176 target_domain_name = identity_info->domain_name.string;
177 if (target_domain_name == NULL) {
178 target_domain_name = "";
181 account_name = identity_info->account_name.string;
182 if (account_name == NULL) {
183 account_name = "";
186 if (IS_DC && target_domain_name[0] == '\0') {
187 const char *p = NULL;
189 p = strchr_m(account_name, '@');
190 if (p != NULL) {
191 target_domain_name = p + 1;
195 if (IS_DC && target_domain_name[0] == '\0') {
196 DBG_ERR("target_domain[%s] account[%s]\n",
197 target_domain_name, account_name);
198 return NT_STATUS_REQUEST_NOT_ACCEPTED;
201 domain = find_auth_domain(0, target_domain_name);
202 if (domain == NULL) {
203 DBG_INFO("target_domain[%s] for account[%s] not known\n",
204 target_domain_name, account_name);
205 req->out.result = NT_STATUS_NO_SUCH_USER;
206 req->out.authoritative = 0;
207 return NT_STATUS_OK;
210 DEBUG(5, ("wb_irpc_SamLogon called\n"));
212 return wb_irpc_forward_rpc_call(msg, msg,
213 global_event_context(),
214 req, NDR_WINBIND_SAMLOGON,
215 "winbind_SamLogon",
216 domain, IRPC_CALL_TIMEOUT);
219 static NTSTATUS wb_irpc_LogonControl(struct irpc_message *msg,
220 struct winbind_LogonControl *req)
222 TALLOC_CTX *frame = talloc_stackframe();
223 char *domain_name = NULL;
224 struct winbindd_domain *domain = NULL;
226 DEBUG(5, ("wb_irpc_LogonControl called\n"));
228 switch (req->in.function_code) {
229 case NETLOGON_CONTROL_REDISCOVER:
230 case NETLOGON_CONTROL_TC_QUERY:
231 case NETLOGON_CONTROL_CHANGE_PASSWORD:
232 case NETLOGON_CONTROL_TC_VERIFY:
233 if (req->in.data->domain == NULL) {
234 TALLOC_FREE(frame);
235 return NT_STATUS_INVALID_PARAMETER;
238 domain_name = talloc_strdup(frame, req->in.data->domain);
239 if (domain_name == NULL) {
240 req->out.result = WERR_NOT_ENOUGH_MEMORY;
241 TALLOC_FREE(frame);
242 return NT_STATUS_OK;
245 break;
246 default:
247 TALLOC_FREE(frame);
248 return NT_STATUS_NOT_IMPLEMENTED;
251 if (req->in.function_code == NETLOGON_CONTROL_REDISCOVER) {
252 char *p = NULL;
255 * NETLOGON_CONTROL_REDISCOVER
256 * get's an optional \dcname appended to the domain name
258 p = strchr_m(domain_name, '\\');
259 if (p != NULL) {
260 *p = '\0';
264 domain = find_domain_from_name_noinit(domain_name);
265 if (domain == NULL) {
266 req->out.result = WERR_NO_SUCH_DOMAIN;
267 TALLOC_FREE(frame);
268 return NT_STATUS_OK;
271 TALLOC_FREE(frame);
272 return wb_irpc_forward_rpc_call(msg, msg,
273 global_event_context(),
274 req, NDR_WINBIND_LOGONCONTROL,
275 "winbind_LogonControl",
276 domain, 45 /* timeout */);
279 static NTSTATUS wb_irpc_GetForestTrustInformation(struct irpc_message *msg,
280 struct winbind_GetForestTrustInformation *req)
282 struct winbindd_domain *domain = NULL;
284 if (req->in.trusted_domain_name == NULL) {
285 req->out.result = WERR_NO_SUCH_DOMAIN;
286 return NT_STATUS_OK;
289 domain = find_trust_from_name_noinit(req->in.trusted_domain_name);
290 if (domain == NULL) {
291 req->out.result = WERR_NO_SUCH_DOMAIN;
292 return NT_STATUS_OK;
296 * checking for domain->internal and domain->primary
297 * makes sure we only do some work when running as DC.
300 if (domain->internal) {
301 req->out.result = WERR_NO_SUCH_DOMAIN;
302 return NT_STATUS_OK;
305 if (domain->primary) {
306 req->out.result = WERR_NO_SUCH_DOMAIN;
307 return NT_STATUS_OK;
310 DEBUG(5, ("wb_irpc_GetForestTrustInformation called\n"));
312 return wb_irpc_forward_rpc_call(msg, msg,
313 global_event_context(),
314 req, NDR_WINBIND_GETFORESTTRUSTINFORMATION,
315 "winbind_GetForestTrustInformation",
316 domain, 45 /* timeout */);
319 static NTSTATUS wb_irpc_SendToSam(struct irpc_message *msg,
320 struct winbind_SendToSam *req)
322 /* TODO make sure that it is RWDC */
323 struct winbindd_domain *domain = find_our_domain();
324 if (domain == NULL) {
325 return NT_STATUS_NO_SUCH_DOMAIN;
328 DEBUG(5, ("wb_irpc_SendToSam called\n"));
330 return wb_irpc_forward_rpc_call(msg, msg,
331 global_event_context(),
332 req, NDR_WINBIND_SENDTOSAM,
333 "winbind_SendToSam",
334 domain, IRPC_CALL_TIMEOUT);
337 struct wb_irpc_lsa_LookupSids3_state {
338 struct irpc_message *msg;
339 struct lsa_LookupSids3 *req;
342 static void wb_irpc_lsa_LookupSids3_done(struct tevent_req *subreq);
344 static NTSTATUS wb_irpc_lsa_LookupSids3_call(struct irpc_message *msg,
345 struct lsa_LookupSids3 *req)
347 struct wb_irpc_lsa_LookupSids3_state *state = NULL;
348 struct tevent_req *subreq = NULL;
349 struct dom_sid *sids = NULL;
350 uint32_t i;
352 state = talloc_zero(msg, struct wb_irpc_lsa_LookupSids3_state);
353 if (state == NULL) {
354 return NT_STATUS_NO_MEMORY;
357 state->msg = msg;
358 state->req = req;
360 state->req->out.domains = talloc_zero(state->msg,
361 struct lsa_RefDomainList *);
362 if (state->req->out.domains == NULL) {
363 return NT_STATUS_NO_MEMORY;
365 state->req->out.names = talloc_zero(state->msg,
366 struct lsa_TransNameArray2);
367 if (state->req->out.names == NULL) {
368 return NT_STATUS_NO_MEMORY;
370 state->req->out.count = talloc_zero(state->msg, uint32_t);
371 if (state->req->out.count == NULL) {
372 return NT_STATUS_NO_MEMORY;
375 state->req->out.names->names = talloc_zero_array(state->msg,
376 struct lsa_TranslatedName2,
377 req->in.sids->num_sids);
378 if (state->req->out.names->names == NULL) {
379 return NT_STATUS_NO_MEMORY;
382 sids = talloc_zero_array(state, struct dom_sid,
383 req->in.sids->num_sids);
384 if (sids == NULL) {
385 return NT_STATUS_NO_MEMORY;
388 for (i = 0; i < req->in.sids->num_sids; i++) {
389 if (req->in.sids->sids[i].sid == NULL) {
390 return NT_STATUS_REQUEST_NOT_ACCEPTED;
393 sids[i] = *req->in.sids->sids[i].sid;
396 subreq = wb_lookupsids_send(msg,
397 global_event_context(),
398 sids, req->in.sids->num_sids);
399 if (subreq == NULL) {
400 return NT_STATUS_NO_MEMORY;
402 tevent_req_set_callback(subreq, wb_irpc_lsa_LookupSids3_done, state);
403 msg->defer_reply = true;
405 return NT_STATUS_OK;
408 static void wb_irpc_lsa_LookupSids3_done(struct tevent_req *subreq)
410 struct wb_irpc_lsa_LookupSids3_state *state =
411 tevent_req_callback_data(subreq,
412 struct wb_irpc_lsa_LookupSids3_state);
413 struct lsa_RefDomainList *domains = NULL;
414 struct lsa_TransNameArray *names = NULL;
415 NTSTATUS status;
416 uint32_t i;
418 status = wb_lookupsids_recv(subreq, state->msg,
419 &domains, &names);
420 TALLOC_FREE(subreq);
421 if (!NT_STATUS_IS_OK(status)) {
422 DEBUG(0,("RPC callback failed for %s - %s\n",
423 __func__, nt_errstr(status)));
424 irpc_send_reply(state->msg, status);
425 return;
428 if (names->count > state->req->in.sids->num_sids) {
429 status = NT_STATUS_INTERNAL_ERROR;
430 DEBUG(0,("RPC callback failed for %s - %s\n",
431 __func__, nt_errstr(status)));
432 irpc_send_reply(state->msg, status);
433 return;
436 *state->req->out.domains = domains;
437 for (i = 0; i < names->count; i++) {
438 struct lsa_TranslatedName2 *n2 =
439 &state->req->out.names->names[i];
441 n2->sid_type = names->names[i].sid_type;
442 n2->name = names->names[i].name;
443 n2->sid_index = names->names[i].sid_index;
444 n2->unknown = 0;
446 if (n2->sid_type != SID_NAME_UNKNOWN) {
447 (*state->req->out.count)++;
450 state->req->out.names->count = names->count;
452 if (*state->req->out.count == 0) {
453 state->req->out.result = NT_STATUS_NONE_MAPPED;
454 } else if (*state->req->out.count != names->count) {
455 state->req->out.result = NT_STATUS_SOME_NOT_MAPPED;
456 } else {
457 state->req->out.result = NT_STATUS_OK;
460 irpc_send_reply(state->msg, NT_STATUS_OK);
461 return;
464 struct wb_irpc_lsa_LookupNames4_name {
465 void *state;
466 uint32_t idx;
467 const char *namespace;
468 const char *domain;
469 char *name;
470 struct dom_sid sid;
471 enum lsa_SidType type;
472 struct dom_sid *authority_sid;
475 struct wb_irpc_lsa_LookupNames4_state {
476 struct irpc_message *msg;
477 struct lsa_LookupNames4 *req;
478 struct wb_irpc_lsa_LookupNames4_name *names;
479 uint32_t num_pending;
480 uint32_t num_domain_sids;
481 struct dom_sid *domain_sids;
484 static void wb_irpc_lsa_LookupNames4_done(struct tevent_req *subreq);
486 static NTSTATUS wb_irpc_lsa_LookupNames4_call(struct irpc_message *msg,
487 struct lsa_LookupNames4 *req)
489 struct wb_irpc_lsa_LookupNames4_state *state = NULL;
490 struct tevent_req *subreq = NULL;
491 uint32_t i;
494 state = talloc_zero(msg, struct wb_irpc_lsa_LookupNames4_state);
495 if (state == NULL) {
496 return NT_STATUS_NO_MEMORY;
499 state->msg = msg;
500 state->req = req;
502 state->req->out.domains = talloc_zero(state->msg,
503 struct lsa_RefDomainList *);
504 if (state->req->out.domains == NULL) {
505 return NT_STATUS_NO_MEMORY;
507 state->req->out.sids = talloc_zero(state->msg,
508 struct lsa_TransSidArray3);
509 if (state->req->out.sids == NULL) {
510 return NT_STATUS_NO_MEMORY;
512 state->req->out.count = talloc_zero(state->msg, uint32_t);
513 if (state->req->out.count == NULL) {
514 return NT_STATUS_NO_MEMORY;
517 state->req->out.sids->sids = talloc_zero_array(state->msg,
518 struct lsa_TranslatedSid3,
519 req->in.num_names);
520 if (state->req->out.sids->sids == NULL) {
521 return NT_STATUS_NO_MEMORY;
524 state->names = talloc_zero_array(state,
525 struct wb_irpc_lsa_LookupNames4_name,
526 req->in.num_names);
527 if (state->names == NULL) {
528 return NT_STATUS_NO_MEMORY;
531 for (i = 0; i < req->in.num_names; i++) {
532 struct wb_irpc_lsa_LookupNames4_name *nstate =
533 &state->names[i];
534 char *p = NULL;
536 if (req->in.names[i].string == NULL) {
537 DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
538 __location__, req->in.names[i].string);
539 return NT_STATUS_REQUEST_NOT_ACCEPTED;
541 nstate->state = state;
542 nstate->idx = i;
543 nstate->name = talloc_strdup(state->names,
544 req->in.names[i].string);
545 if (nstate->name == NULL) {
546 return NT_STATUS_NO_MEMORY;
548 nstate->type = SID_NAME_UNKNOWN;
550 /* cope with the name being a fully qualified name */
551 p = strchr(nstate->name, '\\');
552 if (p != NULL) {
553 *p = 0;
554 nstate->domain = nstate->name;
555 nstate->namespace = nstate->domain;
556 nstate->name = p+1;
557 } else if ((p = strchr(nstate->name, '@')) != NULL) {
558 /* upn */
559 nstate->domain = "";
560 nstate->namespace = p + 1;
561 } else {
563 * TODO: select the domain based on
564 * req->in.level and req->in.client_revision
566 * For now we don't allow this.
568 DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
569 __location__, nstate->name);
570 return NT_STATUS_REQUEST_NOT_ACCEPTED;
573 subreq = wb_lookupname_send(msg,
574 global_event_context(),
575 nstate->namespace,
576 nstate->domain,
577 nstate->name,
578 LOOKUP_NAME_NO_NSS);
579 if (subreq == NULL) {
580 return NT_STATUS_NO_MEMORY;
582 tevent_req_set_callback(subreq,
583 wb_irpc_lsa_LookupNames4_done,
584 nstate);
585 state->num_pending++;
588 msg->defer_reply = true;
590 return NT_STATUS_OK;
593 static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req *subreq);
595 static void wb_irpc_lsa_LookupNames4_done(struct tevent_req *subreq)
597 struct wb_irpc_lsa_LookupNames4_name *nstate =
598 (struct wb_irpc_lsa_LookupNames4_name *)
599 tevent_req_callback_data_void(subreq);
600 struct wb_irpc_lsa_LookupNames4_state *state =
601 talloc_get_type_abort(nstate->state,
602 struct wb_irpc_lsa_LookupNames4_state);
603 struct dom_sid_buf buf;
604 NTSTATUS status;
606 SMB_ASSERT(state->num_pending > 0);
607 state->num_pending--;
608 status = wb_lookupname_recv(subreq, &nstate->sid, &nstate->type);
609 TALLOC_FREE(subreq);
610 if (!NT_STATUS_IS_OK(status)) {
611 DEBUG(0,("RPC callback failed for %s - %s\n",
612 __func__, nt_errstr(status)));
613 irpc_send_reply(state->msg, status);
614 return;
617 status = dom_sid_split_rid(state, &nstate->sid,
618 &nstate->authority_sid, NULL);
619 if (!NT_STATUS_IS_OK(status)) {
620 DBG_ERR("dom_sid_split_rid(%s) failed - %s\n",
621 dom_sid_str_buf(&nstate->sid, &buf),
622 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 dom_sid_str_buf(nstate->authority_sid, &buf),
634 nt_errstr(status));
635 irpc_send_reply(state->msg, status);
636 return;
639 if (state->num_pending > 0) {
641 * wait for more...
643 return;
647 * Now resolve all domains back to a name
648 * to get a good lsa_RefDomainList
650 subreq = wb_lookupsids_send(state,
651 global_event_context(),
652 state->domain_sids,
653 state->num_domain_sids);
654 if (subreq == NULL) {
655 status = NT_STATUS_NO_MEMORY;
656 DBG_ERR("wb_lookupsids_send - %s\n",
657 nt_errstr(status));
658 irpc_send_reply(state->msg, status);
659 return;
661 tevent_req_set_callback(subreq,
662 wb_irpc_lsa_LookupNames4_domains_done,
663 state);
665 return;
668 static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req *subreq)
670 struct wb_irpc_lsa_LookupNames4_state *state =
671 tevent_req_callback_data(subreq,
672 struct wb_irpc_lsa_LookupNames4_state);
673 struct lsa_RefDomainList *domains = NULL;
674 struct lsa_TransNameArray *names = NULL;
675 NTSTATUS status;
676 uint32_t i;
678 status = wb_lookupsids_recv(subreq, state->msg,
679 &domains, &names);
680 TALLOC_FREE(subreq);
681 if (!NT_STATUS_IS_OK(status)) {
682 DEBUG(0,("RPC callback failed for %s - %s\n",
683 __func__, nt_errstr(status)));
684 irpc_send_reply(state->msg, status);
685 return;
688 *state->req->out.domains = domains;
689 for (i = 0; i < state->req->in.num_names; i++) {
690 struct wb_irpc_lsa_LookupNames4_name *nstate =
691 &state->names[i];
692 struct lsa_TranslatedSid3 *s3 =
693 &state->req->out.sids->sids[i];
694 uint32_t di;
696 s3->sid_type = nstate->type;
697 if (s3->sid_type != SID_NAME_UNKNOWN) {
698 s3->sid = &nstate->sid;
699 } else {
700 s3->sid = NULL;
702 s3->sid_index = UINT32_MAX;
703 for (di = 0; di < domains->count; di++) {
704 bool match;
706 if (domains->domains[di].sid == NULL) {
707 continue;
710 match = dom_sid_equal(nstate->authority_sid,
711 domains->domains[di].sid);
712 if (match) {
713 s3->sid_index = di;
714 break;
717 if (s3->sid_type != SID_NAME_UNKNOWN) {
718 (*state->req->out.count)++;
721 state->req->out.sids->count = state->req->in.num_names;
723 if (*state->req->out.count == 0) {
724 state->req->out.result = NT_STATUS_NONE_MAPPED;
725 } else if (*state->req->out.count != state->req->in.num_names) {
726 state->req->out.result = NT_STATUS_SOME_NOT_MAPPED;
727 } else {
728 state->req->out.result = NT_STATUS_OK;
731 irpc_send_reply(state->msg, NT_STATUS_OK);
732 return;
735 struct wb_irpc_GetDCName_state {
736 struct irpc_message *msg;
737 struct wbint_DsGetDcName *req;
740 static void wb_irpc_GetDCName_done(struct tevent_req *subreq);
742 static NTSTATUS wb_irpc_GetDCName(struct irpc_message *msg,
743 struct wbint_DsGetDcName *req)
746 struct tevent_req *subreq = NULL;
747 struct wb_irpc_GetDCName_state *state = NULL;
749 state = talloc_zero(msg, struct wb_irpc_GetDCName_state);
750 if (state == NULL) {
751 return NT_STATUS_NO_MEMORY;
754 state->msg = msg;
755 state->req = req;
757 subreq = wb_dsgetdcname_send(msg,
758 global_event_context(),
759 req->in.domain_name,
760 req->in.domain_guid,
761 req->in.site_name,
762 req->in.flags);
763 if (subreq == NULL) {
764 return NT_STATUS_NO_MEMORY;
767 tevent_req_set_callback(subreq,
768 wb_irpc_GetDCName_done,
769 state);
771 msg->defer_reply = true;
773 return NT_STATUS_OK;
776 static void wb_irpc_GetDCName_done(struct tevent_req *subreq)
778 struct wb_irpc_GetDCName_state *state = tevent_req_callback_data(
779 subreq, struct wb_irpc_GetDCName_state);
780 NTSTATUS status;
782 status = wb_dsgetdcname_recv(subreq, state->msg,
783 state->req->out.dc_info);
784 TALLOC_FREE(subreq);
785 if (!NT_STATUS_IS_OK(status)) {
786 DBG_INFO("RPC callback failed for %s - %s\n", "DSGETDCNAME",
787 nt_errstr(status));
790 state->req->out.result = status;
792 irpc_send_reply(state->msg, NT_STATUS_OK);
795 NTSTATUS wb_irpc_register(void)
797 NTSTATUS status;
799 status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS,
800 wb_irpc_DsrUpdateReadOnlyServerDnsRecords, NULL);
801 if (!NT_STATUS_IS_OK(status)) {
802 return status;
804 status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_SAMLOGON,
805 wb_irpc_SamLogon, NULL);
806 if (!NT_STATUS_IS_OK(status)) {
807 return status;
809 status = IRPC_REGISTER(winbind_imessaging_context(), winbind,
810 WINBIND_LOGONCONTROL,
811 wb_irpc_LogonControl, NULL);
812 if (!NT_STATUS_IS_OK(status)) {
813 return status;
815 status = IRPC_REGISTER(winbind_imessaging_context(), winbind,
816 WINBIND_GETFORESTTRUSTINFORMATION,
817 wb_irpc_GetForestTrustInformation, NULL);
818 if (!NT_STATUS_IS_OK(status)) {
819 return status;
821 status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_SENDTOSAM,
822 wb_irpc_SendToSam, NULL);
823 if (!NT_STATUS_IS_OK(status)) {
824 return status;
826 status = IRPC_REGISTER(winbind_imessaging_context(),
827 lsarpc, LSA_LOOKUPSIDS3,
828 wb_irpc_lsa_LookupSids3_call, NULL);
829 if (!NT_STATUS_IS_OK(status)) {
830 return status;
832 status = IRPC_REGISTER(winbind_imessaging_context(),
833 lsarpc, LSA_LOOKUPNAMES4,
834 wb_irpc_lsa_LookupNames4_call, NULL);
835 if (!NT_STATUS_IS_OK(status)) {
836 return status;
838 status = IRPC_REGISTER(winbind_imessaging_context(),
839 winbind, WBINT_DSGETDCNAME,
840 wb_irpc_GetDCName, NULL);
841 if (!NT_STATUS_IS_OK(status)) {
842 return status;
845 return NT_STATUS_OK;