2 Unix SMB/CIFS implementation.
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 3 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 License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "nsswitch/winbind_nss.h"
27 #define DBGC_CLASS DBGC_WINBIND
29 NSS_STATUS winbindd_request_response(int req_type,
30 struct winbindd_request *request,
31 struct winbindd_response *response);
33 /* Call winbindd to convert a name to a sid */
35 BOOL winbind_lookup_name(const char *dom_name, const char *name, DOM_SID *sid,
36 enum lsa_SidType *name_type)
38 struct winbindd_request request;
39 struct winbindd_response response;
42 if (!sid || !name_type)
45 /* Send off request */
48 ZERO_STRUCT(response);
50 fstrcpy(request.data.name.dom_name, dom_name);
51 fstrcpy(request.data.name.name, name);
53 if ((result = winbindd_request_response(WINBINDD_LOOKUPNAME, &request,
54 &response)) == NSS_STATUS_SUCCESS) {
55 if (!string_to_sid(sid, response.data.sid.sid))
57 *name_type = (enum lsa_SidType)response.data.sid.type;
60 return result == NSS_STATUS_SUCCESS;
63 /* Call winbindd to convert sid to name */
65 BOOL winbind_lookup_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
66 const char **domain, const char **name,
67 enum lsa_SidType *name_type)
69 struct winbindd_request request;
70 struct winbindd_response response;
73 /* Initialise request */
76 ZERO_STRUCT(response);
78 fstrcpy(request.data.sid, sid_string_static(sid));
82 result = winbindd_request_response(WINBINDD_LOOKUPSID, &request,
85 if (result != NSS_STATUS_SUCCESS) {
92 *domain = talloc_strdup(mem_ctx, response.data.name.dom_name);
93 if (*domain == NULL) {
94 DEBUG(0, ("talloc failed\n"));
99 *name = talloc_strdup(mem_ctx, response.data.name.name);
101 DEBUG(0, ("talloc failed\n"));
106 *name_type = (enum lsa_SidType)response.data.name.type;
108 DEBUG(10, ("winbind_lookup_sid: SUCCESS: SID %s -> %s %s\n",
109 sid_string_static(sid), response.data.name.dom_name,
110 response.data.name.name));
114 BOOL winbind_lookup_rids(TALLOC_CTX *mem_ctx,
115 const DOM_SID *domain_sid,
116 int num_rids, uint32 *rids,
117 const char **domain_name,
118 const char ***names, enum lsa_SidType **types)
124 struct winbindd_request request;
125 struct winbindd_response response;
132 /* Initialise request */
134 ZERO_STRUCT(request);
135 ZERO_STRUCT(response);
137 fstrcpy(request.data.sid, sid_string_static(domain_sid));
143 for (i=0; i<num_rids; i++) {
144 sprintf_append(mem_ctx, &ridlist, &len, &buflen,
148 if ((num_rids != 0) && (ridlist == NULL)) {
152 request.extra_data.data = ridlist;
153 request.extra_len = strlen(ridlist)+1;
155 result = winbindd_request_response(WINBINDD_LOOKUPRIDS,
156 &request, &response);
158 TALLOC_FREE(ridlist);
160 if (result != NSS_STATUS_SUCCESS) {
164 *domain_name = talloc_strdup(mem_ctx, response.data.domain_name);
167 *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
168 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
170 if ((*names == NULL) || (*types == NULL)) {
178 p = (char *)response.extra_data.data;
180 for (i=0; i<num_rids; i++) {
184 DEBUG(10, ("Got invalid reply: %s\n",
185 (char *)response.extra_data.data));
189 (*types)[i] = (enum lsa_SidType)strtoul(p, &q, 10);
192 DEBUG(10, ("Got invalid reply: %s\n",
193 (char *)response.extra_data.data));
201 DEBUG(10, ("Got invalid reply: %s\n",
202 (char *)response.extra_data.data));
208 (*names)[i] = talloc_strdup(*names, p);
214 DEBUG(10, ("Got invalid reply: %s\n",
215 (char *)response.extra_data.data));
219 SAFE_FREE(response.extra_data.data);
229 /* Call winbindd to convert SID to uid */
231 BOOL winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
233 struct winbindd_request request;
234 struct winbindd_response response;
241 /* Initialise request */
243 ZERO_STRUCT(request);
244 ZERO_STRUCT(response);
246 sid_to_string(sid_str, sid);
247 fstrcpy(request.data.sid, sid_str);
251 result = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response);
253 /* Copy out result */
255 if (result == NSS_STATUS_SUCCESS) {
256 *puid = response.data.uid;
259 return (result == NSS_STATUS_SUCCESS);
262 /* Call winbindd to convert uid to sid */
264 BOOL winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
266 struct winbindd_request request;
267 struct winbindd_response response;
273 /* Initialise request */
275 ZERO_STRUCT(request);
276 ZERO_STRUCT(response);
278 request.data.uid = uid;
282 result = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response);
284 /* Copy out result */
286 if (result == NSS_STATUS_SUCCESS) {
287 if (!string_to_sid(sid, response.data.sid.sid))
290 sid_copy(sid, &global_sid_NULL);
293 return (result == NSS_STATUS_SUCCESS);
296 /* Call winbindd to convert SID to gid */
298 BOOL winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
300 struct winbindd_request request;
301 struct winbindd_response response;
308 /* Initialise request */
310 ZERO_STRUCT(request);
311 ZERO_STRUCT(response);
313 sid_to_string(sid_str, sid);
314 fstrcpy(request.data.sid, sid_str);
318 result = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response);
320 /* Copy out result */
322 if (result == NSS_STATUS_SUCCESS) {
323 *pgid = response.data.gid;
326 return (result == NSS_STATUS_SUCCESS);
329 /* Call winbindd to convert gid to sid */
331 BOOL winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
333 struct winbindd_request request;
334 struct winbindd_response response;
340 /* Initialise request */
342 ZERO_STRUCT(request);
343 ZERO_STRUCT(response);
345 request.data.gid = gid;
349 result = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response);
351 /* Copy out result */
353 if (result == NSS_STATUS_SUCCESS) {
354 if (!string_to_sid(sid, response.data.sid.sid))
357 sid_copy(sid, &global_sid_NULL);
360 return (result == NSS_STATUS_SUCCESS);
363 /* Call winbindd to convert SID to uid */
365 BOOL winbind_sids_to_unixids(struct id_map *ids, int num_ids)
367 struct winbindd_request request;
368 struct winbindd_response response;
373 /* Initialise request */
375 ZERO_STRUCT(request);
376 ZERO_STRUCT(response);
378 request.extra_len = num_ids * sizeof(DOM_SID);
380 sids = (DOM_SID *)SMB_MALLOC(request.extra_len);
381 for (i = 0; i < num_ids; i++) {
382 sid_copy(&sids[i], ids[i].sid);
385 request.extra_data.data = (char *)sids;
389 result = winbindd_request_response(WINBINDD_SIDS_TO_XIDS, &request, &response);
391 /* Copy out result */
393 if (result == NSS_STATUS_SUCCESS) {
394 struct unixid *wid = (struct unixid *)response.extra_data.data;
396 for (i = 0; i < num_ids; i++) {
397 if (wid[i].type == -1) {
398 ids[i].status = ID_UNMAPPED;
400 ids[i].status = ID_MAPPED;
401 ids[i].xid.type = wid[i].type;
402 ids[i].xid.id = wid[i].id;
407 SAFE_FREE(request.extra_data.data);
408 SAFE_FREE(response.extra_data.data);
410 return (result == NSS_STATUS_SUCCESS);
413 BOOL winbind_idmap_dump_maps(TALLOC_CTX *memctx, const char *file)
415 struct winbindd_request request;
416 struct winbindd_response response;
419 ZERO_STRUCT(request);
420 ZERO_STRUCT(response);
422 request.extra_data.data = SMB_STRDUP(file);
423 request.extra_len = strlen(request.extra_data.data) + 1;
425 result = winbindd_request_response(WINBINDD_DUMP_MAPS, &request, &response);
427 SAFE_FREE(request.extra_data.data);
428 return (result == NSS_STATUS_SUCCESS);
431 BOOL winbind_allocate_uid(uid_t *uid)
433 struct winbindd_request request;
434 struct winbindd_response response;
437 /* Initialise request */
439 ZERO_STRUCT(request);
440 ZERO_STRUCT(response);
444 result = winbindd_request_response(WINBINDD_ALLOCATE_UID,
445 &request, &response);
447 if (result != NSS_STATUS_SUCCESS)
450 /* Copy out result */
451 *uid = response.data.uid;
456 BOOL winbind_allocate_gid(gid_t *gid)
458 struct winbindd_request request;
459 struct winbindd_response response;
462 /* Initialise request */
464 ZERO_STRUCT(request);
465 ZERO_STRUCT(response);
469 result = winbindd_request_response(WINBINDD_ALLOCATE_GID,
470 &request, &response);
472 if (result != NSS_STATUS_SUCCESS)
475 /* Copy out result */
476 *gid = response.data.gid;
481 BOOL winbind_set_mapping(const struct id_map *map)
483 struct winbindd_request request;
484 struct winbindd_response response;
487 /* Initialise request */
489 ZERO_STRUCT(request);
490 ZERO_STRUCT(response);
494 request.data.dual_idmapset.id = map->xid.id;
495 request.data.dual_idmapset.type = map->xid.type;
496 sid_to_string(request.data.dual_idmapset.sid, map->sid);
498 result = winbindd_request_response(WINBINDD_SET_MAPPING, &request, &response);
500 return (result == NSS_STATUS_SUCCESS);
503 BOOL winbind_set_uid_hwm(unsigned long id)
505 struct winbindd_request request;
506 struct winbindd_response response;
509 /* Initialise request */
511 ZERO_STRUCT(request);
512 ZERO_STRUCT(response);
516 request.data.dual_idmapset.id = id;
517 request.data.dual_idmapset.type = ID_TYPE_UID;
519 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
521 return (result == NSS_STATUS_SUCCESS);
524 BOOL winbind_set_gid_hwm(unsigned long id)
526 struct winbindd_request request;
527 struct winbindd_response response;
530 /* Initialise request */
532 ZERO_STRUCT(request);
533 ZERO_STRUCT(response);
537 request.data.dual_idmapset.id = id;
538 request.data.dual_idmapset.type = ID_TYPE_GID;
540 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
542 return (result == NSS_STATUS_SUCCESS);
545 /**********************************************************************
546 simple wrapper function to see if winbindd is alive
547 **********************************************************************/
549 BOOL winbind_ping( void )
553 result = winbindd_request_response(WINBINDD_PING, NULL, NULL);
555 return result == NSS_STATUS_SUCCESS;
558 /**********************************************************************
561 result == NSS_STATUS_UNAVAIL: winbind not around
562 result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
564 Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off and
565 when winbind return WINBINDD_ERROR. So the semantics of this routine depends
566 on winbind_on. Grepping for winbind_off I just found 3 places where winbind
567 is turned off, and this does not conflict (as far as I have seen) with the
568 callers of is_trusted_domains.
570 I *hate* global variables....
574 **********************************************************************/
576 NSS_STATUS wb_is_trusted_domain(const char *domain)
578 struct winbindd_request request;
579 struct winbindd_response response;
583 ZERO_STRUCT(request);
584 ZERO_STRUCT(response);
586 fstrcpy(request.domain_name, domain);
588 return winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response);