source: trunk-3.0/source/nsswitch/wb_client.c@ 101

Last change on this file since 101 was 39, checked in by Paul Smedley, 18 years ago

Upgrade source to 3.0.25a

File size: 13.2 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 winbind client code
5
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 2000
8
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 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 Library General Public
20 License along with this library; if not, write to the
21 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA.
23*/
24
25#include "includes.h"
26#include "nsswitch/winbind_nss.h"
27
28#undef DBGC_CLASS
29#define DBGC_CLASS DBGC_WINBIND
30
31NSS_STATUS winbindd_request_response(int req_type,
32 struct winbindd_request *request,
33 struct winbindd_response *response);
34
35/* Call winbindd to convert a name to a sid */
36
37BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
38 enum lsa_SidType *name_type)
39{
40 struct winbindd_request request;
41 struct winbindd_response response;
42 NSS_STATUS result;
43
44 if (!sid || !name_type)
45 return False;
46
47 /* Send off request */
48
49 ZERO_STRUCT(request);
50 ZERO_STRUCT(response);
51
52 fstrcpy(request.data.name.dom_name, dom_name);
53 fstrcpy(request.data.name.name, name);
54
55 if ((result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request,
56 &response)) == NSS_STATUS_SUCCESS) {
57 if (!string_to_sid(sid, response.data.sid.sid))
58 return False;
59 *name_type = (enum lsa_SidType)response.data.sid.type;
60 }
61
62 return result == NSS_STATUS_SUCCESS;
63}
64
65/* Call winbindd to convert sid to name */
66
67BOOL winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
68 const char **domain, const char **name,
69 enum lsa_SidType *name_type)
70{
71 struct winbindd_request request;
72 struct winbindd_response response;
73 NSS_STATUS result;
74
75 /* Initialise request */
76
77 ZERO_STRUCT(request);
78 ZERO_STRUCT(response);
79
80 fstrcpy(request.data.sid, sid_string_static(sid));
81
82 /* Make request */
83
84 result = winbindd_request_response(WINBINDD_LOOKUPSID, &request,
85 &response);
86
87 if (result != NSS_STATUS_SUCCESS) {
88 return False;
89 }
90
91 /* Copy out result */
92
93 if (domain != NULL) {
94 *domain = talloc_strdup(mem_ctx, response.data.name.dom_name);
95 if (*domain == NULL) {
96 DEBUG(0, ("talloc failed\n"));
97 return False;
98 }
99 }
100 if (name != NULL) {
101 *name = talloc_strdup(mem_ctx, response.data.name.name);
102 if (*name == NULL) {
103 DEBUG(0, ("talloc failed\n"));
104 return False;
105 }
106 }
107
108 *name_type = (enum lsa_SidType)response.data.name.type;
109
110 DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
111 sid_string_static(sid), response.data.name.dom_name,
112 response.data.name.name));
113 return True;
114}
115
116BOOL winbind_lookup_rids(TALLOC_CTX *mem_ctx,
117 const DOM_SID *domain_sid,
118 int num_rids, uint32 *rids,
119 const char **domain_name,
120 const char ***names, enum lsa_SidType **types)
121{
122 size_t i, buflen;
123 ssize_t len;
124 char *ridlist;
125 char *p;
126 struct winbindd_request request;
127 struct winbindd_response response;
128 NSS_STATUS result;
129
130 if (num_rids == 0) {
131 return False;
132 }
133
134 /* Initialise request */
135
136 ZERO_STRUCT(request);
137 ZERO_STRUCT(response);
138
139 fstrcpy(request.data.sid, sid_string_static(domain_sid));
140
141 len = 0;
142 buflen = 0;
143 ridlist = NULL;
144
145 for (i=0; i<num_rids; i++) {
146 sprintf_append(mem_ctx, &ridlist, &len, &buflen,
147 "%ld\n", rids[i]);
148 }
149
150 if ((num_rids != 0) && (ridlist == NULL)) {
151 return False;
152 }
153
154 request.extra_data.data = ridlist;
155 request.extra_len = strlen(ridlist)+1;
156
157 result = winbindd_request_response(WINBINDD_LOOKUPRIDS,
158 &request, &response);
159
160 TALLOC_FREE(ridlist);
161
162 if (result != NSS_STATUS_SUCCESS) {
163 return False;
164 }
165
166 *domain_name = talloc_strdup(mem_ctx, response.data.domain_name);
167
168 if (num_rids) {
169 *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
170 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
171
172 if ((*names == NULL) || (*types == NULL)) {
173 goto fail;
174 }
175 } else {
176 *names = NULL;
177 *types = NULL;
178 }
179
180 p = (char *)response.extra_data.data;
181
182 for (i=0; i<num_rids; i++) {
183 char *q;
184
185 if (*p == '\0') {
186 DEBUG(10, ("Got invalid reply: %s\n",
187 (char *)response.extra_data.data));
188 goto fail;
189 }
190
191 (*types)[i] = (enum lsa_SidType)strtoul(p, &q, 10);
192
193 if (*q != ' ') {
194 DEBUG(10, ("Got invalid reply: %s\n",
195 (char *)response.extra_data.data));
196 goto fail;
197 }
198
199 p = q+1;
200
201 q = strchr(p, '\n');
202 if (q == NULL) {
203 DEBUG(10, ("Got invalid reply: %s\n",
204 (char *)response.extra_data.data));
205 goto fail;
206 }
207
208 *q = '\0';
209
210 (*names)[i] = talloc_strdup(*names, p);
211
212 p = q+1;
213 }
214
215 if (*p != '\0') {
216 DEBUG(10, ("Got invalid reply: %s\n",
217 (char *)response.extra_data.data));
218 goto fail;
219 }
220
221 SAFE_FREE(response.extra_data.data);
222
223 return True;
224
225 fail:
226 TALLOC_FREE(*names);
227 TALLOC_FREE(*types);
228 return False;
229}
230
231/* Call winbindd to convert SID to uid */
232
233BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
234{
235 struct winbindd_request request;
236 struct winbindd_response response;
237 int result;
238 fstring sid_str;
239
240 if (!puid)
241 return False;
242
243 /* Initialise request */
244
245 ZERO_STRUCT(request);
246 ZERO_STRUCT(response);
247
248 sid_to_string(sid_str, sid);
249 fstrcpy(request.data.sid, sid_str);
250
251 /* Make request */
252
253 result = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response);
254
255 /* Copy out result */
256
257 if (result == NSS_STATUS_SUCCESS) {
258 *puid = response.data.uid;
259 }
260
261 return (result == NSS_STATUS_SUCCESS);
262}
263
264/* Call winbindd to convert uid to sid */
265
266BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
267{
268 struct winbindd_request request;
269 struct winbindd_response response;
270 int result;
271
272 if (!sid)
273 return False;
274
275 /* Initialise request */
276
277 ZERO_STRUCT(request);
278 ZERO_STRUCT(response);
279
280 request.data.uid = uid;
281
282 /* Make request */
283
284 result = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response);
285
286 /* Copy out result */
287
288 if (result == NSS_STATUS_SUCCESS) {
289 if (!string_to_sid(sid, response.data.sid.sid))
290 return False;
291 } else {
292 sid_copy(sid, &global_sid_NULL);
293 }
294
295 return (result == NSS_STATUS_SUCCESS);
296}
297
298/* Call winbindd to convert SID to gid */
299
300BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
301{
302 struct winbindd_request request;
303 struct winbindd_response response;
304 int result;
305 fstring sid_str;
306
307 if (!pgid)
308 return False;
309
310 /* Initialise request */
311
312 ZERO_STRUCT(request);
313 ZERO_STRUCT(response);
314
315 sid_to_string(sid_str, sid);
316 fstrcpy(request.data.sid, sid_str);
317
318 /* Make request */
319
320 result = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response);
321
322 /* Copy out result */
323
324 if (result == NSS_STATUS_SUCCESS) {
325 *pgid = response.data.gid;
326 }
327
328 return (result == NSS_STATUS_SUCCESS);
329}
330
331/* Call winbindd to convert gid to sid */
332
333BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
334{
335 struct winbindd_request request;
336 struct winbindd_response response;
337 int result;
338
339 if (!sid)
340 return False;
341
342 /* Initialise request */
343
344 ZERO_STRUCT(request);
345 ZERO_STRUCT(response);
346
347 request.data.gid = gid;
348
349 /* Make request */
350
351 result = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response);
352
353 /* Copy out result */
354
355 if (result == NSS_STATUS_SUCCESS) {
356 if (!string_to_sid(sid, response.data.sid.sid))
357 return False;
358 } else {
359 sid_copy(sid, &global_sid_NULL);
360 }
361
362 return (result == NSS_STATUS_SUCCESS);
363}
364
365/* Call winbindd to convert SID to uid */
366
367BOOL winbind_sids_to_unixids(struct id_map *ids, int num_ids)
368{
369 struct winbindd_request request;
370 struct winbindd_response response;
371 int result;
372 DOM_SID *sids;
373 int i;
374
375 /* Initialise request */
376
377 ZERO_STRUCT(request);
378 ZERO_STRUCT(response);
379
380 request.extra_len = num_ids * sizeof(DOM_SID);
381
382 sids = (DOM_SID *)SMB_MALLOC(request.extra_len);
383 for (i = 0; i < num_ids; i++) {
384 sid_copy(&sids[i], ids[i].sid);
385 }
386
387 request.extra_data.data = (char *)sids;
388
389 /* Make request */
390
391 result = winbindd_request_response(WINBINDD_SIDS_TO_XIDS, &request, &response);
392
393 /* Copy out result */
394
395 if (result == NSS_STATUS_SUCCESS) {
396 struct unixid *wid = (struct unixid *)response.extra_data.data;
397
398 for (i = 0; i < num_ids; i++) {
399 if (wid[i].type == -1) {
400 ids[i].status = ID_UNMAPPED;
401 } else {
402 ids[i].status = ID_MAPPED;
403 ids[i].xid.type = wid[i].type;
404 ids[i].xid.id = wid[i].id;
405 }
406 }
407 }
408
409 SAFE_FREE(request.extra_data.data);
410 SAFE_FREE(response.extra_data.data);
411
412 return (result == NSS_STATUS_SUCCESS);
413}
414
415BOOL winbind_idmap_dump_maps(TALLOC_CTX *memctx, const char *file)
416{
417 struct winbindd_request request;
418 struct winbindd_response response;
419 int result;
420
421 ZERO_STRUCT(request);
422 ZERO_STRUCT(response);
423
424 request.extra_data.data = SMB_STRDUP(file);
425 request.extra_len = strlen(request.extra_data.data) + 1;
426
427 result = winbindd_request_response(WINBINDD_DUMP_MAPS, &request, &response);
428
429 SAFE_FREE(request.extra_data.data);
430 return (result == NSS_STATUS_SUCCESS);
431}
432
433BOOL winbind_allocate_uid(uid_t *uid)
434{
435 struct winbindd_request request;
436 struct winbindd_response response;
437 int result;
438
439 /* Initialise request */
440
441 ZERO_STRUCT(request);
442 ZERO_STRUCT(response);
443
444 /* Make request */
445
446 result = winbindd_request_response(WINBINDD_ALLOCATE_UID,
447 &request, &response);
448
449 if (result != NSS_STATUS_SUCCESS)
450 return False;
451
452 /* Copy out result */
453 *uid = response.data.uid;
454
455 return True;
456}
457
458BOOL winbind_allocate_gid(gid_t *gid)
459{
460 struct winbindd_request request;
461 struct winbindd_response response;
462 int result;
463
464 /* Initialise request */
465
466 ZERO_STRUCT(request);
467 ZERO_STRUCT(response);
468
469 /* Make request */
470
471 result = winbindd_request_response(WINBINDD_ALLOCATE_GID,
472 &request, &response);
473
474 if (result != NSS_STATUS_SUCCESS)
475 return False;
476
477 /* Copy out result */
478 *gid = response.data.gid;
479
480 return True;
481}
482
483BOOL winbind_set_mapping(const struct id_map *map)
484{
485 struct winbindd_request request;
486 struct winbindd_response response;
487 int result;
488
489 /* Initialise request */
490
491 ZERO_STRUCT(request);
492 ZERO_STRUCT(response);
493
494 /* Make request */
495
496 request.data.dual_idmapset.id = map->xid.id;
497 request.data.dual_idmapset.type = map->xid.type;
498 sid_to_string(request.data.dual_idmapset.sid, map->sid);
499
500 result = winbindd_request_response(WINBINDD_SET_MAPPING, &request, &response);
501
502 return (result == NSS_STATUS_SUCCESS);
503}
504
505BOOL winbind_set_uid_hwm(unsigned long id)
506{
507 struct winbindd_request request;
508 struct winbindd_response response;
509 int result;
510
511 /* Initialise request */
512
513 ZERO_STRUCT(request);
514 ZERO_STRUCT(response);
515
516 /* Make request */
517
518 request.data.dual_idmapset.id = id;
519 request.data.dual_idmapset.type = ID_TYPE_UID;
520
521 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
522
523 return (result == NSS_STATUS_SUCCESS);
524}
525
526BOOL winbind_set_gid_hwm(unsigned long id)
527{
528 struct winbindd_request request;
529 struct winbindd_response response;
530 int result;
531
532 /* Initialise request */
533
534 ZERO_STRUCT(request);
535 ZERO_STRUCT(response);
536
537 /* Make request */
538
539 request.data.dual_idmapset.id = id;
540 request.data.dual_idmapset.type = ID_TYPE_GID;
541
542 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
543
544 return (result == NSS_STATUS_SUCCESS);
545}
546
547/**********************************************************************
548 simple wrapper function to see if winbindd is alive
549**********************************************************************/
550
551BOOL winbind_ping( void )
552{
553 NSS_STATUS result;
554
555 result = winbindd_request_response(WINBINDD_PING, NULL, NULL);
556
557 return result == NSS_STATUS_SUCCESS;
558}
559
560/**********************************************************************
561 Is a domain trusted?
562
563 result == NSS_STATUS_UNAVAIL: winbind not around
564 result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
565
566 Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off and
567 when winbind return WINBINDD_ERROR. So the semantics of this routine depends
568 on winbind_on. Grepping for winbind_off I just found 3 places where winbind
569 is turned off, and this does not conflict (as far as I have seen) with the
570 callers of is_trusted_domains.
571
572 I *hate* global variables....
573
574 Volker
575
576**********************************************************************/
577
578NSS_STATUS wb_is_trusted_domain(const char *domain)
579{
580 struct winbindd_request request;
581 struct winbindd_response response;
582
583 /* Call winbindd */
584
585 ZERO_STRUCT(request);
586 ZERO_STRUCT(response);
587
588 fstrcpy(request.domain_name, domain);
589
590 return winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response);
591}
Note: See TracBrowser for help on using the repository browser.