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
36 wbcErr
wbcCtxPing(struct wbcContext
*ctx
)
38 struct winbindd_request request
;
39 struct winbindd_response response
;
41 /* Initialize request */
44 ZERO_STRUCT(response
);
46 return wbcRequestResponse(ctx
, WINBINDD_PING
, &request
, &response
);
52 return wbcCtxPing(NULL
);
55 static void wbcInterfaceDetailsDestructor(void *ptr
)
57 struct wbcInterfaceDetails
*i
= (struct wbcInterfaceDetails
*)ptr
;
58 free(i
->winbind_version
);
59 free(i
->netbios_name
);
60 free(i
->netbios_domain
);
65 * @brief Query useful information about the winbind service
67 * @param *_details pointer to hold the struct wbcInterfaceDetails
73 wbcErr
wbcCtxInterfaceDetails(struct wbcContext
*ctx
,
74 struct wbcInterfaceDetails
**_details
)
76 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
77 struct wbcInterfaceDetails
*info
;
78 struct wbcDomainInfo
*domain
= NULL
;
79 struct winbindd_request request
;
80 struct winbindd_response response
;
82 /* Initialize request */
85 ZERO_STRUCT(response
);
87 info
= (struct wbcInterfaceDetails
*)wbcAllocateMemory(
88 1, sizeof(struct wbcInterfaceDetails
),
89 wbcInterfaceDetailsDestructor
);
90 BAIL_ON_PTR_ERROR(info
, wbc_status
);
92 /* first the interface version */
93 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_INTERFACE_VERSION
,
95 BAIL_ON_WBC_ERROR(wbc_status
);
96 info
->interface_version
= response
.data
.interface_version
;
98 /* then the samba version and the winbind separator */
99 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_INFO
, NULL
, &response
);
100 BAIL_ON_WBC_ERROR(wbc_status
);
102 info
->winbind_version
= strdup(response
.data
.info
.samba_version
);
103 BAIL_ON_PTR_ERROR(info
->winbind_version
, wbc_status
);
104 info
->winbind_separator
= response
.data
.info
.winbind_separator
;
106 /* then the local netbios name */
107 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_NETBIOS_NAME
,
109 BAIL_ON_WBC_ERROR(wbc_status
);
111 info
->netbios_name
= strdup(response
.data
.netbios_name
);
112 BAIL_ON_PTR_ERROR(info
->netbios_name
, wbc_status
);
114 /* then the local workgroup name */
115 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DOMAIN_NAME
,
117 BAIL_ON_WBC_ERROR(wbc_status
);
119 info
->netbios_domain
= strdup(response
.data
.domain_name
);
120 BAIL_ON_PTR_ERROR(info
->netbios_domain
, wbc_status
);
122 wbc_status
= wbcCtxDomainInfo(ctx
, info
->netbios_domain
, &domain
);
123 if (wbc_status
== WBC_ERR_DOMAIN_NOT_FOUND
) {
124 /* maybe it's a standalone server */
127 BAIL_ON_WBC_ERROR(wbc_status
);
131 info
->dns_domain
= strdup(domain
->dns_name
);
132 wbcFreeMemory(domain
);
133 BAIL_ON_PTR_ERROR(info
->dns_domain
, wbc_status
);
135 info
->dns_domain
= NULL
;
141 wbc_status
= WBC_ERR_SUCCESS
;
149 wbcErr
wbcInterfaceDetails(struct wbcInterfaceDetails
**_details
)
151 return wbcCtxInterfaceDetails(NULL
, _details
);
154 static void wbcDomainInfoDestructor(void *ptr
)
156 struct wbcDomainInfo
*i
= (struct wbcDomainInfo
*)ptr
;
161 /** @brief Lookup the current status of a trusted domain, sync wrapper
163 * @param domain Domain to query
164 * @param *dinfo Pointer to returned struct wbcDomainInfo
170 wbcErr
wbcCtxDomainInfo(struct wbcContext
*ctx
,
172 struct wbcDomainInfo
**dinfo
)
174 struct winbindd_request request
;
175 struct winbindd_response response
;
176 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
177 struct wbcDomainInfo
*info
= NULL
;
179 if (!domain
|| !dinfo
) {
180 wbc_status
= WBC_ERR_INVALID_PARAM
;
181 BAIL_ON_WBC_ERROR(wbc_status
);
184 /* Initialize request */
186 ZERO_STRUCT(request
);
187 ZERO_STRUCT(response
);
189 strncpy(request
.domain_name
, domain
,
190 sizeof(request
.domain_name
)-1);
192 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DOMAIN_INFO
,
195 BAIL_ON_WBC_ERROR(wbc_status
);
197 info
= (struct wbcDomainInfo
*)wbcAllocateMemory(
198 1, sizeof(struct wbcDomainInfo
), wbcDomainInfoDestructor
);
199 BAIL_ON_PTR_ERROR(info
, wbc_status
);
201 info
->short_name
= strdup(response
.data
.domain_info
.name
);
202 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
204 info
->dns_name
= strdup(response
.data
.domain_info
.alt_name
);
205 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
207 wbc_status
= wbcStringToSid(response
.data
.domain_info
.sid
,
209 BAIL_ON_WBC_ERROR(wbc_status
);
211 if (response
.data
.domain_info
.native_mode
)
212 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_NATIVE
;
213 if (response
.data
.domain_info
.active_directory
)
214 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_AD
;
215 if (response
.data
.domain_info
.primary
)
216 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_PRIMARY
;
221 wbc_status
= WBC_ERR_SUCCESS
;
229 wbcErr
wbcDomainInfo(const char *domain
, struct wbcDomainInfo
**dinfo
)
231 return wbcCtxDomainInfo(NULL
, domain
, dinfo
);
234 /* Get the list of current DCs */
236 wbcErr
wbcCtxDcInfo(struct wbcContext
*ctx
,
237 const char *domain
, size_t *num_dcs
,
238 const char ***dc_names
, const char ***dc_ips
)
240 struct winbindd_request request
;
241 struct winbindd_response response
;
242 const char **names
= NULL
;
243 const char **ips
= NULL
;
244 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
249 /* Initialise request */
251 ZERO_STRUCT(request
);
252 ZERO_STRUCT(response
);
254 if (domain
!= NULL
) {
255 strncpy(request
.domain_name
, domain
,
256 sizeof(request
.domain_name
) - 1);
259 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DC_INFO
,
260 &request
, &response
);
261 BAIL_ON_WBC_ERROR(wbc_status
);
263 names
= wbcAllocateStringArray(response
.data
.num_entries
);
264 BAIL_ON_PTR_ERROR(names
, wbc_status
);
266 ips
= wbcAllocateStringArray(response
.data
.num_entries
);
267 BAIL_ON_PTR_ERROR(ips
, wbc_status
);
269 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
271 p
= (char *)response
.extra_data
.data
;
273 if (response
.length
< (sizeof(struct winbindd_response
)+1)) {
277 extra_len
= response
.length
- sizeof(struct winbindd_response
);
279 if (p
[extra_len
-1] != '\0') {
283 for (i
=0; i
<response
.data
.num_entries
; i
++) {
290 names
[i
] = strndup(p
, q
-p
);
291 BAIL_ON_PTR_ERROR(names
[i
], wbc_status
);
298 ips
[i
] = strndup(p
, q
-p
);
299 BAIL_ON_PTR_ERROR(ips
[i
], wbc_status
);
306 wbc_status
= WBC_ERR_SUCCESS
;
308 if (response
.extra_data
.data
)
309 free(response
.extra_data
.data
);
311 if (WBC_ERROR_IS_OK(wbc_status
)) {
312 *num_dcs
= response
.data
.num_entries
;
318 wbcFreeMemory(names
);
324 wbcErr
wbcDcInfo(const char *domain
, size_t *num_dcs
,
325 const char ***dc_names
, const char ***dc_ips
)
327 return wbcCtxDcInfo(NULL
, domain
, num_dcs
, dc_names
, dc_ips
);
330 /* Resolve a NetbiosName via WINS */
332 wbcErr
wbcCtxResolveWinsByName(struct wbcContext
*ctx
,
333 const char *name
, char **ip
)
335 struct winbindd_request request
;
336 struct winbindd_response response
;
337 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
340 ZERO_STRUCT(request
);
341 ZERO_STRUCT(response
);
345 strncpy(request
.data
.winsreq
, name
,
346 sizeof(request
.data
.winsreq
)-1);
348 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_WINS_BYNAME
,
351 BAIL_ON_WBC_ERROR(wbc_status
);
353 /* Display response */
355 ipaddr
= wbcStrDup(response
.data
.winsresp
);
356 BAIL_ON_PTR_ERROR(ipaddr
, wbc_status
);
359 wbc_status
= WBC_ERR_SUCCESS
;
366 wbcErr
wbcResolveWinsByName(const char *name
, char **ip
)
368 return wbcCtxResolveWinsByName(NULL
, name
, ip
);
371 /* Resolve an IP address via WINS into a NetbiosName */
373 wbcErr
wbcCtxResolveWinsByIP(struct wbcContext
*ctx
,
374 const char *ip
, char **name
)
376 struct winbindd_request request
;
377 struct winbindd_response response
;
378 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
381 ZERO_STRUCT(request
);
382 ZERO_STRUCT(response
);
386 strncpy(request
.data
.winsreq
, ip
,
387 sizeof(request
.data
.winsreq
)-1);
389 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_WINS_BYIP
,
392 BAIL_ON_WBC_ERROR(wbc_status
);
394 /* Display response */
396 name_str
= wbcStrDup(response
.data
.winsresp
);
397 BAIL_ON_PTR_ERROR(name_str
, wbc_status
);
400 wbc_status
= WBC_ERR_SUCCESS
;
407 wbcErr
wbcResolveWinsByIP(const char *ip
, char **name
)
409 return wbcCtxResolveWinsByIP(NULL
, ip
, name
);
415 static wbcErr
process_domain_info_string(struct wbcDomainInfo
*info
,
418 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
425 if ((s
= strchr(r
, '\\')) == NULL
) {
426 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
427 BAIL_ON_WBC_ERROR(wbc_status
);
432 info
->short_name
= strdup(r
);
433 BAIL_ON_PTR_ERROR(info
->short_name
, wbc_status
);
438 if ((s
= strchr(r
, '\\')) == NULL
) {
439 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
440 BAIL_ON_WBC_ERROR(wbc_status
);
445 info
->dns_name
= strdup(r
);
446 BAIL_ON_PTR_ERROR(info
->dns_name
, wbc_status
);
450 if ((s
= strchr(r
, '\\')) == NULL
) {
451 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
452 BAIL_ON_WBC_ERROR(wbc_status
);
457 wbc_status
= wbcStringToSid(r
, &info
->sid
);
458 BAIL_ON_WBC_ERROR(wbc_status
);
462 if ((s
= strchr(r
, '\\')) == NULL
) {
463 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
464 BAIL_ON_WBC_ERROR(wbc_status
);
469 if (strncmp(r
, "Routed", strlen("Routed")) == 0) {
470 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_NONE
;
471 info
->trust_routing
= strdup(r
);
472 BAIL_ON_PTR_ERROR(info
->trust_routing
, wbc_status
);
473 } else if (strcmp(r
, "Local") == 0) {
474 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_LOCAL
;
475 } else if (strcmp(r
, "Workstation") == 0) {
476 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_WKSTA
;
477 } else if (strcmp(r
, "RWDC") == 0) {
478 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_RWDC
;
479 } else if (strcmp(r
, "RODC") == 0) {
480 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_RODC
;
481 } else if (strcmp(r
, "PDC") == 0) {
482 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_PDC
;
483 } else if (strcmp(r
, "External") == 0) {
484 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_EXTERNAL
;
485 } else if (strcmp(r
, "Forest") == 0) {
486 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_FOREST
;
487 } else if (strcmp(r
, "In Forest") == 0) {
488 info
->trust_type
= WBC_DOMINFO_TRUSTTYPE_IN_FOREST
;
490 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
491 BAIL_ON_WBC_ERROR(wbc_status
);
496 if ((s
= strchr(r
, '\\')) == NULL
) {
497 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
498 BAIL_ON_WBC_ERROR(wbc_status
);
503 if (strcmp(r
, "Yes") == 0) {
504 info
->trust_flags
|= WBC_DOMINFO_TRUST_TRANSITIVE
;
509 if ((s
= strchr(r
, '\\')) == NULL
) {
510 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
511 BAIL_ON_WBC_ERROR(wbc_status
);
516 if (strcmp(r
, "Yes") == 0) {
517 info
->trust_flags
|= WBC_DOMINFO_TRUST_INCOMING
;
522 if ((s
= strchr(r
, '\\')) == NULL
) {
523 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
524 BAIL_ON_WBC_ERROR(wbc_status
);
529 if (strcmp(r
, "Yes") == 0) {
530 info
->trust_flags
|= WBC_DOMINFO_TRUST_OUTGOING
;
533 /* Online/Offline status */
535 if ( strcmp(r
, "Offline") == 0) {
536 info
->domain_flags
|= WBC_DOMINFO_DOMAIN_OFFLINE
;
539 wbc_status
= WBC_ERR_SUCCESS
;
545 static void wbcDomainInfoListDestructor(void *ptr
)
547 struct wbcDomainInfo
*i
= (struct wbcDomainInfo
*)ptr
;
549 while (i
->short_name
!= NULL
) {
552 free(i
->trust_routing
);
557 /* Enumerate the domain trusts known by Winbind */
559 wbcErr
wbcCtxListTrusts(struct wbcContext
*ctx
,
560 struct wbcDomainInfo
**domains
, size_t *num_domains
)
562 struct winbindd_response response
;
563 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
565 char *extra_data
= NULL
;
566 struct wbcDomainInfo
*d_list
= NULL
;
572 ZERO_STRUCT(response
);
576 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LIST_TRUSTDOM
,
579 BAIL_ON_WBC_ERROR(wbc_status
);
581 /* Decode the response */
583 p
= (char *)response
.extra_data
.data
;
585 if ((p
== NULL
) || (strlen(p
) == 0)) {
586 /* We should always at least get back our
589 wbc_status
= WBC_ERR_DOMAIN_NOT_FOUND
;
590 BAIL_ON_WBC_ERROR(wbc_status
);
593 d_list
= (struct wbcDomainInfo
*)wbcAllocateMemory(
594 response
.data
.num_entries
+ 1,sizeof(struct wbcDomainInfo
),
595 wbcDomainInfoListDestructor
);
596 BAIL_ON_PTR_ERROR(d_list
, wbc_status
);
598 extra_data
= strdup((char*)response
.extra_data
.data
);
599 BAIL_ON_PTR_ERROR(extra_data
, wbc_status
);
603 /* Outer loop processes the list of domain information */
605 for (i
=0; i
<response
.data
.num_entries
&& p
; i
++) {
606 char *next
= strchr(p
, '\n');
613 wbc_status
= process_domain_info_string(&d_list
[i
], p
);
614 BAIL_ON_WBC_ERROR(wbc_status
);
624 winbindd_free_response(&response
);
625 wbcFreeMemory(d_list
);
631 wbcErr
wbcListTrusts(struct wbcDomainInfo
**domains
, size_t *num_domains
)
633 return wbcCtxListTrusts(NULL
, domains
, num_domains
);
636 static void wbcDomainControllerInfoDestructor(void *ptr
)
638 struct wbcDomainControllerInfo
*i
=
639 (struct wbcDomainControllerInfo
*)ptr
;
643 /* Enumerate the domain trusts known by Winbind */
645 wbcErr
wbcCtxLookupDomainController(struct wbcContext
*ctx
,
646 const char *domain
, uint32_t flags
,
647 struct wbcDomainControllerInfo
**dc_info
)
649 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
650 struct winbindd_request request
;
651 struct winbindd_response response
;
652 struct wbcDomainControllerInfo
*dc
= NULL
;
654 /* validate input params */
656 if (!domain
|| !dc_info
) {
657 wbc_status
= WBC_ERR_INVALID_PARAM
;
658 BAIL_ON_WBC_ERROR(wbc_status
);
661 ZERO_STRUCT(request
);
662 ZERO_STRUCT(response
);
664 strncpy(request
.data
.dsgetdcname
.domain_name
, domain
,
665 sizeof(request
.data
.dsgetdcname
.domain_name
)-1);
667 request
.flags
= flags
;
669 dc
= (struct wbcDomainControllerInfo
*)wbcAllocateMemory(
670 1, sizeof(struct wbcDomainControllerInfo
),
671 wbcDomainControllerInfoDestructor
);
672 BAIL_ON_PTR_ERROR(dc
, wbc_status
);
676 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DSGETDCNAME
,
679 BAIL_ON_WBC_ERROR(wbc_status
);
681 dc
->dc_name
= strdup(response
.data
.dsgetdcname
.dc_unc
);
682 BAIL_ON_PTR_ERROR(dc
->dc_name
, wbc_status
);
693 wbcErr
wbcLookupDomainController(const char *domain
, uint32_t flags
,
694 struct wbcDomainControllerInfo
**dc_info
)
696 return wbcCtxLookupDomainController(NULL
, domain
, flags
, dc_info
);
699 static void wbcDomainControllerInfoExDestructor(void *ptr
)
701 struct wbcDomainControllerInfoEx
*i
=
702 (struct wbcDomainControllerInfoEx
*)ptr
;
703 free(discard_const_p(char, i
->dc_unc
));
704 free(discard_const_p(char, i
->dc_address
));
705 free(discard_const_p(char, i
->domain_guid
));
706 free(discard_const_p(char, i
->domain_name
));
707 free(discard_const_p(char, i
->forest_name
));
708 free(discard_const_p(char, i
->dc_site_name
));
709 free(discard_const_p(char, i
->client_site_name
));
712 static wbcErr
wbc_create_domain_controller_info_ex(const struct winbindd_response
*resp
,
713 struct wbcDomainControllerInfoEx
**_i
)
715 wbcErr wbc_status
= WBC_ERR_SUCCESS
;
716 struct wbcDomainControllerInfoEx
*i
;
719 i
= (struct wbcDomainControllerInfoEx
*)wbcAllocateMemory(
720 1, sizeof(struct wbcDomainControllerInfoEx
),
721 wbcDomainControllerInfoExDestructor
);
722 BAIL_ON_PTR_ERROR(i
, wbc_status
);
724 i
->dc_unc
= strdup(resp
->data
.dsgetdcname
.dc_unc
);
725 BAIL_ON_PTR_ERROR(i
->dc_unc
, wbc_status
);
727 i
->dc_address
= strdup(resp
->data
.dsgetdcname
.dc_address
);
728 BAIL_ON_PTR_ERROR(i
->dc_address
, wbc_status
);
730 i
->dc_address_type
= resp
->data
.dsgetdcname
.dc_address_type
;
732 wbc_status
= wbcStringToGuid(resp
->data
.dsgetdcname
.domain_guid
, &guid
);
733 if (WBC_ERROR_IS_OK(wbc_status
)) {
734 i
->domain_guid
= (struct wbcGuid
*)malloc(
735 sizeof(struct wbcGuid
));
736 BAIL_ON_PTR_ERROR(i
->domain_guid
, wbc_status
);
738 *i
->domain_guid
= guid
;
741 i
->domain_name
= strdup(resp
->data
.dsgetdcname
.domain_name
);
742 BAIL_ON_PTR_ERROR(i
->domain_name
, wbc_status
);
744 if (resp
->data
.dsgetdcname
.forest_name
[0] != '\0') {
745 i
->forest_name
= strdup(resp
->data
.dsgetdcname
.forest_name
);
746 BAIL_ON_PTR_ERROR(i
->forest_name
, wbc_status
);
749 i
->dc_flags
= resp
->data
.dsgetdcname
.dc_flags
;
751 if (resp
->data
.dsgetdcname
.dc_site_name
[0] != '\0') {
752 i
->dc_site_name
= strdup(resp
->data
.dsgetdcname
.dc_site_name
);
753 BAIL_ON_PTR_ERROR(i
->dc_site_name
, wbc_status
);
756 if (resp
->data
.dsgetdcname
.client_site_name
[0] != '\0') {
757 i
->client_site_name
= strdup(
758 resp
->data
.dsgetdcname
.client_site_name
);
759 BAIL_ON_PTR_ERROR(i
->client_site_name
, wbc_status
);
772 /* Get extended domain controller information */
774 wbcErr
wbcCtxLookupDomainControllerEx(struct wbcContext
*ctx
,
776 struct wbcGuid
*guid
,
779 struct wbcDomainControllerInfoEx
**dc_info
)
781 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
782 struct winbindd_request request
;
783 struct winbindd_response response
;
785 /* validate input params */
787 if (!domain
|| !dc_info
) {
788 wbc_status
= WBC_ERR_INVALID_PARAM
;
789 BAIL_ON_WBC_ERROR(wbc_status
);
792 ZERO_STRUCT(request
);
793 ZERO_STRUCT(response
);
795 request
.data
.dsgetdcname
.flags
= flags
;
797 strncpy(request
.data
.dsgetdcname
.domain_name
, domain
,
798 sizeof(request
.data
.dsgetdcname
.domain_name
)-1);
801 strncpy(request
.data
.dsgetdcname
.site_name
, site
,
802 sizeof(request
.data
.dsgetdcname
.site_name
)-1);
808 wbc_status
= wbcGuidToString(guid
, &str
);
809 BAIL_ON_WBC_ERROR(wbc_status
);
811 strncpy(request
.data
.dsgetdcname
.domain_guid
, str
,
812 sizeof(request
.data
.dsgetdcname
.domain_guid
)-1);
819 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_DSGETDCNAME
,
822 BAIL_ON_WBC_ERROR(wbc_status
);
825 wbc_status
= wbc_create_domain_controller_info_ex(&response
,
827 BAIL_ON_WBC_ERROR(wbc_status
);
830 wbc_status
= WBC_ERR_SUCCESS
;
836 wbcErr
wbcLookupDomainControllerEx(const char *domain
,
837 struct wbcGuid
*guid
,
840 struct wbcDomainControllerInfoEx
**dc_info
)
842 return wbcCtxLookupDomainControllerEx(NULL
, domain
, guid
, site
,
846 static void wbcNamedBlobDestructor(void *ptr
)
848 struct wbcNamedBlob
*b
= (struct wbcNamedBlob
*)ptr
;
850 while (b
->name
!= NULL
) {
851 free(discard_const_p(char, b
->name
));
857 /* Initialize a named blob and add to list of blobs */
859 wbcErr
wbcAddNamedBlob(size_t *num_blobs
,
860 struct wbcNamedBlob
**pblobs
,
866 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
867 struct wbcNamedBlob
*blobs
, *blob
;
870 return WBC_ERR_INVALID_PARAM
;
874 * Overallocate the b->name==NULL terminator for
875 * wbcNamedBlobDestructor
877 blobs
= (struct wbcNamedBlob
*)wbcAllocateMemory(
878 *num_blobs
+ 2, sizeof(struct wbcNamedBlob
),
879 wbcNamedBlobDestructor
);
882 return WBC_ERR_NO_MEMORY
;
885 if (*pblobs
!= NULL
) {
886 struct wbcNamedBlob
*old
= *pblobs
;
887 memcpy(blobs
, old
, sizeof(struct wbcNamedBlob
) * (*num_blobs
));
888 if (*num_blobs
!= 0) {
889 /* end indicator for wbcNamedBlobDestructor */
896 blob
= &blobs
[*num_blobs
];
898 blob
->name
= strdup(name
);
899 BAIL_ON_PTR_ERROR(blob
->name
, wbc_status
);
902 blob
->blob
.length
= length
;
903 blob
->blob
.data
= (uint8_t *)malloc(length
);
904 BAIL_ON_PTR_ERROR(blob
->blob
.data
, wbc_status
);
905 memcpy(blob
->blob
.data
, data
, length
);
911 wbc_status
= WBC_ERR_SUCCESS
;
913 wbcFreeMemory(blobs
);
918 void wbcSetClientProcessName(const char *name
)
920 winbind_set_client_name(name
);