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/>.
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"
34 #include "lib/global_contexts.h"
35 #include "lib/param/param.h"
38 struct imessaging_context
*winbind_imessaging_context(void)
40 static struct imessaging_context
*msg
= NULL
;
41 struct messaging_context
*msg_ctx
;
42 struct server_id myself
;
43 struct loadparm_context
*lp_ctx
;
49 msg_ctx
= global_messaging_context();
50 if (msg_ctx
== NULL
) {
51 smb_panic("global_messaging_context failed\n");
53 myself
= messaging_server_id(msg_ctx
);
55 lp_ctx
= loadparm_init_s3(NULL
, loadparm_s3_helpers());
57 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
61 * Note we MUST use the NULL context here, not the autofree context,
62 * to avoid side effects in forked children exiting.
64 msg
= imessaging_init(NULL
, lp_ctx
, myself
, global_event_context());
65 talloc_unlink(NULL
, lp_ctx
);
68 smb_panic("Could not init winbindd's messaging context.\n");
73 struct wb_irpc_forward_state
{
74 struct irpc_message
*msg
;
76 struct dcesrv_call_state
*dce_call
;
80 called when the forwarded rpc request is finished
82 static void wb_irpc_forward_callback(struct tevent_req
*subreq
)
84 struct wb_irpc_forward_state
*st
=
85 tevent_req_callback_data(subreq
,
86 struct wb_irpc_forward_state
);
87 const char *opname
= st
->opname
;
90 status
= dcerpc_binding_handle_call_recv(subreq
);
92 if (!NT_STATUS_IS_OK(status
)) {
93 DEBUG(0,("RPC callback failed for %s - %s\n",
94 opname
, nt_errstr(status
)));
95 irpc_send_reply(st
->msg
, status
);
99 irpc_send_reply(st
->msg
, status
);
105 * Forward a RPC call using IRPC to another task
108 static NTSTATUS
wb_irpc_forward_rpc_call(struct irpc_message
*msg
, TALLOC_CTX
*mem_ctx
,
109 struct tevent_context
*ev
,
110 void *r
, uint32_t callid
,
112 struct winbindd_domain
*domain
,
115 struct wb_irpc_forward_state
*st
;
116 struct dcerpc_binding_handle
*binding_handle
;
117 struct tevent_req
*subreq
;
119 st
= talloc(mem_ctx
, struct wb_irpc_forward_state
);
121 return NT_STATUS_NO_MEMORY
;
127 binding_handle
= dom_child_handle(domain
);
128 if (binding_handle
== NULL
) {
129 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
130 opname
, domain
->name
));
131 return NT_STATUS_UNSUCCESSFUL
;
134 /* reset timeout for the handle */
135 dcerpc_binding_handle_set_timeout(binding_handle
, timeout
);
137 /* forward the call */
138 subreq
= dcerpc_binding_handle_call_send(st
, ev
,
140 NULL
, &ndr_table_winbind
,
143 if (subreq
== NULL
) {
144 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
145 opname
, domain
->name
));
146 return NT_STATUS_UNSUCCESSFUL
;
149 /* mark the request as replied async */
150 msg
->defer_reply
= true;
152 /* setup the callback */
153 tevent_req_set_callback(subreq
, wb_irpc_forward_callback
, st
);
157 static NTSTATUS
wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message
*msg
,
158 struct winbind_DsrUpdateReadOnlyServerDnsRecords
*req
)
160 struct winbindd_domain
*domain
= find_our_domain();
161 if (domain
== NULL
) {
162 return NT_STATUS_NO_SUCH_DOMAIN
;
165 DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n"));
167 return wb_irpc_forward_rpc_call(msg
, msg
,
168 global_event_context(),
169 req
, NDR_WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS
,
170 "winbind_DsrUpdateReadOnlyServerDnsRecords",
171 domain
, IRPC_CALL_TIMEOUT
);
174 static NTSTATUS
wb_irpc_SamLogon(struct irpc_message
*msg
,
175 struct winbind_SamLogon
*req
)
177 struct winbindd_domain
*domain
;
178 struct netr_IdentityInfo
*identity_info
;
179 const char *target_domain_name
= NULL
;
180 const char *account_name
= NULL
;
183 * Make sure we start with authoritative=true,
184 * it will only set to false if we don't know the
187 req
->out
.authoritative
= true;
189 switch (req
->in
.logon_level
) {
190 case NetlogonInteractiveInformation
:
191 case NetlogonServiceInformation
:
192 case NetlogonInteractiveTransitiveInformation
:
193 case NetlogonServiceTransitiveInformation
:
194 if (req
->in
.logon
.password
== NULL
) {
195 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
197 identity_info
= &req
->in
.logon
.password
->identity_info
;
200 case NetlogonNetworkInformation
:
201 case NetlogonNetworkTransitiveInformation
:
202 if (req
->in
.logon
.network
== NULL
) {
203 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
206 identity_info
= &req
->in
.logon
.network
->identity_info
;
209 case NetlogonGenericInformation
:
210 if (req
->in
.logon
.generic
== NULL
) {
211 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
214 identity_info
= &req
->in
.logon
.generic
->identity_info
;
218 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
221 target_domain_name
= identity_info
->domain_name
.string
;
222 if (target_domain_name
== NULL
) {
223 target_domain_name
= "";
226 account_name
= identity_info
->account_name
.string
;
227 if (account_name
== NULL
) {
231 if (IS_DC
&& target_domain_name
[0] == '\0') {
232 const char *p
= NULL
;
234 p
= strchr_m(account_name
, '@');
236 target_domain_name
= p
+ 1;
240 if (IS_DC
&& target_domain_name
[0] == '\0') {
241 DBG_ERR("target_domain[%s] account[%s]\n",
242 target_domain_name
, account_name
);
243 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
246 domain
= find_auth_domain(0, target_domain_name
);
247 if (domain
== NULL
) {
248 DBG_INFO("target_domain[%s] for account[%s] not known\n",
249 target_domain_name
, account_name
);
250 req
->out
.result
= NT_STATUS_NO_SUCH_USER
;
251 req
->out
.authoritative
= 0;
255 DEBUG(5, ("wb_irpc_SamLogon called\n"));
257 return wb_irpc_forward_rpc_call(msg
, msg
,
258 global_event_context(),
259 req
, NDR_WINBIND_SAMLOGON
,
261 domain
, IRPC_CALL_TIMEOUT
);
264 static NTSTATUS
wb_irpc_LogonControl(struct irpc_message
*msg
,
265 struct winbind_LogonControl
*req
)
267 TALLOC_CTX
*frame
= talloc_stackframe();
268 char *domain_name
= NULL
;
269 struct winbindd_domain
*domain
= NULL
;
271 DEBUG(5, ("wb_irpc_LogonControl called\n"));
273 switch (req
->in
.function_code
) {
274 case NETLOGON_CONTROL_REDISCOVER
:
275 case NETLOGON_CONTROL_TC_QUERY
:
276 case NETLOGON_CONTROL_CHANGE_PASSWORD
:
277 case NETLOGON_CONTROL_TC_VERIFY
:
278 if (req
->in
.data
->domain
== NULL
) {
280 return NT_STATUS_INVALID_PARAMETER
;
283 domain_name
= talloc_strdup(frame
, req
->in
.data
->domain
);
284 if (domain_name
== NULL
) {
285 req
->out
.result
= WERR_NOT_ENOUGH_MEMORY
;
293 return NT_STATUS_NOT_IMPLEMENTED
;
296 if (req
->in
.function_code
== NETLOGON_CONTROL_REDISCOVER
) {
300 * NETLOGON_CONTROL_REDISCOVER
301 * gets an optional \dcname appended to the domain name
303 p
= strchr_m(domain_name
, '\\');
309 domain
= find_domain_from_name_noinit(domain_name
);
310 if (domain
== NULL
) {
311 req
->out
.result
= WERR_NO_SUCH_DOMAIN
;
317 return wb_irpc_forward_rpc_call(msg
, msg
,
318 global_event_context(),
319 req
, NDR_WINBIND_LOGONCONTROL
,
320 "winbind_LogonControl",
321 domain
, 45 /* timeout */);
324 static NTSTATUS
wb_irpc_GetForestTrustInformation(struct irpc_message
*msg
,
325 struct winbind_GetForestTrustInformation
*req
)
327 struct winbindd_domain
*domain
= NULL
;
329 if (req
->in
.trusted_domain_name
== NULL
) {
330 req
->out
.result
= WERR_NO_SUCH_DOMAIN
;
334 domain
= find_trust_from_name_noinit(req
->in
.trusted_domain_name
);
335 if (domain
== NULL
) {
336 req
->out
.result
= WERR_NO_SUCH_DOMAIN
;
341 * checking for domain->internal and domain->primary
342 * makes sure we only do some work when running as DC.
345 if (domain
->internal
) {
346 req
->out
.result
= WERR_NO_SUCH_DOMAIN
;
350 if (domain
->primary
) {
351 req
->out
.result
= WERR_NO_SUCH_DOMAIN
;
355 DEBUG(5, ("wb_irpc_GetForestTrustInformation called\n"));
357 return wb_irpc_forward_rpc_call(msg
, msg
,
358 global_event_context(),
359 req
, NDR_WINBIND_GETFORESTTRUSTINFORMATION
,
360 "winbind_GetForestTrustInformation",
361 domain
, 45 /* timeout */);
364 static NTSTATUS
wb_irpc_SendToSam(struct irpc_message
*msg
,
365 struct winbind_SendToSam
*req
)
367 /* TODO make sure that it is RWDC */
368 struct winbindd_domain
*domain
= find_our_domain();
369 if (domain
== NULL
) {
370 return NT_STATUS_NO_SUCH_DOMAIN
;
373 DEBUG(5, ("wb_irpc_SendToSam called\n"));
375 return wb_irpc_forward_rpc_call(msg
, msg
,
376 global_event_context(),
377 req
, NDR_WINBIND_SENDTOSAM
,
379 domain
, IRPC_CALL_TIMEOUT
);
382 struct wb_irpc_lsa_LookupSids3_state
{
383 struct irpc_message
*msg
;
384 struct lsa_LookupSids3
*req
;
387 static void wb_irpc_lsa_LookupSids3_done(struct tevent_req
*subreq
);
389 static NTSTATUS
wb_irpc_lsa_LookupSids3_call(struct irpc_message
*msg
,
390 struct lsa_LookupSids3
*req
)
392 struct wb_irpc_lsa_LookupSids3_state
*state
= NULL
;
393 struct tevent_req
*subreq
= NULL
;
394 struct dom_sid
*sids
= NULL
;
397 state
= talloc_zero(msg
, struct wb_irpc_lsa_LookupSids3_state
);
399 return NT_STATUS_NO_MEMORY
;
405 state
->req
->out
.domains
= talloc_zero(state
->msg
,
406 struct lsa_RefDomainList
*);
407 if (state
->req
->out
.domains
== NULL
) {
408 return NT_STATUS_NO_MEMORY
;
410 state
->req
->out
.names
= talloc_zero(state
->msg
,
411 struct lsa_TransNameArray2
);
412 if (state
->req
->out
.names
== NULL
) {
413 return NT_STATUS_NO_MEMORY
;
415 state
->req
->out
.count
= talloc_zero(state
->msg
, uint32_t);
416 if (state
->req
->out
.count
== NULL
) {
417 return NT_STATUS_NO_MEMORY
;
420 state
->req
->out
.names
->names
= talloc_zero_array(state
->msg
,
421 struct lsa_TranslatedName2
,
422 req
->in
.sids
->num_sids
);
423 if (state
->req
->out
.names
->names
== NULL
) {
424 return NT_STATUS_NO_MEMORY
;
427 sids
= talloc_zero_array(state
, struct dom_sid
,
428 req
->in
.sids
->num_sids
);
430 return NT_STATUS_NO_MEMORY
;
433 for (i
= 0; i
< req
->in
.sids
->num_sids
; i
++) {
434 if (req
->in
.sids
->sids
[i
].sid
== NULL
) {
435 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
438 sids
[i
] = *req
->in
.sids
->sids
[i
].sid
;
441 subreq
= wb_lookupsids_send(msg
,
442 global_event_context(),
443 sids
, req
->in
.sids
->num_sids
);
444 if (subreq
== NULL
) {
445 return NT_STATUS_NO_MEMORY
;
447 tevent_req_set_callback(subreq
, wb_irpc_lsa_LookupSids3_done
, state
);
448 msg
->defer_reply
= true;
453 static void wb_irpc_lsa_LookupSids3_done(struct tevent_req
*subreq
)
455 struct wb_irpc_lsa_LookupSids3_state
*state
=
456 tevent_req_callback_data(subreq
,
457 struct wb_irpc_lsa_LookupSids3_state
);
458 struct lsa_RefDomainList
*domains
= NULL
;
459 struct lsa_TransNameArray
*names
= NULL
;
463 status
= wb_lookupsids_recv(subreq
, state
->msg
,
466 if (!NT_STATUS_IS_OK(status
)) {
467 DEBUG(0,("RPC callback failed for %s - %s\n",
468 __func__
, nt_errstr(status
)));
469 irpc_send_reply(state
->msg
, status
);
473 if (names
->count
> state
->req
->in
.sids
->num_sids
) {
474 status
= NT_STATUS_INTERNAL_ERROR
;
475 DEBUG(0,("RPC callback failed for %s - %s\n",
476 __func__
, nt_errstr(status
)));
477 irpc_send_reply(state
->msg
, status
);
481 *state
->req
->out
.domains
= domains
;
482 for (i
= 0; i
< names
->count
; i
++) {
483 struct lsa_TranslatedName2
*n2
=
484 &state
->req
->out
.names
->names
[i
];
486 n2
->sid_type
= names
->names
[i
].sid_type
;
487 n2
->name
= names
->names
[i
].name
;
488 n2
->sid_index
= names
->names
[i
].sid_index
;
491 if (n2
->sid_type
!= SID_NAME_UNKNOWN
) {
492 (*state
->req
->out
.count
)++;
495 state
->req
->out
.names
->count
= names
->count
;
497 if (*state
->req
->out
.count
== 0) {
498 state
->req
->out
.result
= NT_STATUS_NONE_MAPPED
;
499 } else if (*state
->req
->out
.count
!= names
->count
) {
500 state
->req
->out
.result
= NT_STATUS_SOME_NOT_MAPPED
;
502 state
->req
->out
.result
= NT_STATUS_OK
;
505 irpc_send_reply(state
->msg
, NT_STATUS_OK
);
509 struct wb_irpc_lsa_LookupNames4_name
{
512 const char *namespace;
516 enum lsa_SidType type
;
517 struct dom_sid
*authority_sid
;
520 struct wb_irpc_lsa_LookupNames4_state
{
521 struct irpc_message
*msg
;
522 struct lsa_LookupNames4
*req
;
523 struct wb_irpc_lsa_LookupNames4_name
*names
;
524 uint32_t num_pending
;
525 uint32_t num_domain_sids
;
526 struct dom_sid
*domain_sids
;
529 static void wb_irpc_lsa_LookupNames4_done(struct tevent_req
*subreq
);
531 static NTSTATUS
wb_irpc_lsa_LookupNames4_call(struct irpc_message
*msg
,
532 struct lsa_LookupNames4
*req
)
534 struct wb_irpc_lsa_LookupNames4_state
*state
= NULL
;
535 struct tevent_req
*subreq
= NULL
;
539 state
= talloc_zero(msg
, struct wb_irpc_lsa_LookupNames4_state
);
541 return NT_STATUS_NO_MEMORY
;
547 state
->req
->out
.domains
= talloc_zero(state
->msg
,
548 struct lsa_RefDomainList
*);
549 if (state
->req
->out
.domains
== NULL
) {
550 return NT_STATUS_NO_MEMORY
;
552 state
->req
->out
.sids
= talloc_zero(state
->msg
,
553 struct lsa_TransSidArray3
);
554 if (state
->req
->out
.sids
== NULL
) {
555 return NT_STATUS_NO_MEMORY
;
557 state
->req
->out
.count
= talloc_zero(state
->msg
, uint32_t);
558 if (state
->req
->out
.count
== NULL
) {
559 return NT_STATUS_NO_MEMORY
;
562 state
->req
->out
.sids
->sids
= talloc_zero_array(state
->msg
,
563 struct lsa_TranslatedSid3
,
565 if (state
->req
->out
.sids
->sids
== NULL
) {
566 return NT_STATUS_NO_MEMORY
;
569 state
->names
= talloc_zero_array(state
,
570 struct wb_irpc_lsa_LookupNames4_name
,
572 if (state
->names
== NULL
) {
573 return NT_STATUS_NO_MEMORY
;
576 for (i
= 0; i
< req
->in
.num_names
; i
++) {
577 struct wb_irpc_lsa_LookupNames4_name
*nstate
=
581 if (req
->in
.names
[i
].string
== NULL
) {
582 DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
583 __location__
, req
->in
.names
[i
].string
);
584 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
586 nstate
->state
= state
;
588 nstate
->name
= talloc_strdup(state
->names
,
589 req
->in
.names
[i
].string
);
590 if (nstate
->name
== NULL
) {
591 return NT_STATUS_NO_MEMORY
;
593 nstate
->type
= SID_NAME_UNKNOWN
;
595 /* cope with the name being a fully qualified name */
596 p
= strchr(nstate
->name
, '\\');
599 nstate
->domain
= nstate
->name
;
600 nstate
->namespace = nstate
->domain
;
602 } else if ((p
= strchr(nstate
->name
, '@')) != NULL
) {
605 nstate
->namespace = p
+ 1;
608 * TODO: select the domain based on
609 * req->in.level and req->in.client_revision
611 * For now we don't allow this.
613 DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
614 __location__
, nstate
->name
);
615 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
618 subreq
= wb_lookupname_send(msg
,
619 global_event_context(),
624 if (subreq
== NULL
) {
625 return NT_STATUS_NO_MEMORY
;
627 tevent_req_set_callback(subreq
,
628 wb_irpc_lsa_LookupNames4_done
,
630 state
->num_pending
++;
633 msg
->defer_reply
= true;
638 static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req
*subreq
);
640 static void wb_irpc_lsa_LookupNames4_done(struct tevent_req
*subreq
)
642 struct wb_irpc_lsa_LookupNames4_name
*nstate
=
643 (struct wb_irpc_lsa_LookupNames4_name
*)
644 tevent_req_callback_data_void(subreq
);
645 struct wb_irpc_lsa_LookupNames4_state
*state
=
646 talloc_get_type_abort(nstate
->state
,
647 struct wb_irpc_lsa_LookupNames4_state
);
648 struct dom_sid_buf buf
;
651 SMB_ASSERT(state
->num_pending
> 0);
652 state
->num_pending
--;
653 status
= wb_lookupname_recv(subreq
, &nstate
->sid
, &nstate
->type
);
655 if (NT_STATUS_IS_OK(status
) && nstate
->type
== SID_NAME_UNKNOWN
) {
656 status
= NT_STATUS_NONE_MAPPED
;
658 if (!NT_STATUS_IS_OK(status
)) {
659 DEBUG(0,("RPC callback failed for %s - %s\n",
660 __func__
, nt_errstr(status
)));
661 irpc_send_reply(state
->msg
, status
);
665 status
= dom_sid_split_rid(state
, &nstate
->sid
,
666 &nstate
->authority_sid
, NULL
);
667 if (!NT_STATUS_IS_OK(status
)) {
668 DBG_ERR("dom_sid_split_rid(%s) failed - %s\n",
669 dom_sid_str_buf(&nstate
->sid
, &buf
),
671 irpc_send_reply(state
->msg
, status
);
675 status
= add_sid_to_array_unique(state
,
676 nstate
->authority_sid
,
678 &state
->num_domain_sids
);
679 if (!NT_STATUS_IS_OK(status
)) {
680 DBG_ERR("add_sid_to_array_unique(%s) failed - %s\n",
681 dom_sid_str_buf(nstate
->authority_sid
, &buf
),
683 irpc_send_reply(state
->msg
, status
);
687 if (state
->num_pending
> 0) {
695 * Now resolve all domains back to a name
696 * to get a good lsa_RefDomainList
698 subreq
= wb_lookupsids_send(state
,
699 global_event_context(),
701 state
->num_domain_sids
);
702 if (subreq
== NULL
) {
703 status
= NT_STATUS_NO_MEMORY
;
704 DBG_ERR("wb_lookupsids_send - %s\n",
706 irpc_send_reply(state
->msg
, status
);
709 tevent_req_set_callback(subreq
,
710 wb_irpc_lsa_LookupNames4_domains_done
,
716 static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req
*subreq
)
718 struct wb_irpc_lsa_LookupNames4_state
*state
=
719 tevent_req_callback_data(subreq
,
720 struct wb_irpc_lsa_LookupNames4_state
);
721 struct lsa_RefDomainList
*domains
= NULL
;
722 struct lsa_TransNameArray
*names
= NULL
;
726 status
= wb_lookupsids_recv(subreq
, state
->msg
,
729 if (!NT_STATUS_IS_OK(status
)) {
730 DEBUG(0,("RPC callback failed for %s - %s\n",
731 __func__
, nt_errstr(status
)));
732 irpc_send_reply(state
->msg
, status
);
736 *state
->req
->out
.domains
= domains
;
737 for (i
= 0; i
< state
->req
->in
.num_names
; i
++) {
738 struct wb_irpc_lsa_LookupNames4_name
*nstate
=
740 struct lsa_TranslatedSid3
*s3
=
741 &state
->req
->out
.sids
->sids
[i
];
744 s3
->sid_type
= nstate
->type
;
745 if (s3
->sid_type
!= SID_NAME_UNKNOWN
) {
746 s3
->sid
= &nstate
->sid
;
750 s3
->sid_index
= UINT32_MAX
;
751 for (di
= 0; di
< domains
->count
; di
++) {
754 if (domains
->domains
[di
].sid
== NULL
) {
758 match
= dom_sid_equal(nstate
->authority_sid
,
759 domains
->domains
[di
].sid
);
765 if (s3
->sid_type
!= SID_NAME_UNKNOWN
) {
766 (*state
->req
->out
.count
)++;
769 state
->req
->out
.sids
->count
= state
->req
->in
.num_names
;
771 if (*state
->req
->out
.count
== 0) {
772 state
->req
->out
.result
= NT_STATUS_NONE_MAPPED
;
773 } else if (*state
->req
->out
.count
!= state
->req
->in
.num_names
) {
774 state
->req
->out
.result
= NT_STATUS_SOME_NOT_MAPPED
;
776 state
->req
->out
.result
= NT_STATUS_OK
;
779 irpc_send_reply(state
->msg
, NT_STATUS_OK
);
783 struct wb_irpc_GetDCName_state
{
784 struct irpc_message
*msg
;
785 struct wbint_DsGetDcName
*req
;
788 static void wb_irpc_GetDCName_done(struct tevent_req
*subreq
);
790 static NTSTATUS
wb_irpc_GetDCName(struct irpc_message
*msg
,
791 struct wbint_DsGetDcName
*req
)
794 struct tevent_req
*subreq
= NULL
;
795 struct wb_irpc_GetDCName_state
*state
= NULL
;
797 state
= talloc_zero(msg
, struct wb_irpc_GetDCName_state
);
799 return NT_STATUS_NO_MEMORY
;
805 subreq
= wb_dsgetdcname_send(msg
,
806 global_event_context(),
811 if (subreq
== NULL
) {
812 return NT_STATUS_NO_MEMORY
;
815 tevent_req_set_callback(subreq
,
816 wb_irpc_GetDCName_done
,
819 msg
->defer_reply
= true;
824 static void wb_irpc_GetDCName_done(struct tevent_req
*subreq
)
826 struct wb_irpc_GetDCName_state
*state
= tevent_req_callback_data(
827 subreq
, struct wb_irpc_GetDCName_state
);
830 status
= wb_dsgetdcname_recv(subreq
, state
->msg
,
831 state
->req
->out
.dc_info
);
833 if (!NT_STATUS_IS_OK(status
)) {
834 DBG_INFO("RPC callback failed for %s - %s\n", "DSGETDCNAME",
838 state
->req
->out
.result
= status
;
840 irpc_send_reply(state
->msg
, NT_STATUS_OK
);
843 NTSTATUS
wb_irpc_register(void)
847 status
= IRPC_REGISTER(winbind_imessaging_context(), winbind
, WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS
,
848 wb_irpc_DsrUpdateReadOnlyServerDnsRecords
, NULL
);
849 if (!NT_STATUS_IS_OK(status
)) {
852 status
= IRPC_REGISTER(winbind_imessaging_context(), winbind
, WINBIND_SAMLOGON
,
853 wb_irpc_SamLogon
, NULL
);
854 if (!NT_STATUS_IS_OK(status
)) {
857 status
= IRPC_REGISTER(winbind_imessaging_context(), winbind
,
858 WINBIND_LOGONCONTROL
,
859 wb_irpc_LogonControl
, NULL
);
860 if (!NT_STATUS_IS_OK(status
)) {
863 status
= IRPC_REGISTER(winbind_imessaging_context(), winbind
,
864 WINBIND_GETFORESTTRUSTINFORMATION
,
865 wb_irpc_GetForestTrustInformation
, NULL
);
866 if (!NT_STATUS_IS_OK(status
)) {
869 status
= IRPC_REGISTER(winbind_imessaging_context(), winbind
, WINBIND_SENDTOSAM
,
870 wb_irpc_SendToSam
, NULL
);
871 if (!NT_STATUS_IS_OK(status
)) {
874 status
= IRPC_REGISTER(winbind_imessaging_context(),
875 lsarpc
, LSA_LOOKUPSIDS3
,
876 wb_irpc_lsa_LookupSids3_call
, NULL
);
877 if (!NT_STATUS_IS_OK(status
)) {
880 status
= IRPC_REGISTER(winbind_imessaging_context(),
881 lsarpc
, LSA_LOOKUPNAMES4
,
882 wb_irpc_lsa_LookupNames4_call
, NULL
);
883 if (!NT_STATUS_IS_OK(status
)) {
886 status
= IRPC_REGISTER(winbind_imessaging_context(),
887 winbind
, WBINT_DSGETDCNAME
,
888 wb_irpc_GetDCName
, NULL
);
889 if (!NT_STATUS_IS_OK(status
)) {