VERSION: Raise version number up to 3.0.36.
[Samba.git] / source / nsswitch / wb_client.c
blob25fbefc45e1742cca66a2516a7ce3f7893b6abc1
1 /*
2 Unix SMB/CIFS implementation.
4 winbind client code
6 Copyright (C) Tim Potter 2000
7 Copyright (C) Andrew Tridgell 2000
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.
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 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.
25 #include "includes.h"
26 #include "nsswitch/winbind_nss.h"
28 #undef DBGC_CLASS
29 #define DBGC_CLASS DBGC_WINBIND
31 NSS_STATUS winbindd_request_response(int req_type,
32 struct winbindd_request *request,
33 struct winbindd_response *response);
35 /* Call winbindd to convert a name to a sid */
37 BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
38 enum lsa_SidType *name_type)
40 struct winbindd_request request;
41 struct winbindd_response response;
42 NSS_STATUS result;
44 if (!sid || !name_type)
45 return False;
47 /* Send off request */
49 ZERO_STRUCT(request);
50 ZERO_STRUCT(response);
52 fstrcpy(request.data.name.dom_name, dom_name);
53 fstrcpy(request.data.name.name, name);
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;
62 return result == NSS_STATUS_SUCCESS;
65 /* Call winbindd to convert sid to name */
67 BOOL winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
68 const char **domain, const char **name,
69 enum lsa_SidType *name_type)
71 struct winbindd_request request;
72 struct winbindd_response response;
73 NSS_STATUS result;
75 /* Initialise request */
77 ZERO_STRUCT(request);
78 ZERO_STRUCT(response);
80 fstrcpy(request.data.sid, sid_string_static(sid));
82 /* Make request */
84 result = winbindd_request_response(WINBINDD_LOOKUPSID, &request,
85 &response);
87 if (result != NSS_STATUS_SUCCESS) {
88 return False;
91 /* Copy out result */
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;
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;
108 *name_type = (enum lsa_SidType)response.data.name.type;
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;
116 BOOL 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)
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;
130 if (num_rids == 0) {
131 return False;
134 /* Initialise request */
136 ZERO_STRUCT(request);
137 ZERO_STRUCT(response);
139 fstrcpy(request.data.sid, sid_string_static(domain_sid));
141 len = 0;
142 buflen = 0;
143 ridlist = NULL;
145 for (i=0; i<num_rids; i++) {
146 sprintf_append(mem_ctx, &ridlist, &len, &buflen,
147 "%ld\n", rids[i]);
150 if ((num_rids != 0) && (ridlist == NULL)) {
151 return False;
154 request.extra_data.data = ridlist;
155 request.extra_len = strlen(ridlist)+1;
157 result = winbindd_request_response(WINBINDD_LOOKUPRIDS,
158 &request, &response);
160 TALLOC_FREE(ridlist);
162 if (result != NSS_STATUS_SUCCESS) {
163 return False;
166 *domain_name = talloc_strdup(mem_ctx, response.data.domain_name);
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);
172 if ((*names == NULL) || (*types == NULL)) {
173 goto fail;
175 } else {
176 *names = NULL;
177 *types = NULL;
180 p = (char *)response.extra_data.data;
182 for (i=0; i<num_rids; i++) {
183 char *q;
185 if (*p == '\0') {
186 DEBUG(10, ("Got invalid reply: %s\n",
187 (char *)response.extra_data.data));
188 goto fail;
191 (*types)[i] = (enum lsa_SidType)strtoul(p, &q, 10);
193 if (*q != ' ') {
194 DEBUG(10, ("Got invalid reply: %s\n",
195 (char *)response.extra_data.data));
196 goto fail;
199 p = q+1;
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;
208 *q = '\0';
210 (*names)[i] = talloc_strdup(*names, p);
212 p = q+1;
215 if (*p != '\0') {
216 DEBUG(10, ("Got invalid reply: %s\n",
217 (char *)response.extra_data.data));
218 goto fail;
221 SAFE_FREE(response.extra_data.data);
223 return True;
225 fail:
226 TALLOC_FREE(*names);
227 TALLOC_FREE(*types);
228 return False;
231 /* Call winbindd to convert SID to uid */
233 BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
235 struct winbindd_request request;
236 struct winbindd_response response;
237 int result;
238 fstring sid_str;
240 if (!puid)
241 return False;
243 /* Initialise request */
245 ZERO_STRUCT(request);
246 ZERO_STRUCT(response);
248 sid_to_string(sid_str, sid);
249 fstrcpy(request.data.sid, sid_str);
251 /* Make request */
253 result = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response);
255 /* Copy out result */
257 if (result == NSS_STATUS_SUCCESS) {
258 *puid = response.data.uid;
261 return (result == NSS_STATUS_SUCCESS);
264 /* Call winbindd to convert uid to sid */
266 BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
268 struct winbindd_request request;
269 struct winbindd_response response;
270 int result;
272 if (!sid)
273 return False;
275 /* Initialise request */
277 ZERO_STRUCT(request);
278 ZERO_STRUCT(response);
280 request.data.uid = uid;
282 /* Make request */
284 result = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response);
286 /* Copy out result */
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);
295 return (result == NSS_STATUS_SUCCESS);
298 /* Call winbindd to convert SID to gid */
300 BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
302 struct winbindd_request request;
303 struct winbindd_response response;
304 int result;
305 fstring sid_str;
307 if (!pgid)
308 return False;
310 /* Initialise request */
312 ZERO_STRUCT(request);
313 ZERO_STRUCT(response);
315 sid_to_string(sid_str, sid);
316 fstrcpy(request.data.sid, sid_str);
318 /* Make request */
320 result = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response);
322 /* Copy out result */
324 if (result == NSS_STATUS_SUCCESS) {
325 *pgid = response.data.gid;
328 return (result == NSS_STATUS_SUCCESS);
331 /* Call winbindd to convert gid to sid */
333 BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
335 struct winbindd_request request;
336 struct winbindd_response response;
337 int result;
339 if (!sid)
340 return False;
342 /* Initialise request */
344 ZERO_STRUCT(request);
345 ZERO_STRUCT(response);
347 request.data.gid = gid;
349 /* Make request */
351 result = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response);
353 /* Copy out result */
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);
362 return (result == NSS_STATUS_SUCCESS);
365 /* Call winbindd to convert SID to uid */
367 BOOL winbind_sids_to_unixids(struct id_map *ids, int num_ids)
369 struct winbindd_request request;
370 struct winbindd_response response;
371 int result;
372 DOM_SID *sids;
373 int i;
375 /* Initialise request */
377 ZERO_STRUCT(request);
378 ZERO_STRUCT(response);
380 request.extra_len = num_ids * sizeof(DOM_SID);
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);
387 request.extra_data.data = (char *)sids;
389 /* Make request */
391 result = winbindd_request_response(WINBINDD_SIDS_TO_XIDS, &request, &response);
393 /* Copy out result */
395 if (result == NSS_STATUS_SUCCESS) {
396 struct unixid *wid = (struct unixid *)response.extra_data.data;
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;
409 SAFE_FREE(request.extra_data.data);
410 SAFE_FREE(response.extra_data.data);
412 return (result == NSS_STATUS_SUCCESS);
415 BOOL winbind_idmap_dump_maps(TALLOC_CTX *memctx, const char *file)
417 struct winbindd_request request;
418 struct winbindd_response response;
419 int result;
421 ZERO_STRUCT(request);
422 ZERO_STRUCT(response);
424 request.extra_data.data = SMB_STRDUP(file);
425 request.extra_len = strlen(request.extra_data.data) + 1;
427 result = winbindd_request_response(WINBINDD_DUMP_MAPS, &request, &response);
429 SAFE_FREE(request.extra_data.data);
430 return (result == NSS_STATUS_SUCCESS);
433 BOOL winbind_allocate_uid(uid_t *uid)
435 struct winbindd_request request;
436 struct winbindd_response response;
437 int result;
439 /* Initialise request */
441 ZERO_STRUCT(request);
442 ZERO_STRUCT(response);
444 /* Make request */
446 result = winbindd_request_response(WINBINDD_ALLOCATE_UID,
447 &request, &response);
449 if (result != NSS_STATUS_SUCCESS)
450 return False;
452 /* Copy out result */
453 *uid = response.data.uid;
455 return True;
458 BOOL winbind_allocate_gid(gid_t *gid)
460 struct winbindd_request request;
461 struct winbindd_response response;
462 int result;
464 /* Initialise request */
466 ZERO_STRUCT(request);
467 ZERO_STRUCT(response);
469 /* Make request */
471 result = winbindd_request_response(WINBINDD_ALLOCATE_GID,
472 &request, &response);
474 if (result != NSS_STATUS_SUCCESS)
475 return False;
477 /* Copy out result */
478 *gid = response.data.gid;
480 return True;
483 BOOL winbind_set_mapping(const struct id_map *map)
485 struct winbindd_request request;
486 struct winbindd_response response;
487 int result;
489 /* Initialise request */
491 ZERO_STRUCT(request);
492 ZERO_STRUCT(response);
494 /* Make request */
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);
500 result = winbindd_request_response(WINBINDD_SET_MAPPING, &request, &response);
502 return (result == NSS_STATUS_SUCCESS);
505 BOOL winbind_set_uid_hwm(unsigned long id)
507 struct winbindd_request request;
508 struct winbindd_response response;
509 int result;
511 /* Initialise request */
513 ZERO_STRUCT(request);
514 ZERO_STRUCT(response);
516 /* Make request */
518 request.data.dual_idmapset.id = id;
519 request.data.dual_idmapset.type = ID_TYPE_UID;
521 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
523 return (result == NSS_STATUS_SUCCESS);
526 BOOL winbind_set_gid_hwm(unsigned long id)
528 struct winbindd_request request;
529 struct winbindd_response response;
530 int result;
532 /* Initialise request */
534 ZERO_STRUCT(request);
535 ZERO_STRUCT(response);
537 /* Make request */
539 request.data.dual_idmapset.id = id;
540 request.data.dual_idmapset.type = ID_TYPE_GID;
542 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
544 return (result == NSS_STATUS_SUCCESS);
547 /**********************************************************************
548 simple wrapper function to see if winbindd is alive
549 **********************************************************************/
551 BOOL winbind_ping( void )
553 NSS_STATUS result;
555 result = winbindd_request_response(WINBINDD_PING, NULL, NULL);
557 return result == NSS_STATUS_SUCCESS;
560 /**********************************************************************
561 Is a domain trusted?
563 result == NSS_STATUS_UNAVAIL: winbind not around
564 result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
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.
572 I *hate* global variables....
574 Volker
576 **********************************************************************/
578 NSS_STATUS wb_is_trusted_domain(const char *domain)
580 struct winbindd_request request;
581 struct winbindd_response response;
583 /* Call winbindd */
585 ZERO_STRUCT(request);
586 ZERO_STRUCT(response);
588 fstrcpy(request.domain_name, domain);
590 return winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response);