2 Unix SMB/CIFS implementation.
6 Copyright (C) 2009,2010 Kai Blin <kai@samba.org>
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 "wbc_async.h"
28 struct wbc_sid_to_uid_state
{
29 struct winbindd_request req
;
33 static void wbcSidToUid_done(struct tevent_req
*subreq
);
36 * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed
38 * @param mem_ctx talloc context to allocate the request from
39 * @param ev tevent context to use for async operation
40 * @param wb_ctx winbind context to use
41 * @param *sid pointer to the domain SID to be resolved
43 * @return tevent_req on success, NULL on error
46 struct tevent_req
*wbcSidToUid_send(TALLOC_CTX
*mem_ctx
,
47 struct tevent_context
*ev
,
48 struct wb_context
*wb_ctx
,
49 const struct wbcDomainSid
*sid
)
51 struct tevent_req
*req
, *subreq
;
52 struct wbc_sid_to_uid_state
*state
;
54 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
56 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_sid_to_uid_state
);
61 ZERO_STRUCT(state
->req
);
63 state
->req
.cmd
= WINBINDD_SID_TO_UID
;
64 wbc_status
= wbcSidToString(sid
, &sid_string
);
65 if (!WBC_ERROR_IS_OK(wbc_status
)) {
66 return tevent_req_post(req
, ev
);
68 strncpy(state
->req
.data
.sid
, sid_string
, sizeof(state
->req
.data
.sid
)-1);
69 wbcFreeMemory(sid_string
);
71 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
72 if (tevent_req_nomem(subreq
, req
)) {
73 return tevent_req_post(req
, ev
);
76 tevent_req_set_callback(subreq
, wbcSidToUid_done
, req
);
80 static void wbcSidToUid_done(struct tevent_req
*subreq
)
82 struct tevent_req
*req
= tevent_req_callback_data(
83 subreq
, struct tevent_req
);
84 struct wbc_sid_to_uid_state
*state
= tevent_req_data(
85 req
, struct wbc_sid_to_uid_state
);
86 struct winbindd_response
*resp
;
89 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
91 if (!WBC_ERROR_IS_OK(wbc_status
)) {
92 tevent_req_error(req
, wbc_status
);
95 state
->uid
= resp
->data
.uid
;
102 * @brief Receive a Unix uid mapped to a Windows SID
104 * @param req tevent_req containing the request
105 * @param *puid pointer to hold the resolved uid_t value
110 wbcErr
wbcSidToUid_recv(struct tevent_req
*req
, uid_t
*puid
)
112 struct wbc_sid_to_uid_state
*state
= tevent_req_data(
113 req
, struct wbc_sid_to_uid_state
);
116 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
117 tevent_req_received(req
);
123 tevent_req_received(req
);
124 return WBC_ERR_SUCCESS
;
128 struct wbc_uid_to_sid_state
{
129 struct winbindd_request req
;
130 struct wbcDomainSid
*sid
;
133 static void wbcUidToSid_done(struct tevent_req
*subreq
);
136 * @brief Request a Windows SID for an Unix uid, allocating an SID if needed
138 * @param mem_ctx talloc context to allocate the request from
139 * @param ev tevent context to use for async operation
140 * @param wb_ctx winbind context to use
141 * @param uid uid to be resolved to a SID
143 * @return tevent_req on success, NULL on error
146 struct tevent_req
*wbcUidToSid_send(TALLOC_CTX
*mem_ctx
,
147 struct tevent_context
*ev
,
148 struct wb_context
*wb_ctx
,
151 struct tevent_req
*req
, *subreq
;
152 struct wbc_uid_to_sid_state
*state
;
154 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_uid_to_sid_state
);
159 ZERO_STRUCT(state
->req
);
161 state
->req
.cmd
= WINBINDD_UID_TO_SID
;
162 state
->req
.data
.uid
= uid
;
164 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
165 if (tevent_req_nomem(subreq
, req
)) {
166 return tevent_req_post(req
, ev
);
169 tevent_req_set_callback(subreq
, wbcUidToSid_done
, req
);
173 static void wbcUidToSid_done(struct tevent_req
*subreq
)
175 struct tevent_req
*req
= tevent_req_callback_data(
176 subreq
, struct tevent_req
);
177 struct wbc_uid_to_sid_state
*state
= tevent_req_data(
178 req
, struct wbc_uid_to_sid_state
);
179 struct winbindd_response
*resp
;
182 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
184 if (!WBC_ERROR_IS_OK(wbc_status
)) {
185 tevent_req_error(req
, wbc_status
);
189 state
->sid
= talloc(state
, struct wbcDomainSid
);
190 if (state
->sid
== NULL
) {
192 tevent_req_error(req
, WBC_ERR_NO_MEMORY
);
196 wbc_status
= wbcStringToSid(resp
->data
.sid
.sid
, state
->sid
);
199 if (!WBC_ERROR_IS_OK(wbc_status
)) {
200 tevent_req_error(req
, wbc_status
);
204 tevent_req_done(req
);
208 * @brief Receive a Unix uid mapped to a Windows SID
210 * @param req tevent_req containing the request
211 * @param *psid pointer to hold the resolved SID
216 wbcErr
wbcUidToSid_recv(struct tevent_req
*req
, struct wbcDomainSid
*psid
)
218 struct wbc_uid_to_sid_state
*state
= tevent_req_data(
219 req
, struct wbc_uid_to_sid_state
);
223 tevent_req_received(req
);
224 return WBC_ERR_INVALID_PARAM
;
227 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
228 tevent_req_received(req
);
232 memcpy(psid
, state
->sid
, sizeof(struct wbcDomainSid
));
234 tevent_req_received(req
);
235 return WBC_ERR_SUCCESS
;
239 struct wbc_sid_to_gid_state
{
240 struct winbindd_request req
;
244 static void wbcSidToGid_done(struct tevent_req
*subreq
);
247 * @brief Request to convert a Windows SID to a Unix gid,
248 * allocating a gid if needed
250 * @param mem_ctx talloc context to allocate the request from
251 * @param ev tevent context to use for async operation
252 * @param wb_ctx winbind context to use
253 * @param *sid pointer to the domain SID to be resolved
255 * @return tevent_req on success, NULL on error
258 struct tevent_req
*wbcSidToGid_send(TALLOC_CTX
*mem_ctx
,
259 struct tevent_context
*ev
,
260 struct wb_context
*wb_ctx
,
261 const struct wbcDomainSid
*sid
)
263 struct tevent_req
*req
, *subreq
;
264 struct wbc_sid_to_gid_state
*state
;
266 wbcErr wbc_status
= WBC_ERR_UNKNOWN_FAILURE
;
268 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_sid_to_gid_state
);
273 ZERO_STRUCT(state
->req
);
275 state
->req
.cmd
= WINBINDD_SID_TO_GID
;
276 wbc_status
= wbcSidToString(sid
, &sid_string
);
277 if (!WBC_ERROR_IS_OK(wbc_status
)) {
278 return tevent_req_post(req
, ev
);
280 strncpy(state
->req
.data
.sid
, sid_string
, sizeof(state
->req
.data
.sid
)-1);
281 wbcFreeMemory(sid_string
);
283 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
284 if (tevent_req_nomem(subreq
, req
)) {
285 return tevent_req_post(req
, ev
);
288 tevent_req_set_callback(subreq
, wbcSidToGid_done
, req
);
292 static void wbcSidToGid_done(struct tevent_req
*subreq
)
294 struct tevent_req
*req
= tevent_req_callback_data(
295 subreq
, struct tevent_req
);
296 struct wbc_sid_to_gid_state
*state
= tevent_req_data(
297 req
, struct wbc_sid_to_gid_state
);
298 struct winbindd_response
*resp
;
301 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
303 if (!WBC_ERROR_IS_OK(wbc_status
)) {
304 tevent_req_error(req
, wbc_status
);
307 state
->gid
= resp
->data
.gid
;
310 tevent_req_done(req
);
314 * @brief Receive a Unix gid mapped to a Windows SID
316 * @param req tevent_req containing the request
317 * @param *pgid pointer to hold the resolved gid_t value
322 wbcErr
wbcSidToGid_recv(struct tevent_req
*req
, gid_t
*pgid
)
324 struct wbc_sid_to_gid_state
*state
= tevent_req_data(
325 req
, struct wbc_sid_to_gid_state
);
328 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
329 tevent_req_received(req
);
335 tevent_req_received(req
);
336 return WBC_ERR_SUCCESS
;
340 struct wbc_gid_to_sid_state
{
341 struct winbindd_request req
;
342 struct wbcDomainSid
*sid
;
345 static void wbcGidToSid_done(struct tevent_req
*subreq
);
348 * @brief Request a Windows SID for an Unix Gid, allocating an SID if needed
350 * @param mem_ctx talloc context to allocate the request from
351 * @param ev tevent context to use for async operation
352 * @param wb_ctx winbind context to use
353 * @param gid gid to be resolved to a SID
355 * @return tevent_req on success, NULL on error
358 struct tevent_req
*wbcGidToSid_send(TALLOC_CTX
*mem_ctx
,
359 struct tevent_context
*ev
,
360 struct wb_context
*wb_ctx
,
363 struct tevent_req
*req
, *subreq
;
364 struct wbc_gid_to_sid_state
*state
;
366 req
= tevent_req_create(mem_ctx
, &state
, struct wbc_gid_to_sid_state
);
371 ZERO_STRUCT(state
->req
);
373 state
->req
.cmd
= WINBINDD_GID_TO_SID
;
374 state
->req
.data
.gid
= gid
;
376 subreq
= wb_trans_send(state
, ev
, wb_ctx
, false, &state
->req
);
377 if (tevent_req_nomem(subreq
, req
)) {
378 return tevent_req_post(req
, ev
);
381 tevent_req_set_callback(subreq
, wbcGidToSid_done
, req
);
385 static void wbcGidToSid_done(struct tevent_req
*subreq
)
387 struct tevent_req
*req
= tevent_req_callback_data(
388 subreq
, struct tevent_req
);
389 struct wbc_gid_to_sid_state
*state
= tevent_req_data(
390 req
, struct wbc_gid_to_sid_state
);
391 struct winbindd_response
*resp
;
394 wbc_status
= wb_trans_recv(subreq
, state
, &resp
);
396 if (!WBC_ERROR_IS_OK(wbc_status
)) {
397 tevent_req_error(req
, wbc_status
);
401 state
->sid
= talloc(state
, struct wbcDomainSid
);
402 if (state
->sid
== NULL
) {
404 tevent_req_error(req
, WBC_ERR_NO_MEMORY
);
408 wbc_status
= wbcStringToSid(resp
->data
.sid
.sid
, state
->sid
);
411 if (!WBC_ERROR_IS_OK(wbc_status
)) {
412 tevent_req_error(req
, wbc_status
);
416 tevent_req_done(req
);
420 * @brief Receive a Unix gid mapped to a Windows SID
422 * @param req tevent_req containing the request
423 * @param *psid pointer to hold the resolved SID
428 wbcErr
wbcGidToSid_recv(struct tevent_req
*req
, struct wbcDomainSid
*psid
)
430 struct wbc_gid_to_sid_state
*state
= tevent_req_data(
431 req
, struct wbc_gid_to_sid_state
);
435 tevent_req_received(req
);
436 return WBC_ERR_INVALID_PARAM
;
439 if (tevent_req_is_wbcerr(req
, &wbc_status
)) {
440 tevent_req_received(req
);
444 memcpy(psid
, state
->sid
, sizeof(struct wbcDomainSid
));
446 tevent_req_received(req
);
447 return WBC_ERR_SUCCESS
;