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"
30 /* Convert a sid to a string into a buffer. Return the string
31 * length. If buflen is too small, return the string length that would
32 * result if it was long enough. */
33 int wbcSidToStringBuf(const struct wbcDomainSid
*sid
, char *buf
, int buflen
)
39 strlcpy(buf
, "(NULL SID)", buflen
);
40 return 10; /* strlen("(NULL SID)") */
43 id_auth
= (uint64_t)sid
->id_auth
[5] +
44 ((uint64_t)sid
->id_auth
[4] << 8) +
45 ((uint64_t)sid
->id_auth
[3] << 16) +
46 ((uint64_t)sid
->id_auth
[2] << 24) +
47 ((uint64_t)sid
->id_auth
[1] << 32) +
48 ((uint64_t)sid
->id_auth
[0] << 40);
50 ofs
= snprintf(buf
, buflen
, "S-%hhu-", (unsigned char)sid
->sid_rev_num
);
51 if (id_auth
>= UINT32_MAX
) {
52 ofs
+= snprintf(buf
+ ofs
, MAX(buflen
- ofs
, 0), "0x%llx",
53 (unsigned long long)id_auth
);
55 ofs
+= snprintf(buf
+ ofs
, MAX(buflen
- ofs
, 0), "%llu",
56 (unsigned long long)id_auth
);
59 for (i
= 0; i
< sid
->num_auths
; i
++) {
60 ofs
+= snprintf(buf
+ ofs
, MAX(buflen
- ofs
, 0), "-%u",
61 (unsigned int)sid
->sub_auths
[i
]);
66 /* Convert a binary SID to a character string */
67 wbcErr
wbcSidToString(const struct wbcDomainSid
*sid
,
70 char buf
[WBC_SID_STRING_BUFLEN
];
75 return WBC_ERR_INVALID_SID
;
78 len
= wbcSidToStringBuf(sid
, buf
, sizeof(buf
));
80 if (len
+1 > sizeof(buf
)) {
81 return WBC_ERR_INVALID_SID
;
84 result
= (char *)wbcAllocateMemory(len
+1, 1, NULL
);
86 return WBC_ERR_NO_MEMORY
;
88 memcpy(result
, buf
, len
+1);
91 return WBC_ERR_SUCCESS
;
94 #define AUTHORITY_MASK (~(0xffffffffffffULL))
96 /* Convert a character string to a binary SID */
97 wbcErr
wbcStringToSid(const char *str
,
98 struct wbcDomainSid
*sid
)
103 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
106 wbc_status
= WBC_ERR_INVALID_PARAM
;
107 BAIL_ON_WBC_ERROR(wbc_status
);
110 /* Sanity check for either "S-" or "s-" */
113 || (str
[0]!='S' && str
[0]!='s')
116 wbc_status
= WBC_ERR_INVALID_PARAM
;
117 BAIL_ON_WBC_ERROR(wbc_status
);
120 /* Get the SID revision number */
123 x
= (uint64_t)strtoul(p
, &q
, 10);
124 if (x
==0 || x
> UINT8_MAX
|| !q
|| *q
!='-') {
125 wbc_status
= WBC_ERR_INVALID_SID
;
126 BAIL_ON_WBC_ERROR(wbc_status
);
128 sid
->sid_rev_num
= (uint8_t)x
;
131 * Next the Identifier Authority. This is stored big-endian in a
132 * 6 byte array. If the authority value is >= UINT_MAX, then it should
133 * be expressed as a hex value, according to MS-DTYP.
136 x
= strtoull(p
, &q
, 0);
137 if (!q
|| *q
!='-' || (x
& AUTHORITY_MASK
)) {
138 wbc_status
= WBC_ERR_INVALID_SID
;
139 BAIL_ON_WBC_ERROR(wbc_status
);
141 sid
->id_auth
[5] = (x
& 0x0000000000ffULL
);
142 sid
->id_auth
[4] = (x
& 0x00000000ff00ULL
) >> 8;
143 sid
->id_auth
[3] = (x
& 0x000000ff0000ULL
) >> 16;
144 sid
->id_auth
[2] = (x
& 0x0000ff000000ULL
) >> 24;
145 sid
->id_auth
[1] = (x
& 0x00ff00000000ULL
) >> 32;
146 sid
->id_auth
[0] = (x
& 0xff0000000000ULL
) >> 40;
148 /* now read the the subauthorities */
151 while (sid
->num_auths
< WBC_MAXSUBAUTHS
) {
152 x
= strtoull(p
, &q
, 10);
155 if (x
> UINT32_MAX
) {
156 wbc_status
= WBC_ERR_INVALID_SID
;
157 BAIL_ON_WBC_ERROR(wbc_status
);
159 sid
->sub_auths
[sid
->num_auths
++] = x
;
167 /* IF we ended early, then the SID could not be converted */
170 wbc_status
= WBC_ERR_INVALID_SID
;
171 BAIL_ON_WBC_ERROR(wbc_status
);
174 wbc_status
= WBC_ERR_SUCCESS
;
182 /* Convert a domain and name to SID */
183 wbcErr
wbcLookupName(const char *domain
,
185 struct wbcDomainSid
*sid
,
186 enum wbcSidType
*name_type
)
188 struct winbindd_request request
;
189 struct winbindd_response response
;
190 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
192 if (!sid
|| !name_type
) {
193 wbc_status
= WBC_ERR_INVALID_PARAM
;
194 BAIL_ON_WBC_ERROR(wbc_status
);
197 /* Initialize request */
199 ZERO_STRUCT(request
);
200 ZERO_STRUCT(response
);
202 /* dst is already null terminated from the memset above */
204 strncpy(request
.data
.name
.dom_name
, domain
,
205 sizeof(request
.data
.name
.dom_name
)-1);
206 strncpy(request
.data
.name
.name
, name
,
207 sizeof(request
.data
.name
.name
)-1);
209 wbc_status
= wbcRequestResponse(WINBINDD_LOOKUPNAME
,
212 BAIL_ON_WBC_ERROR(wbc_status
);
214 wbc_status
= wbcStringToSid(response
.data
.sid
.sid
, sid
);
215 BAIL_ON_WBC_ERROR(wbc_status
);
217 *name_type
= (enum wbcSidType
)response
.data
.sid
.type
;
219 wbc_status
= WBC_ERR_SUCCESS
;
226 /* Convert a SID to a domain and name */
227 wbcErr
wbcLookupSid(const struct wbcDomainSid
*sid
,
230 enum wbcSidType
*pname_type
)
232 struct winbindd_request request
;
233 struct winbindd_response response
;
234 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
238 return WBC_ERR_INVALID_PARAM
;
241 /* Initialize request */
243 ZERO_STRUCT(request
);
244 ZERO_STRUCT(response
);
246 wbcSidToStringBuf(sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
250 wbc_status
= wbcRequestResponse(WINBINDD_LOOKUPSID
, &request
,
252 if (!WBC_ERROR_IS_OK(wbc_status
)) {
256 /* Copy out result */
258 wbc_status
= WBC_ERR_NO_MEMORY
;
262 domain
= wbcStrDup(response
.data
.name
.dom_name
);
263 if (domain
== NULL
) {
266 name
= wbcStrDup(response
.data
.name
.name
);
270 if (pdomain
!= NULL
) {
278 if (pname_type
!= NULL
) {
279 *pname_type
= (enum wbcSidType
)response
.data
.name
.type
;
281 wbc_status
= WBC_ERR_SUCCESS
;
284 wbcFreeMemory(domain
);
288 static void wbcDomainInfosDestructor(void *ptr
)
290 struct wbcDomainInfo
*i
= (struct wbcDomainInfo
*)ptr
;
292 while (i
->short_name
!= NULL
) {
293 wbcFreeMemory(i
->short_name
);
294 wbcFreeMemory(i
->dns_name
);
299 static void wbcTranslatedNamesDestructor(void *ptr
)
301 struct wbcTranslatedName
*n
= (struct wbcTranslatedName
*)ptr
;
303 while (n
->name
!= NULL
) {
304 wbcFreeMemory(n
->name
);
309 wbcErr
wbcLookupSids(const struct wbcDomainSid
*sids
, int num_sids
,
310 struct wbcDomainInfo
**pdomains
, int *pnum_domains
,
311 struct wbcTranslatedName
**pnames
)
313 struct winbindd_request request
;
314 struct winbindd_response response
;
315 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
316 int buflen
, i
, extra_len
, num_domains
, num_names
;
317 char *sidlist
, *p
, *q
, *extra_data
;
318 struct wbcDomainInfo
*domains
= NULL
;
319 struct wbcTranslatedName
*names
= NULL
;
321 buflen
= num_sids
* (WBC_SID_STRING_BUFLEN
+ 1) + 1;
323 sidlist
= (char *)malloc(buflen
);
324 if (sidlist
== NULL
) {
325 return WBC_ERR_NO_MEMORY
;
330 for (i
=0; i
<num_sids
; i
++) {
334 remaining
= buflen
- (p
- sidlist
);
336 len
= wbcSidToStringBuf(&sids
[i
], p
, remaining
);
337 if (len
> remaining
) {
339 return WBC_ERR_UNKNOWN_FAILURE
;
347 ZERO_STRUCT(request
);
348 ZERO_STRUCT(response
);
350 request
.extra_data
.data
= sidlist
;
351 request
.extra_len
= p
- sidlist
;
353 wbc_status
= wbcRequestResponse(WINBINDD_LOOKUPSIDS
,
354 &request
, &response
);
356 if (!WBC_ERROR_IS_OK(wbc_status
)) {
360 extra_len
= response
.length
- sizeof(struct winbindd_response
);
361 extra_data
= (char *)response
.extra_data
.data
;
363 if ((extra_len
<= 0) || (extra_data
[extra_len
-1] != '\0')) {
364 goto wbc_err_invalid
;
369 num_domains
= strtoul(p
, &q
, 10);
371 goto wbc_err_invalid
;
375 domains
= (struct wbcDomainInfo
*)wbcAllocateMemory(
376 num_domains
+1, sizeof(struct wbcDomainInfo
),
377 wbcDomainInfosDestructor
);
378 if (domains
== NULL
) {
379 wbc_status
= WBC_ERR_NO_MEMORY
;
383 for (i
=0; i
<num_domains
; i
++) {
387 goto wbc_err_invalid
;
390 wbc_status
= wbcStringToSid(p
, &domains
[i
].sid
);
391 if (!WBC_ERROR_IS_OK(wbc_status
)) {
398 goto wbc_err_invalid
;
401 domains
[i
].short_name
= wbcStrDup(p
);
402 if (domains
[i
].short_name
== NULL
) {
403 wbc_status
= WBC_ERR_NO_MEMORY
;
409 num_names
= strtoul(p
, &q
, 10);
411 goto wbc_err_invalid
;
415 if (num_names
!= num_sids
) {
416 goto wbc_err_invalid
;
419 names
= (struct wbcTranslatedName
*)wbcAllocateMemory(
420 num_names
+1, sizeof(struct wbcTranslatedName
),
421 wbcTranslatedNamesDestructor
);
423 wbc_status
= WBC_ERR_NO_MEMORY
;
427 for (i
=0; i
<num_names
; i
++) {
429 names
[i
].domain_index
= strtoul(p
, &q
, 10);
430 if (names
[i
].domain_index
< 0) {
431 goto wbc_err_invalid
;
433 if (names
[i
].domain_index
>= num_domains
) {
434 goto wbc_err_invalid
;
438 goto wbc_err_invalid
;
442 names
[i
].type
= strtoul(p
, &q
, 10);
444 goto wbc_err_invalid
;
450 goto wbc_err_invalid
;
453 names
[i
].name
= wbcStrDup(p
);
454 if (names
[i
].name
== NULL
) {
455 wbc_status
= WBC_ERR_NO_MEMORY
;
461 goto wbc_err_invalid
;
466 winbindd_free_response(&response
);
467 return WBC_ERR_SUCCESS
;
470 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
472 winbindd_free_response(&response
);
473 wbcFreeMemory(domains
);
474 wbcFreeMemory(names
);
478 /* Translate a collection of RIDs within a domain to names */
480 wbcErr
wbcLookupRids(struct wbcDomainSid
*dom_sid
,
483 const char **pp_domain_name
,
484 const char ***pnames
,
485 enum wbcSidType
**ptypes
)
487 size_t i
, len
, ridbuf_size
;
490 struct winbindd_request request
;
491 struct winbindd_response response
;
492 char *domain_name
= NULL
;
493 const char **names
= NULL
;
494 enum wbcSidType
*types
= NULL
;
495 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
497 /* Initialise request */
499 ZERO_STRUCT(request
);
500 ZERO_STRUCT(response
);
502 if (!dom_sid
|| (num_rids
== 0)) {
503 wbc_status
= WBC_ERR_INVALID_PARAM
;
504 BAIL_ON_WBC_ERROR(wbc_status
);
507 wbcSidToStringBuf(dom_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
509 /* Even if all the Rids were of maximum 32bit values,
510 we would only have 11 bytes per rid in the final array
511 ("4294967296" + \n). Add one more byte for the
514 ridbuf_size
= (sizeof(char)*11) * num_rids
+ 1;
516 ridlist
= (char *)malloc(ridbuf_size
);
517 BAIL_ON_PTR_ERROR(ridlist
, wbc_status
);
520 for (i
=0; i
<num_rids
; i
++) {
521 len
+= snprintf(ridlist
+ len
, ridbuf_size
- len
, "%u\n",
527 request
.extra_data
.data
= ridlist
;
528 request
.extra_len
= len
;
530 wbc_status
= wbcRequestResponse(WINBINDD_LOOKUPRIDS
,
534 BAIL_ON_WBC_ERROR(wbc_status
);
536 domain_name
= wbcStrDup(response
.data
.domain_name
);
537 BAIL_ON_PTR_ERROR(domain_name
, wbc_status
);
539 names
= wbcAllocateStringArray(num_rids
);
540 BAIL_ON_PTR_ERROR(names
, wbc_status
);
542 types
= (enum wbcSidType
*)wbcAllocateMemory(
543 num_rids
, sizeof(enum wbcSidType
), NULL
);
544 BAIL_ON_PTR_ERROR(types
, wbc_status
);
546 p
= (char *)response
.extra_data
.data
;
548 for (i
=0; i
<num_rids
; i
++) {
552 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
556 types
[i
] = (enum wbcSidType
)strtoul(p
, &q
, 10);
559 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
565 if ((q
= strchr(p
, '\n')) == NULL
) {
566 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
572 names
[i
] = strdup(p
);
573 BAIL_ON_PTR_ERROR(names
[i
], wbc_status
);
579 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
583 wbc_status
= WBC_ERR_SUCCESS
;
586 winbindd_free_response(&response
);
588 if (WBC_ERROR_IS_OK(wbc_status
)) {
589 *pp_domain_name
= domain_name
;
594 wbcFreeMemory(domain_name
);
595 wbcFreeMemory(names
);
596 wbcFreeMemory(types
);
602 /* Get the groups a user belongs to */
603 wbcErr
wbcLookupUserSids(const struct wbcDomainSid
*user_sid
,
604 bool domain_groups_only
,
606 struct wbcDomainSid
**_sids
)
610 struct winbindd_request request
;
611 struct winbindd_response response
;
612 struct wbcDomainSid
*sids
= NULL
;
613 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
616 /* Initialise request */
618 ZERO_STRUCT(request
);
619 ZERO_STRUCT(response
);
622 wbc_status
= WBC_ERR_INVALID_PARAM
;
623 BAIL_ON_WBC_ERROR(wbc_status
);
626 wbcSidToStringBuf(user_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
628 if (domain_groups_only
) {
629 cmd
= WINBINDD_GETUSERDOMGROUPS
;
631 cmd
= WINBINDD_GETUSERSIDS
;
634 wbc_status
= wbcRequestResponse(cmd
,
637 BAIL_ON_WBC_ERROR(wbc_status
);
639 if (response
.data
.num_entries
&&
640 !response
.extra_data
.data
) {
641 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
642 BAIL_ON_WBC_ERROR(wbc_status
);
645 sids
= (struct wbcDomainSid
*)wbcAllocateMemory(
646 response
.data
.num_entries
, sizeof(struct wbcDomainSid
),
648 BAIL_ON_PTR_ERROR(sids
, wbc_status
);
650 s
= (const char *)response
.extra_data
.data
;
651 for (i
= 0; i
< response
.data
.num_entries
; i
++) {
652 char *n
= strchr(s
, '\n');
656 wbc_status
= wbcStringToSid(s
, &sids
[i
]);
657 BAIL_ON_WBC_ERROR(wbc_status
);
661 *num_sids
= response
.data
.num_entries
;
664 wbc_status
= WBC_ERR_SUCCESS
;
667 winbindd_free_response(&response
);
676 wbcErr
_sid_to_rid(struct wbcDomainSid
*sid
, uint32_t *rid
)
678 if (sid
->num_auths
< 1) {
679 return WBC_ERR_INVALID_RESPONSE
;
681 *rid
= sid
->sub_auths
[sid
->num_auths
- 1];
683 return WBC_ERR_SUCCESS
;
686 /* Get alias membership for sids */
687 wbcErr
wbcGetSidAliases(const struct wbcDomainSid
*dom_sid
,
688 struct wbcDomainSid
*sids
,
690 uint32_t **alias_rids
,
691 uint32_t *num_alias_rids
)
695 struct winbindd_request request
;
696 struct winbindd_response response
;
697 ssize_t extra_data_len
= 0;
698 char * extra_data
= NULL
;
700 struct wbcDomainSid sid
;
701 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
702 uint32_t * rids
= NULL
;
704 /* Initialise request */
706 ZERO_STRUCT(request
);
707 ZERO_STRUCT(response
);
710 wbc_status
= WBC_ERR_INVALID_PARAM
;
714 wbcSidToStringBuf(dom_sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
716 /* Lets assume each sid is around 57 characters
717 * S-1-5-21-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */
718 buflen
= 57 * num_sids
;
719 extra_data
= (char *)malloc(buflen
);
721 wbc_status
= WBC_ERR_NO_MEMORY
;
725 /* Build the sid list */
726 for (i
=0; i
<num_sids
; i
++) {
727 char sid_str
[WBC_SID_STRING_BUFLEN
];
730 sid_len
= wbcSidToStringBuf(&sids
[i
], sid_str
, sizeof(sid_str
));
732 if (buflen
< extra_data_len
+ sid_len
+ 2) {
734 extra_data
= (char *)realloc(extra_data
, buflen
);
736 wbc_status
= WBC_ERR_NO_MEMORY
;
737 BAIL_ON_WBC_ERROR(wbc_status
);
741 strncpy(&extra_data
[extra_data_len
], sid_str
,
742 buflen
- extra_data_len
);
743 extra_data_len
+= sid_len
;
744 extra_data
[extra_data_len
++] = '\n';
745 extra_data
[extra_data_len
] = '\0';
749 request
.extra_data
.data
= extra_data
;
750 request
.extra_len
= extra_data_len
;
752 wbc_status
= wbcRequestResponse(WINBINDD_GETSIDALIASES
,
755 BAIL_ON_WBC_ERROR(wbc_status
);
757 if (response
.data
.num_entries
&&
758 !response
.extra_data
.data
) {
759 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
763 rids
= (uint32_t *)wbcAllocateMemory(response
.data
.num_entries
,
764 sizeof(uint32_t), NULL
);
765 BAIL_ON_PTR_ERROR(sids
, wbc_status
);
767 s
= (const char *)response
.extra_data
.data
;
768 for (i
= 0; i
< response
.data
.num_entries
; i
++) {
769 char *n
= strchr(s
, '\n');
773 wbc_status
= wbcStringToSid(s
, &sid
);
774 BAIL_ON_WBC_ERROR(wbc_status
);
775 wbc_status
= _sid_to_rid(&sid
, &rids
[i
]);
776 BAIL_ON_WBC_ERROR(wbc_status
);
780 *num_alias_rids
= response
.data
.num_entries
;
783 wbc_status
= WBC_ERR_SUCCESS
;
787 winbindd_free_response(&response
);
794 wbcErr
wbcListUsers(const char *domain_name
,
795 uint32_t *_num_users
,
796 const char ***_users
)
798 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
799 struct winbindd_request request
;
800 struct winbindd_response response
;
801 uint32_t num_users
= 0;
802 const char **users
= NULL
;
805 /* Initialise request */
807 ZERO_STRUCT(request
);
808 ZERO_STRUCT(response
);
811 strncpy(request
.domain_name
, domain_name
,
812 sizeof(request
.domain_name
)-1);
815 wbc_status
= wbcRequestResponse(WINBINDD_LIST_USERS
,
818 BAIL_ON_WBC_ERROR(wbc_status
);
820 users
= wbcAllocateStringArray(response
.data
.num_entries
);
822 return WBC_ERR_NO_MEMORY
;
825 /* Look through extra data */
827 next
= (const char *)response
.extra_data
.data
;
832 if (num_users
>= response
.data
.num_entries
) {
833 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
838 k
= strchr(next
, ',');
847 users
[num_users
] = strdup(current
);
848 BAIL_ON_PTR_ERROR(users
[num_users
], wbc_status
);
851 if (num_users
!= response
.data
.num_entries
) {
852 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
856 *_num_users
= response
.data
.num_entries
;
859 wbc_status
= WBC_ERR_SUCCESS
;
862 winbindd_free_response(&response
);
863 wbcFreeMemory(users
);
868 wbcErr
wbcListGroups(const char *domain_name
,
869 uint32_t *_num_groups
,
870 const char ***_groups
)
872 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
873 struct winbindd_request request
;
874 struct winbindd_response response
;
875 uint32_t num_groups
= 0;
876 const char **groups
= NULL
;
879 /* Initialise request */
881 ZERO_STRUCT(request
);
882 ZERO_STRUCT(response
);
885 strncpy(request
.domain_name
, domain_name
,
886 sizeof(request
.domain_name
)-1);
889 wbc_status
= wbcRequestResponse(WINBINDD_LIST_GROUPS
,
892 BAIL_ON_WBC_ERROR(wbc_status
);
894 groups
= wbcAllocateStringArray(response
.data
.num_entries
);
895 if (groups
== NULL
) {
896 return WBC_ERR_NO_MEMORY
;
899 /* Look through extra data */
901 next
= (const char *)response
.extra_data
.data
;
906 if (num_groups
>= response
.data
.num_entries
) {
907 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
912 k
= strchr(next
, ',');
921 groups
[num_groups
] = strdup(current
);
922 BAIL_ON_PTR_ERROR(groups
[num_groups
], wbc_status
);
925 if (num_groups
!= response
.data
.num_entries
) {
926 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
930 *_num_groups
= response
.data
.num_entries
;
933 wbc_status
= WBC_ERR_SUCCESS
;
936 winbindd_free_response(&response
);
937 wbcFreeMemory(groups
);
941 wbcErr
wbcGetDisplayName(const struct wbcDomainSid
*sid
,
944 enum wbcSidType
*pname_type
)
949 enum wbcSidType name_type
;
951 wbc_status
= wbcLookupSid(sid
, &domain
, &name
, &name_type
);
952 BAIL_ON_WBC_ERROR(wbc_status
);
954 if (name_type
== WBC_SID_NAME_USER
) {
958 wbc_status
= wbcSidToUid(sid
, &uid
);
959 BAIL_ON_WBC_ERROR(wbc_status
);
961 wbc_status
= wbcGetpwuid(uid
, &pwd
);
962 BAIL_ON_WBC_ERROR(wbc_status
);
966 name
= wbcStrDup(pwd
->pw_gecos
);
968 BAIL_ON_PTR_ERROR(name
, wbc_status
);
971 wbc_status
= WBC_ERR_SUCCESS
;
974 if (WBC_ERROR_IS_OK(wbc_status
)) {
977 *pname_type
= name_type
;
979 wbcFreeMemory(domain
);
986 const char* wbcSidTypeString(enum wbcSidType type
)
989 case WBC_SID_NAME_USE_NONE
: return "SID_NONE";
990 case WBC_SID_NAME_USER
: return "SID_USER";
991 case WBC_SID_NAME_DOM_GRP
: return "SID_DOM_GROUP";
992 case WBC_SID_NAME_DOMAIN
: return "SID_DOMAIN";
993 case WBC_SID_NAME_ALIAS
: return "SID_ALIAS";
994 case WBC_SID_NAME_WKN_GRP
: return "SID_WKN_GROUP";
995 case WBC_SID_NAME_DELETED
: return "SID_DELETED";
996 case WBC_SID_NAME_INVALID
: return "SID_INVALID";
997 case WBC_SID_NAME_UNKNOWN
: return "SID_UNKNOWN";
998 case WBC_SID_NAME_COMPUTER
: return "SID_COMPUTER";
999 default: return "Unknown type";