build: Check for functions needed by Samba3
[Samba/gebeck_regimport.git] / nsswitch / libwbclient / wbc_idmap_async.c
blobdcf59cbb583577087f181b32f348f50479dec351
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind client API
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 */
24 #include "replace.h"
25 #include "libwbclient.h"
26 #include "wbc_async.h"
28 struct wbc_sid_to_uid_state {
29 struct winbindd_request req;
30 uid_t uid;
33 static void wbcSidToUid_done(struct tevent_req *subreq);
35 /**
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;
53 char *sid_string;
54 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
56 req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_uid_state);
57 if (req == NULL) {
58 return NULL;
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);
77 return 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;
87 wbcErr wbc_status;
89 wbc_status = wb_trans_recv(subreq, state, &resp);
90 TALLOC_FREE(subreq);
91 if (!WBC_ERROR_IS_OK(wbc_status)) {
92 tevent_req_error(req, wbc_status);
93 return;
95 state->uid = resp->data.uid;
96 TALLOC_FREE(resp);
98 tevent_req_done(req);
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
107 * @return #wbcErr
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);
114 wbcErr wbc_status;
116 if (tevent_req_is_wbcerr(req, &wbc_status)) {
117 tevent_req_received(req);
118 return wbc_status;
121 *puid = state->uid;
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,
149 uid_t uid)
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);
155 if (req == NULL) {
156 return NULL;
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);
170 return 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;
180 wbcErr wbc_status;
182 wbc_status = wb_trans_recv(subreq, state, &resp);
183 TALLOC_FREE(subreq);
184 if (!WBC_ERROR_IS_OK(wbc_status)) {
185 tevent_req_error(req, wbc_status);
186 return;
189 state->sid = talloc(state, struct wbcDomainSid);
190 if (state->sid == NULL) {
191 TALLOC_FREE(resp);
192 tevent_req_error(req, WBC_ERR_NO_MEMORY);
193 return;
196 wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
197 TALLOC_FREE(resp);
199 if (!WBC_ERROR_IS_OK(wbc_status)) {
200 tevent_req_error(req, wbc_status);
201 return;
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
213 * @return #wbcErr
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);
220 wbcErr wbc_status;
222 if (psid == NULL) {
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);
229 return wbc_status;
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;
241 gid_t gid;
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;
265 char *sid_string;
266 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
268 req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_gid_state);
269 if (req == NULL) {
270 return NULL;
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);
289 return 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;
299 wbcErr wbc_status;
301 wbc_status = wb_trans_recv(subreq, state, &resp);
302 TALLOC_FREE(subreq);
303 if (!WBC_ERROR_IS_OK(wbc_status)) {
304 tevent_req_error(req, wbc_status);
305 return;
307 state->gid = resp->data.gid;
308 TALLOC_FREE(resp);
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
319 * @return #wbcErr
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);
326 wbcErr wbc_status;
328 if (tevent_req_is_wbcerr(req, &wbc_status)) {
329 tevent_req_received(req);
330 return wbc_status;
333 *pgid = state->gid;
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,
361 gid_t gid)
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);
367 if (req == NULL) {
368 return NULL;
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);
382 return 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;
392 wbcErr wbc_status;
394 wbc_status = wb_trans_recv(subreq, state, &resp);
395 TALLOC_FREE(subreq);
396 if (!WBC_ERROR_IS_OK(wbc_status)) {
397 tevent_req_error(req, wbc_status);
398 return;
401 state->sid = talloc(state, struct wbcDomainSid);
402 if (state->sid == NULL) {
403 TALLOC_FREE(resp);
404 tevent_req_error(req, WBC_ERR_NO_MEMORY);
405 return;
408 wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
409 TALLOC_FREE(resp);
411 if (!WBC_ERROR_IS_OK(wbc_status)) {
412 tevent_req_error(req, wbc_status);
413 return;
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
425 * @return #wbcErr
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);
432 wbcErr wbc_status;
434 if (psid == NULL) {
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);
441 return wbc_status;
444 memcpy(psid, state->sid, sizeof(struct wbcDomainSid));
446 tevent_req_received(req);
447 return WBC_ERR_SUCCESS;