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 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.
26 #include "nsswitch/winbind_nss.h"
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
;
44 if (!sid
|| !name_type
)
47 /* Send off 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
))
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
;
75 /* Initialise request */
78 ZERO_STRUCT(response
);
80 fstrcpy(request
.data
.sid
, sid_string_static(sid
));
84 result
= winbindd_request_response(WINBINDD_LOOKUPSID
, &request
,
87 if (result
!= NSS_STATUS_SUCCESS
) {
94 *domain
= talloc_strdup(mem_ctx
, response
.data
.name
.dom_name
);
95 if (*domain
== NULL
) {
96 DEBUG(0, ("talloc failed\n"));
101 *name
= talloc_strdup(mem_ctx
, response
.data
.name
.name
);
103 DEBUG(0, ("talloc failed\n"));
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
));
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
)
126 struct winbindd_request request
;
127 struct winbindd_response response
;
134 /* Initialise request */
136 ZERO_STRUCT(request
);
137 ZERO_STRUCT(response
);
139 fstrcpy(request
.data
.sid
, sid_string_static(domain_sid
));
145 for (i
=0; i
<num_rids
; i
++) {
146 sprintf_append(mem_ctx
, &ridlist
, &len
, &buflen
,
150 if ((num_rids
!= 0) && (ridlist
== NULL
)) {
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
) {
166 *domain_name
= talloc_strdup(mem_ctx
, response
.data
.domain_name
);
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
)) {
180 p
= (char *)response
.extra_data
.data
;
182 for (i
=0; i
<num_rids
; i
++) {
186 DEBUG(10, ("Got invalid reply: %s\n",
187 (char *)response
.extra_data
.data
));
191 (*types
)[i
] = (enum lsa_SidType
)strtoul(p
, &q
, 10);
194 DEBUG(10, ("Got invalid reply: %s\n",
195 (char *)response
.extra_data
.data
));
203 DEBUG(10, ("Got invalid reply: %s\n",
204 (char *)response
.extra_data
.data
));
210 (*names
)[i
] = talloc_strdup(*names
, p
);
216 DEBUG(10, ("Got invalid reply: %s\n",
217 (char *)response
.extra_data
.data
));
221 SAFE_FREE(response
.extra_data
.data
);
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
;
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
);
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
;
275 /* Initialise request */
277 ZERO_STRUCT(request
);
278 ZERO_STRUCT(response
);
280 request
.data
.uid
= uid
;
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
))
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
;
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
);
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
;
342 /* Initialise request */
344 ZERO_STRUCT(request
);
345 ZERO_STRUCT(response
);
347 request
.data
.gid
= gid
;
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
))
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
;
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
;
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
;
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
;
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
;
439 /* Initialise request */
441 ZERO_STRUCT(request
);
442 ZERO_STRUCT(response
);
446 result
= winbindd_request_response(WINBINDD_ALLOCATE_UID
,
447 &request
, &response
);
449 if (result
!= NSS_STATUS_SUCCESS
)
452 /* Copy out result */
453 *uid
= response
.data
.uid
;
458 BOOL
winbind_allocate_gid(gid_t
*gid
)
460 struct winbindd_request request
;
461 struct winbindd_response response
;
464 /* Initialise request */
466 ZERO_STRUCT(request
);
467 ZERO_STRUCT(response
);
471 result
= winbindd_request_response(WINBINDD_ALLOCATE_GID
,
472 &request
, &response
);
474 if (result
!= NSS_STATUS_SUCCESS
)
477 /* Copy out result */
478 *gid
= response
.data
.gid
;
483 BOOL
winbind_set_mapping(const struct id_map
*map
)
485 struct winbindd_request request
;
486 struct winbindd_response response
;
489 /* Initialise request */
491 ZERO_STRUCT(request
);
492 ZERO_STRUCT(response
);
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
;
511 /* Initialise request */
513 ZERO_STRUCT(request
);
514 ZERO_STRUCT(response
);
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
;
532 /* Initialise request */
534 ZERO_STRUCT(request
);
535 ZERO_STRUCT(response
);
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 )
555 result
= winbindd_request_response(WINBINDD_PING
, NULL
, NULL
);
557 return result
== NSS_STATUS_SUCCESS
;
560 /**********************************************************************
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....
576 **********************************************************************/
578 NSS_STATUS
wb_is_trusted_domain(const char *domain
)
580 struct winbindd_request request
;
581 struct winbindd_response response
;
585 ZERO_STRUCT(request
);
586 ZERO_STRUCT(response
);
588 fstrcpy(request
.domain_name
, domain
);
590 return winbindd_request_response(WINBINDD_DOMAIN_INFO
, &request
, &response
);