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 *name_type
= (enum wbcSidType
)response
.data
.sid
.type
;
222 if (*name_type
== WBC_SID_NAME_UNKNOWN
) {
223 return WBC_ERR_NOT_MAPPED
;
226 wbc_status
= wbcStringToSid(response
.data
.sid
.sid
, sid
);
227 BAIL_ON_WBC_ERROR(wbc_status
);
229 wbc_status
= WBC_ERR_SUCCESS
;
236 wbcErr
wbcLookupName(const char *domain
,
238 struct wbcDomainSid
*sid
,
239 enum wbcSidType
*name_type
)
241 return wbcCtxLookupName(NULL
, domain
, name
, sid
, name_type
);
245 /* Convert a SID to a domain and name */
247 wbcErr
wbcCtxLookupSid(struct wbcContext
*ctx
,
248 const struct wbcDomainSid
*sid
,
251 enum wbcSidType
*pname_type
)
253 struct winbindd_request request
;
254 struct winbindd_response response
;
255 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
259 return WBC_ERR_INVALID_PARAM
;
262 /* Initialize request */
264 ZERO_STRUCT(request
);
265 ZERO_STRUCT(response
);
267 wbcSidToStringBuf(sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
271 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LOOKUPSID
,
274 if (!WBC_ERROR_IS_OK(wbc_status
)) {
278 /* Copy out result */
280 wbc_status
= WBC_ERR_NO_MEMORY
;
284 domain
= wbcStrDup(response
.data
.name
.dom_name
);
285 if (domain
== NULL
) {
288 name
= wbcStrDup(response
.data
.name
.name
);
292 if (pdomain
!= NULL
) {
300 if (pname_type
!= NULL
) {
301 *pname_type
= (enum wbcSidType
)response
.data
.name
.type
;
303 wbc_status
= WBC_ERR_SUCCESS
;
306 wbcFreeMemory(domain
);
311 wbcErr
wbcLookupSid(const struct wbcDomainSid
*sid
,
314 enum wbcSidType
*pname_type
)
316 return wbcCtxLookupSid(NULL
, sid
, pdomain
, pname
, pname_type
);
319 static void wbcDomainInfosDestructor(void *ptr
)
321 struct wbcDomainInfo
*i
= (struct wbcDomainInfo
*)ptr
;
323 while (i
->short_name
!= NULL
) {
324 wbcFreeMemory(i
->short_name
);
325 wbcFreeMemory(i
->dns_name
);
330 static void wbcTranslatedNamesDestructor(void *ptr
)
332 struct wbcTranslatedName
*n
= (struct wbcTranslatedName
*)ptr
;
334 while (n
->name
!= NULL
) {
335 wbcFreeMemory(n
->name
);
341 wbcErr
wbcCtxLookupSids(struct wbcContext
*ctx
,
342 const struct wbcDomainSid
*sids
, int num_sids
,
343 struct wbcDomainInfo
**pdomains
, int *pnum_domains
,
344 struct wbcTranslatedName
**pnames
)
346 struct winbindd_request request
;
347 struct winbindd_response response
;
348 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
349 int buflen
, i
, extra_len
, num_domains
, num_names
;
350 char *sidlist
, *p
, *q
, *extra_data
;
351 struct wbcDomainInfo
*domains
= NULL
;
352 struct wbcTranslatedName
*names
= NULL
;
355 buflen
= num_sids
* (WBC_SID_STRING_BUFLEN
+ 1) + 1;
357 sidlist
= (char *)malloc(buflen
);
358 if (sidlist
== NULL
) {
359 return WBC_ERR_NO_MEMORY
;
364 for (i
=0; i
<num_sids
; i
++) {
368 remaining
= buflen
- (p
- sidlist
);
370 len
= wbcSidToStringBuf(&sids
[i
], p
, remaining
);
371 if (len
> remaining
) {
373 return WBC_ERR_UNKNOWN_FAILURE
;
381 ZERO_STRUCT(request
);
382 ZERO_STRUCT(response
);
384 request
.extra_data
.data
= sidlist
;
385 request
.extra_len
= p
- sidlist
;
387 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LOOKUPSIDS
,
388 &request
, &response
);
390 if (!WBC_ERROR_IS_OK(wbc_status
)) {
394 extra_len
= response
.length
- sizeof(struct winbindd_response
);
395 extra_data
= (char *)response
.extra_data
.data
;
397 if ((extra_len
<= 0) || (extra_data
[extra_len
-1] != '\0')) {
398 goto wbc_err_invalid
;
403 num_domains
= smb_strtoul(p
, &q
, 10, &error
, SMB_STR_STANDARD
);
404 if (*q
!= '\n' || error
!= 0) {
405 goto wbc_err_invalid
;
409 domains
= (struct wbcDomainInfo
*)wbcAllocateMemory(
410 num_domains
+1, sizeof(struct wbcDomainInfo
),
411 wbcDomainInfosDestructor
);
412 if (domains
== NULL
) {
413 wbc_status
= WBC_ERR_NO_MEMORY
;
417 for (i
=0; i
<num_domains
; i
++) {
421 goto wbc_err_invalid
;
424 wbc_status
= wbcStringToSid(p
, &domains
[i
].sid
);
425 if (!WBC_ERROR_IS_OK(wbc_status
)) {
432 goto wbc_err_invalid
;
435 domains
[i
].short_name
= wbcStrDup(p
);
436 if (domains
[i
].short_name
== NULL
) {
437 wbc_status
= WBC_ERR_NO_MEMORY
;
443 num_names
= smb_strtoul(p
, &q
, 10, &error
, SMB_STR_STANDARD
);
444 if (*q
!= '\n' || error
!= 0) {
445 goto wbc_err_invalid
;
449 if (num_names
!= num_sids
) {
450 goto wbc_err_invalid
;
453 names
= (struct wbcTranslatedName
*)wbcAllocateMemory(
454 num_names
+1, sizeof(struct wbcTranslatedName
),
455 wbcTranslatedNamesDestructor
);
457 wbc_status
= WBC_ERR_NO_MEMORY
;
461 for (i
=0; i
<num_names
; i
++) {
463 names
[i
].domain_index
= smb_strtoul(p
,
468 if (names
[i
].domain_index
< 0 || error
!= 0) {
469 goto wbc_err_invalid
;
471 if (names
[i
].domain_index
>= num_domains
) {
472 goto wbc_err_invalid
;
476 goto wbc_err_invalid
;
480 names
[i
].type
= smb_strtoul(p
, &q
, 10, &error
, SMB_STR_STANDARD
);
481 if (*q
!= ' ' || error
!= 0) {
482 goto wbc_err_invalid
;
488 goto wbc_err_invalid
;
491 names
[i
].name
= wbcStrDup(p
);
492 if (names
[i
].name
== NULL
) {
493 wbc_status
= WBC_ERR_NO_MEMORY
;
499 goto wbc_err_invalid
;
504 winbindd_free_response(&response
);
505 return WBC_ERR_SUCCESS
;
508 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
510 winbindd_free_response(&response
);
511 wbcFreeMemory(domains
);
512 wbcFreeMemory(names
);
517 wbcErr
wbcLookupSids(const struct wbcDomainSid
*sids
, int num_sids
,
518 struct wbcDomainInfo
**pdomains
, int *pnum_domains
,
519 struct wbcTranslatedName
**pnames
)
521 return wbcCtxLookupSids(NULL
, sids
, num_sids
, pdomains
,
522 pnum_domains
, pnames
);
525 /* Translate a collection of RIDs within a domain to names */
528 wbcErr
wbcCtxLookupRids(struct wbcContext
*ctx
, struct wbcDomainSid
*dom_sid
,
531 const char **pp_domain_name
,
532 const char ***pnames
,
533 enum wbcSidType
**ptypes
)
536 size_t len
, ridbuf_size
;
540 struct winbindd_request request
;
541 struct winbindd_response response
;
542 char *domain_name
= NULL
;
543 const char **names
= NULL
;
544 enum wbcSidType
*types
= NULL
;
545 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
547 /* Initialise request */
549 ZERO_STRUCT(request
);
550 ZERO_STRUCT(response
);
552 if (!dom_sid
|| (num_rids
== 0)) {
553 wbc_status
= WBC_ERR_INVALID_PARAM
;
554 BAIL_ON_WBC_ERROR(wbc_status
);
557 wbcSidToStringBuf(dom_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
559 /* Even if all the Rids were of maximum 32bit values,
560 we would only have 11 bytes per rid in the final array
561 ("4294967296" + \n). Add one more byte for the
564 ridbuf_size
= (sizeof(char)*11) * num_rids
+ 1;
566 ridlist
= (char *)malloc(ridbuf_size
);
567 BAIL_ON_PTR_ERROR(ridlist
, wbc_status
);
570 for (i
=0; i
<num_rids
; i
++) {
571 len
+= snprintf(ridlist
+ len
, ridbuf_size
- len
, "%u\n",
577 request
.extra_data
.data
= ridlist
;
578 request
.extra_len
= len
;
580 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LOOKUPRIDS
,
584 BAIL_ON_WBC_ERROR(wbc_status
);
586 domain_name
= wbcStrDup(response
.data
.domain_name
);
587 BAIL_ON_PTR_ERROR(domain_name
, wbc_status
);
589 names
= wbcAllocateStringArray(num_rids
);
590 BAIL_ON_PTR_ERROR(names
, wbc_status
);
592 types
= (enum wbcSidType
*)wbcAllocateMemory(
593 num_rids
, sizeof(enum wbcSidType
), NULL
);
594 BAIL_ON_PTR_ERROR(types
, wbc_status
);
596 p
= (char *)response
.extra_data
.data
;
598 for (i
=0; i
<num_rids
; i
++) {
602 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
606 types
[i
] = (enum wbcSidType
)smb_strtoul(p
,
612 if (*q
!= ' ' || error
!= 0) {
613 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
619 if ((q
= strchr(p
, '\n')) == NULL
) {
620 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
626 names
[i
] = strdup(p
);
627 BAIL_ON_PTR_ERROR(names
[i
], wbc_status
);
633 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
637 wbc_status
= WBC_ERR_SUCCESS
;
640 winbindd_free_response(&response
);
642 if (WBC_ERROR_IS_OK(wbc_status
)) {
643 *pp_domain_name
= domain_name
;
648 wbcFreeMemory(domain_name
);
649 wbcFreeMemory(names
);
650 wbcFreeMemory(types
);
657 wbcErr
wbcLookupRids(struct wbcDomainSid
*dom_sid
,
660 const char **pp_domain_name
,
661 const char ***pnames
,
662 enum wbcSidType
**ptypes
)
664 return wbcCtxLookupRids(NULL
, dom_sid
, num_rids
, rids
,
665 pp_domain_name
, pnames
, ptypes
);
668 /* Get the groups a user belongs to */
670 wbcErr
wbcCtxLookupUserSids(struct wbcContext
*ctx
,
671 const struct wbcDomainSid
*user_sid
,
672 bool domain_groups_only
,
674 struct wbcDomainSid
**_sids
)
678 struct winbindd_request request
;
679 struct winbindd_response response
;
680 struct wbcDomainSid
*sids
= NULL
;
681 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
684 /* Initialise request */
686 ZERO_STRUCT(request
);
687 ZERO_STRUCT(response
);
690 wbc_status
= WBC_ERR_INVALID_PARAM
;
691 BAIL_ON_WBC_ERROR(wbc_status
);
694 wbcSidToStringBuf(user_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
696 if (domain_groups_only
) {
697 cmd
= WINBINDD_GETUSERDOMGROUPS
;
699 cmd
= WINBINDD_GETUSERSIDS
;
702 wbc_status
= wbcRequestResponse(ctx
, cmd
,
705 BAIL_ON_WBC_ERROR(wbc_status
);
707 if (response
.data
.num_entries
&&
708 !response
.extra_data
.data
) {
709 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
710 BAIL_ON_WBC_ERROR(wbc_status
);
713 sids
= (struct wbcDomainSid
*)wbcAllocateMemory(
714 response
.data
.num_entries
, sizeof(struct wbcDomainSid
),
716 BAIL_ON_PTR_ERROR(sids
, wbc_status
);
718 s
= (const char *)response
.extra_data
.data
;
719 for (i
= 0; i
< response
.data
.num_entries
; i
++) {
720 char *n
= strchr(s
, '\n');
724 wbc_status
= wbcStringToSid(s
, &sids
[i
]);
725 BAIL_ON_WBC_ERROR(wbc_status
);
729 *num_sids
= response
.data
.num_entries
;
732 wbc_status
= WBC_ERR_SUCCESS
;
735 winbindd_free_response(&response
);
744 wbcErr
wbcLookupUserSids(const struct wbcDomainSid
*user_sid
,
745 bool domain_groups_only
,
747 struct wbcDomainSid
**_sids
)
749 return wbcCtxLookupUserSids(NULL
, user_sid
, domain_groups_only
,
754 wbcErr
_sid_to_rid(struct wbcDomainSid
*sid
, uint32_t *rid
)
756 if (sid
->num_auths
< 1) {
757 return WBC_ERR_INVALID_RESPONSE
;
759 *rid
= sid
->sub_auths
[sid
->num_auths
- 1];
761 return WBC_ERR_SUCCESS
;
764 /* Get alias membership for sids */
766 wbcErr
wbcCtxGetSidAliases(struct wbcContext
*ctx
,
767 const struct wbcDomainSid
*dom_sid
,
768 struct wbcDomainSid
*sids
,
770 uint32_t **alias_rids
,
771 uint32_t *num_alias_rids
)
775 struct winbindd_request request
;
776 struct winbindd_response response
;
777 ssize_t extra_data_len
= 0;
778 char * extra_data
= NULL
;
780 struct wbcDomainSid sid
;
781 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
782 uint32_t * rids
= NULL
;
784 /* Initialise request */
786 ZERO_STRUCT(request
);
787 ZERO_STRUCT(response
);
790 wbc_status
= WBC_ERR_INVALID_PARAM
;
794 wbcSidToStringBuf(dom_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
796 /* Lets assume each sid is around 57 characters
797 * S-1-5-21-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
798 buflen
= 57 * num_sids
;
799 extra_data
= (char *)malloc(buflen
);
801 wbc_status
= WBC_ERR_NO_MEMORY
;
805 /* Build the sid list */
806 for (i
=0; i
<num_sids
; i
++) {
807 char sid_str
[WBC_SID_STRING_BUFLEN
];
810 sid_len
= wbcSidToStringBuf(&sids
[i
], sid_str
, sizeof(sid_str
));
812 if (buflen
< extra_data_len
+ sid_len
+ 2) {
813 char * tmp_data
= NULL
;
815 tmp_data
= (char *)realloc(extra_data
, buflen
);
817 wbc_status
= WBC_ERR_NO_MEMORY
;
818 BAIL_ON_WBC_ERROR(wbc_status
);
820 extra_data
= tmp_data
;
823 strncpy(&extra_data
[extra_data_len
], sid_str
,
824 buflen
- extra_data_len
);
825 extra_data_len
+= sid_len
;
826 extra_data
[extra_data_len
++] = '\n';
827 extra_data
[extra_data_len
] = '\0';
831 request
.extra_data
.data
= extra_data
;
832 request
.extra_len
= extra_data_len
;
834 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_GETSIDALIASES
,
837 BAIL_ON_WBC_ERROR(wbc_status
);
839 if (response
.data
.num_entries
&&
840 !response
.extra_data
.data
) {
841 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
845 rids
= (uint32_t *)wbcAllocateMemory(response
.data
.num_entries
,
846 sizeof(uint32_t), NULL
);
847 BAIL_ON_PTR_ERROR(rids
, wbc_status
);
849 s
= (const char *)response
.extra_data
.data
;
850 for (i
= 0; i
< response
.data
.num_entries
; i
++) {
851 char *n
= strchr(s
, '\n');
855 wbc_status
= wbcStringToSid(s
, &sid
);
856 BAIL_ON_WBC_ERROR(wbc_status
);
857 wbc_status
= _sid_to_rid(&sid
, &rids
[i
]);
858 BAIL_ON_WBC_ERROR(wbc_status
);
862 *num_alias_rids
= response
.data
.num_entries
;
865 wbc_status
= WBC_ERR_SUCCESS
;
869 winbindd_free_response(&response
);
875 wbcErr
wbcGetSidAliases(const struct wbcDomainSid
*dom_sid
,
876 struct wbcDomainSid
*sids
,
878 uint32_t **alias_rids
,
879 uint32_t *num_alias_rids
)
881 return wbcCtxGetSidAliases(NULL
, dom_sid
, sids
, num_sids
,
882 alias_rids
, num_alias_rids
);
888 wbcErr
wbcCtxListUsers(struct wbcContext
*ctx
,
889 const char *domain_name
,
890 uint32_t *_num_users
,
891 const char ***_users
)
893 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
894 struct winbindd_request request
;
895 struct winbindd_response response
;
896 uint32_t num_users
= 0;
897 const char **users
= NULL
;
900 /* Initialise request */
902 ZERO_STRUCT(request
);
903 ZERO_STRUCT(response
);
906 strncpy(request
.domain_name
, domain_name
,
907 sizeof(request
.domain_name
)-1);
910 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LIST_USERS
,
913 BAIL_ON_WBC_ERROR(wbc_status
);
915 users
= wbcAllocateStringArray(response
.data
.num_entries
);
917 return WBC_ERR_NO_MEMORY
;
920 /* Look through extra data */
922 next
= (const char *)response
.extra_data
.data
;
927 if (num_users
>= response
.data
.num_entries
) {
928 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
933 k
= strchr(next
, ',');
942 users
[num_users
] = strdup(current
);
943 BAIL_ON_PTR_ERROR(users
[num_users
], wbc_status
);
946 if (num_users
!= response
.data
.num_entries
) {
947 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
951 *_num_users
= response
.data
.num_entries
;
954 wbc_status
= WBC_ERR_SUCCESS
;
957 winbindd_free_response(&response
);
958 wbcFreeMemory(users
);
963 wbcErr
wbcListUsers(const char *domain_name
,
964 uint32_t *_num_users
,
965 const char ***_users
)
967 return wbcCtxListUsers(NULL
, domain_name
, _num_users
, _users
);
972 wbcErr
wbcCtxListGroups(struct wbcContext
*ctx
,
973 const char *domain_name
,
974 uint32_t *_num_groups
,
975 const char ***_groups
)
977 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
978 struct winbindd_request request
;
979 struct winbindd_response response
;
980 uint32_t num_groups
= 0;
981 const char **groups
= NULL
;
984 /* Initialise request */
986 ZERO_STRUCT(request
);
987 ZERO_STRUCT(response
);
990 strncpy(request
.domain_name
, domain_name
,
991 sizeof(request
.domain_name
)-1);
994 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_LIST_GROUPS
,
997 BAIL_ON_WBC_ERROR(wbc_status
);
999 groups
= wbcAllocateStringArray(response
.data
.num_entries
);
1000 if (groups
== NULL
) {
1001 return WBC_ERR_NO_MEMORY
;
1004 /* Look through extra data */
1006 next
= (const char *)response
.extra_data
.data
;
1008 const char *current
;
1011 if (num_groups
>= response
.data
.num_entries
) {
1012 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
1017 k
= strchr(next
, ',');
1026 groups
[num_groups
] = strdup(current
);
1027 BAIL_ON_PTR_ERROR(groups
[num_groups
], wbc_status
);
1030 if (num_groups
!= response
.data
.num_entries
) {
1031 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
1035 *_num_groups
= response
.data
.num_entries
;
1038 wbc_status
= WBC_ERR_SUCCESS
;
1041 winbindd_free_response(&response
);
1042 wbcFreeMemory(groups
);
1047 wbcErr
wbcListGroups(const char *domain_name
,
1048 uint32_t *_num_groups
,
1049 const char ***_groups
)
1051 return wbcCtxListGroups(NULL
, domain_name
, _num_groups
, _groups
);
1055 wbcErr
wbcCtxGetDisplayName(struct wbcContext
*ctx
,
1056 const struct wbcDomainSid
*sid
,
1059 enum wbcSidType
*pname_type
)
1062 char *domain
= NULL
;
1064 enum wbcSidType name_type
;
1066 wbc_status
= wbcCtxLookupSid(ctx
, sid
, &domain
, &name
, &name_type
);
1067 BAIL_ON_WBC_ERROR(wbc_status
);
1069 if (name_type
== WBC_SID_NAME_USER
) {
1073 wbc_status
= wbcCtxSidToUid(ctx
, sid
, &uid
);
1074 BAIL_ON_WBC_ERROR(wbc_status
);
1076 wbc_status
= wbcCtxGetpwuid(ctx
, uid
, &pwd
);
1077 BAIL_ON_WBC_ERROR(wbc_status
);
1079 wbcFreeMemory(name
);
1081 name
= wbcStrDup(pwd
->pw_gecos
);
1083 BAIL_ON_PTR_ERROR(name
, wbc_status
);
1086 wbc_status
= WBC_ERR_SUCCESS
;
1089 if (WBC_ERROR_IS_OK(wbc_status
)) {
1092 *pname_type
= name_type
;
1094 wbcFreeMemory(domain
);
1095 wbcFreeMemory(name
);
1102 wbcErr
wbcGetDisplayName(const struct wbcDomainSid
*sid
,
1105 enum wbcSidType
*pname_type
)
1107 return wbcCtxGetDisplayName(NULL
, sid
, pdomain
, pfullname
, pname_type
);
1111 const char* wbcSidTypeString(enum wbcSidType type
)
1114 case WBC_SID_NAME_USE_NONE
: return "SID_NONE";
1115 case WBC_SID_NAME_USER
: return "SID_USER";
1116 case WBC_SID_NAME_DOM_GRP
: return "SID_DOM_GROUP";
1117 case WBC_SID_NAME_DOMAIN
: return "SID_DOMAIN";
1118 case WBC_SID_NAME_ALIAS
: return "SID_ALIAS";
1119 case WBC_SID_NAME_WKN_GRP
: return "SID_WKN_GROUP";
1120 case WBC_SID_NAME_DELETED
: return "SID_DELETED";
1121 case WBC_SID_NAME_INVALID
: return "SID_INVALID";
1122 case WBC_SID_NAME_UNKNOWN
: return "SID_UNKNOWN";
1123 case WBC_SID_NAME_COMPUTER
: return "SID_COMPUTER";
1124 case WBC_SID_NAME_LABEL
: return "SID_LABEL";
1125 default: return "Unknown type";