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;