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 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.
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 Lesser 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 (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);
166 *names = TALLOC_ARRAY(mem_ctx, const char *, num_rids);
167 *types = TALLOC_ARRAY(mem_ctx, enum lsa_SidType, num_rids);
169 if ((*names == NULL) || (*types == NULL)) {
173 p = (char *)response.extra_data.data;
175 for (i=0; i<num_rids; i++) {
179 DEBUG(10, ("Got invalid reply: %s\n",
180 (char *)response.extra_data.data));
184 (*types)[i] = (enum lsa_SidType)strtoul(p, &q, 10);
187 DEBUG(10, ("Got invalid reply: %s\n",
188 (char *)response.extra_data.data));
196 DEBUG(10, ("Got invalid reply: %s\n",
197 (char *)response.extra_data.data));
203 (*names)[i] = talloc_strdup(*names, p);
209 DEBUG(10, ("Got invalid reply: %s\n",
210 (char *)response.extra_data.data));
214 SAFE_FREE(response.extra_data.data);
224 /* Call winbindd to convert SID to uid */
226 bool winbind_sid_to_uid(uid_t *puid, const DOM_SID *sid)
228 struct winbindd_request request;
229 struct winbindd_response response;
236 /* Initialise request */
238 ZERO_STRUCT(request);
239 ZERO_STRUCT(response);
241 sid_to_string(sid_str, sid);
242 fstrcpy(request.data.sid, sid_str);
246 result = winbindd_request_response(WINBINDD_SID_TO_UID, &request, &response);
248 /* Copy out result */
250 if (result == NSS_STATUS_SUCCESS) {
251 *puid = response.data.uid;
254 return (result == NSS_STATUS_SUCCESS);
257 /* Call winbindd to convert uid to sid */
259 bool winbind_uid_to_sid(DOM_SID *sid, uid_t uid)
261 struct winbindd_request request;
262 struct winbindd_response response;
268 /* Initialise request */
270 ZERO_STRUCT(request);
271 ZERO_STRUCT(response);
273 request.data.uid = uid;
277 result = winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response);
279 /* Copy out result */
281 if (result == NSS_STATUS_SUCCESS) {
282 if (!string_to_sid(sid, response.data.sid.sid))
285 sid_copy(sid, &global_sid_NULL);
288 return (result == NSS_STATUS_SUCCESS);
291 /* Call winbindd to convert SID to gid */
293 bool winbind_sid_to_gid(gid_t *pgid, const DOM_SID *sid)
295 struct winbindd_request request;
296 struct winbindd_response response;
303 /* Initialise request */
305 ZERO_STRUCT(request);
306 ZERO_STRUCT(response);
308 sid_to_string(sid_str, sid);
309 fstrcpy(request.data.sid, sid_str);
313 result = winbindd_request_response(WINBINDD_SID_TO_GID, &request, &response);
315 /* Copy out result */
317 if (result == NSS_STATUS_SUCCESS) {
318 *pgid = response.data.gid;
321 return (result == NSS_STATUS_SUCCESS);
324 /* Call winbindd to convert gid to sid */
326 bool winbind_gid_to_sid(DOM_SID *sid, gid_t gid)
328 struct winbindd_request request;
329 struct winbindd_response response;
335 /* Initialise request */
337 ZERO_STRUCT(request);
338 ZERO_STRUCT(response);
340 request.data.gid = gid;
344 result = winbindd_request_response(WINBINDD_GID_TO_SID, &request, &response);
346 /* Copy out result */
348 if (result == NSS_STATUS_SUCCESS) {
349 if (!string_to_sid(sid, response.data.sid.sid))
352 sid_copy(sid, &global_sid_NULL);
355 return (result == NSS_STATUS_SUCCESS);
358 /* Call winbindd to convert SID to uid */
360 bool winbind_sids_to_unixids(struct id_map *ids, int num_ids)
362 struct winbindd_request request;
363 struct winbindd_response response;
368 /* Initialise request */
370 ZERO_STRUCT(request);
371 ZERO_STRUCT(response);
373 request.extra_len = num_ids * sizeof(DOM_SID);
375 sids = (DOM_SID *)SMB_MALLOC(request.extra_len);
376 for (i = 0; i < num_ids; i++) {
377 sid_copy(&sids[i], ids[i].sid);
380 request.extra_data.data = (char *)sids;
384 result = winbindd_request_response(WINBINDD_SIDS_TO_XIDS, &request, &response);
386 /* Copy out result */
388 if (result == NSS_STATUS_SUCCESS) {
389 struct unixid *wid = (struct unixid *)response.extra_data.data;
391 for (i = 0; i < num_ids; i++) {
392 if (wid[i].type == -1) {
393 ids[i].status = ID_UNMAPPED;
395 ids[i].status = ID_MAPPED;
396 ids[i].xid.type = wid[i].type;
397 ids[i].xid.id = wid[i].id;
402 SAFE_FREE(request.extra_data.data);
403 SAFE_FREE(response.extra_data.data);
405 return (result == NSS_STATUS_SUCCESS);
408 bool winbind_idmap_dump_maps(TALLOC_CTX *memctx, const char *file)
410 struct winbindd_request request;
411 struct winbindd_response response;
414 ZERO_STRUCT(request);
415 ZERO_STRUCT(response);
417 request.extra_data.data = SMB_STRDUP(file);
418 request.extra_len = strlen(request.extra_data.data) + 1;
420 result = winbindd_request_response(WINBINDD_DUMP_MAPS, &request, &response);
422 SAFE_FREE(request.extra_data.data);
423 return (result == NSS_STATUS_SUCCESS);
426 bool winbind_allocate_uid(uid_t *uid)
428 struct winbindd_request request;
429 struct winbindd_response response;
432 /* Initialise request */
434 ZERO_STRUCT(request);
435 ZERO_STRUCT(response);
439 result = winbindd_request_response(WINBINDD_ALLOCATE_UID,
440 &request, &response);
442 if (result != NSS_STATUS_SUCCESS)
445 /* Copy out result */
446 *uid = response.data.uid;
451 bool winbind_allocate_gid(gid_t *gid)
453 struct winbindd_request request;
454 struct winbindd_response response;
457 /* Initialise request */
459 ZERO_STRUCT(request);
460 ZERO_STRUCT(response);
464 result = winbindd_request_response(WINBINDD_ALLOCATE_GID,
465 &request, &response);
467 if (result != NSS_STATUS_SUCCESS)
470 /* Copy out result */
471 *gid = response.data.gid;
476 bool winbind_set_mapping(const struct id_map *map)
478 struct winbindd_request request;
479 struct winbindd_response response;
482 /* Initialise request */
484 ZERO_STRUCT(request);
485 ZERO_STRUCT(response);
489 request.data.dual_idmapset.id = map->xid.id;
490 request.data.dual_idmapset.type = map->xid.type;
491 sid_to_string(request.data.dual_idmapset.sid, map->sid);
493 result = winbindd_request_response(WINBINDD_SET_MAPPING, &request, &response);
495 return (result == NSS_STATUS_SUCCESS);
498 bool winbind_set_uid_hwm(unsigned long id)
500 struct winbindd_request request;
501 struct winbindd_response response;
504 /* Initialise request */
506 ZERO_STRUCT(request);
507 ZERO_STRUCT(response);
511 request.data.dual_idmapset.id = id;
512 request.data.dual_idmapset.type = ID_TYPE_UID;
514 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
516 return (result == NSS_STATUS_SUCCESS);
519 bool winbind_set_gid_hwm(unsigned long id)
521 struct winbindd_request request;
522 struct winbindd_response response;
525 /* Initialise request */
527 ZERO_STRUCT(request);
528 ZERO_STRUCT(response);
532 request.data.dual_idmapset.id = id;
533 request.data.dual_idmapset.type = ID_TYPE_GID;
535 result = winbindd_request_response(WINBINDD_SET_HWM, &request, &response);
537 return (result == NSS_STATUS_SUCCESS);
540 /**********************************************************************
541 simple wrapper function to see if winbindd is alive
542 **********************************************************************/
544 bool winbind_ping( void )
548 result = winbindd_request_response(WINBINDD_PING, NULL, NULL);
550 return result == NSS_STATUS_SUCCESS;
553 /**********************************************************************
556 result == NSS_STATUS_UNAVAIL: winbind not around
557 result == NSS_STATUS_NOTFOUND: winbind around, but domain missing
559 Due to a bad API NSS_STATUS_NOTFOUND is returned both when winbind_off and
560 when winbind return WINBINDD_ERROR. So the semantics of this routine depends
561 on winbind_on. Grepping for winbind_off I just found 3 places where winbind
562 is turned off, and this does not conflict (as far as I have seen) with the
563 callers of is_trusted_domains.
565 I *hate* global variables....
569 **********************************************************************/
571 NSS_STATUS wb_is_trusted_domain(const char *domain)
573 struct winbindd_request request;
574 struct winbindd_response response;
578 ZERO_STRUCT(request);
579 ZERO_STRUCT(response);
581 fstrcpy(request.domain_name, domain);
583 return winbindd_request_response(WINBINDD_DOMAIN_INFO, &request, &response);