s4:dsdb Move linked attribute restrictions to objectclass_attrs
[Samba.git] / nsswitch / libwbclient / wbc_util_async.c
blob8801b8ecc51519bdca1ecac0f5dffafbb20ebdc7
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind client API
6 Copyright (C) 2009,2010 Kai Blin <kai@samba.org>
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* Required Headers */
24 #include "replace.h"
25 #include "libwbclient.h"
26 #include "wbc_async.h"
28 struct wbc_ping_state {
29 struct winbindd_request req;
32 static void wbcPing_done(struct tevent_req *subreq);
34 /** @brief Ping winbind to see if the service is up and running
36 * @param mem_ctx talloc context to allocate the request from
37 * @param ev event context to use for async operation
38 * @param wb_ctx winbind context to use
40 * @return Async request on successful dispatch of the request, NULL on error
43 struct tevent_req *wbcPing_send(TALLOC_CTX *mem_ctx,
44 struct tevent_context *ev,
45 struct wb_context *wb_ctx)
47 struct tevent_req *req, *subreq;
48 struct wbc_ping_state *state;
50 req = tevent_req_create(mem_ctx, &state, struct wbc_ping_state);
51 if (req == NULL) {
52 return NULL;
55 ZERO_STRUCT(state->req);
57 state->req.cmd = WINBINDD_PING;
58 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
59 if (tevent_req_nomem(subreq, req)) {
60 return tevent_req_post(req, ev);
63 tevent_req_set_callback(subreq, wbcPing_done, req);
64 return req;
67 static void wbcPing_done(struct tevent_req *subreq)
69 struct tevent_req *req = tevent_req_callback_data(
70 subreq, struct tevent_req);
71 struct wbc_ping_state *state = tevent_req_data(
72 req, struct wbc_ping_state);
73 struct winbindd_response *resp;
74 wbcErr wbc_status;
76 wbc_status = wb_trans_recv(subreq, state, &resp);
77 TALLOC_FREE(subreq);
78 if (!WBC_ERROR_IS_OK(wbc_status)) {
79 tevent_req_error(req, wbc_status);
80 return;
82 TALLOC_FREE(resp);
84 tevent_req_done(req);
87 /** @brief Receive ping response from winbind
89 * @param req async request sent in #wbcPing_send
91 * @return NT_STATUS_OK on success, an error status on error.
94 wbcErr wbcPing_recv(struct tevent_req *req)
96 wbcErr wbc_status;
98 if (tevent_req_is_wbcerr(req, &wbc_status)) {
99 tevent_req_received(req);
100 return wbc_status;
103 tevent_req_received(req);
104 return WBC_ERR_SUCCESS;
108 struct wbc_interface_version_state {
109 struct winbindd_request req;
110 uint32_t version;
113 static void wbcInterfaceVersion_done(struct tevent_req *subreq);
116 * @brief Request the interface version from winbind
118 * @param mem_ctx talloc context to allocate memory from
119 * @param ev tevent context to use for async requests
120 * @param wb_ctx winbind context
122 * @return tevevt_req on success, NULL on failure
125 struct tevent_req *wbcInterfaceVersion_send(TALLOC_CTX *mem_ctx,
126 struct tevent_context *ev,
127 struct wb_context *wb_ctx)
129 struct tevent_req *req, *subreq;
130 struct wbc_interface_version_state *state;
132 req = tevent_req_create(mem_ctx, &state, struct wbc_interface_version_state);
133 if (req == NULL) {
134 return NULL;
137 ZERO_STRUCT(state->req);
138 state->req.cmd = WINBINDD_INTERFACE_VERSION;
140 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
141 if (tevent_req_nomem(subreq, req)) {
142 return tevent_req_post(req, ev);
145 tevent_req_set_callback(subreq, wbcInterfaceVersion_done, req);
147 return req;
150 static void wbcInterfaceVersion_done(struct tevent_req *subreq)
152 struct tevent_req *req = tevent_req_callback_data(
153 subreq, struct tevent_req);
154 struct wbc_interface_version_state *state = tevent_req_data(
155 req, struct wbc_interface_version_state);
156 struct winbindd_response *resp;
157 wbcErr wbc_status;
159 wbc_status = wb_trans_recv(subreq, state, &resp);
160 TALLOC_FREE(subreq);
161 if (!WBC_ERROR_IS_OK(wbc_status)) {
162 tevent_req_error(req, wbc_status);
163 return;
165 state->version = resp->data.interface_version;
166 TALLOC_FREE(resp);
168 tevent_req_done(req);
172 * @brief Receive the winbind interface version
174 * @param req tevent_req containing the request
175 * @param interface_version pointer to uint32_t to hold the interface
176 * version
178 * @return #wbcErr
181 wbcErr wbcInterfaceVersion_recv(struct tevent_req *req,
182 uint32_t *interface_version)
184 struct wbc_interface_version_state *state = tevent_req_data(
185 req, struct wbc_interface_version_state);
186 wbcErr wbc_status;
188 if (tevent_req_is_wbcerr(req, &wbc_status)) {
189 tevent_req_received(req);
190 return wbc_status;
193 *interface_version = state->version;
195 tevent_req_received(req);
196 return WBC_ERR_SUCCESS;
199 struct wbc_info_state {
200 struct winbindd_request req;
201 char separator;
202 char *version_string;
205 static void wbcInfo_done(struct tevent_req *subreq);
208 * @brief Request information about the winbind service
210 * @param mem_ctx talloc context to allocate memory from
211 * @param ev tevent context to use for async requests
212 * @param wb_ctx winbind context
214 * @return tevent_req on success, NULL on failure
217 struct tevent_req *wbcInfo_send(TALLOC_CTX *mem_ctx,
218 struct tevent_context *ev,
219 struct wb_context *wb_ctx)
221 struct tevent_req *req, *subreq;
222 struct wbc_info_state *state;
224 req = tevent_req_create(mem_ctx, &state, struct wbc_info_state);
225 if (req == NULL) {
226 return NULL;
229 ZERO_STRUCT(state->req);
230 state->req.cmd = WINBINDD_INFO;
232 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
233 if (tevent_req_nomem(subreq, req)) {
234 return tevent_req_post(req, ev);
237 tevent_req_set_callback(subreq, wbcInfo_done, req);
238 return req;
241 static void wbcInfo_done(struct tevent_req *subreq)
243 struct tevent_req *req = tevent_req_callback_data(
244 subreq, struct tevent_req);
245 struct wbc_info_state *state = tevent_req_data(
246 req, struct wbc_info_state);
247 struct winbindd_response *resp;
248 wbcErr wbc_status;
250 wbc_status = wb_trans_recv(subreq, state, &resp);
251 TALLOC_FREE(subreq);
252 if (!WBC_ERROR_IS_OK(wbc_status)) {
253 tevent_req_error(req, wbc_status);
254 return;
256 state->version_string = talloc_strdup(state,
257 resp->data.info.samba_version);
258 if (tevent_req_nomem(state->version_string, subreq)) {
259 return;
261 state->separator = resp->data.info.winbind_separator;
262 TALLOC_FREE(resp);
264 tevent_req_done(req);
268 * @brief Receive information about the running winbind service
270 * @param req tevent_req containing the request
271 * @param mem_ctx talloc context to allocate memory from
272 * @param winbind_separator pointer to a char to hold the separator
273 * @param version_string pointer to a string to hold the version string
275 * @return #wbcErr
278 wbcErr wbcInfo_recv(struct tevent_req *req,
279 TALLOC_CTX *mem_ctx,
280 char *winbind_separator,
281 char **version_string)
283 struct wbc_info_state *state = tevent_req_data(
284 req, struct wbc_info_state);
285 wbcErr wbc_status;
287 if (tevent_req_is_wbcerr(req, &wbc_status)) {
288 tevent_req_received(req);
289 return wbc_status;
292 *winbind_separator = state->separator;
293 *version_string = talloc_steal(mem_ctx, state->version_string);
295 tevent_req_received(req);
296 return WBC_ERR_SUCCESS;
299 struct wbc_netbios_name_state {
300 struct winbindd_request req;
301 char *netbios_name;
304 static void wbcNetbiosName_done(struct tevent_req *subreq);
307 * @brief Request the machine's netbios name
309 * @param mem_ctx talloc context to allocate memory from
310 * @param ev tevent context to use for async requests
311 * @param wb_ctx winbind context
313 * @return tevent_req on success, NULL on failure
316 struct tevent_req *wbcNetbiosName_send(TALLOC_CTX *mem_ctx,
317 struct tevent_context *ev,
318 struct wb_context *wb_ctx)
320 struct tevent_req *req, *subreq;
321 struct wbc_netbios_name_state *state;
323 req = tevent_req_create(mem_ctx, &state, struct wbc_netbios_name_state);
324 if (req == NULL) {
325 return NULL;
328 ZERO_STRUCT(state->req);
329 state->req.cmd = WINBINDD_NETBIOS_NAME;
331 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
332 if (tevent_req_nomem(subreq, req)) {
333 return tevent_req_post(req, ev);
336 tevent_req_set_callback(subreq, wbcNetbiosName_done, req);
337 return req;
340 static void wbcNetbiosName_done(struct tevent_req *subreq)
342 struct tevent_req *req = tevent_req_callback_data(
343 subreq, struct tevent_req);
344 struct wbc_netbios_name_state *state = tevent_req_data(
345 req, struct wbc_netbios_name_state);
346 struct winbindd_response *resp;
347 wbcErr wbc_status;
349 wbc_status = wb_trans_recv(subreq, state, &resp);
350 TALLOC_FREE(subreq);
351 if (!WBC_ERROR_IS_OK(wbc_status)) {
352 tevent_req_error(req, wbc_status);
353 return;
355 state->netbios_name = talloc_strdup(state,
356 resp->data.info.samba_version);
357 if (tevent_req_nomem(state->netbios_name, subreq)) {
358 return;
360 TALLOC_FREE(resp);
362 tevent_req_done(req);
366 * @brief Receive the machine's netbios name
368 * @param req tevent_req containing the request
369 * @param mem_ctx talloc context to allocate memory from
370 * @param netbios_name pointer to a string to hold the netbios name
372 * @return #wbcErr
375 wbcErr wbcNetbiosName_recv(struct tevent_req *req,
376 TALLOC_CTX *mem_ctx,
377 char **netbios_name)
379 struct wbc_netbios_name_state *state = tevent_req_data(
380 req, struct wbc_netbios_name_state);
381 wbcErr wbc_status;
383 if (tevent_req_is_wbcerr(req, &wbc_status)) {
384 tevent_req_received(req);
385 return wbc_status;
388 *netbios_name = talloc_steal(mem_ctx, state->netbios_name);
390 tevent_req_received(req);
391 return WBC_ERR_SUCCESS;
394 struct wbc_domain_name_state {
395 struct winbindd_request req;
396 char *domain_name;
399 static void wbcDomainName_done(struct tevent_req *subreq);
402 * @brief Request the machine's domain name
404 * @param mem_ctx talloc context to allocate memory from
405 * @param ev tevent context to use for async requests
406 * @param wb_ctx winbind context
408 * @return tevent_req on success, NULL on failure
411 struct tevent_req *wbcDomainName_send(TALLOC_CTX *mem_ctx,
412 struct tevent_context *ev,
413 struct wb_context *wb_ctx)
415 struct tevent_req *req, *subreq;
416 struct wbc_domain_name_state *state;
418 req = tevent_req_create(mem_ctx, &state, struct wbc_domain_name_state);
419 if (req == NULL) {
420 return NULL;
423 ZERO_STRUCT(state->req);
424 state->req.cmd = WINBINDD_DOMAIN_NAME;
426 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
427 if (tevent_req_nomem(subreq, req)) {
428 return tevent_req_post(req, ev);
431 tevent_req_set_callback(subreq, wbcDomainName_done, req);
432 return req;
435 static void wbcDomainName_done(struct tevent_req *subreq)
437 struct tevent_req *req = tevent_req_callback_data(
438 subreq, struct tevent_req);
439 struct wbc_domain_name_state *state = tevent_req_data(
440 req, struct wbc_domain_name_state);
441 struct winbindd_response *resp;
442 wbcErr wbc_status;
444 wbc_status = wb_trans_recv(subreq, state, &resp);
445 TALLOC_FREE(subreq);
446 if (!WBC_ERROR_IS_OK(wbc_status)) {
447 tevent_req_error(req, wbc_status);
448 return;
450 state->domain_name = talloc_strdup(state, resp->data.domain_name);
451 if (tevent_req_nomem(state->domain_name, subreq)) {
452 return;
454 TALLOC_FREE(resp);
456 tevent_req_done(req);
460 * @brief Receive the machine's domain name
462 * @param req tevent_req containing the request
463 * @param mem_ctx talloc context to allocate memory from
464 * @param domain_name pointer to a string to hold the domain name
466 * @return #wbcErr
469 wbcErr wbcDomainName_recv(struct tevent_req *req,
470 TALLOC_CTX *mem_ctx,
471 char **domain_name)
473 struct wbc_domain_name_state *state = tevent_req_data(
474 req, struct wbc_domain_name_state);
475 wbcErr wbc_status;
477 if (tevent_req_is_wbcerr(req, &wbc_status)) {
478 tevent_req_received(req);
479 return wbc_status;
482 *domain_name = talloc_steal(mem_ctx, state->domain_name);
484 tevent_req_received(req);
485 return WBC_ERR_SUCCESS;
488 struct wbc_interface_details_state {
489 struct tevent_context *ev;
490 struct wb_context *wb_ctx;
491 struct wbcDomainInfo *dinfo;
492 struct wbcInterfaceDetails *details;
495 static void wbcInterfaceDetails_version(struct tevent_req *subreq);
496 static void wbcInterfaceDetails_info(struct tevent_req *subreq);
497 static void wbcInterfaceDetails_netbios_name(struct tevent_req *subreq);
498 static void wbcInterfaceDetails_domain_name(struct tevent_req *subreq);
499 static void wbcInterfaceDetails_domain_info(struct tevent_req *subreq);
502 * @brief Request some useful details about the winbind service
504 * @param mem_ctx talloc context to allocate memory from
505 * @param ev tevent context to use for async requests
506 * @param wb_ctx winbind context
508 * @return tevent_req on success, NULL on failure
511 struct tevent_req *wbcInterfaceDetails_send(TALLOC_CTX *mem_ctx,
512 struct tevent_context *ev,
513 struct wb_context *wb_ctx)
515 struct tevent_req *req, *subreq;
516 struct wbc_interface_details_state *state;
518 req = tevent_req_create(mem_ctx, &state,
519 struct wbc_interface_details_state);
520 if (req == NULL) {
521 return NULL;
524 state->ev = ev;
525 state->wb_ctx = wb_ctx;
526 state->details = talloc(state, struct wbcInterfaceDetails);
527 if (tevent_req_nomem(state->details, req)) {
528 return tevent_req_post(req, ev);
531 subreq = wbcInterfaceVersion_send(state, ev, wb_ctx);
532 if (tevent_req_nomem(subreq, req)) {
533 return tevent_req_post(req, ev);
536 tevent_req_set_callback(subreq, wbcInterfaceDetails_version, req);
537 return req;
540 static void wbcInterfaceDetails_version(struct tevent_req *subreq)
542 struct tevent_req *req = tevent_req_callback_data(
543 subreq, struct tevent_req);
544 struct wbc_interface_details_state *state = tevent_req_data(
545 req, struct wbc_interface_details_state);
546 wbcErr wbc_status;
549 wbc_status = wbcInterfaceVersion_recv(subreq,
550 &state->details->interface_version);
551 TALLOC_FREE(subreq);
552 if (!WBC_ERROR_IS_OK(wbc_status)) {
553 tevent_req_error(req, wbc_status);
554 return;
557 subreq = wbcInfo_send(state, state->ev, state->wb_ctx);
558 if (tevent_req_nomem(subreq, req)) {
559 return;
562 tevent_req_set_callback(subreq, wbcInterfaceDetails_info, req);
565 static void wbcInterfaceDetails_info(struct tevent_req *subreq)
567 struct tevent_req *req = tevent_req_callback_data(
568 subreq, struct tevent_req);
569 struct wbc_interface_details_state *state = tevent_req_data(
570 req, struct wbc_interface_details_state);
571 wbcErr wbc_status;
573 wbc_status = wbcInfo_recv(subreq, state->details,
574 &state->details->winbind_separator,
575 &state->details->winbind_version);
576 TALLOC_FREE(subreq);
577 if (!WBC_ERROR_IS_OK(wbc_status)) {
578 tevent_req_error(req, wbc_status);
579 return;
582 subreq = wbcNetbiosName_send(state, state->ev, state->wb_ctx);
583 if (tevent_req_nomem(subreq, req)) {
584 return;
587 tevent_req_set_callback(subreq, wbcInterfaceDetails_netbios_name, req);
590 static void wbcInterfaceDetails_netbios_name(struct tevent_req *subreq)
592 struct tevent_req *req = tevent_req_callback_data(
593 subreq, struct tevent_req);
594 struct wbc_interface_details_state *state = tevent_req_data(
595 req, struct wbc_interface_details_state);
596 wbcErr wbc_status;
598 wbc_status = wbcNetbiosName_recv(subreq, state->details,
599 &state->details->netbios_name);
600 TALLOC_FREE(subreq);
601 if (!WBC_ERROR_IS_OK(wbc_status)) {
602 tevent_req_error(req, wbc_status);
603 return;
606 subreq = wbcDomainName_send(state, state->ev, state->wb_ctx);
607 if (tevent_req_nomem(subreq, req)) {
608 return;
611 tevent_req_set_callback(subreq, wbcInterfaceDetails_domain_name, req);
614 static void wbcInterfaceDetails_domain_name(struct tevent_req *subreq)
616 struct tevent_req *req = tevent_req_callback_data(
617 subreq, struct tevent_req);
618 struct wbc_interface_details_state *state = tevent_req_data(
619 req, struct wbc_interface_details_state);
620 wbcErr wbc_status;
622 wbc_status = wbcDomainName_recv(subreq, state->details,
623 &state->details->netbios_domain);
624 TALLOC_FREE(subreq);
625 if (!WBC_ERROR_IS_OK(wbc_status)) {
626 tevent_req_error(req, wbc_status);
627 return;
630 subreq = wbcDomainInfo_send(state, state->ev, state->wb_ctx,
631 state->details->netbios_domain);
632 if (tevent_req_nomem(subreq, req)) {
633 return;
636 tevent_req_set_callback(subreq, wbcInterfaceDetails_domain_info, req);
639 static void wbcInterfaceDetails_domain_info(struct tevent_req *subreq)
641 struct tevent_req *req = tevent_req_callback_data(
642 subreq, struct tevent_req);
643 struct wbc_interface_details_state *state = tevent_req_data(
644 req, struct wbc_interface_details_state);
645 struct wbcDomainInfo *domain;
646 wbcErr wbc_status;
648 wbc_status = wbcDomainInfo_recv(subreq, state, &domain);
649 TALLOC_FREE(subreq);
650 if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
651 tevent_req_done(req);
652 return;
655 if (!WBC_ERROR_IS_OK(wbc_status)) {
656 tevent_req_error(req, wbc_status);
657 return;
659 state->details->dns_domain = talloc_strdup(state->details,
660 domain->dns_name);
661 if (tevent_req_nomem(state->details->dns_domain, req)) {
662 return;
665 TALLOC_FREE(domain);
666 tevent_req_done(req);
670 * @brief Receive useful information about the winbind service
672 * @param req tevent_req containing the request
673 * @param mem_ctx talloc context to allocate memory from
674 * @param *details pointer to hold the struct wbcInterfaceDetails
676 * @return #wbcErr
679 wbcErr wbcInterfaceDetails_recv(struct tevent_req *req,
680 TALLOC_CTX *mem_ctx,
681 struct wbcInterfaceDetails **details)
683 struct wbc_interface_details_state *state = tevent_req_data(
684 req, struct wbc_interface_details_state);
685 wbcErr wbc_status;
687 if (tevent_req_is_wbcerr(req, &wbc_status)) {
688 tevent_req_received(req);
689 return wbc_status;
692 *details = talloc_steal(mem_ctx, state->details);
694 tevent_req_received(req);
695 return WBC_ERR_SUCCESS;
698 struct wbc_domain_info_state {
699 struct winbindd_request req;
700 struct wbcDomainInfo *info;
703 static void wbcDomainInfo_done(struct tevent_req *subreq);
706 * @brief Request status of a given trusted domain
708 * @param mem_ctx talloc context to allocate memory from
709 * @param ev tevent context to use for async requests
710 * @param wb_ctx winbind context
711 * @param domain domain to request status from
713 * @return tevent_req on success, NULL on failure
716 struct tevent_req *wbcDomainInfo_send(TALLOC_CTX *mem_ctx,
717 struct tevent_context *ev,
718 struct wb_context *wb_ctx,
719 const char *domain)
721 struct tevent_req *req, *subreq;
722 struct wbc_domain_info_state *state;
724 if (!domain) {
725 return NULL;
728 req = tevent_req_create(mem_ctx, &state, struct wbc_domain_info_state);
729 if (req == NULL) {
730 return NULL;
733 state->info = talloc(state, struct wbcDomainInfo);
734 if (tevent_req_nomem(state->info, req)) {
735 return tevent_req_post(req, ev);
738 ZERO_STRUCT(state->req);
740 strncpy(state->req.domain_name, domain,
741 sizeof(state->req.domain_name)-1);
743 state->req.cmd = WINBINDD_DOMAIN_INFO;
745 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
746 if (tevent_req_nomem(subreq, req)) {
747 return tevent_req_post(req, ev);
750 tevent_req_set_callback(subreq, wbcDomainInfo_done, req);
751 return req;
754 static void wbcDomainInfo_done(struct tevent_req *subreq)
756 struct tevent_req *req = tevent_req_callback_data(
757 subreq, struct tevent_req);
758 struct wbc_domain_info_state *state = tevent_req_data(
759 req, struct wbc_domain_info_state);
760 struct winbindd_response *resp;
761 wbcErr wbc_status;
763 wbc_status = wb_trans_recv(subreq, state, &resp);
764 TALLOC_FREE(subreq);
765 if (!WBC_ERROR_IS_OK(wbc_status)) {
766 tevent_req_error(req, wbc_status);
767 return;
770 state->info->short_name = talloc_strdup(state->info,
771 resp->data.domain_info.name);
772 if (tevent_req_nomem(state->info->short_name, req)) {
773 return;
776 state->info->dns_name = talloc_strdup(state->info,
777 resp->data.domain_info.alt_name);
778 if (tevent_req_nomem(state->info->dns_name, req)) {
779 return;
782 wbc_status = wbcStringToSid(resp->data.domain_info.sid,
783 &state->info->sid);
784 if (!WBC_ERROR_IS_OK(wbc_status)) {
785 tevent_req_error(req, wbc_status);
786 return;
789 if (resp->data.domain_info.native_mode) {
790 state->info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
792 if (resp->data.domain_info.active_directory) {
793 state->info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
795 if (resp->data.domain_info.primary) {
796 state->info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
799 TALLOC_FREE(resp);
801 tevent_req_done(req);
805 * @brief Receive information about a trusted domain
807 * @param req tevent_req containing the request
808 * @param mem_ctx talloc context to allocate memory from
809 * @param *dinfo pointer to returned struct wbcDomainInfo
811 * @return #wbcErr
814 wbcErr wbcDomainInfo_recv(struct tevent_req *req,
815 TALLOC_CTX *mem_ctx,
816 struct wbcDomainInfo **dinfo)
818 struct wbc_domain_info_state *state = tevent_req_data(
819 req, struct wbc_domain_info_state);
820 wbcErr wbc_status;
822 if (tevent_req_is_wbcerr(req, &wbc_status)) {
823 tevent_req_received(req);
824 return wbc_status;
827 if (dinfo == NULL) {
828 tevent_req_received(req);
829 return WBC_ERR_INVALID_PARAM;
832 *dinfo = talloc_steal(mem_ctx, state->info);
834 tevent_req_received(req);
835 return WBC_ERR_SUCCESS;