2 Unix SMB/CIFS implementation.
6 Copyright (C) Gerald (Jerry) Carter 2007
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 3 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* Required Headers */
25 #include "libwbclient.h"
26 #include "../winbind_client.h"
28 /* Convert a Windows SID to a Unix uid, allocating an uid if needed */
29 wbcErr
wbcCtxSidToUid(struct wbcContext
*ctx
, const struct wbcDomainSid
*sid
,
32 struct winbindd_request request
;
33 struct winbindd_response response
;
34 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
37 wbc_status
= WBC_ERR_INVALID_PARAM
;
38 BAIL_ON_WBC_ERROR(wbc_status
);
41 /* Initialize request */
44 ZERO_STRUCT(response
);
46 wbcSidToStringBuf(sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
50 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_SID_TO_UID
,
53 BAIL_ON_WBC_ERROR(wbc_status
);
55 *puid
= response
.data
.uid
;
57 wbc_status
= WBC_ERR_SUCCESS
;
63 wbcErr
wbcSidToUid(const struct wbcDomainSid
*sid
, uid_t
*puid
)
65 return wbcCtxSidToUid(NULL
, sid
, puid
);
68 /* Convert a Windows SID to a Unix uid if there already is a mapping */
69 wbcErr
wbcQuerySidToUid(const struct wbcDomainSid
*sid
,
72 return WBC_ERR_NOT_IMPLEMENTED
;
75 /* Convert a Unix uid to a Windows SID, allocating a SID if needed */
76 wbcErr
wbcCtxUidToSid(struct wbcContext
*ctx
, uid_t uid
,
77 struct wbcDomainSid
*sid
)
79 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
80 struct winbindd_request request
;
81 struct winbindd_response response
;
84 wbc_status
= WBC_ERR_INVALID_PARAM
;
85 BAIL_ON_WBC_ERROR(wbc_status
);
88 /* Initialize request */
91 ZERO_STRUCT(response
);
93 request
.data
.uid
= uid
;
97 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_UID_TO_SID
,
100 BAIL_ON_WBC_ERROR(wbc_status
);
102 wbc_status
= wbcStringToSid(response
.data
.sid
.sid
, sid
);
103 BAIL_ON_WBC_ERROR(wbc_status
);
109 wbcErr
wbcUidToSid(uid_t uid
, struct wbcDomainSid
*sid
)
111 return wbcCtxUidToSid(NULL
, uid
, sid
);
114 /* Convert a Unix uid to a Windows SID if there already is a mapping */
115 wbcErr
wbcQueryUidToSid(uid_t uid
,
116 struct wbcDomainSid
*sid
)
118 return WBC_ERR_NOT_IMPLEMENTED
;
121 /** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
123 * @param *sid Pointer to the domain SID to be resolved
124 * @param *pgid Pointer to the resolved gid_t value
130 wbcErr
wbcCtxSidToGid(struct wbcContext
*ctx
, const struct wbcDomainSid
*sid
,
133 struct winbindd_request request
;
134 struct winbindd_response response
;
135 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
138 wbc_status
= WBC_ERR_INVALID_PARAM
;
139 BAIL_ON_WBC_ERROR(wbc_status
);
142 /* Initialize request */
144 ZERO_STRUCT(request
);
145 ZERO_STRUCT(response
);
147 wbcSidToStringBuf(sid
, request
.data
.sid
, sizeof(request
.data
.sid
));
151 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_SID_TO_GID
,
154 BAIL_ON_WBC_ERROR(wbc_status
);
156 *pgid
= response
.data
.gid
;
158 wbc_status
= WBC_ERR_SUCCESS
;
164 wbcErr
wbcSidToGid(const struct wbcDomainSid
*sid
, gid_t
*pgid
)
166 return wbcCtxSidToGid(NULL
, sid
, pgid
);
169 /* Convert a Windows SID to a Unix gid if there already is a mapping */
171 wbcErr
wbcQuerySidToGid(const struct wbcDomainSid
*sid
,
174 return WBC_ERR_NOT_IMPLEMENTED
;
178 /* Convert a Unix gid to a Windows SID, allocating a SID if needed */
179 wbcErr
wbcCtxGidToSid(struct wbcContext
*ctx
, gid_t gid
,
180 struct wbcDomainSid
*sid
)
182 struct winbindd_request request
;
183 struct winbindd_response response
;
184 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
187 wbc_status
= WBC_ERR_INVALID_PARAM
;
188 BAIL_ON_WBC_ERROR(wbc_status
);
191 /* Initialize request */
193 ZERO_STRUCT(request
);
194 ZERO_STRUCT(response
);
196 request
.data
.gid
= gid
;
200 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_GID_TO_SID
,
203 BAIL_ON_WBC_ERROR(wbc_status
);
205 wbc_status
= wbcStringToSid(response
.data
.sid
.sid
, sid
);
206 BAIL_ON_WBC_ERROR(wbc_status
);
212 wbcErr
wbcGidToSid(gid_t gid
, struct wbcDomainSid
*sid
)
214 return wbcCtxGidToSid(NULL
, gid
, sid
);
217 /* Convert a Unix gid to a Windows SID if there already is a mapping */
218 wbcErr
wbcQueryGidToSid(gid_t gid
,
219 struct wbcDomainSid
*sid
)
221 return WBC_ERR_NOT_IMPLEMENTED
;
224 /* Obtain a new uid from Winbind */
225 wbcErr
wbcCtxAllocateUid(struct wbcContext
*ctx
, uid_t
*puid
)
227 struct winbindd_request request
;
228 struct winbindd_response response
;
229 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
232 return WBC_ERR_INVALID_PARAM
;
234 /* Initialise request */
236 ZERO_STRUCT(request
);
237 ZERO_STRUCT(response
);
241 wbc_status
= wbcRequestResponsePriv(ctx
, WINBINDD_ALLOCATE_UID
,
242 &request
, &response
);
243 BAIL_ON_WBC_ERROR(wbc_status
);
245 /* Copy out result */
246 *puid
= response
.data
.uid
;
248 wbc_status
= WBC_ERR_SUCCESS
;
254 wbcErr
wbcAllocateUid(uid_t
*puid
)
256 return wbcCtxAllocateUid(NULL
, puid
);
259 /* Obtain a new gid from Winbind */
260 wbcErr
wbcCtxAllocateGid(struct wbcContext
*ctx
, gid_t
*pgid
)
262 struct winbindd_request request
;
263 struct winbindd_response response
;
264 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
267 return WBC_ERR_INVALID_PARAM
;
269 /* Initialise request */
271 ZERO_STRUCT(request
);
272 ZERO_STRUCT(response
);
276 wbc_status
= wbcRequestResponsePriv(ctx
, WINBINDD_ALLOCATE_GID
,
277 &request
, &response
);
278 BAIL_ON_WBC_ERROR(wbc_status
);
280 /* Copy out result */
281 *pgid
= response
.data
.gid
;
283 wbc_status
= WBC_ERR_SUCCESS
;
289 wbcErr
wbcAllocateGid(gid_t
*pgid
)
291 return wbcCtxAllocateGid(NULL
, pgid
);
294 /* we can't include smb.h here... */
295 #define _ID_TYPE_UID 1
296 #define _ID_TYPE_GID 2
298 /* Set an user id mapping - not implemented any more */
299 wbcErr
wbcSetUidMapping(uid_t uid
, const struct wbcDomainSid
*sid
)
301 return WBC_ERR_NOT_IMPLEMENTED
;
304 /* Set a group id mapping - not implemented any more */
305 wbcErr
wbcSetGidMapping(gid_t gid
, const struct wbcDomainSid
*sid
)
307 return WBC_ERR_NOT_IMPLEMENTED
;
310 /* Remove a user id mapping - not implemented any more */
311 wbcErr
wbcRemoveUidMapping(uid_t uid
, const struct wbcDomainSid
*sid
)
313 return WBC_ERR_NOT_IMPLEMENTED
;
316 /* Remove a group id mapping - not implemented any more */
317 wbcErr
wbcRemoveGidMapping(gid_t gid
, const struct wbcDomainSid
*sid
)
319 return WBC_ERR_NOT_IMPLEMENTED
;
322 /* Set the highwater mark for allocated uids - not implemented any more */
323 wbcErr
wbcSetUidHwm(uid_t uid_hwm
)
325 return WBC_ERR_NOT_IMPLEMENTED
;
328 /* Set the highwater mark for allocated gids - not implemented any more */
329 wbcErr
wbcSetGidHwm(gid_t gid_hwm
)
331 return WBC_ERR_NOT_IMPLEMENTED
;
334 /* Convert a list of SIDs */
335 wbcErr
wbcCtxSidsToUnixIds(struct wbcContext
*ctx
,
336 const struct wbcDomainSid
*sids
,
337 uint32_t num_sids
, struct wbcUnixId
*ids
)
339 struct winbindd_request request
;
340 struct winbindd_response response
;
341 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
342 int buflen
, extra_len
;
344 char *sidlist
, *p
, *extra_data
;
346 buflen
= num_sids
* (WBC_SID_STRING_BUFLEN
+ 1) + 1;
348 sidlist
= (char *)malloc(buflen
);
349 if (sidlist
== NULL
) {
350 return WBC_ERR_NO_MEMORY
;
355 for (i
=0; i
<num_sids
; i
++) {
359 remaining
= buflen
- (p
- sidlist
);
361 len
= wbcSidToStringBuf(&sids
[i
], p
, remaining
);
362 if (len
> remaining
) {
364 return WBC_ERR_UNKNOWN_FAILURE
;
372 ZERO_STRUCT(request
);
373 ZERO_STRUCT(response
);
375 request
.extra_data
.data
= sidlist
;
376 request
.extra_len
= p
- sidlist
;
378 wbc_status
= wbcRequestResponse(ctx
, WINBINDD_SIDS_TO_XIDS
,
379 &request
, &response
);
381 if (!WBC_ERROR_IS_OK(wbc_status
)) {
385 extra_len
= response
.length
- sizeof(struct winbindd_response
);
386 extra_data
= (char *)response
.extra_data
.data
;
388 if ((extra_len
<= 0) || (extra_data
[extra_len
-1] != '\0')) {
389 goto wbc_err_invalid
;
394 for (i
=0; i
<num_sids
; i
++) {
395 struct wbcUnixId
*id
= &ids
[i
];
400 id
->type
= WBC_ID_TYPE_UID
;
401 id
->id
.uid
= strtoul(p
+1, &q
, 10);
404 id
->type
= WBC_ID_TYPE_GID
;
405 id
->id
.gid
= strtoul(p
+1, &q
, 10);
408 id
->type
= WBC_ID_TYPE_BOTH
;
409 id
->id
.uid
= strtoul(p
+1, &q
, 10);
412 id
->type
= WBC_ID_TYPE_NOT_SPECIFIED
;
416 if (q
== NULL
|| q
[0] != '\n') {
417 goto wbc_err_invalid
;
421 wbc_status
= WBC_ERR_SUCCESS
;
425 wbc_status
= WBC_ERR_INVALID_RESPONSE
;
427 winbindd_free_response(&response
);
431 wbcErr
wbcSidsToUnixIds(const struct wbcDomainSid
*sids
, uint32_t num_sids
,
432 struct wbcUnixId
*ids
)
434 return wbcCtxSidsToUnixIds(NULL
, sids
, num_sids
, ids
);