2 Unix SMB/CIFS implementation.
6 Copyright (C) Gerald (Jerry) Carter 2007-2008
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 3 of the License, or (at your option) any later version.
14 This library 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 GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* Required Headers */
26 #include "libwbclient.h"
30 struct wbc_ping_state
{
31 struct winbindd_request req
;
34 static void wbcPing_done(struct tevent_req
*subreq
);
36 /** @brief Ping winbind to see if the service is up and running
38 * @param mem_ctx talloc context to allocate the request from
39 * @param ev event context to use for async operation
40 * @param wb_ctx winbind context to use
42 * @return Async request on successful dispatch of the request, NULL on error
45 struct tevent_req
*wbcPing_send(TALLOC_CTX
*mem_ctx
,
46 struct tevent_context
*ev
,
47 struct wb_context
*wb_ctx
)
49 struct tevent_req
*req
, *subreq
;
50 struct wbc_ping_state
*state
;
52 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_ping_state
);
57 ZERO_STRUCT(state
->req
);
59 state
->req
.cmd
= WINBINDD_PING
;
60 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
61 if (tevent_req_nomem(subreq
, req
)) {
62 return tevent_req_post(req
, ev
);
65 tevent_req_set_callback(subreq
, wbcPing_done
, req
);
69 static void wbcPing_done(struct tevent_req
*subreq
)
71 struct tevent_req
*req
= tevent_req_callback_data(
72 subreq
, struct tevent_req
);
73 struct wbc_ping_state
*state
= tevent_req_data(
74 req
, struct wbc_ping_state
);
75 struct winbindd_response
*resp
;
78 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
80 if (!WBC_ERROR_IS_OK(wbc_status
)) {
81 tevent_req_error(req
, wbc_status
);
89 /** @brief Receive ping response from winbind
91 * @param req async request sent in #wbcPing_send
93 * @return NT_STATUS_OK on success, an error status on error.
96 wbcErr
wbcPing_recv(struct tevent_req
*req
)
100 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
101 tevent_req_received(req
);
105 tevent_req_received(req
);
106 return WBC_ERR_SUCCESS
;
109 /** @brief Ping winbindd to see if the daemon is running
115 struct winbindd_request request
;
116 struct winbindd_response response
;
118 /* Initialize request */
120 ZERO_STRUCT(request
);
121 ZERO_STRUCT(response
);
123 return wbcRequestResponse(WINBINDD_PING
, &request
, &response
);
126 struct wbc_interface_version_state
{
127 struct winbindd_request req
;
131 static void wbcInterfaceVersion_done(struct tevent_req
*subreq
);
134 * @brief Request the interface version from winbind
136 * @param mem_ctx talloc context to allocate memory from
137 * @param ev tevent context to use for async requests
138 * @param wb_ctx winbind context
140 * @return tevevt_req on success, NULL on failure
143 struct tevent_req
*wbcInterfaceVersion_send(TALLOC_CTX
*mem_ctx
,
144 struct tevent_context
*ev
,
145 struct wb_context
*wb_ctx
)
147 struct tevent_req
*req
, *subreq
;
148 struct wbc_interface_version_state
*state
;
150 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_interface_version_state
);
155 ZERO_STRUCT(state
->req
);
156 state
->req
.cmd
= WINBINDD_INTERFACE_VERSION
;
158 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
159 if (tevent_req_nomem(subreq
, req
)) {
160 return tevent_req_post(req
, ev
);
163 tevent_req_set_callback(subreq
, wbcInterfaceVersion_done
, req
);
168 static void wbcInterfaceVersion_done(struct tevent_req
*subreq
)
170 struct tevent_req
*req
= tevent_req_callback_data(
171 subreq
, struct tevent_req
);
172 struct wbc_interface_version_state
*state
= tevent_req_data(
173 req
, struct wbc_interface_version_state
);
174 struct winbindd_response
*resp
;
177 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
179 if (!WBC_ERROR_IS_OK(wbc_status
)) {
180 tevent_req_error(req
, wbc_status
);
183 state
->version
= resp
->data
.interface_version
;
186 tevent_req_done(req
);
190 * @brief Receive the winbind interface version
192 * @param req tevent_req containing the request
193 * @param interface_version pointer to uint32_t to hold the interface
199 wbcErr
wbcInterfaceVersion_recv(struct tevent_req
*req
,
200 uint32_t *interface_version
)
202 struct wbc_interface_version_state
*state
= tevent_req_data(
203 req
, struct wbc_interface_version_state
);
206 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
207 tevent_req_received(req
);
211 *interface_version
= state
->version
;
213 tevent_req_received(req
);
214 return WBC_ERR_SUCCESS
;
217 struct wbc_info_state
{
218 struct winbindd_request req
;
220 char *version_string
;
223 static void wbcInfo_done(struct tevent_req
*subreq
);
226 * @brief Request information about the winbind service
228 * @param mem_ctx talloc context to allocate memory from
229 * @param ev tevent context to use for async requests
230 * @param wb_ctx winbind context
232 * @return tevent_req on success, NULL on failure
235 struct tevent_req
*wbcInfo_send(TALLOC_CTX
*mem_ctx
,
236 struct tevent_context
*ev
,
237 struct wb_context
*wb_ctx
)
239 struct tevent_req
*req
, *subreq
;
240 struct wbc_info_state
*state
;
242 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_info_state
);
247 ZERO_STRUCT(state
->req
);
248 state
->req
.cmd
= WINBINDD_INFO
;
250 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
251 if (tevent_req_nomem(subreq
, req
)) {
252 return tevent_req_post(req
, ev
);
255 tevent_req_set_callback(subreq
, wbcInfo_done
, req
);
259 static void wbcInfo_done(struct tevent_req
*subreq
)
261 struct tevent_req
*req
= tevent_req_callback_data(
262 subreq
, struct tevent_req
);
263 struct wbc_info_state
*state
= tevent_req_data(
264 req
, struct wbc_info_state
);
265 struct winbindd_response
*resp
;
268 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
270 if (!WBC_ERROR_IS_OK(wbc_status
)) {
271 tevent_req_error(req
, wbc_status
);
274 state
->version_string
= talloc_strdup(state
,
275 resp
->data
.info
.samba_version
);
276 if (tevent_req_nomem(state
->version_string
, subreq
)) {
279 state
->separator
= resp
->data
.info
.winbind_separator
;
282 tevent_req_done(req
);
286 * @brief Receive information about the running winbind service
288 * @param req tevent_req containing the request
289 * @param mem_ctx talloc context to allocate memory from
290 * @param winbind_separator pointer to a char to hold the separator
291 * @param version_string pointer to a string to hold the version string
296 wbcErr
wbcInfo_recv(struct tevent_req
*req
,
298 char *winbind_separator
,
299 char **version_string
)
301 struct wbc_info_state
*state
= tevent_req_data(
302 req
, struct wbc_info_state
);
305 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
306 tevent_req_received(req
);
310 *winbind_separator
= state
->separator
;
311 *version_string
= talloc_steal(mem_ctx
, state
->version_string
);
313 tevent_req_received(req
);
314 return WBC_ERR_SUCCESS
;
317 struct wbc_netbios_name_state
{
318 struct winbindd_request req
;
322 static void wbcNetbiosName_done(struct tevent_req
*subreq
);
325 * @brief Request the machine's netbios name
327 * @param mem_ctx talloc context to allocate memory from
328 * @param ev tevent context to use for async requests
329 * @param wb_ctx winbind context
331 * @return tevent_req on success, NULL on failure
334 struct tevent_req
*wbcNetbiosName_send(TALLOC_CTX
*mem_ctx
,
335 struct tevent_context
*ev
,
336 struct wb_context
*wb_ctx
)
338 struct tevent_req
*req
, *subreq
;
339 struct wbc_netbios_name_state
*state
;
341 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_netbios_name_state
);
346 ZERO_STRUCT(state
->req
);
347 state
->req
.cmd
= WINBINDD_NETBIOS_NAME
;
349 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
350 if (tevent_req_nomem(subreq
, req
)) {
351 return tevent_req_post(req
, ev
);
354 tevent_req_set_callback(subreq
, wbcNetbiosName_done
, req
);
358 static void wbcNetbiosName_done(struct tevent_req
*subreq
)
360 struct tevent_req
*req
= tevent_req_callback_data(
361 subreq
, struct tevent_req
);
362 struct wbc_netbios_name_state
*state
= tevent_req_data(
363 req
, struct wbc_netbios_name_state
);
364 struct winbindd_response
*resp
;
367 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
369 if (!WBC_ERROR_IS_OK(wbc_status
)) {
370 tevent_req_error(req
, wbc_status
);
373 state
->netbios_name
= talloc_strdup(state
,
374 resp
->data
.info
.samba_version
);
375 if (tevent_req_nomem(state
->netbios_name
, subreq
)) {
380 tevent_req_done(req
);
384 * @brief Receive the machine's netbios name
386 * @param req tevent_req containing the request
387 * @param mem_ctx talloc context to allocate memory from
388 * @param netbios_name pointer to a string to hold the netbios name
393 wbcErr
wbcNetbiosName_recv(struct tevent_req
*req
,
397 struct wbc_netbios_name_state
*state
= tevent_req_data(
398 req
, struct wbc_netbios_name_state
);
401 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
402 tevent_req_received(req
);
406 *netbios_name
= talloc_steal(mem_ctx
, state
->netbios_name
);
408 tevent_req_received(req
);
409 return WBC_ERR_SUCCESS
;
412 wbcErr
wbcInterfaceDetails(struct wbcInterfaceDetails
**_details
)
414 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
415 struct wbcInterfaceDetails
*info
;
416 struct wbcDomainInfo
*domain
= NULL
;
417 struct winbindd_request request
;
418 struct winbindd_response response
;
420 /* Initialize request */
422 ZERO_STRUCT(request
);
423 ZERO_STRUCT(response
);
425 info
= talloc(NULL
, struct wbcInterfaceDetails
);
426 BAIL_ON_PTR_ERROR(info
, wbc_status
);
428 /* first the interface version */
429 wbc_status
= wbcRequestResponse(WINBINDD_INTERFACE_VERSION
, NULL
, &response
);
430 BAIL_ON_WBC_ERROR(wbc_status
);
431 info
->interface_version
= response
.data
.interface_version
;
433 /* then the samba version and the winbind separator */
434 wbc_status
= wbcRequestResponse(WINBINDD_INFO
, NULL
, &response
);
435 BAIL_ON_WBC_ERROR(wbc_status
);
437 info
->winbind_version
= talloc_strdup(info
,
438 response
.data
.info
.samba_version
);
439 BAIL_ON_PTR_ERROR(info
->winbind_version
, wbc_status
);
440 info
->winbind_separator
= response
.data
.info
.winbind_separator
;
442 /* then the local netbios name */
443 wbc_status
= wbcRequestResponse(WINBINDD_NETBIOS_NAME
, NULL
, &response
);
444 BAIL_ON_WBC_ERROR(wbc_status
);
446 info
->netbios_name
= talloc_strdup(info
,
447 response
.data
.netbios_name
);
448 BAIL_ON_PTR_ERROR(info
->netbios_name
, wbc_status
);
450 /* then the local workgroup name */
451 wbc_status
= wbcRequestResponse(WINBINDD_DOMAIN_NAME
, NULL
, &response
);
452 BAIL_ON_WBC_ERROR(wbc_status
);
454 info
->netbios_domain
= talloc_strdup(info
,
455 response
.data
.domain_name
);
456 BAIL_ON_PTR_ERROR(info
->netbios_domain
, wbc_status
);
458 wbc_status
= wbcDomainInfo(info
->netbios_domain
, &domain
);
459 if (wbc_status
== WBC_ERR_DOMAIN_NOT_FOUND
) {
460 /* maybe it's a standalone server */
462 wbc_status
= WBC_ERR_SUCCESS
;
464 BAIL_ON_WBC_ERROR(wbc_status
);
468 info
->dns_domain
= talloc_strdup(info
,
470 wbcFreeMemory(domain
);
471 BAIL_ON_PTR_ERROR(info
->dns_domain
, wbc_status
);
473 info
->dns_domain
= NULL
;
479 wbc_status
= WBC_ERR_SUCCESS
;
487 /* Lookup the current status of a trusted domain */
488 wbcErr
wbcDomainInfo(const char *domain
, struct wbcDomainInfo
**dinfo
)
490 struct winbindd_request request
;
491 struct winbindd_response response
;
492 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
493 struct wbcDomainInfo
*info
= NULL
;
495 if (!domain
|| !dinfo
) {
496 wbc_status
= WBC_ERR_INVALID_PARAM
;
497 BAIL_ON_WBC_ERROR(wbc_status
);
500 /* Initialize request */
502 ZERO_STRUCT(request
);
503 ZERO_STRUCT(response
);
505 strncpy(request
.domain_name
, domain
,
506 sizeof(request
.domain_name
)-1);
508 wbc_status
= wbcRequestResponse(WINBINDD_DOMAIN_INFO
,
511 BAIL_ON_WBC_ERROR(wbc_status
);
513 info
= talloc(NULL
, struct wbcDomainInfo
);
514 BAIL_ON_PTR_ERROR(info
, wbc_status
);
516 info
->short_name
= talloc_strdup(info
,
517 response
.data
.domain_info
.name
);
518 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
520 info
->dns_name
= talloc_strdup(info
,
521 response
.data
.domain_info
.alt_name
);
522 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
524 wbc_status
= wbcStringToSid(response
.data
.domain_info
.sid
,
526 BAIL_ON_WBC_ERROR(wbc_status
);
528 if (response
.data
.domain_info
.native_mode
)
529 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_NATIVE
;
530 if (response
.data
.domain_info
.active_directory
)
531 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_AD
;
532 if (response
.data
.domain_info
.primary
)
533 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_PRIMARY
;
537 wbc_status
= WBC_ERR_SUCCESS
;
540 if (!WBC_ERROR_IS_OK(wbc_status
)) {
548 /* Resolve a NetbiosName via WINS */
549 wbcErr
wbcResolveWinsByName(const char *name
, char **ip
)
551 struct winbindd_request request
;
552 struct winbindd_response response
;
553 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
556 ZERO_STRUCT(request
);
557 ZERO_STRUCT(response
);
561 strncpy(request
.data
.winsreq
, name
,
562 sizeof(request
.data
.winsreq
)-1);
564 wbc_status
= wbcRequestResponse(WINBINDD_WINS_BYNAME
,
567 BAIL_ON_WBC_ERROR(wbc_status
);
569 /* Display response */
571 ipaddr
= talloc_strdup(NULL
, response
.data
.winsresp
);
572 BAIL_ON_PTR_ERROR(ipaddr
, wbc_status
);
575 wbc_status
= WBC_ERR_SUCCESS
;
581 /* Resolve an IP address via WINS into a NetbiosName */
582 wbcErr
wbcResolveWinsByIP(const char *ip
, char **name
)
584 struct winbindd_request request
;
585 struct winbindd_response response
;
586 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
589 ZERO_STRUCT(request
);
590 ZERO_STRUCT(response
);
594 strncpy(request
.data
.winsreq
, ip
,
595 sizeof(request
.data
.winsreq
)-1);
597 wbc_status
= wbcRequestResponse(WINBINDD_WINS_BYIP
,
600 BAIL_ON_WBC_ERROR(wbc_status
);
602 /* Display response */
604 name_str
= talloc_strdup(NULL
, response
.data
.winsresp
);
605 BAIL_ON_PTR_ERROR(name_str
, wbc_status
);
608 wbc_status
= WBC_ERR_SUCCESS
;
617 static wbcErr
process_domain_info_string(TALLOC_CTX
*ctx
,
618 struct wbcDomainInfo
*info
,
621 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
625 if (!info
|| !info_string
) {
626 wbc_status
= WBC_ERR_INVALID_PARAM
;
627 BAIL_ON_WBC_ERROR(wbc_status
);
635 if ((s
= strchr(r
, '\\')) == NULL
) {
636 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
637 BAIL_ON_WBC_ERROR(wbc_status
);
642 info
->short_name
= talloc_strdup(ctx
, r
);
643 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
648 if ((s
= strchr(r
, '\\')) == NULL
) {
649 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
650 BAIL_ON_WBC_ERROR(wbc_status
);
655 info
->dns_name
= talloc_strdup(ctx
, r
);
656 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
660 if ((s
= strchr(r
, '\\')) == NULL
) {
661 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
662 BAIL_ON_WBC_ERROR(wbc_status
);
667 wbc_status
= wbcStringToSid(r
, &info
->sid
);
668 BAIL_ON_WBC_ERROR(wbc_status
);
672 if ((s
= strchr(r
, '\\')) == NULL
) {
673 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
674 BAIL_ON_WBC_ERROR(wbc_status
);
679 if (strcmp(r
, "None") == 0) {
680 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_NONE
;
681 } else if (strcmp(r
, "External") == 0) {
682 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_EXTERNAL
;
683 } else if (strcmp(r
, "Forest") == 0) {
684 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_FOREST
;
685 } else if (strcmp(r
, "In Forest") == 0) {
686 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_IN_FOREST
;
688 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
689 BAIL_ON_WBC_ERROR(wbc_status
);
694 if ((s
= strchr(r
, '\\')) == NULL
) {
695 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
696 BAIL_ON_WBC_ERROR(wbc_status
);
701 if (strcmp(r
, "Yes") == 0) {
702 info
->trust_flags
|= WBC_DOMINFO_TRUST_TRANSITIVE
;
707 if ((s
= strchr(r
, '\\')) == NULL
) {
708 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
709 BAIL_ON_WBC_ERROR(wbc_status
);
714 if (strcmp(r
, "Yes") == 0) {
715 info
->trust_flags
|= WBC_DOMINFO_TRUST_INCOMING
;
720 if ((s
= strchr(r
, '\\')) == NULL
) {
721 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
722 BAIL_ON_WBC_ERROR(wbc_status
);
727 if (strcmp(r
, "Yes") == 0) {
728 info
->trust_flags
|= WBC_DOMINFO_TRUST_OUTGOING
;
731 /* Online/Offline status */
735 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
736 BAIL_ON_WBC_ERROR(wbc_status
);
738 if ( strcmp(r
, "Offline") == 0) {
739 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_OFFLINE
;
742 wbc_status
= WBC_ERR_SUCCESS
;
748 /* Enumerate the domain trusts known by Winbind */
749 wbcErr
wbcListTrusts(struct wbcDomainInfo
**domains
, size_t *num_domains
)
751 struct winbindd_response response
;
752 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
755 char *extra_data
= NULL
;
757 struct wbcDomainInfo
*d_list
= NULL
;
763 ZERO_STRUCT(response
);
767 wbc_status
= wbcRequestResponse(WINBINDD_LIST_TRUSTDOM
,
770 BAIL_ON_WBC_ERROR(wbc_status
);
772 /* Decode the response */
774 p
= (char *)response
.extra_data
.data
;
776 if ((p
== NULL
) || (strlen(p
) == 0)) {
777 /* We should always at least get back our
780 wbc_status
= WBC_ERR_DOMAIN_NOT_FOUND
;
781 BAIL_ON_WBC_ERROR(wbc_status
);
784 /* Count number of domains */
790 if ((q
= strchr(p
, '\n')) != NULL
)
795 d_list
= talloc_array(NULL
, struct wbcDomainInfo
, count
);
796 BAIL_ON_PTR_ERROR(d_list
, wbc_status
);
798 extra_data
= strdup((char*)response
.extra_data
.data
);
799 BAIL_ON_PTR_ERROR(extra_data
, wbc_status
);
803 /* Outer loop processes the list of domain information */
805 for (i
=0; i
<count
&& p
; i
++) {
806 char *next
= strchr(p
, '\n');
813 wbc_status
= process_domain_info_string(d_list
, &d_list
[i
], p
);
814 BAIL_ON_WBC_ERROR(wbc_status
);
823 if (!WBC_ERROR_IS_OK(wbc_status
)) {
833 /* Enumerate the domain trusts known by Winbind */
834 wbcErr
wbcLookupDomainController(const char *domain
,
836 struct wbcDomainControllerInfo
**dc_info
)
838 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
839 struct winbindd_request request
;
840 struct winbindd_response response
;
841 struct wbcDomainControllerInfo
*dc
= NULL
;
843 /* validate input params */
845 if (!domain
|| !dc_info
) {
846 wbc_status
= WBC_ERR_INVALID_PARAM
;
847 BAIL_ON_WBC_ERROR(wbc_status
);
850 ZERO_STRUCT(request
);
851 ZERO_STRUCT(response
);
853 strncpy(request
.data
.dsgetdcname
.domain_name
, domain
,
854 sizeof(request
.data
.dsgetdcname
.domain_name
)-1);
856 request
.flags
= flags
;
858 dc
= talloc(NULL
, struct wbcDomainControllerInfo
);
859 BAIL_ON_PTR_ERROR(dc
, wbc_status
);
863 wbc_status
= wbcRequestResponse(WINBINDD_DSGETDCNAME
,
866 BAIL_ON_WBC_ERROR(wbc_status
);
868 dc
->dc_name
= talloc_strdup(dc
, response
.data
.dsgetdcname
.dc_unc
);
869 BAIL_ON_PTR_ERROR(dc
->dc_name
, wbc_status
);
874 if (!WBC_ERROR_IS_OK(wbc_status
)) {
881 static wbcErr
wbc_create_domain_controller_info_ex(TALLOC_CTX
*mem_ctx
,
882 const struct winbindd_response
*resp
,
883 struct wbcDomainControllerInfoEx
**_i
)
885 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
886 struct wbcDomainControllerInfoEx
*i
;
889 i
= talloc(mem_ctx
, struct wbcDomainControllerInfoEx
);
890 BAIL_ON_PTR_ERROR(i
, wbc_status
);
892 i
->dc_unc
= talloc_strdup(i
, resp
->data
.dsgetdcname
.dc_unc
);
893 BAIL_ON_PTR_ERROR(i
->dc_unc
, wbc_status
);
895 i
->dc_address
= talloc_strdup(i
, resp
->data
.dsgetdcname
.dc_address
);
896 BAIL_ON_PTR_ERROR(i
->dc_address
, wbc_status
);
898 i
->dc_address_type
= resp
->data
.dsgetdcname
.dc_address_type
;
900 wbc_status
= wbcStringToGuid(resp
->data
.dsgetdcname
.domain_guid
, &guid
);
901 if (WBC_ERROR_IS_OK(wbc_status
)) {
902 i
->domain_guid
= talloc(i
, struct wbcGuid
);
903 BAIL_ON_PTR_ERROR(i
->domain_guid
, wbc_status
);
905 *i
->domain_guid
= guid
;
907 i
->domain_guid
= NULL
;
910 i
->domain_name
= talloc_strdup(i
, resp
->data
.dsgetdcname
.domain_name
);
911 BAIL_ON_PTR_ERROR(i
->domain_name
, wbc_status
);
913 if (resp
->data
.dsgetdcname
.forest_name
[0] != '\0') {
914 i
->forest_name
= talloc_strdup(i
,
915 resp
->data
.dsgetdcname
.forest_name
);
916 BAIL_ON_PTR_ERROR(i
->forest_name
, wbc_status
);
918 i
->forest_name
= NULL
;
921 i
->dc_flags
= resp
->data
.dsgetdcname
.dc_flags
;
923 if (resp
->data
.dsgetdcname
.dc_site_name
[0] != '\0') {
924 i
->dc_site_name
= talloc_strdup(i
,
925 resp
->data
.dsgetdcname
.dc_site_name
);
926 BAIL_ON_PTR_ERROR(i
->dc_site_name
, wbc_status
);
928 i
->dc_site_name
= NULL
;
931 if (resp
->data
.dsgetdcname
.client_site_name
[0] != '\0') {
932 i
->client_site_name
= talloc_strdup(i
,
933 resp
->data
.dsgetdcname
.client_site_name
);
934 BAIL_ON_PTR_ERROR(i
->client_site_name
, wbc_status
);
936 i
->client_site_name
= NULL
;
947 /* Get extended domain controller information */
948 wbcErr
wbcLookupDomainControllerEx(const char *domain
,
949 struct wbcGuid
*guid
,
952 struct wbcDomainControllerInfoEx
**dc_info
)
954 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
955 struct winbindd_request request
;
956 struct winbindd_response response
;
958 /* validate input params */
960 if (!domain
|| !dc_info
) {
961 wbc_status
= WBC_ERR_INVALID_PARAM
;
962 BAIL_ON_WBC_ERROR(wbc_status
);
965 ZERO_STRUCT(request
);
966 ZERO_STRUCT(response
);
968 request
.data
.dsgetdcname
.flags
= flags
;
970 strncpy(request
.data
.dsgetdcname
.domain_name
, domain
,
971 sizeof(request
.data
.dsgetdcname
.domain_name
)-1);
974 strncpy(request
.data
.dsgetdcname
.site_name
, site
,
975 sizeof(request
.data
.dsgetdcname
.site_name
)-1);
981 wbc_status
= wbcGuidToString(guid
, &str
);
982 BAIL_ON_WBC_ERROR(wbc_status
);
984 strncpy(request
.data
.dsgetdcname
.domain_guid
, str
,
985 sizeof(request
.data
.dsgetdcname
.domain_guid
)-1);
992 wbc_status
= wbcRequestResponse(WINBINDD_DSGETDCNAME
,
995 BAIL_ON_WBC_ERROR(wbc_status
);
998 wbc_status
= wbc_create_domain_controller_info_ex(NULL
,
1001 BAIL_ON_WBC_ERROR(wbc_status
);
1004 wbc_status
= WBC_ERR_SUCCESS
;
1009 /* Initialize a named blob and add to list of blobs */
1010 wbcErr
wbcAddNamedBlob(size_t *num_blobs
,
1011 struct wbcNamedBlob
**blobs
,
1017 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
1018 struct wbcNamedBlob blob
;
1020 *blobs
= talloc_realloc(NULL
, *blobs
, struct wbcNamedBlob
,
1022 BAIL_ON_PTR_ERROR(*blobs
, wbc_status
);
1024 blob
.name
= talloc_strdup(*blobs
, name
);
1025 BAIL_ON_PTR_ERROR(blob
.name
, wbc_status
);
1027 blob
.blob
.length
= length
;
1028 blob
.blob
.data
= (uint8_t *)talloc_memdup(*blobs
, data
, length
);
1029 BAIL_ON_PTR_ERROR(blob
.blob
.data
, wbc_status
);
1031 (*(blobs
))[*num_blobs
] = blob
;
1034 wbc_status
= WBC_ERR_SUCCESS
;
1036 if (!WBC_ERROR_IS_OK(wbc_status
)) {
1037 wbcFreeMemory(*blobs
);