2 Unix SMB/CIFS implementation.
6 Copyright (C) Gerald (Jerry) Carter 2007
7 Copyright (C) Volker Lendecke 2010
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 3 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
20 You should have received a copy of the GNU Lesser General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 /* Required Headers */
27 #include "libwbclient.h"
28 #include "../winbind_client.h"
29 #include "lib/util/smb_strtox.h"
31 /* Convert a sid to a string into a buffer. Return the string
32 * length. If buflen is too small, return the string length that would
33 * result if it was long enough. */
35 int wbcSidToStringBuf(const struct wbcDomainSid
*sid
, char *buf
, int buflen
)
41 strlcpy(buf
, "(NULL SID)", buflen
);
42 return 10; /* strlen("(NULL SID)") */
45 id_auth
= (uint64_t)sid
->id_auth
[5] +
46 ((uint64_t)sid
->id_auth
[4] << 8) +
47 ((uint64_t)sid
->id_auth
[3] << 16) +
48 ((uint64_t)sid
->id_auth
[2] << 24) +
49 ((uint64_t)sid
->id_auth
[1] << 32) +
50 ((uint64_t)sid
->id_auth
[0] << 40);
52 ofs
= snprintf(buf
, buflen
, "S-%hhu-", (unsigned char)sid
->sid_rev_num
);
53 if (id_auth
>= UINT32_MAX
) {
54 ofs
+= snprintf(buf
+ ofs
, MAX(buflen
- ofs
, 0), "0x%llx",
55 (unsigned long long)id_auth
);
57 ofs
+= snprintf(buf
+ ofs
, MAX(buflen
- ofs
, 0), "%llu",
58 (unsigned long long)id_auth
);
61 for (i
= 0; i
< sid
->num_auths
; i
++) {
62 ofs
+= snprintf(buf
+ ofs
, MAX(buflen
- ofs
, 0), "-%u",
63 (unsigned int)sid
->sub_auths
[i
]);
68 /* Convert a binary SID to a character string */
70 wbcErr
wbcSidToString(const struct wbcDomainSid
*sid
,
73 char buf
[WBC_SID_STRING_BUFLEN
];
78 return WBC_ERR_INVALID_SID
;
81 len
= wbcSidToStringBuf(sid
, buf
, sizeof(buf
));
83 if (len
>= WBC_SID_STRING_BUFLEN
) {
84 return WBC_ERR_INVALID_SID
;
87 result
= (char *)wbcAllocateMemory(len
+1, 1, NULL
);
89 return WBC_ERR_NO_MEMORY
;
91 memcpy(result
, buf
, len
+1);
94 return WBC_ERR_SUCCESS
;
97 #define AUTHORITY_MASK (~(0xffffffffffffULL))
99 /* Convert a character string to a binary SID */
101 wbcErr
wbcStringToSid(const char *str
,
102 struct wbcDomainSid
*sid
)
108 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
111 wbc_status
= WBC_ERR_INVALID_PARAM
;
112 BAIL_ON_WBC_ERROR(wbc_status
);
115 /* Sanity check for either "S-" or "s-" */
118 || (str
[0]!='S' && str
[0]!='s')
121 wbc_status
= WBC_ERR_INVALID_PARAM
;
122 BAIL_ON_WBC_ERROR(wbc_status
);
125 /* Get the SID revision number */
128 x
= (uint64_t)smb_strtoul(p
, &q
, 10, &error
, SMB_STR_STANDARD
);
129 if (x
== 0 || x
> UINT8_MAX
|| !q
|| *q
!= '-' || error
!= 0) {
130 wbc_status
= WBC_ERR_INVALID_SID
;
131 BAIL_ON_WBC_ERROR(wbc_status
);
133 sid
->sid_rev_num
= (uint8_t)x
;
136 * Next the Identifier Authority. This is stored big-endian in a
137 * 6 byte array. If the authority value is >= UINT_MAX, then it should
138 * be expressed as a hex value, according to MS-DTYP.
141 x
= smb_strtoull(p
, &q
, 0, &error
, SMB_STR_STANDARD
);
142 if (!q
|| *q
!= '-' || (x
& AUTHORITY_MASK
) || error
!= 0) {
143 wbc_status
= WBC_ERR_INVALID_SID
;
144 BAIL_ON_WBC_ERROR(wbc_status
);
146 sid
->id_auth
[5] = (x
& 0x0000000000ffULL
);
147 sid
->id_auth
[4] = (x
& 0x00000000ff00ULL
) >> 8;
148 sid
->id_auth
[3] = (x
& 0x000000ff0000ULL
) >> 16;
149 sid
->id_auth
[2] = (x
& 0x0000ff000000ULL
) >> 24;
150 sid
->id_auth
[1] = (x
& 0x00ff00000000ULL
) >> 32;
151 sid
->id_auth
[0] = (x
& 0xff0000000000ULL
) >> 40;
153 /* now read the the subauthorities */
156 while (sid
->num_auths
< WBC_MAXSUBAUTHS
) {
157 x
= smb_strtoull(p
, &q
, 10, &error
, SMB_STR_ALLOW_NO_CONVERSION
);
160 if (x
> UINT32_MAX
|| error
!= 0) {
161 wbc_status
= WBC_ERR_INVALID_SID
;
162 BAIL_ON_WBC_ERROR(wbc_status
);
164 sid
->sub_auths
[sid
->num_auths
++] = x
;
172 /* IF we ended early, then the SID could not be converted */
175 wbc_status
= WBC_ERR_INVALID_SID
;
176 BAIL_ON_WBC_ERROR(wbc_status
);
179 wbc_status
= WBC_ERR_SUCCESS
;
187 /* Convert a domain and name to SID */
189 wbcErr
wbcCtxLookupName(struct wbcContext
*ctx
,
192 struct wbcDomainSid
*sid
,
193 enum wbcSidType
*name_type
)
195 struct winbindd_request request
;
196 struct winbindd_response response
;
197 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
199 if (!sid
|| !name_type
) {
200 wbc_status
= WBC_ERR_INVALID_PARAM
;
201 BAIL_ON_WBC_ERROR(wbc_status
);
204 /* Initialize request */
206 ZERO_STRUCT(request
);
207 ZERO_STRUCT(response
);
209 /* dst is already null terminated from the memset above */
211 strncpy(request
.data
.name
.dom_name
, domain
,
212 sizeof(request
.data
.name
.dom_name
)-1);
213 strncpy(request
.data
.name
.name
, name
,
214 sizeof(request
.data
.name
.name
)-1);
216 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LOOKUPNAME
,
219 BAIL_ON_WBC_ERROR(wbc_status
);
221 wbc_status
= wbcStringToSid(response
.data
.sid
.sid
, sid
);
222 BAIL_ON_WBC_ERROR(wbc_status
);
224 *name_type
= (enum wbcSidType
)response
.data
.sid
.type
;
226 wbc_status
= WBC_ERR_SUCCESS
;
233 wbcErr
wbcLookupName(const char *domain
,
235 struct wbcDomainSid
*sid
,
236 enum wbcSidType
*name_type
)
238 return wbcCtxLookupName(NULL
, domain
, name
, sid
, name_type
);
242 /* Convert a SID to a domain and name */
244 wbcErr
wbcCtxLookupSid(struct wbcContext
*ctx
,
245 const struct wbcDomainSid
*sid
,
248 enum wbcSidType
*pname_type
)
250 struct winbindd_request request
;
251 struct winbindd_response response
;
252 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
256 return WBC_ERR_INVALID_PARAM
;
259 /* Initialize request */
261 ZERO_STRUCT(request
);
262 ZERO_STRUCT(response
);
264 wbcSidToStringBuf(sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
268 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LOOKUPSID
,
271 if (!WBC_ERROR_IS_OK(wbc_status
)) {
275 /* Copy out result */
277 wbc_status
= WBC_ERR_NO_MEMORY
;
281 domain
= wbcStrDup(response
.data
.name
.dom_name
);
282 if (domain
== NULL
) {
285 name
= wbcStrDup(response
.data
.name
.name
);
289 if (pdomain
!= NULL
) {
297 if (pname_type
!= NULL
) {
298 *pname_type
= (enum wbcSidType
)response
.data
.name
.type
;
300 wbc_status
= WBC_ERR_SUCCESS
;
303 wbcFreeMemory(domain
);
308 wbcErr
wbcLookupSid(const struct wbcDomainSid
*sid
,
311 enum wbcSidType
*pname_type
)
313 return wbcCtxLookupSid(NULL
, sid
, pdomain
, pname
, pname_type
);
316 static void wbcDomainInfosDestructor(void *ptr
)
318 struct wbcDomainInfo
*i
= (struct wbcDomainInfo
*)ptr
;
320 while (i
->short_name
!= NULL
) {
321 wbcFreeMemory(i
->short_name
);
322 wbcFreeMemory(i
->dns_name
);
327 static void wbcTranslatedNamesDestructor(void *ptr
)
329 struct wbcTranslatedName
*n
= (struct wbcTranslatedName
*)ptr
;
331 while (n
->name
!= NULL
) {
332 wbcFreeMemory(n
->name
);
338 wbcErr
wbcCtxLookupSids(struct wbcContext
*ctx
,
339 const struct wbcDomainSid
*sids
, int num_sids
,
340 struct wbcDomainInfo
**pdomains
, int *pnum_domains
,
341 struct wbcTranslatedName
**pnames
)
343 struct winbindd_request request
;
344 struct winbindd_response response
;
345 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
346 int buflen
, i
, extra_len
, num_domains
, num_names
;
347 char *sidlist
, *p
, *q
, *extra_data
;
348 struct wbcDomainInfo
*domains
= NULL
;
349 struct wbcTranslatedName
*names
= NULL
;
352 buflen
= num_sids
* (WBC_SID_STRING_BUFLEN
+ 1) + 1;
354 sidlist
= (char *)malloc(buflen
);
355 if (sidlist
== NULL
) {
356 return WBC_ERR_NO_MEMORY
;
361 for (i
=0; i
<num_sids
; i
++) {
365 remaining
= buflen
- (p
- sidlist
);
367 len
= wbcSidToStringBuf(&sids
[i
], p
, remaining
);
368 if (len
> remaining
) {
370 return WBC_ERR_UNKNOWN_FAILURE
;
378 ZERO_STRUCT(request
);
379 ZERO_STRUCT(response
);
381 request
.extra_data
.data
= sidlist
;
382 request
.extra_len
= p
- sidlist
;
384 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LOOKUPSIDS
,
385 &request
, &response
);
387 if (!WBC_ERROR_IS_OK(wbc_status
)) {
391 extra_len
= response
.length
- sizeof(struct winbindd_response
);
392 extra_data
= (char *)response
.extra_data
.data
;
394 if ((extra_len
<= 0) || (extra_data
[extra_len
-1] != '\0')) {
395 goto wbc_err_invalid
;
400 num_domains
= smb_strtoul(p
, &q
, 10, &error
, SMB_STR_STANDARD
);
401 if (*q
!= '\n' || error
!= 0) {
402 goto wbc_err_invalid
;
406 domains
= (struct wbcDomainInfo
*)wbcAllocateMemory(
407 num_domains
+1, sizeof(struct wbcDomainInfo
),
408 wbcDomainInfosDestructor
);
409 if (domains
== NULL
) {
410 wbc_status
= WBC_ERR_NO_MEMORY
;
414 for (i
=0; i
<num_domains
; i
++) {
418 goto wbc_err_invalid
;
421 wbc_status
= wbcStringToSid(p
, &domains
[i
].sid
);
422 if (!WBC_ERROR_IS_OK(wbc_status
)) {
429 goto wbc_err_invalid
;
432 domains
[i
].short_name
= wbcStrDup(p
);
433 if (domains
[i
].short_name
== NULL
) {
434 wbc_status
= WBC_ERR_NO_MEMORY
;
440 num_names
= smb_strtoul(p
, &q
, 10, &error
, SMB_STR_STANDARD
);
441 if (*q
!= '\n' || error
!= 0) {
442 goto wbc_err_invalid
;
446 if (num_names
!= num_sids
) {
447 goto wbc_err_invalid
;
450 names
= (struct wbcTranslatedName
*)wbcAllocateMemory(
451 num_names
+1, sizeof(struct wbcTranslatedName
),
452 wbcTranslatedNamesDestructor
);
454 wbc_status
= WBC_ERR_NO_MEMORY
;
458 for (i
=0; i
<num_names
; i
++) {
460 names
[i
].domain_index
= smb_strtoul(p
,
465 if (names
[i
].domain_index
< 0 || error
!= 0) {
466 goto wbc_err_invalid
;
468 if (names
[i
].domain_index
>= num_domains
) {
469 goto wbc_err_invalid
;
473 goto wbc_err_invalid
;
477 names
[i
].type
= smb_strtoul(p
, &q
, 10, &error
, SMB_STR_STANDARD
);
478 if (*q
!= ' ' || error
!= 0) {
479 goto wbc_err_invalid
;
485 goto wbc_err_invalid
;
488 names
[i
].name
= wbcStrDup(p
);
489 if (names
[i
].name
== NULL
) {
490 wbc_status
= WBC_ERR_NO_MEMORY
;
496 goto wbc_err_invalid
;
501 winbindd_free_response(&response
);
502 return WBC_ERR_SUCCESS
;
505 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
507 winbindd_free_response(&response
);
508 wbcFreeMemory(domains
);
509 wbcFreeMemory(names
);
514 wbcErr
wbcLookupSids(const struct wbcDomainSid
*sids
, int num_sids
,
515 struct wbcDomainInfo
**pdomains
, int *pnum_domains
,
516 struct wbcTranslatedName
**pnames
)
518 return wbcCtxLookupSids(NULL
, sids
, num_sids
, pdomains
,
519 pnum_domains
, pnames
);
522 /* Translate a collection of RIDs within a domain to names */
525 wbcErr
wbcCtxLookupRids(struct wbcContext
*ctx
, struct wbcDomainSid
*dom_sid
,
528 const char **pp_domain_name
,
529 const char ***pnames
,
530 enum wbcSidType
**ptypes
)
533 size_t len
, ridbuf_size
;
537 struct winbindd_request request
;
538 struct winbindd_response response
;
539 char *domain_name
= NULL
;
540 const char **names
= NULL
;
541 enum wbcSidType
*types
= NULL
;
542 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
544 /* Initialise request */
546 ZERO_STRUCT(request
);
547 ZERO_STRUCT(response
);
549 if (!dom_sid
|| (num_rids
== 0)) {
550 wbc_status
= WBC_ERR_INVALID_PARAM
;
551 BAIL_ON_WBC_ERROR(wbc_status
);
554 wbcSidToStringBuf(dom_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
556 /* Even if all the Rids were of maximum 32bit values,
557 we would only have 11 bytes per rid in the final array
558 ("4294967296" + \n). Add one more byte for the
561 ridbuf_size
= (sizeof(char)*11) * num_rids
+ 1;
563 ridlist
= (char *)malloc(ridbuf_size
);
564 BAIL_ON_PTR_ERROR(ridlist
, wbc_status
);
567 for (i
=0; i
<num_rids
; i
++) {
568 len
+= snprintf(ridlist
+ len
, ridbuf_size
- len
, "%u\n",
574 request
.extra_data
.data
= ridlist
;
575 request
.extra_len
= len
;
577 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LOOKUPRIDS
,
581 BAIL_ON_WBC_ERROR(wbc_status
);
583 domain_name
= wbcStrDup(response
.data
.domain_name
);
584 BAIL_ON_PTR_ERROR(domain_name
, wbc_status
);
586 names
= wbcAllocateStringArray(num_rids
);
587 BAIL_ON_PTR_ERROR(names
, wbc_status
);
589 types
= (enum wbcSidType
*)wbcAllocateMemory(
590 num_rids
, sizeof(enum wbcSidType
), NULL
);
591 BAIL_ON_PTR_ERROR(types
, wbc_status
);
593 p
= (char *)response
.extra_data
.data
;
595 for (i
=0; i
<num_rids
; i
++) {
599 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
603 types
[i
] = (enum wbcSidType
)smb_strtoul(p
,
609 if (*q
!= ' ' || error
!= 0) {
610 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
616 if ((q
= strchr(p
, '\n')) == NULL
) {
617 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
623 names
[i
] = strdup(p
);
624 BAIL_ON_PTR_ERROR(names
[i
], wbc_status
);
630 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
634 wbc_status
= WBC_ERR_SUCCESS
;
637 winbindd_free_response(&response
);
639 if (WBC_ERROR_IS_OK(wbc_status
)) {
640 *pp_domain_name
= domain_name
;
645 wbcFreeMemory(domain_name
);
646 wbcFreeMemory(names
);
647 wbcFreeMemory(types
);
654 wbcErr
wbcLookupRids(struct wbcDomainSid
*dom_sid
,
657 const char **pp_domain_name
,
658 const char ***pnames
,
659 enum wbcSidType
**ptypes
)
661 return wbcCtxLookupRids(NULL
, dom_sid
, num_rids
, rids
,
662 pp_domain_name
, pnames
, ptypes
);
665 /* Get the groups a user belongs to */
667 wbcErr
wbcCtxLookupUserSids(struct wbcContext
*ctx
,
668 const struct wbcDomainSid
*user_sid
,
669 bool domain_groups_only
,
671 struct wbcDomainSid
**_sids
)
675 struct winbindd_request request
;
676 struct winbindd_response response
;
677 struct wbcDomainSid
*sids
= NULL
;
678 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
681 /* Initialise request */
683 ZERO_STRUCT(request
);
684 ZERO_STRUCT(response
);
687 wbc_status
= WBC_ERR_INVALID_PARAM
;
688 BAIL_ON_WBC_ERROR(wbc_status
);
691 wbcSidToStringBuf(user_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
693 if (domain_groups_only
) {
694 cmd
= WINBINDD_GETUSERDOMGROUPS
;
696 cmd
= WINBINDD_GETUSERSIDS
;
699 wbc_status
= wbcRequestResponse(ctx
, cmd
,
702 BAIL_ON_WBC_ERROR(wbc_status
);
704 if (response
.data
.num_entries
&&
705 !response
.extra_data
.data
) {
706 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
707 BAIL_ON_WBC_ERROR(wbc_status
);
710 sids
= (struct wbcDomainSid
*)wbcAllocateMemory(
711 response
.data
.num_entries
, sizeof(struct wbcDomainSid
),
713 BAIL_ON_PTR_ERROR(sids
, wbc_status
);
715 s
= (const char *)response
.extra_data
.data
;
716 for (i
= 0; i
< response
.data
.num_entries
; i
++) {
717 char *n
= strchr(s
, '\n');
721 wbc_status
= wbcStringToSid(s
, &sids
[i
]);
722 BAIL_ON_WBC_ERROR(wbc_status
);
726 *num_sids
= response
.data
.num_entries
;
729 wbc_status
= WBC_ERR_SUCCESS
;
732 winbindd_free_response(&response
);
741 wbcErr
wbcLookupUserSids(const struct wbcDomainSid
*user_sid
,
742 bool domain_groups_only
,
744 struct wbcDomainSid
**_sids
)
746 return wbcCtxLookupUserSids(NULL
, user_sid
, domain_groups_only
,
751 wbcErr
_sid_to_rid(struct wbcDomainSid
*sid
, uint32_t *rid
)
753 if (sid
->num_auths
< 1) {
754 return WBC_ERR_INVALID_RESPONSE
;
756 *rid
= sid
->sub_auths
[sid
->num_auths
- 1];
758 return WBC_ERR_SUCCESS
;
761 /* Get alias membership for sids */
763 wbcErr
wbcCtxGetSidAliases(struct wbcContext
*ctx
,
764 const struct wbcDomainSid
*dom_sid
,
765 struct wbcDomainSid
*sids
,
767 uint32_t **alias_rids
,
768 uint32_t *num_alias_rids
)
772 struct winbindd_request request
;
773 struct winbindd_response response
;
774 ssize_t extra_data_len
= 0;
775 char * extra_data
= NULL
;
777 struct wbcDomainSid sid
;
778 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
779 uint32_t * rids
= NULL
;
781 /* Initialise request */
783 ZERO_STRUCT(request
);
784 ZERO_STRUCT(response
);
787 wbc_status
= WBC_ERR_INVALID_PARAM
;
791 wbcSidToStringBuf(dom_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
793 /* Lets assume each sid is around 57 characters
794 * S-1-5-21-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
795 buflen
= 57 * num_sids
;
796 extra_data
= (char *)malloc(buflen
);
798 wbc_status
= WBC_ERR_NO_MEMORY
;
802 /* Build the sid list */
803 for (i
=0; i
<num_sids
; i
++) {
804 char sid_str
[WBC_SID_STRING_BUFLEN
];
807 sid_len
= wbcSidToStringBuf(&sids
[i
], sid_str
, sizeof(sid_str
));
809 if (buflen
< extra_data_len
+ sid_len
+ 2) {
810 char * tmp_data
= NULL
;
812 tmp_data
= (char *)realloc(extra_data
, buflen
);
814 wbc_status
= WBC_ERR_NO_MEMORY
;
815 BAIL_ON_WBC_ERROR(wbc_status
);
817 extra_data
= tmp_data
;
820 strncpy(&extra_data
[extra_data_len
], sid_str
,
821 buflen
- extra_data_len
);
822 extra_data_len
+= sid_len
;
823 extra_data
[extra_data_len
++] = '\n';
824 extra_data
[extra_data_len
] = '\0';
828 request
.extra_data
.data
= extra_data
;
829 request
.extra_len
= extra_data_len
;
831 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_GETSIDALIASES
,
834 BAIL_ON_WBC_ERROR(wbc_status
);
836 if (response
.data
.num_entries
&&
837 !response
.extra_data
.data
) {
838 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
842 rids
= (uint32_t *)wbcAllocateMemory(response
.data
.num_entries
,
843 sizeof(uint32_t), NULL
);
844 BAIL_ON_PTR_ERROR(rids
, wbc_status
);
846 s
= (const char *)response
.extra_data
.data
;
847 for (i
= 0; i
< response
.data
.num_entries
; i
++) {
848 char *n
= strchr(s
, '\n');
852 wbc_status
= wbcStringToSid(s
, &sid
);
853 BAIL_ON_WBC_ERROR(wbc_status
);
854 wbc_status
= _sid_to_rid(&sid
, &rids
[i
]);
855 BAIL_ON_WBC_ERROR(wbc_status
);
859 *num_alias_rids
= response
.data
.num_entries
;
862 wbc_status
= WBC_ERR_SUCCESS
;
866 winbindd_free_response(&response
);
872 wbcErr
wbcGetSidAliases(const struct wbcDomainSid
*dom_sid
,
873 struct wbcDomainSid
*sids
,
875 uint32_t **alias_rids
,
876 uint32_t *num_alias_rids
)
878 return wbcCtxGetSidAliases(NULL
, dom_sid
, sids
, num_sids
,
879 alias_rids
, num_alias_rids
);
885 wbcErr
wbcCtxListUsers(struct wbcContext
*ctx
,
886 const char *domain_name
,
887 uint32_t *_num_users
,
888 const char ***_users
)
890 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
891 struct winbindd_request request
;
892 struct winbindd_response response
;
893 uint32_t num_users
= 0;
894 const char **users
= NULL
;
897 /* Initialise request */
899 ZERO_STRUCT(request
);
900 ZERO_STRUCT(response
);
903 strncpy(request
.domain_name
, domain_name
,
904 sizeof(request
.domain_name
)-1);
907 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LIST_USERS
,
910 BAIL_ON_WBC_ERROR(wbc_status
);
912 users
= wbcAllocateStringArray(response
.data
.num_entries
);
914 return WBC_ERR_NO_MEMORY
;
917 /* Look through extra data */
919 next
= (const char *)response
.extra_data
.data
;
924 if (num_users
>= response
.data
.num_entries
) {
925 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
930 k
= strchr(next
, ',');
939 users
[num_users
] = strdup(current
);
940 BAIL_ON_PTR_ERROR(users
[num_users
], wbc_status
);
943 if (num_users
!= response
.data
.num_entries
) {
944 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
948 *_num_users
= response
.data
.num_entries
;
951 wbc_status
= WBC_ERR_SUCCESS
;
954 winbindd_free_response(&response
);
955 wbcFreeMemory(users
);
960 wbcErr
wbcListUsers(const char *domain_name
,
961 uint32_t *_num_users
,
962 const char ***_users
)
964 return wbcCtxListUsers(NULL
, domain_name
, _num_users
, _users
);
969 wbcErr
wbcCtxListGroups(struct wbcContext
*ctx
,
970 const char *domain_name
,
971 uint32_t *_num_groups
,
972 const char ***_groups
)
974 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
975 struct winbindd_request request
;
976 struct winbindd_response response
;
977 uint32_t num_groups
= 0;
978 const char **groups
= NULL
;
981 /* Initialise request */
983 ZERO_STRUCT(request
);
984 ZERO_STRUCT(response
);
987 strncpy(request
.domain_name
, domain_name
,
988 sizeof(request
.domain_name
)-1);
991 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LIST_GROUPS
,
994 BAIL_ON_WBC_ERROR(wbc_status
);
996 groups
= wbcAllocateStringArray(response
.data
.num_entries
);
997 if (groups
== NULL
) {
998 return WBC_ERR_NO_MEMORY
;
1001 /* Look through extra data */
1003 next
= (const char *)response
.extra_data
.data
;
1005 const char *current
;
1008 if (num_groups
>= response
.data
.num_entries
) {
1009 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
1014 k
= strchr(next
, ',');
1023 groups
[num_groups
] = strdup(current
);
1024 BAIL_ON_PTR_ERROR(groups
[num_groups
], wbc_status
);
1027 if (num_groups
!= response
.data
.num_entries
) {
1028 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
1032 *_num_groups
= response
.data
.num_entries
;
1035 wbc_status
= WBC_ERR_SUCCESS
;
1038 winbindd_free_response(&response
);
1039 wbcFreeMemory(groups
);
1044 wbcErr
wbcListGroups(const char *domain_name
,
1045 uint32_t *_num_groups
,
1046 const char ***_groups
)
1048 return wbcCtxListGroups(NULL
, domain_name
, _num_groups
, _groups
);
1052 wbcErr
wbcCtxGetDisplayName(struct wbcContext
*ctx
,
1053 const struct wbcDomainSid
*sid
,
1056 enum wbcSidType
*pname_type
)
1059 char *domain
= NULL
;
1061 enum wbcSidType name_type
;
1063 wbc_status
= wbcCtxLookupSid(ctx
, sid
, &domain
, &name
, &name_type
);
1064 BAIL_ON_WBC_ERROR(wbc_status
);
1066 if (name_type
== WBC_SID_NAME_USER
) {
1070 wbc_status
= wbcCtxSidToUid(ctx
, sid
, &uid
);
1071 BAIL_ON_WBC_ERROR(wbc_status
);
1073 wbc_status
= wbcCtxGetpwuid(ctx
, uid
, &pwd
);
1074 BAIL_ON_WBC_ERROR(wbc_status
);
1076 wbcFreeMemory(name
);
1078 name
= wbcStrDup(pwd
->pw_gecos
);
1080 BAIL_ON_PTR_ERROR(name
, wbc_status
);
1083 wbc_status
= WBC_ERR_SUCCESS
;
1086 if (WBC_ERROR_IS_OK(wbc_status
)) {
1089 *pname_type
= name_type
;
1091 wbcFreeMemory(domain
);
1092 wbcFreeMemory(name
);
1099 wbcErr
wbcGetDisplayName(const struct wbcDomainSid
*sid
,
1102 enum wbcSidType
*pname_type
)
1104 return wbcCtxGetDisplayName(NULL
, sid
, pdomain
, pfullname
, pname_type
);
1108 const char* wbcSidTypeString(enum wbcSidType type
)
1111 case WBC_SID_NAME_USE_NONE
: return "SID_NONE";
1112 case WBC_SID_NAME_USER
: return "SID_USER";
1113 case WBC_SID_NAME_DOM_GRP
: return "SID_DOM_GROUP";
1114 case WBC_SID_NAME_DOMAIN
: return "SID_DOMAIN";
1115 case WBC_SID_NAME_ALIAS
: return "SID_ALIAS";
1116 case WBC_SID_NAME_WKN_GRP
: return "SID_WKN_GROUP";
1117 case WBC_SID_NAME_DELETED
: return "SID_DELETED";
1118 case WBC_SID_NAME_INVALID
: return "SID_INVALID";
1119 case WBC_SID_NAME_UNKNOWN
: return "SID_UNKNOWN";
1120 case WBC_SID_NAME_COMPUTER
: return "SID_COMPUTER";
1121 case WBC_SID_NAME_LABEL
: return "SID_LABEL";
1122 default: return "Unknown type";