~zulcss/ubuntu/lucid/likewise-open/likewise-open-sru

« back to all changes in this revision

Viewing changes to samba/source/nsswitch/libwbclient/wbc_util.c

  • Committer: Bazaar Package Importer
  • Author(s): Rick Clark
  • Date: 2008-08-27 08:56:20 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080827085620-5q0f58b9qtog9myq
Tags: 4.1.0.2956-0ubuntu1
* missing-likewise-logo.diff: removed
* fixed copyright notice
* updated Standards-Version to 3.8.0
* removed path from command in prerm
* removed stop in S runlevel

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 
4
4
   Winbind client API
5
5
 
6
 
   Copyright (C) Gerald (Jerry) Carter 2007
 
6
   Copyright (C) Gerald (Jerry) Carter 2007-2008
7
7
 
8
8
 
9
9
   This library is free software; you can redistribute it and/or
44
44
        return wbcRequestResponse(WINBINDD_PING, &request, &response);
45
45
}
46
46
 
 
47
wbcErr 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
 
 
116
done:
 
117
        talloc_free(info);
 
118
        return wbc_status;
 
119
}
 
120
 
 
121
 
47
122
/** @brief Lookup the current status of a trusted domain
48
123
 *
49
124
 * @param domain      Domain to query
95
170
        BAIL_ON_WBC_ERROR(wbc_status);
96
171
 
97
172
        if (response.data.domain_info.native_mode)
98
 
                info->flags |= WBC_DOMINFO_NATIVE;
 
173
                info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE;
99
174
        if (response.data.domain_info.active_directory)
100
 
                info->flags |= WBC_DOMINFO_AD;
 
175
                info->domain_flags |= WBC_DOMINFO_DOMAIN_AD;
101
176
        if (response.data.domain_info.primary)
102
 
                info->flags |= WBC_DOMINFO_PRIMARY;
 
177
                info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY;
103
178
 
104
179
        *dinfo = info;
105
180
 
112
187
 
113
188
        return wbc_status;
114
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
 **/
 
200
wbcErr 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
 **/
 
240
wbcErr 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
 
 
275
static 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
 **/
 
412
wbcErr 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
}