source: trunk/server/nsswitch/libwbclient/wbc_util.c

Last change on this file was 745, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.0

File size: 19.7 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Winbind client asynchronous API, utility functions
5
6 Copyright (C) Gerald (Jerry) Carter 2007-2008
7
8
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.
13
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.
18
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/>.
21*/
22
23/* Required Headers */
24
25#include "replace.h"
26#include "libwbclient.h"
27#include "../winbind_client.h"
28
29/** @brief Ping winbindd to see if the daemon is running
30 *
31 * @return #wbcErr
32 **/
33wbcErr wbcPing(void)
34{
35 struct winbindd_request request;
36 struct winbindd_response response;
37
38 /* Initialize request */
39
40 ZERO_STRUCT(request);
41 ZERO_STRUCT(response);
42
43 return wbcRequestResponse(WINBINDD_PING, &request, &response);
44}
45
46static void wbcInterfaceDetailsDestructor(void *ptr)
47{
48 struct wbcInterfaceDetails *i = (struct wbcInterfaceDetails *)ptr;
49 free(i->winbind_version);
50 free(i->netbios_name);
51 free(i->netbios_domain);
52 free(i->dns_domain);
53}
54
55/**
56 * @brief Query useful information about the winbind service
57 *
58 * @param *_details pointer to hold the struct wbcInterfaceDetails
59 *
60 * @return #wbcErr
61 */
62
63wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
64{
65 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
66 struct wbcInterfaceDetails *info;
67 struct wbcDomainInfo *domain = NULL;
68 struct winbindd_request request;
69 struct winbindd_response response;
70
71 /* Initialize request */
72
73 ZERO_STRUCT(request);
74 ZERO_STRUCT(response);
75
76 info = (struct wbcInterfaceDetails *)wbcAllocateMemory(
77 1, sizeof(struct wbcInterfaceDetails),
78 wbcInterfaceDetailsDestructor);
79 BAIL_ON_PTR_ERROR(info, wbc_status);
80
81 /* first the interface version */
82 wbc_status = wbcRequestResponse(WINBINDD_INTERFACE_VERSION, NULL, &response);
83 BAIL_ON_WBC_ERROR(wbc_status);
84 info->interface_version = response.data.interface_version;
85
86 /* then the samba version and the winbind separator */
87 wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response);
88 BAIL_ON_WBC_ERROR(wbc_status);
89
90 info->winbind_version = strdup(response.data.info.samba_version);
91 BAIL_ON_PTR_ERROR(info->winbind_version, wbc_status);
92 info->winbind_separator = response.data.info.winbind_separator;
93
94 /* then the local netbios name */
95 wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response);
96 BAIL_ON_WBC_ERROR(wbc_status);
97
98 info->netbios_name = strdup(response.data.netbios_name);
99 BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status);
100
101 /* then the local workgroup name */
102 wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response);
103 BAIL_ON_WBC_ERROR(wbc_status);
104
105 info->netbios_domain = strdup(response.data.domain_name);
106 BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status);
107
108 wbc_status = wbcDomainInfo(info->netbios_domain, &domain);
109 if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
110 /* maybe it's a standalone server */
111 domain = NULL;
112 wbc_status = WBC_ERR_SUCCESS;
113 } else {
114 BAIL_ON_WBC_ERROR(wbc_status);
115 }
116
117 if (domain) {
118 info->dns_domain = strdup(domain->dns_name);
119 wbcFreeMemory(domain);
120 BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status);
121 } else {
122 info->dns_domain = NULL;
123 }
124
125 *_details = info;
126 info = NULL;
127
128 wbc_status = WBC_ERR_SUCCESS;
129
130done:
131 wbcFreeMemory(info);
132 return wbc_status;
133}
134
135static void wbcDomainInfoDestructor(void *ptr)
136{
137 struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
138 free(i->short_name);
139 free(i->dns_name);
140}
141
142/** @brief Lookup the current status of a trusted domain, sync wrapper
143 *
144 * @param domain Domain to query
145 * @param *dinfo Pointer to returned struct wbcDomainInfo
146 *
147 * @return #wbcErr
148 */
149
150wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
151{
152 struct winbindd_request request;
153 struct winbindd_response response;
154 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
155 struct wbcDomainInfo *info = NULL;
156
157 if (!domain || !dinfo) {
158 wbc_status = WBC_ERR_INVALID_PARAM;
159 BAIL_ON_WBC_ERROR(wbc_status);
160 }
161
162 /* Initialize request */
163
164 ZERO_STRUCT(request);
165 ZERO_STRUCT(response);
166
167 strncpy(request.domain_name, domain,
168 sizeof(request.domain_name)-1);
169
170 wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO,
171 &request,
172 &response);
173 BAIL_ON_WBC_ERROR(wbc_status);
174
175 info = (struct wbcDomainInfo *)wbcAllocateMemory(
176 1, sizeof(struct wbcDomainInfo), wbcDomainInfoDestructor);
177 BAIL_ON_PTR_ERROR(info, wbc_status);
178
179 info->short_name = strdup(response.data.domain_info.name);
180 BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
181
182 info->dns_name = strdup(response.data.domain_info.alt_name);
183 BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
184
185 wbc_status = wbcStringToSid(response.data.domain_info.sid,
186 &info->sid);
187 BAIL_ON_WBC_ERROR(wbc_status);
188
189 if (response.data.domain_info.native_mode)
190 info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
191 if (response.data.domain_info.active_directory)
192 info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
193 if (response.data.domain_info.primary)
194 info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
195
196 *dinfo = info;
197 info = NULL;
198
199 wbc_status = WBC_ERR_SUCCESS;
200
201 done:
202 wbcFreeMemory(info);
203 return wbc_status;
204}
205
206/* Get the list of current DCs */
207wbcErr wbcDcInfo(const char *domain, size_t *num_dcs,
208 const char ***dc_names, const char ***dc_ips)
209{
210 struct winbindd_request request;
211 struct winbindd_response response;
212 const char **names = NULL;
213 const char **ips = NULL;
214 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
215 size_t extra_len;
216 int i;
217 char *p;
218
219 /* Initialise request */
220
221 ZERO_STRUCT(request);
222 ZERO_STRUCT(response);
223
224 if (domain != NULL) {
225 strncpy(request.domain_name, domain,
226 sizeof(request.domain_name) - 1);
227 }
228
229 wbc_status = wbcRequestResponse(WINBINDD_DC_INFO,
230 &request, &response);
231 BAIL_ON_WBC_ERROR(wbc_status);
232
233 names = wbcAllocateStringArray(response.data.num_entries);
234 BAIL_ON_PTR_ERROR(names, wbc_status);
235
236 ips = wbcAllocateStringArray(response.data.num_entries);
237 BAIL_ON_PTR_ERROR(ips, wbc_status);
238
239 wbc_status = WBC_ERR_INVALID_RESPONSE;
240
241 p = (char *)response.extra_data.data;
242
243 if (response.length < (sizeof(struct winbindd_response)+1)) {
244 goto done;
245 }
246
247 extra_len = response.length - sizeof(struct winbindd_response);
248
249 if (p[extra_len-1] != '\0') {
250 goto done;
251 }
252
253 for (i=0; i<response.data.num_entries; i++) {
254 char *q;
255
256 q = strchr(p, '\n');
257 if (q == NULL) {
258 goto done;
259 }
260 names[i] = strndup(p, q-p);
261 BAIL_ON_PTR_ERROR(names[i], wbc_status);
262 p = q+1;
263
264 q = strchr(p, '\n');
265 if (q == NULL) {
266 goto done;
267 }
268 ips[i] = strndup(p, q-p);
269 BAIL_ON_PTR_ERROR(ips[i], wbc_status);
270 p = q+1;
271 }
272 if (p[0] != '\0') {
273 goto done;
274 }
275
276 wbc_status = WBC_ERR_SUCCESS;
277done:
278 if (response.extra_data.data)
279 free(response.extra_data.data);
280
281 if (WBC_ERROR_IS_OK(wbc_status)) {
282 *num_dcs = response.data.num_entries;
283 *dc_names = names;
284 names = NULL;
285 *dc_ips = ips;
286 ips = NULL;
287 }
288 wbcFreeMemory(names);
289 wbcFreeMemory(ips);
290 return wbc_status;
291}
292
293/* Resolve a NetbiosName via WINS */
294wbcErr wbcResolveWinsByName(const char *name, char **ip)
295{
296 struct winbindd_request request;
297 struct winbindd_response response;
298 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
299 char *ipaddr;
300
301 ZERO_STRUCT(request);
302 ZERO_STRUCT(response);
303
304 /* Send request */
305
306 strncpy(request.data.winsreq, name,
307 sizeof(request.data.winsreq)-1);
308
309 wbc_status = wbcRequestResponse(WINBINDD_WINS_BYNAME,
310 &request,
311 &response);
312 BAIL_ON_WBC_ERROR(wbc_status);
313
314 /* Display response */
315
316 ipaddr = wbcStrDup(response.data.winsresp);
317 BAIL_ON_PTR_ERROR(ipaddr, wbc_status);
318
319 *ip = ipaddr;
320 wbc_status = WBC_ERR_SUCCESS;
321
322 done:
323 return wbc_status;
324}
325
326/* Resolve an IP address via WINS into a NetbiosName */
327wbcErr wbcResolveWinsByIP(const char *ip, char **name)
328{
329 struct winbindd_request request;
330 struct winbindd_response response;
331 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
332 char *name_str;
333
334 ZERO_STRUCT(request);
335 ZERO_STRUCT(response);
336
337 /* Send request */
338
339 strncpy(request.data.winsreq, ip,
340 sizeof(request.data.winsreq)-1);
341
342 wbc_status = wbcRequestResponse(WINBINDD_WINS_BYIP,
343 &request,
344 &response);
345 BAIL_ON_WBC_ERROR(wbc_status);
346
347 /* Display response */
348
349 name_str = wbcStrDup(response.data.winsresp);
350 BAIL_ON_PTR_ERROR(name_str, wbc_status);
351
352 *name = name_str;
353 wbc_status = WBC_ERR_SUCCESS;
354
355 done:
356 return wbc_status;
357}
358
359/**
360 */
361
362static wbcErr process_domain_info_string(struct wbcDomainInfo *info,
363 char *info_string)
364{
365 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
366 char *r = NULL;
367 char *s = NULL;
368
369 r = info_string;
370
371 /* Short Name */
372 if ((s = strchr(r, '\\')) == NULL) {
373 wbc_status = WBC_ERR_INVALID_RESPONSE;
374 BAIL_ON_WBC_ERROR(wbc_status);
375 }
376 *s = '\0';
377 s++;
378
379 info->short_name = strdup(r);
380 BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
381
382
383 /* DNS Name */
384 r = s;
385 if ((s = strchr(r, '\\')) == NULL) {
386 wbc_status = WBC_ERR_INVALID_RESPONSE;
387 BAIL_ON_WBC_ERROR(wbc_status);
388 }
389 *s = '\0';
390 s++;
391
392 info->dns_name = strdup(r);
393 BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
394
395 /* SID */
396 r = s;
397 if ((s = strchr(r, '\\')) == NULL) {
398 wbc_status = WBC_ERR_INVALID_RESPONSE;
399 BAIL_ON_WBC_ERROR(wbc_status);
400 }
401 *s = '\0';
402 s++;
403
404 wbc_status = wbcStringToSid(r, &info->sid);
405 BAIL_ON_WBC_ERROR(wbc_status);
406
407 /* Trust type */
408 r = s;
409 if ((s = strchr(r, '\\')) == NULL) {
410 wbc_status = WBC_ERR_INVALID_RESPONSE;
411 BAIL_ON_WBC_ERROR(wbc_status);
412 }
413 *s = '\0';
414 s++;
415
416 if (strcmp(r, "None") == 0) {
417 info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
418 } else if (strcmp(r, "External") == 0) {
419 info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
420 } else if (strcmp(r, "Forest") == 0) {
421 info->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST;
422 } else if (strcmp(r, "In Forest") == 0) {
423 info->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST;
424 } else {
425 wbc_status = WBC_ERR_INVALID_RESPONSE;
426 BAIL_ON_WBC_ERROR(wbc_status);
427 }
428
429 /* Transitive */
430 r = s;
431 if ((s = strchr(r, '\\')) == NULL) {
432 wbc_status = WBC_ERR_INVALID_RESPONSE;
433 BAIL_ON_WBC_ERROR(wbc_status);
434 }
435 *s = '\0';
436 s++;
437
438 if (strcmp(r, "Yes") == 0) {
439 info->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE;
440 }
441
442 /* Incoming */
443 r = s;
444 if ((s = strchr(r, '\\')) == NULL) {
445 wbc_status = WBC_ERR_INVALID_RESPONSE;
446 BAIL_ON_WBC_ERROR(wbc_status);
447 }
448 *s = '\0';
449 s++;
450
451 if (strcmp(r, "Yes") == 0) {
452 info->trust_flags |= WBC_DOMINFO_TRUST_INCOMING;
453 }
454
455 /* Outgoing */
456 r = s;
457 if ((s = strchr(r, '\\')) == NULL) {
458 wbc_status = WBC_ERR_INVALID_RESPONSE;
459 BAIL_ON_WBC_ERROR(wbc_status);
460 }
461 *s = '\0';
462 s++;
463
464 if (strcmp(r, "Yes") == 0) {
465 info->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING;
466 }
467
468 /* Online/Offline status */
469
470 r = s;
471 if (r == NULL) {
472 wbc_status = WBC_ERR_INVALID_RESPONSE;
473 BAIL_ON_WBC_ERROR(wbc_status);
474 }
475 if ( strcmp(r, "Offline") == 0) {
476 info->domain_flags |= WBC_DOMINFO_DOMAIN_OFFLINE;
477 }
478
479 wbc_status = WBC_ERR_SUCCESS;
480
481 done:
482 return wbc_status;
483}
484
485static void wbcDomainInfoListDestructor(void *ptr)
486{
487 struct wbcDomainInfo *i = (struct wbcDomainInfo *)ptr;
488
489 while (i->short_name != NULL) {
490 free(i->short_name);
491 free(i->dns_name);
492 i += 1;
493 }
494}
495
496/* Enumerate the domain trusts known by Winbind */
497wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
498{
499 struct winbindd_response response;
500 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
501 char *p = NULL;
502 char *extra_data = NULL;
503 struct wbcDomainInfo *d_list = NULL;
504 int i = 0;
505
506 *domains = NULL;
507 *num_domains = 0;
508
509 ZERO_STRUCT(response);
510
511 /* Send request */
512
513 wbc_status = wbcRequestResponse(WINBINDD_LIST_TRUSTDOM,
514 NULL,
515 &response);
516 BAIL_ON_WBC_ERROR(wbc_status);
517
518 /* Decode the response */
519
520 p = (char *)response.extra_data.data;
521
522 if ((p == NULL) || (strlen(p) == 0)) {
523 /* We should always at least get back our
524 own SAM domain */
525
526 wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
527 BAIL_ON_WBC_ERROR(wbc_status);
528 }
529
530 d_list = (struct wbcDomainInfo *)wbcAllocateMemory(
531 response.data.num_entries + 1,sizeof(struct wbcDomainInfo),
532 wbcDomainInfoListDestructor);
533 BAIL_ON_PTR_ERROR(d_list, wbc_status);
534
535 extra_data = strdup((char*)response.extra_data.data);
536 BAIL_ON_PTR_ERROR(extra_data, wbc_status);
537
538 p = extra_data;
539
540 /* Outer loop processes the list of domain information */
541
542 for (i=0; i<response.data.num_entries && p; i++) {
543 char *next = strchr(p, '\n');
544
545 if (next) {
546 *next = '\0';
547 next++;
548 }
549
550 wbc_status = process_domain_info_string(&d_list[i], p);
551 BAIL_ON_WBC_ERROR(wbc_status);
552
553 p = next;
554 }
555
556 *domains = d_list;
557 d_list = NULL;
558 *num_domains = i;
559
560 done:
561 winbindd_free_response(&response);
562 wbcFreeMemory(d_list);
563 free(extra_data);
564 return wbc_status;
565}
566
567static void wbcDomainControllerInfoDestructor(void *ptr)
568{
569 struct wbcDomainControllerInfo *i =
570 (struct wbcDomainControllerInfo *)ptr;
571 free(i->dc_name);
572}
573
574/* Enumerate the domain trusts known by Winbind */
575wbcErr wbcLookupDomainController(const char *domain,
576 uint32_t flags,
577 struct wbcDomainControllerInfo **dc_info)
578{
579 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
580 struct winbindd_request request;
581 struct winbindd_response response;
582 struct wbcDomainControllerInfo *dc = NULL;
583
584 /* validate input params */
585
586 if (!domain || !dc_info) {
587 wbc_status = WBC_ERR_INVALID_PARAM;
588 BAIL_ON_WBC_ERROR(wbc_status);
589 }
590
591 ZERO_STRUCT(request);
592 ZERO_STRUCT(response);
593
594 strncpy(request.data.dsgetdcname.domain_name, domain,
595 sizeof(request.data.dsgetdcname.domain_name)-1);
596
597 request.flags = flags;
598
599 dc = (struct wbcDomainControllerInfo *)wbcAllocateMemory(
600 1, sizeof(struct wbcDomainControllerInfo),
601 wbcDomainControllerInfoDestructor);
602 BAIL_ON_PTR_ERROR(dc, wbc_status);
603
604 /* Send request */
605
606 wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME,
607 &request,
608 &response);
609 BAIL_ON_WBC_ERROR(wbc_status);
610
611 dc->dc_name = strdup(response.data.dsgetdcname.dc_unc);
612 BAIL_ON_PTR_ERROR(dc->dc_name, wbc_status);
613
614 *dc_info = dc;
615 dc = NULL;
616
617done:
618 wbcFreeMemory(dc);
619 return wbc_status;
620}
621
622static void wbcDomainControllerInfoExDestructor(void *ptr)
623{
624 struct wbcDomainControllerInfoEx *i =
625 (struct wbcDomainControllerInfoEx *)ptr;
626 free((char *)(i->dc_unc));
627 free((char *)(i->dc_address));
628 free((char *)(i->domain_guid));
629 free((char *)(i->domain_name));
630 free((char *)(i->forest_name));
631 free((char *)(i->dc_site_name));
632 free((char *)(i->client_site_name));
633}
634
635static wbcErr wbc_create_domain_controller_info_ex(const struct winbindd_response *resp,
636 struct wbcDomainControllerInfoEx **_i)
637{
638 wbcErr wbc_status = WBC_ERR_SUCCESS;
639 struct wbcDomainControllerInfoEx *i;
640 struct wbcGuid guid;
641
642 i = (struct wbcDomainControllerInfoEx *)wbcAllocateMemory(
643 1, sizeof(struct wbcDomainControllerInfoEx),
644 wbcDomainControllerInfoExDestructor);
645 BAIL_ON_PTR_ERROR(i, wbc_status);
646
647 i->dc_unc = strdup(resp->data.dsgetdcname.dc_unc);
648 BAIL_ON_PTR_ERROR(i->dc_unc, wbc_status);
649
650 i->dc_address = strdup(resp->data.dsgetdcname.dc_address);
651 BAIL_ON_PTR_ERROR(i->dc_address, wbc_status);
652
653 i->dc_address_type = resp->data.dsgetdcname.dc_address_type;
654
655 wbc_status = wbcStringToGuid(resp->data.dsgetdcname.domain_guid, &guid);
656 if (WBC_ERROR_IS_OK(wbc_status)) {
657 i->domain_guid = (struct wbcGuid *)malloc(
658 sizeof(struct wbcGuid));
659 BAIL_ON_PTR_ERROR(i->domain_guid, wbc_status);
660
661 *i->domain_guid = guid;
662 }
663
664 i->domain_name = strdup(resp->data.dsgetdcname.domain_name);
665 BAIL_ON_PTR_ERROR(i->domain_name, wbc_status);
666
667 if (resp->data.dsgetdcname.forest_name[0] != '\0') {
668 i->forest_name = strdup(resp->data.dsgetdcname.forest_name);
669 BAIL_ON_PTR_ERROR(i->forest_name, wbc_status);
670 }
671
672 i->dc_flags = resp->data.dsgetdcname.dc_flags;
673
674 if (resp->data.dsgetdcname.dc_site_name[0] != '\0') {
675 i->dc_site_name = strdup(resp->data.dsgetdcname.dc_site_name);
676 BAIL_ON_PTR_ERROR(i->dc_site_name, wbc_status);
677 }
678
679 if (resp->data.dsgetdcname.client_site_name[0] != '\0') {
680 i->client_site_name = strdup(
681 resp->data.dsgetdcname.client_site_name);
682 BAIL_ON_PTR_ERROR(i->client_site_name, wbc_status);
683 }
684
685 *_i = i;
686 i = NULL;
687
688done:
689 if (i != NULL) {
690 wbcFreeMemory(i);
691 }
692 return wbc_status;
693}
694
695/* Get extended domain controller information */
696wbcErr wbcLookupDomainControllerEx(const char *domain,
697 struct wbcGuid *guid,
698 const char *site,
699 uint32_t flags,
700 struct wbcDomainControllerInfoEx **dc_info)
701{
702 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
703 struct winbindd_request request;
704 struct winbindd_response response;
705
706 /* validate input params */
707
708 if (!domain || !dc_info) {
709 wbc_status = WBC_ERR_INVALID_PARAM;
710 BAIL_ON_WBC_ERROR(wbc_status);
711 }
712
713 ZERO_STRUCT(request);
714 ZERO_STRUCT(response);
715
716 request.data.dsgetdcname.flags = flags;
717
718 strncpy(request.data.dsgetdcname.domain_name, domain,
719 sizeof(request.data.dsgetdcname.domain_name)-1);
720
721 if (site) {
722 strncpy(request.data.dsgetdcname.site_name, site,
723 sizeof(request.data.dsgetdcname.site_name)-1);
724 }
725
726 if (guid) {
727 char *str = NULL;
728
729 wbc_status = wbcGuidToString(guid, &str);
730 BAIL_ON_WBC_ERROR(wbc_status);
731
732 strncpy(request.data.dsgetdcname.domain_guid, str,
733 sizeof(request.data.dsgetdcname.domain_guid)-1);
734
735 wbcFreeMemory(str);
736 }
737
738 /* Send request */
739
740 wbc_status = wbcRequestResponse(WINBINDD_DSGETDCNAME,
741 &request,
742 &response);
743 BAIL_ON_WBC_ERROR(wbc_status);
744
745 if (dc_info) {
746 wbc_status = wbc_create_domain_controller_info_ex(&response,
747 dc_info);
748 BAIL_ON_WBC_ERROR(wbc_status);
749 }
750
751 wbc_status = WBC_ERR_SUCCESS;
752done:
753 return wbc_status;
754}
755
756static void wbcNamedBlobDestructor(void *ptr)
757{
758 struct wbcNamedBlob *b = (struct wbcNamedBlob *)ptr;
759
760 while (b->name != NULL) {
761 free((char *)(b->name));
762 free(b->blob.data);
763 b += 1;
764 }
765}
766
767/* Initialize a named blob and add to list of blobs */
768wbcErr wbcAddNamedBlob(size_t *num_blobs,
769 struct wbcNamedBlob **pblobs,
770 const char *name,
771 uint32_t flags,
772 uint8_t *data,
773 size_t length)
774{
775 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
776 struct wbcNamedBlob *blobs, *blob;
777
778 if (name == NULL) {
779 return WBC_ERR_INVALID_PARAM;
780 }
781
782 /*
783 * Overallocate the b->name==NULL terminator for
784 * wbcNamedBlobDestructor
785 */
786 blobs = (struct wbcNamedBlob *)wbcAllocateMemory(
787 *num_blobs + 2, sizeof(struct wbcNamedBlob),
788 wbcNamedBlobDestructor);
789
790 if (blobs == NULL) {
791 return WBC_ERR_NO_MEMORY;
792 }
793
794 if (*pblobs != NULL) {
795 struct wbcNamedBlob *old = *pblobs;
796 memcpy(blobs, old, sizeof(struct wbcNamedBlob) * (*num_blobs));
797 if (*num_blobs != 0) {
798 /* end indicator for wbcNamedBlobDestructor */
799 old[0].name = NULL;
800 }
801 wbcFreeMemory(old);
802 }
803 *pblobs = blobs;
804
805 blob = &blobs[*num_blobs];
806
807 blob->name = strdup(name);
808 BAIL_ON_PTR_ERROR(blob->name, wbc_status);
809 blob->flags = flags;
810
811 blob->blob.length = length;
812 blob->blob.data = (uint8_t *)malloc(length);
813 BAIL_ON_PTR_ERROR(blob->blob.data, wbc_status);
814 memcpy(blob->blob.data, data, length);
815
816 *num_blobs += 1;
817 *pblobs = blobs;
818 blobs = NULL;
819
820 wbc_status = WBC_ERR_SUCCESS;
821done:
822 wbcFreeMemory(blobs);
823 return wbc_status;
824}
Note: See TracBrowser for help on using the repository browser.