source: branches/samba-3.2.x/source/nsswitch/libwbclient/wbc_util.c

Last change on this file was 133, checked in by Paul Smedley, 17 years ago

Update trunk to 3.2.0pre3

File size: 10.8 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Winbind client API
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 "libwbclient.h"
26
27
28
29/** @brief Ping winbindd to see if the daemon is running
30 *
31 * @return #wbcErr
32 **/
33
34wbcErr wbcPing(void)
35{
36 struct winbindd_request request;
37 struct winbindd_response response;
38
39 /* Initialize request */
40
41 ZERO_STRUCT(request);
42 ZERO_STRUCT(response);
43
44 return wbcRequestResponse(WINBINDD_PING, &request, &response);
45}
46
47wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details)
48{
49 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
50 struct wbcInterfaceDetails *info;
51 struct wbcDomainInfo *domain = NULL;
52 struct winbindd_request request;
53 struct winbindd_response response;
54
55 /* Initialize request */
56
57 ZERO_STRUCT(request);
58 ZERO_STRUCT(response);
59
60 info = talloc(NULL, struct wbcInterfaceDetails);
61 BAIL_ON_PTR_ERROR(info, wbc_status);
62
63 /* first the interface version */
64 wbc_status = wbcRequestResponse(WINBINDD_INTERFACE_VERSION, NULL, &response);
65 BAIL_ON_WBC_ERROR(wbc_status);
66 info->interface_version = response.data.interface_version;
67
68 /* then the samba version and the winbind separator */
69 wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response);
70 BAIL_ON_WBC_ERROR(wbc_status);
71
72 info->winbind_version = talloc_strdup(info,
73 response.data.info.samba_version);
74 BAIL_ON_PTR_ERROR(info->winbind_version, wbc_status);
75 info->winbind_separator = response.data.info.winbind_separator;
76
77 /* then the local netbios name */
78 wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response);
79 BAIL_ON_WBC_ERROR(wbc_status);
80
81 info->netbios_name = talloc_strdup(info,
82 response.data.netbios_name);
83 BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status);
84
85 /* then the local workgroup name */
86 wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response);
87 BAIL_ON_WBC_ERROR(wbc_status);
88
89 info->netbios_domain = talloc_strdup(info,
90 response.data.domain_name);
91 BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status);
92
93 wbc_status = wbcDomainInfo(info->netbios_domain, &domain);
94 if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) {
95 /* maybe it's a standalone server */
96 domain = NULL;
97 wbc_status = WBC_ERR_SUCCESS;
98 } else {
99 BAIL_ON_WBC_ERROR(wbc_status);
100 }
101
102 if (domain) {
103 info->dns_domain = talloc_strdup(info,
104 domain->dns_name);
105 wbcFreeMemory(domain);
106 BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status);
107 } else {
108 info->dns_domain = NULL;
109 }
110
111 *_details = info;
112 info = NULL;
113
114 wbc_status = WBC_ERR_SUCCESS;
115
116done:
117 talloc_free(info);
118 return wbc_status;
119}
120
121
122/** @brief Lookup the current status of a trusted domain
123 *
124 * @param domain Domain to query
125 * @param *dinfo Pointer to returned domain_info struct
126 *
127 * @return #wbcErr
128 *
129 **/
130
131
132wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
133{
134 struct winbindd_request request;
135 struct winbindd_response response;
136 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
137 struct wbcDomainInfo *info = NULL;
138
139 if (!domain || !dinfo) {
140 wbc_status = WBC_ERR_INVALID_PARAM;
141 BAIL_ON_WBC_ERROR(wbc_status);
142 }
143
144 /* Initialize request */
145
146 ZERO_STRUCT(request);
147 ZERO_STRUCT(response);
148
149 strncpy(request.domain_name, domain,
150 sizeof(request.domain_name)-1);
151
152 wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO,
153 &request,
154 &response);
155 BAIL_ON_WBC_ERROR(wbc_status);
156
157 info = talloc(NULL, struct wbcDomainInfo);
158 BAIL_ON_PTR_ERROR(info, wbc_status);
159
160 info->short_name = talloc_strdup(info,
161 response.data.domain_info.name);
162 BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
163
164 info->dns_name = talloc_strdup(info,
165 response.data.domain_info.alt_name);
166 BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
167
168 wbc_status = wbcStringToSid(response.data.domain_info.sid,
169 &info->sid);
170 BAIL_ON_WBC_ERROR(wbc_status);
171
172 if (response.data.domain_info.native_mode)
173 info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
174 if (response.data.domain_info.active_directory)
175 info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
176 if (response.data.domain_info.primary)
177 info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
178
179 *dinfo = info;
180
181 wbc_status = WBC_ERR_SUCCESS;
182
183 done:
184 if (!WBC_ERROR_IS_OK(wbc_status)) {
185 talloc_free(info);
186 }
187
188 return wbc_status;
189}
190
191
192/** @brief Resolve a NetbiosName via WINS
193 *
194 * @param name Name to resolve
195 * @param *ip Pointer to the ip address string
196 *
197 * @return #wbcErr
198 *
199 **/
200wbcErr wbcResolveWinsByName(const char *name, char **ip)
201{
202 struct winbindd_request request;
203 struct winbindd_response response;
204 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
205 char *ipaddr;
206
207 ZERO_STRUCT(request);
208 ZERO_STRUCT(response);
209
210 /* Send request */
211
212 strncpy(request.data.winsreq, name,
213 sizeof(request.data.winsreq)-1);
214
215 wbc_status = wbcRequestResponse(WINBINDD_WINS_BYNAME,
216 &request,
217 &response);
218 BAIL_ON_WBC_ERROR(wbc_status);
219
220 /* Display response */
221
222 ipaddr = talloc_strdup(NULL, response.data.winsresp);
223 BAIL_ON_PTR_ERROR(ipaddr, wbc_status);
224
225 *ip = ipaddr;
226 wbc_status = WBC_ERR_SUCCESS;
227
228 done:
229 return wbc_status;
230}
231
232/** @brief Resolve an IP address via WINS into a NetbiosName
233 *
234 * @param ip The ip address string
235 * @param *name Pointer to the name
236 *
237 * @return #wbcErr
238 *
239 **/
240wbcErr wbcResolveWinsByIP(const char *ip, char **name)
241{
242 struct winbindd_request request;
243 struct winbindd_response response;
244 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
245 char *name_str;
246
247 ZERO_STRUCT(request);
248 ZERO_STRUCT(response);
249
250 /* Send request */
251
252 strncpy(request.data.winsreq, ip,
253 sizeof(request.data.winsreq)-1);
254
255 wbc_status = wbcRequestResponse(WINBINDD_WINS_BYIP,
256 &request,
257 &response);
258 BAIL_ON_WBC_ERROR(wbc_status);
259
260 /* Display response */
261
262 name_str = talloc_strdup(NULL, response.data.winsresp);
263 BAIL_ON_PTR_ERROR(name_str, wbc_status);
264
265 *name = name_str;
266 wbc_status = WBC_ERR_SUCCESS;
267
268 done:
269 return wbc_status;
270}
271
272/**
273 */
274
275static wbcErr process_domain_info_string(TALLOC_CTX *ctx,
276 struct wbcDomainInfo *info,
277 char *info_string)
278{
279 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
280 char *r = NULL;
281 char *s = NULL;
282
283 if (!info || !info_string) {
284 wbc_status = WBC_ERR_INVALID_PARAM;
285 BAIL_ON_WBC_ERROR(wbc_status);
286 }
287
288 r = info_string;
289
290 /* Short Name */
291 if ((s = strchr(r, '\\')) == NULL) {
292 wbc_status = WBC_ERR_INVALID_RESPONSE;
293 BAIL_ON_WBC_ERROR(wbc_status);
294 }
295 *s = '\0';
296 s++;
297
298 info->short_name = talloc_strdup(ctx, r);
299 BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
300
301
302 /* DNS Name */
303 r = s;
304 if ((s = strchr(r, '\\')) == NULL) {
305 wbc_status = WBC_ERR_INVALID_RESPONSE;
306 BAIL_ON_WBC_ERROR(wbc_status);
307 }
308 *s = '\0';
309 s++;
310
311 info->dns_name = talloc_strdup(ctx, r);
312 BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
313
314 /* SID */
315 r = s;
316 if ((s = strchr(r, '\\')) == NULL) {
317 wbc_status = WBC_ERR_INVALID_RESPONSE;
318 BAIL_ON_WBC_ERROR(wbc_status);
319 }
320 *s = '\0';
321 s++;
322
323 wbc_status = wbcStringToSid(r, &info->sid);
324 BAIL_ON_WBC_ERROR(wbc_status);
325
326 /* Trust type */
327 r = s;
328 if ((s = strchr(r, '\\')) == NULL) {
329 wbc_status = WBC_ERR_INVALID_RESPONSE;
330 BAIL_ON_WBC_ERROR(wbc_status);
331 }
332 *s = '\0';
333 s++;
334
335 if (strcmp(r, "None") == 0) {
336 info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
337 } else if (strcmp(r, "External") == 0) {
338 info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
339 } else if (strcmp(r, "Forest") == 0) {
340 info->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST;
341 } else if (strcmp(r, "In Forest") == 0) {
342 info->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST;
343 } else {
344 wbc_status = WBC_ERR_INVALID_RESPONSE;
345 BAIL_ON_WBC_ERROR(wbc_status);
346 }
347
348 /* Transitive */
349 r = s;
350 if ((s = strchr(r, '\\')) == NULL) {
351 wbc_status = WBC_ERR_INVALID_RESPONSE;
352 BAIL_ON_WBC_ERROR(wbc_status);
353 }
354 *s = '\0';
355 s++;
356
357 if (strcmp(r, "Yes") == 0) {
358 info->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE;
359 }
360
361 /* Incoming */
362 r = s;
363 if ((s = strchr(r, '\\')) == NULL) {
364 wbc_status = WBC_ERR_INVALID_RESPONSE;
365 BAIL_ON_WBC_ERROR(wbc_status);
366 }
367 *s = '\0';
368 s++;
369
370 if (strcmp(r, "Yes") == 0) {
371 info->trust_flags |= WBC_DOMINFO_TRUST_INCOMING;
372 }
373
374 /* Outgoing */
375 r = s;
376 if ((s = strchr(r, '\\')) == NULL) {
377 wbc_status = WBC_ERR_INVALID_RESPONSE;
378 BAIL_ON_WBC_ERROR(wbc_status);
379 }
380 *s = '\0';
381 s++;
382
383 if (strcmp(r, "Yes") == 0) {
384 info->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING;
385 }
386
387 /* Online/Offline status */
388
389 r = s;
390 if (r == NULL) {
391 wbc_status = WBC_ERR_INVALID_RESPONSE;
392 BAIL_ON_WBC_ERROR(wbc_status);
393 }
394 if ( strcmp(r, "Offline") == 0) {
395 info->domain_flags |= WBC_DOMINFO_DOMAIN_OFFLINE;
396 }
397
398 wbc_status = WBC_ERR_SUCCESS;
399
400 done:
401 return wbc_status;
402}
403
404/** @brief Enumerate the domain trusts known by Winbind
405 *
406 * @param **domains Pointer to the allocated domain list array
407 * @param *num_domains Pointer to number of domains returned
408 *
409 * @return #wbcErr
410 *
411 **/
412wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
413{
414 struct winbindd_response response;
415 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
416 char *p = NULL;
417 char *q = NULL;
418 char *extra_data = NULL;
419 int count = 0;
420 struct wbcDomainInfo *d_list = NULL;
421 int i = 0;
422
423 *domains = NULL;
424 *num_domains = 0;
425
426 ZERO_STRUCT(response);
427
428 /* Send request */
429
430 wbc_status = wbcRequestResponse(WINBINDD_LIST_TRUSTDOM,
431 NULL,
432 &response);
433 BAIL_ON_WBC_ERROR(wbc_status);
434
435 /* Decode the response */
436
437 p = (char *)response.extra_data.data;
438
439 if (strlen(p) == 0) {
440 /* We should always at least get back our
441 own SAM domain */
442
443 wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
444 BAIL_ON_WBC_ERROR(wbc_status);
445 }
446
447 /* Count number of domains */
448
449 count = 0;
450 while (p) {
451 count++;
452
453 if ((q = strchr(p, '\n')) != NULL)
454 q++;
455 p = q;
456 }
457
458 d_list = talloc_array(NULL, struct wbcDomainInfo, count);
459 BAIL_ON_PTR_ERROR(d_list, wbc_status);
460
461 extra_data = strdup((char*)response.extra_data.data);
462 BAIL_ON_PTR_ERROR(extra_data, wbc_status);
463
464 p = extra_data;
465
466 /* Outer loop processes the list of domain information */
467
468 for (i=0; i<count && p; i++) {
469 char *next = strchr(p, '\n');
470
471 if (next) {
472 *next = '\0';
473 next++;
474 }
475
476 wbc_status = process_domain_info_string(d_list, &d_list[i], p);
477 BAIL_ON_WBC_ERROR(wbc_status);
478
479 p = next;
480 }
481
482 *domains = d_list;
483 *num_domains = i;
484
485 done:
486 if (!WBC_ERROR_IS_OK(wbc_status)) {
487 if (d_list)
488 talloc_free(d_list);
489 if (extra_data)
490 free(extra_data);
491 }
492
493 return wbc_status;
494}
Note: See TracBrowser for help on using the repository browser.