2 Unix SMB/CIFS implementation.
4 Winbind client asynchronous API, utility functions
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"
27 #include "../winbind_client.h"
29 /** @brief Ping winbindd to see if the daemon is running
31 * @param *ctx wbclient Context
35 wbcErr
wbcCtxPing(struct wbcContext
*ctx
)
37 struct winbindd_request request
;
38 struct winbindd_response response
;
40 /* Initialize request */
43 ZERO_STRUCT(response
);
45 return wbcRequestResponse(ctx
, WINBINDD_PING
, &request
, &response
);
50 return wbcCtxPing(NULL
);
53 static void wbcInterfaceDetailsDestructor(void *ptr
)
55 struct wbcInterfaceDetails
*i
= (struct wbcInterfaceDetails
*)ptr
;
56 free(i
->winbind_version
);
57 free(i
->netbios_name
);
58 free(i
->netbios_domain
);
63 * @brief Query useful information about the winbind service
65 * @param *_details pointer to hold the struct wbcInterfaceDetails
70 wbcErr
wbcCtxInterfaceDetails(struct wbcContext
*ctx
,
71 struct wbcInterfaceDetails
**_details
)
73 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
74 struct wbcInterfaceDetails
*info
;
75 struct wbcDomainInfo
*domain
= NULL
;
76 struct winbindd_request request
;
77 struct winbindd_response response
;
79 /* Initialize request */
82 ZERO_STRUCT(response
);
84 info
= (struct wbcInterfaceDetails
*)wbcAllocateMemory(
85 1, sizeof(struct wbcInterfaceDetails
),
86 wbcInterfaceDetailsDestructor
);
87 BAIL_ON_PTR_ERROR(info
, wbc_status
);
89 /* first the interface version */
90 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_INTERFACE_VERSION
,
92 BAIL_ON_WBC_ERROR(wbc_status
);
93 info
->interface_version
= response
.data
.interface_version
;
95 /* then the samba version and the winbind separator */
96 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_INFO
, NULL
, &response
);
97 BAIL_ON_WBC_ERROR(wbc_status
);
99 info
->winbind_version
= strdup(response
.data
.info
.samba_version
);
100 BAIL_ON_PTR_ERROR(info
->winbind_version
, wbc_status
);
101 info
->winbind_separator
= response
.data
.info
.winbind_separator
;
103 /* then the local netbios name */
104 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_NETBIOS_NAME
,
106 BAIL_ON_WBC_ERROR(wbc_status
);
108 info
->netbios_name
= strdup(response
.data
.netbios_name
);
109 BAIL_ON_PTR_ERROR(info
->netbios_name
, wbc_status
);
111 /* then the local workgroup name */
112 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DOMAIN_NAME
,
114 BAIL_ON_WBC_ERROR(wbc_status
);
116 info
->netbios_domain
= strdup(response
.data
.domain_name
);
117 BAIL_ON_PTR_ERROR(info
->netbios_domain
, wbc_status
);
119 wbc_status
= wbcCtxDomainInfo(ctx
, info
->netbios_domain
, &domain
);
120 if (wbc_status
== WBC_ERR_DOMAIN_NOT_FOUND
) {
121 /* maybe it's a standalone server */
124 BAIL_ON_WBC_ERROR(wbc_status
);
128 info
->dns_domain
= strdup(domain
->dns_name
);
129 wbcFreeMemory(domain
);
130 BAIL_ON_PTR_ERROR(info
->dns_domain
, wbc_status
);
132 info
->dns_domain
= NULL
;
138 wbc_status
= WBC_ERR_SUCCESS
;
145 wbcErr
wbcInterfaceDetails(struct wbcInterfaceDetails
**_details
)
147 return wbcCtxInterfaceDetails(NULL
, _details
);
150 static void wbcDomainInfoDestructor(void *ptr
)
152 struct wbcDomainInfo
*i
= (struct wbcDomainInfo
*)ptr
;
157 /** @brief Lookup the current status of a trusted domain, sync wrapper
159 * @param domain Domain to query
160 * @param *dinfo Pointer to returned struct wbcDomainInfo
165 wbcErr
wbcCtxDomainInfo(struct wbcContext
*ctx
,
167 struct wbcDomainInfo
**dinfo
)
169 struct winbindd_request request
;
170 struct winbindd_response response
;
171 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
172 struct wbcDomainInfo
*info
= NULL
;
174 if (!domain
|| !dinfo
) {
175 wbc_status
= WBC_ERR_INVALID_PARAM
;
176 BAIL_ON_WBC_ERROR(wbc_status
);
179 /* Initialize request */
181 ZERO_STRUCT(request
);
182 ZERO_STRUCT(response
);
184 strncpy(request
.domain_name
, domain
,
185 sizeof(request
.domain_name
)-1);
187 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DOMAIN_INFO
,
190 BAIL_ON_WBC_ERROR(wbc_status
);
192 info
= (struct wbcDomainInfo
*)wbcAllocateMemory(
193 1, sizeof(struct wbcDomainInfo
), wbcDomainInfoDestructor
);
194 BAIL_ON_PTR_ERROR(info
, wbc_status
);
196 info
->short_name
= strdup(response
.data
.domain_info
.name
);
197 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
199 info
->dns_name
= strdup(response
.data
.domain_info
.alt_name
);
200 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
202 wbc_status
= wbcStringToSid(response
.data
.domain_info
.sid
,
204 BAIL_ON_WBC_ERROR(wbc_status
);
206 if (response
.data
.domain_info
.native_mode
)
207 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_NATIVE
;
208 if (response
.data
.domain_info
.active_directory
)
209 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_AD
;
210 if (response
.data
.domain_info
.primary
)
211 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_PRIMARY
;
216 wbc_status
= WBC_ERR_SUCCESS
;
223 wbcErr
wbcDomainInfo(const char *domain
, struct wbcDomainInfo
**dinfo
)
225 return wbcCtxDomainInfo(NULL
, domain
, dinfo
);
228 /* Get the list of current DCs */
229 wbcErr
wbcCtxDcInfo(struct wbcContext
*ctx
,
230 const char *domain
, size_t *num_dcs
,
231 const char ***dc_names
, const char ***dc_ips
)
233 struct winbindd_request request
;
234 struct winbindd_response response
;
235 const char **names
= NULL
;
236 const char **ips
= NULL
;
237 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
242 /* Initialise request */
244 ZERO_STRUCT(request
);
245 ZERO_STRUCT(response
);
247 if (domain
!= NULL
) {
248 strncpy(request
.domain_name
, domain
,
249 sizeof(request
.domain_name
) - 1);
252 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DC_INFO
,
253 &request
, &response
);
254 BAIL_ON_WBC_ERROR(wbc_status
);
256 names
= wbcAllocateStringArray(response
.data
.num_entries
);
257 BAIL_ON_PTR_ERROR(names
, wbc_status
);
259 ips
= wbcAllocateStringArray(response
.data
.num_entries
);
260 BAIL_ON_PTR_ERROR(ips
, wbc_status
);
262 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
264 p
= (char *)response
.extra_data
.data
;
266 if (response
.length
< (sizeof(struct winbindd_response
)+1)) {
270 extra_len
= response
.length
- sizeof(struct winbindd_response
);
272 if (p
[extra_len
-1] != '\0') {
276 for (i
=0; i
<response
.data
.num_entries
; i
++) {
283 names
[i
] = strndup(p
, q
-p
);
284 BAIL_ON_PTR_ERROR(names
[i
], wbc_status
);
291 ips
[i
] = strndup(p
, q
-p
);
292 BAIL_ON_PTR_ERROR(ips
[i
], wbc_status
);
299 wbc_status
= WBC_ERR_SUCCESS
;
301 if (response
.extra_data
.data
)
302 free(response
.extra_data
.data
);
304 if (WBC_ERROR_IS_OK(wbc_status
)) {
305 *num_dcs
= response
.data
.num_entries
;
311 wbcFreeMemory(names
);
316 wbcErr
wbcDcInfo(const char *domain
, size_t *num_dcs
,
317 const char ***dc_names
, const char ***dc_ips
)
319 return wbcCtxDcInfo(NULL
, domain
, num_dcs
, dc_names
, dc_ips
);
322 /* Resolve a NetbiosName via WINS */
323 wbcErr
wbcCtxResolveWinsByName(struct wbcContext
*ctx
,
324 const char *name
, char **ip
)
326 struct winbindd_request request
;
327 struct winbindd_response response
;
328 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
331 ZERO_STRUCT(request
);
332 ZERO_STRUCT(response
);
336 strncpy(request
.data
.winsreq
, name
,
337 sizeof(request
.data
.winsreq
)-1);
339 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_WINS_BYNAME
,
342 BAIL_ON_WBC_ERROR(wbc_status
);
344 /* Display response */
346 ipaddr
= wbcStrDup(response
.data
.winsresp
);
347 BAIL_ON_PTR_ERROR(ipaddr
, wbc_status
);
350 wbc_status
= WBC_ERR_SUCCESS
;
356 wbcErr
wbcResolveWinsByName(const char *name
, char **ip
)
358 return wbcCtxResolveWinsByName(NULL
, name
, ip
);
361 /* Resolve an IP address via WINS into a NetbiosName */
362 wbcErr
wbcCtxResolveWinsByIP(struct wbcContext
*ctx
,
363 const char *ip
, char **name
)
365 struct winbindd_request request
;
366 struct winbindd_response response
;
367 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
370 ZERO_STRUCT(request
);
371 ZERO_STRUCT(response
);
375 strncpy(request
.data
.winsreq
, ip
,
376 sizeof(request
.data
.winsreq
)-1);
378 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_WINS_BYIP
,
381 BAIL_ON_WBC_ERROR(wbc_status
);
383 /* Display response */
385 name_str
= wbcStrDup(response
.data
.winsresp
);
386 BAIL_ON_PTR_ERROR(name_str
, wbc_status
);
389 wbc_status
= WBC_ERR_SUCCESS
;
395 wbcErr
wbcResolveWinsByIP(const char *ip
, char **name
)
397 return wbcCtxResolveWinsByIP(NULL
, ip
, name
);
403 static wbcErr
process_domain_info_string(struct wbcDomainInfo
*info
,
406 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
413 if ((s
= strchr(r
, '\\')) == NULL
) {
414 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
415 BAIL_ON_WBC_ERROR(wbc_status
);
420 info
->short_name
= strdup(r
);
421 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
426 if ((s
= strchr(r
, '\\')) == NULL
) {
427 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
428 BAIL_ON_WBC_ERROR(wbc_status
);
433 info
->dns_name
= strdup(r
);
434 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
438 if ((s
= strchr(r
, '\\')) == NULL
) {
439 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
440 BAIL_ON_WBC_ERROR(wbc_status
);
445 wbc_status
= wbcStringToSid(r
, &info
->sid
);
446 BAIL_ON_WBC_ERROR(wbc_status
);
450 if ((s
= strchr(r
, '\\')) == NULL
) {
451 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
452 BAIL_ON_WBC_ERROR(wbc_status
);
457 if (strncmp(r
, "Routed", strlen("Routed")) == 0) {
458 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_NONE
;
459 info
->trust_routing
= strdup(r
);
460 BAIL_ON_PTR_ERROR(info
->trust_routing
, wbc_status
);
461 } else if (strcmp(r
, "Local") == 0) {
462 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_LOCAL
;
463 } else if (strcmp(r
, "Workstation") == 0) {
464 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_WKSTA
;
465 } else if (strcmp(r
, "RWDC") == 0) {
466 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_RWDC
;
467 } else if (strcmp(r
, "RODC") == 0) {
468 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_RODC
;
469 } else if (strcmp(r
, "PDC") == 0) {
470 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_PDC
;
471 } else if (strcmp(r
, "External") == 0) {
472 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_EXTERNAL
;
473 } else if (strcmp(r
, "Forest") == 0) {
474 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_FOREST
;
475 } else if (strcmp(r
, "In Forest") == 0) {
476 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_IN_FOREST
;
478 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
479 BAIL_ON_WBC_ERROR(wbc_status
);
484 if ((s
= strchr(r
, '\\')) == NULL
) {
485 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
486 BAIL_ON_WBC_ERROR(wbc_status
);
491 if (strcmp(r
, "Yes") == 0) {
492 info
->trust_flags
|= WBC_DOMINFO_TRUST_TRANSITIVE
;
497 if ((s
= strchr(r
, '\\')) == NULL
) {
498 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
499 BAIL_ON_WBC_ERROR(wbc_status
);
504 if (strcmp(r
, "Yes") == 0) {
505 info
->trust_flags
|= WBC_DOMINFO_TRUST_INCOMING
;
510 if ((s
= strchr(r
, '\\')) == NULL
) {
511 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
512 BAIL_ON_WBC_ERROR(wbc_status
);
517 if (strcmp(r
, "Yes") == 0) {
518 info
->trust_flags
|= WBC_DOMINFO_TRUST_OUTGOING
;
521 /* Online/Offline status */
523 if ( strcmp(r
, "Offline") == 0) {
524 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_OFFLINE
;
527 wbc_status
= WBC_ERR_SUCCESS
;
533 static void wbcDomainInfoListDestructor(void *ptr
)
535 struct wbcDomainInfo
*i
= (struct wbcDomainInfo
*)ptr
;
537 while (i
->short_name
!= NULL
) {
544 /* Enumerate the domain trusts known by Winbind */
545 wbcErr
wbcCtxListTrusts(struct wbcContext
*ctx
,
546 struct wbcDomainInfo
**domains
, size_t *num_domains
)
548 struct winbindd_response response
;
549 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
551 char *extra_data
= NULL
;
552 struct wbcDomainInfo
*d_list
= NULL
;
558 ZERO_STRUCT(response
);
562 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LIST_TRUSTDOM
,
565 BAIL_ON_WBC_ERROR(wbc_status
);
567 /* Decode the response */
569 p
= (char *)response
.extra_data
.data
;
571 if ((p
== NULL
) || (strlen(p
) == 0)) {
572 /* We should always at least get back our
575 wbc_status
= WBC_ERR_DOMAIN_NOT_FOUND
;
576 BAIL_ON_WBC_ERROR(wbc_status
);
579 d_list
= (struct wbcDomainInfo
*)wbcAllocateMemory(
580 response
.data
.num_entries
+ 1,sizeof(struct wbcDomainInfo
),
581 wbcDomainInfoListDestructor
);
582 BAIL_ON_PTR_ERROR(d_list
, wbc_status
);
584 extra_data
= strdup((char*)response
.extra_data
.data
);
585 BAIL_ON_PTR_ERROR(extra_data
, wbc_status
);
589 /* Outer loop processes the list of domain information */
591 for (i
=0; i
<response
.data
.num_entries
&& p
; i
++) {
592 char *next
= strchr(p
, '\n');
599 wbc_status
= process_domain_info_string(&d_list
[i
], p
);
600 BAIL_ON_WBC_ERROR(wbc_status
);
610 winbindd_free_response(&response
);
611 wbcFreeMemory(d_list
);
616 wbcErr
wbcListTrusts(struct wbcDomainInfo
**domains
, size_t *num_domains
)
618 return wbcCtxListTrusts(NULL
, domains
, num_domains
);
621 static void wbcDomainControllerInfoDestructor(void *ptr
)
623 struct wbcDomainControllerInfo
*i
=
624 (struct wbcDomainControllerInfo
*)ptr
;
628 /* Enumerate the domain trusts known by Winbind */
629 wbcErr
wbcCtxLookupDomainController(struct wbcContext
*ctx
,
630 const char *domain
, uint32_t flags
,
631 struct wbcDomainControllerInfo
**dc_info
)
633 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
634 struct winbindd_request request
;
635 struct winbindd_response response
;
636 struct wbcDomainControllerInfo
*dc
= NULL
;
638 /* validate input params */
640 if (!domain
|| !dc_info
) {
641 wbc_status
= WBC_ERR_INVALID_PARAM
;
642 BAIL_ON_WBC_ERROR(wbc_status
);
645 ZERO_STRUCT(request
);
646 ZERO_STRUCT(response
);
648 strncpy(request
.data
.dsgetdcname
.domain_name
, domain
,
649 sizeof(request
.data
.dsgetdcname
.domain_name
)-1);
651 request
.flags
= flags
;
653 dc
= (struct wbcDomainControllerInfo
*)wbcAllocateMemory(
654 1, sizeof(struct wbcDomainControllerInfo
),
655 wbcDomainControllerInfoDestructor
);
656 BAIL_ON_PTR_ERROR(dc
, wbc_status
);
660 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DSGETDCNAME
,
663 BAIL_ON_WBC_ERROR(wbc_status
);
665 dc
->dc_name
= strdup(response
.data
.dsgetdcname
.dc_unc
);
666 BAIL_ON_PTR_ERROR(dc
->dc_name
, wbc_status
);
676 wbcErr
wbcLookupDomainController(const char *domain
, uint32_t flags
,
677 struct wbcDomainControllerInfo
**dc_info
)
679 return wbcCtxLookupDomainController(NULL
, domain
, flags
, dc_info
);
682 static void wbcDomainControllerInfoExDestructor(void *ptr
)
684 struct wbcDomainControllerInfoEx
*i
=
685 (struct wbcDomainControllerInfoEx
*)ptr
;
686 free(discard_const_p(char, i
->dc_unc
));
687 free(discard_const_p(char, i
->dc_address
));
688 free(discard_const_p(char, i
->domain_guid
));
689 free(discard_const_p(char, i
->domain_name
));
690 free(discard_const_p(char, i
->forest_name
));
691 free(discard_const_p(char, i
->dc_site_name
));
692 free(discard_const_p(char, i
->client_site_name
));
695 static wbcErr
wbc_create_domain_controller_info_ex(const struct winbindd_response
*resp
,
696 struct wbcDomainControllerInfoEx
**_i
)
698 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
699 struct wbcDomainControllerInfoEx
*i
;
702 i
= (struct wbcDomainControllerInfoEx
*)wbcAllocateMemory(
703 1, sizeof(struct wbcDomainControllerInfoEx
),
704 wbcDomainControllerInfoExDestructor
);
705 BAIL_ON_PTR_ERROR(i
, wbc_status
);
707 i
->dc_unc
= strdup(resp
->data
.dsgetdcname
.dc_unc
);
708 BAIL_ON_PTR_ERROR(i
->dc_unc
, wbc_status
);
710 i
->dc_address
= strdup(resp
->data
.dsgetdcname
.dc_address
);
711 BAIL_ON_PTR_ERROR(i
->dc_address
, wbc_status
);
713 i
->dc_address_type
= resp
->data
.dsgetdcname
.dc_address_type
;
715 wbc_status
= wbcStringToGuid(resp
->data
.dsgetdcname
.domain_guid
, &guid
);
716 if (WBC_ERROR_IS_OK(wbc_status
)) {
717 i
->domain_guid
= (struct wbcGuid
*)malloc(
718 sizeof(struct wbcGuid
));
719 BAIL_ON_PTR_ERROR(i
->domain_guid
, wbc_status
);
721 *i
->domain_guid
= guid
;
724 i
->domain_name
= strdup(resp
->data
.dsgetdcname
.domain_name
);
725 BAIL_ON_PTR_ERROR(i
->domain_name
, wbc_status
);
727 if (resp
->data
.dsgetdcname
.forest_name
[0] != '\0') {
728 i
->forest_name
= strdup(resp
->data
.dsgetdcname
.forest_name
);
729 BAIL_ON_PTR_ERROR(i
->forest_name
, wbc_status
);
732 i
->dc_flags
= resp
->data
.dsgetdcname
.dc_flags
;
734 if (resp
->data
.dsgetdcname
.dc_site_name
[0] != '\0') {
735 i
->dc_site_name
= strdup(resp
->data
.dsgetdcname
.dc_site_name
);
736 BAIL_ON_PTR_ERROR(i
->dc_site_name
, wbc_status
);
739 if (resp
->data
.dsgetdcname
.client_site_name
[0] != '\0') {
740 i
->client_site_name
= strdup(
741 resp
->data
.dsgetdcname
.client_site_name
);
742 BAIL_ON_PTR_ERROR(i
->client_site_name
, wbc_status
);
755 /* Get extended domain controller information */
756 wbcErr
wbcCtxLookupDomainControllerEx(struct wbcContext
*ctx
,
758 struct wbcGuid
*guid
,
761 struct wbcDomainControllerInfoEx
**dc_info
)
763 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
764 struct winbindd_request request
;
765 struct winbindd_response response
;
767 /* validate input params */
769 if (!domain
|| !dc_info
) {
770 wbc_status
= WBC_ERR_INVALID_PARAM
;
771 BAIL_ON_WBC_ERROR(wbc_status
);
774 ZERO_STRUCT(request
);
775 ZERO_STRUCT(response
);
777 request
.data
.dsgetdcname
.flags
= flags
;
779 strncpy(request
.data
.dsgetdcname
.domain_name
, domain
,
780 sizeof(request
.data
.dsgetdcname
.domain_name
)-1);
783 strncpy(request
.data
.dsgetdcname
.site_name
, site
,
784 sizeof(request
.data
.dsgetdcname
.site_name
)-1);
790 wbc_status
= wbcGuidToString(guid
, &str
);
791 BAIL_ON_WBC_ERROR(wbc_status
);
793 strncpy(request
.data
.dsgetdcname
.domain_guid
, str
,
794 sizeof(request
.data
.dsgetdcname
.domain_guid
)-1);
801 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DSGETDCNAME
,
804 BAIL_ON_WBC_ERROR(wbc_status
);
807 wbc_status
= wbc_create_domain_controller_info_ex(&response
,
809 BAIL_ON_WBC_ERROR(wbc_status
);
812 wbc_status
= WBC_ERR_SUCCESS
;
817 wbcErr
wbcLookupDomainControllerEx(const char *domain
,
818 struct wbcGuid
*guid
,
821 struct wbcDomainControllerInfoEx
**dc_info
)
823 return wbcCtxLookupDomainControllerEx(NULL
, domain
, guid
, site
,
827 static void wbcNamedBlobDestructor(void *ptr
)
829 struct wbcNamedBlob
*b
= (struct wbcNamedBlob
*)ptr
;
831 while (b
->name
!= NULL
) {
832 free(discard_const_p(char, b
->name
));
838 /* Initialize a named blob and add to list of blobs */
839 wbcErr
wbcAddNamedBlob(size_t *num_blobs
,
840 struct wbcNamedBlob
**pblobs
,
846 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
847 struct wbcNamedBlob
*blobs
, *blob
;
850 return WBC_ERR_INVALID_PARAM
;
854 * Overallocate the b->name==NULL terminator for
855 * wbcNamedBlobDestructor
857 blobs
= (struct wbcNamedBlob
*)wbcAllocateMemory(
858 *num_blobs
+ 2, sizeof(struct wbcNamedBlob
),
859 wbcNamedBlobDestructor
);
862 return WBC_ERR_NO_MEMORY
;
865 if (*pblobs
!= NULL
) {
866 struct wbcNamedBlob
*old
= *pblobs
;
867 memcpy(blobs
, old
, sizeof(struct wbcNamedBlob
) * (*num_blobs
));
868 if (*num_blobs
!= 0) {
869 /* end indicator for wbcNamedBlobDestructor */
876 blob
= &blobs
[*num_blobs
];
878 blob
->name
= strdup(name
);
879 BAIL_ON_PTR_ERROR(blob
->name
, wbc_status
);
882 blob
->blob
.length
= length
;
883 blob
->blob
.data
= (uint8_t *)malloc(length
);
884 BAIL_ON_PTR_ERROR(blob
->blob
.data
, wbc_status
);
885 memcpy(blob
->blob
.data
, data
, length
);
891 wbc_status
= WBC_ERR_SUCCESS
;
893 wbcFreeMemory(blobs
);
897 void wbcSetClientProcessName(const char *name
)
899 winbind_set_client_name(name
);