From b99d9f86e42fd5ffe660166b34d097eff25f18f8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Sat, 13 Feb 2010 13:42:56 +0100 Subject: libwbclient: Separate out the async functions --- nsswitch/libwbclient/wbc_idmap_async.c | 447 +++++++++++++++++++++++++++++++++ 1 file changed, 447 insertions(+) create mode 100644 nsswitch/libwbclient/wbc_idmap_async.c (limited to 'nsswitch/libwbclient/wbc_idmap_async.c') diff --git a/nsswitch/libwbclient/wbc_idmap_async.c b/nsswitch/libwbclient/wbc_idmap_async.c new file mode 100644 index 0000000000..4b84bb9ca5 --- /dev/null +++ b/nsswitch/libwbclient/wbc_idmap_async.c @@ -0,0 +1,447 @@ +/* + Unix SMB/CIFS implementation. + + Winbind client API + + Copyright (C) 2009,2010 Kai Blin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with this program. If not, see . +*/ + +/* Required Headers */ + +#include "replace.h" +#include "libwbclient.h" + +struct wbc_sid_to_uid_state { + struct winbindd_request req; + uid_t uid; +}; + +static void wbcSidToUid_done(struct tevent_req *subreq); + +/** + * @brief Convert a Windows SID to a Unix uid, allocating an uid if needed + * + * @param mem_ctx talloc context to allocate the request from + * @param ev tevent context to use for async operation + * @param wb_ctx winbind context to use + * @param *sid pointer to the domain SID to be resolved + * + * @return tevent_req on success, NULL on error + */ + +struct tevent_req *wbcSidToUid_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, + const struct wbcDomainSid *sid) +{ + struct tevent_req *req, *subreq; + struct wbc_sid_to_uid_state *state; + char *sid_string; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + + req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_uid_state); + if (req == NULL) { + return NULL; + } + + ZERO_STRUCT(state->req); + + state->req.cmd = WINBINDD_SID_TO_UID; + wbc_status = wbcSidToString(sid, &sid_string); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return tevent_req_post(req, ev); + } + strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1); + wbcFreeMemory(sid_string); + + subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + tevent_req_set_callback(subreq, wbcSidToUid_done, req); + return req; +} + +static void wbcSidToUid_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wbc_sid_to_uid_state *state = tevent_req_data( + req, struct wbc_sid_to_uid_state); + struct winbindd_response *resp; + wbcErr wbc_status; + + wbc_status = wb_trans_recv(subreq, state, &resp); + TALLOC_FREE(subreq); + if (!WBC_ERROR_IS_OK(wbc_status)) { + tevent_req_error(req, wbc_status); + return; + } + state->uid = resp->data.uid; + TALLOC_FREE(resp); + + tevent_req_done(req); +} + +/** + * @brief Receive a Unix uid mapped to a Windows SID + * + * @param req tevent_req containing the request + * @param *puid pointer to hold the resolved uid_t value + * + * @return #wbcErr + */ + +wbcErr wbcSidToUid_recv(struct tevent_req *req, uid_t *puid) +{ + struct wbc_sid_to_uid_state *state = tevent_req_data( + req, struct wbc_sid_to_uid_state); + wbcErr wbc_status; + + if (tevent_req_is_wbcerr(req, &wbc_status)) { + tevent_req_received(req); + return wbc_status; + } + + *puid = state->uid; + + tevent_req_received(req); + return WBC_ERR_SUCCESS; +} + + +struct wbc_uid_to_sid_state { + struct winbindd_request req; + struct wbcDomainSid *sid; +}; + +static void wbcUidToSid_done(struct tevent_req *subreq); + +/** + * @brief Request a Windows SID for an Unix uid, allocating an SID if needed + * + * @param mem_ctx talloc context to allocate the request from + * @param ev tevent context to use for async operation + * @param wb_ctx winbind context to use + * @param uid uid to be resolved to a SID + * + * @return tevent_req on success, NULL on error + */ + +struct tevent_req *wbcUidToSid_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, + uid_t uid) +{ + struct tevent_req *req, *subreq; + struct wbc_uid_to_sid_state *state; + + req = tevent_req_create(mem_ctx, &state, struct wbc_uid_to_sid_state); + if (req == NULL) { + return NULL; + } + + ZERO_STRUCT(state->req); + + state->req.cmd = WINBINDD_UID_TO_SID; + state->req.data.uid = uid; + + subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + tevent_req_set_callback(subreq, wbcUidToSid_done, req); + return req; +} + +static void wbcUidToSid_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wbc_uid_to_sid_state *state = tevent_req_data( + req, struct wbc_uid_to_sid_state); + struct winbindd_response *resp; + wbcErr wbc_status; + + wbc_status = wb_trans_recv(subreq, state, &resp); + TALLOC_FREE(subreq); + if (!WBC_ERROR_IS_OK(wbc_status)) { + tevent_req_error(req, wbc_status); + return; + } + + state->sid = talloc(state, struct wbcDomainSid); + if (state->sid == NULL) { + TALLOC_FREE(resp); + tevent_req_error(req, WBC_ERR_NO_MEMORY); + return; + } + + wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid); + TALLOC_FREE(resp); + + if (!WBC_ERROR_IS_OK(wbc_status)) { + tevent_req_error(req, wbc_status); + return; + } + + tevent_req_done(req); +} + +/** + * @brief Receive a Unix uid mapped to a Windows SID + * + * @param req tevent_req containing the request + * @param *psid pointer to hold the resolved SID + * + * @return #wbcErr + */ + +wbcErr wbcUidToSid_recv(struct tevent_req *req, struct wbcDomainSid *psid) +{ + struct wbc_uid_to_sid_state *state = tevent_req_data( + req, struct wbc_uid_to_sid_state); + wbcErr wbc_status; + + if (psid == NULL) { + tevent_req_received(req); + return WBC_ERR_INVALID_PARAM; + } + + if (tevent_req_is_wbcerr(req, &wbc_status)) { + tevent_req_received(req); + return wbc_status; + } + + memcpy(psid, state->sid, sizeof(struct wbcDomainSid)); + + tevent_req_received(req); + return WBC_ERR_SUCCESS; +} + + +struct wbc_sid_to_gid_state { + struct winbindd_request req; + gid_t gid; +}; + +static void wbcSidToGid_done(struct tevent_req *subreq); + +/** + * @brief Request to convert a Windows SID to a Unix gid, + * allocating a gid if needed + * + * @param mem_ctx talloc context to allocate the request from + * @param ev tevent context to use for async operation + * @param wb_ctx winbind context to use + * @param *sid pointer to the domain SID to be resolved + * + * @return tevent_req on success, NULL on error + */ + +struct tevent_req *wbcSidToGid_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, + const struct wbcDomainSid *sid) +{ + struct tevent_req *req, *subreq; + struct wbc_sid_to_gid_state *state; + char *sid_string; + wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; + + req = tevent_req_create(mem_ctx, &state, struct wbc_sid_to_gid_state); + if (req == NULL) { + return NULL; + } + + ZERO_STRUCT(state->req); + + state->req.cmd = WINBINDD_SID_TO_GID; + wbc_status = wbcSidToString(sid, &sid_string); + if (!WBC_ERROR_IS_OK(wbc_status)) { + return tevent_req_post(req, ev); + } + strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1); + wbcFreeMemory(sid_string); + + subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + tevent_req_set_callback(subreq, wbcSidToGid_done, req); + return req; +} + +static void wbcSidToGid_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wbc_sid_to_gid_state *state = tevent_req_data( + req, struct wbc_sid_to_gid_state); + struct winbindd_response *resp; + wbcErr wbc_status; + + wbc_status = wb_trans_recv(subreq, state, &resp); + TALLOC_FREE(subreq); + if (!WBC_ERROR_IS_OK(wbc_status)) { + tevent_req_error(req, wbc_status); + return; + } + state->gid = resp->data.gid; + TALLOC_FREE(resp); + + tevent_req_done(req); +} + +/** + * @brief Receive a Unix gid mapped to a Windows SID + * + * @param req tevent_req containing the request + * @param *pgid pointer to hold the resolved gid_t value + * + * @return #wbcErr + */ + +wbcErr wbcSidToGid_recv(struct tevent_req *req, gid_t *pgid) +{ + struct wbc_sid_to_gid_state *state = tevent_req_data( + req, struct wbc_sid_to_gid_state); + wbcErr wbc_status; + + if (tevent_req_is_wbcerr(req, &wbc_status)) { + tevent_req_received(req); + return wbc_status; + } + + *pgid = state->gid; + + tevent_req_received(req); + return WBC_ERR_SUCCESS; +} + + +struct wbc_gid_to_sid_state { + struct winbindd_request req; + struct wbcDomainSid *sid; +}; + +static void wbcGidToSid_done(struct tevent_req *subreq); + +/** + * @brief Request a Windows SID for an Unix Gid, allocating an SID if needed + * + * @param mem_ctx talloc context to allocate the request from + * @param ev tevent context to use for async operation + * @param wb_ctx winbind context to use + * @param gid gid to be resolved to a SID + * + * @return tevent_req on success, NULL on error + */ + +struct tevent_req *wbcGidToSid_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct wb_context *wb_ctx, + gid_t gid) +{ + struct tevent_req *req, *subreq; + struct wbc_gid_to_sid_state *state; + + req = tevent_req_create(mem_ctx, &state, struct wbc_gid_to_sid_state); + if (req == NULL) { + return NULL; + } + + ZERO_STRUCT(state->req); + + state->req.cmd = WINBINDD_GID_TO_SID; + state->req.data.gid = gid; + + subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + + tevent_req_set_callback(subreq, wbcGidToSid_done, req); + return req; +} + +static void wbcGidToSid_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct wbc_gid_to_sid_state *state = tevent_req_data( + req, struct wbc_gid_to_sid_state); + struct winbindd_response *resp; + wbcErr wbc_status; + + wbc_status = wb_trans_recv(subreq, state, &resp); + TALLOC_FREE(subreq); + if (!WBC_ERROR_IS_OK(wbc_status)) { + tevent_req_error(req, wbc_status); + return; + } + + state->sid = talloc(state, struct wbcDomainSid); + if (state->sid == NULL) { + TALLOC_FREE(resp); + tevent_req_error(req, WBC_ERR_NO_MEMORY); + return; + } + + wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid); + TALLOC_FREE(resp); + + if (!WBC_ERROR_IS_OK(wbc_status)) { + tevent_req_error(req, wbc_status); + return; + } + + tevent_req_done(req); +} + +/** + * @brief Receive a Unix gid mapped to a Windows SID + * + * @param req tevent_req containing the request + * @param *psid pointer to hold the resolved SID + * + * @return #wbcErr + */ + +wbcErr wbcGidToSid_recv(struct tevent_req *req, struct wbcDomainSid *psid) +{ + struct wbc_gid_to_sid_state *state = tevent_req_data( + req, struct wbc_gid_to_sid_state); + wbcErr wbc_status; + + if (psid == NULL) { + tevent_req_received(req); + return WBC_ERR_INVALID_PARAM; + } + + if (tevent_req_is_wbcerr(req, &wbc_status)) { + tevent_req_received(req); + return wbc_status; + } + + memcpy(psid, state->sid, sizeof(struct wbcDomainSid)); + + tevent_req_received(req); + return WBC_ERR_SUCCESS; +} -- cgit