libwbclient: Separate out the async functions
[Samba/kamenim.git] / nsswitch / libwbclient / wbc_sid_async.c
blob7e3bd75d82eb5fd979c4be245fb87bf07241b73b
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 "../winbind_client.h"
28 struct wbc_lookup_name_state {
29 struct winbindd_request req;
30 struct wb_context *wb_ctx;
31 struct wbcDomainSid *sid;
32 enum wbcSidType name_type;
35 static void wbcLookupName_done(struct tevent_req *subreq);
37 /**
38 * @brief Request a conversion of a domaind and name to a domain sid
40 * @param mem_ctx talloc context to allocate the request from
41 * @param ev tevent context to use for async operation
42 * @param wb_ctx winbind context to use
43 * @param *domain Pointer to the domain to be resolved
44 * @param *name Pointer to the name to be resolved
46 * @return tevent_req on success, NULL on error
47 **/
49 struct tevent_req *wbcLookupName_send(TALLOC_CTX *mem_ctx,
50 struct tevent_context *ev,
51 struct wb_context *wb_ctx,
52 const char *domain,
53 const char *name)
55 struct tevent_req *req, *subreq;
56 struct wbc_lookup_name_state *state;
58 req = tevent_req_create(mem_ctx, &state, struct wbc_lookup_name_state);
59 if (req == NULL) {
60 return NULL;
63 ZERO_STRUCT(state->req);
65 state->req.cmd = WINBINDD_LOOKUPNAME;
66 strncpy(state->req.data.name.dom_name, domain,
67 sizeof(state->req.data.name.dom_name)-1);
68 strncpy(state->req.data.name.name, name,
69 sizeof(state->req.data.name.name)-1);
70 state->wb_ctx = wb_ctx;
73 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
74 if (tevent_req_nomem(subreq, req)) {
75 return tevent_req_post(req, ev);
78 tevent_req_set_callback(subreq, wbcLookupName_done, req);
79 return req;
82 static void wbcLookupName_done(struct tevent_req *subreq)
84 struct tevent_req *req = tevent_req_callback_data(
85 subreq, struct tevent_req);
86 struct wbc_lookup_name_state *state = tevent_req_data(
87 req, struct wbc_lookup_name_state);
88 struct winbindd_response *resp;
89 wbcErr wbc_status;
91 wbc_status = wb_trans_recv(subreq, state, &resp);
92 TALLOC_FREE(subreq);
93 if (!WBC_ERROR_IS_OK(wbc_status)) {
94 tevent_req_error(req, wbc_status);
95 return;
98 state->sid = talloc(state, struct wbcDomainSid);
99 if (tevent_req_nomem(state->sid, req)) {
100 return;
103 wbc_status = wbcStringToSid(resp->data.sid.sid, state->sid);
104 if (!WBC_ERROR_IS_OK(wbc_status)) {
105 wbcDebug(state->wb_ctx, WBC_DEBUG_ERROR,
106 "wbcStringToSid returned %s!\n",
107 wbcErrorString(wbc_status));
108 tevent_req_error(req, wbc_status);
109 return;
112 state->name_type = (enum wbcSidType)resp->data.sid.type;
114 TALLOC_FREE(resp);
116 tevent_req_done(req);
120 * @brief Receive a conversion a SID to a domain and name
122 * @param *
123 * @param *pname Resolved User or group name
124 * @param *pname_type Pointer to the resolved SID type
126 * @return #wbcErr
129 wbcErr wbcLookupName_recv(struct tevent_req *req,
130 struct wbcDomainSid *sid,
131 enum wbcSidType *name_type)
133 struct wbc_lookup_name_state *state = tevent_req_data(
134 req, struct wbc_lookup_name_state);
135 wbcErr wbc_status = WBC_ERR_SUCCESS;
137 if (!sid || !name_type) {
138 wbcDebug(state->wb_ctx, WBC_DEBUG_TRACE,
139 "Sid is %p, name_type is %p\n", sid, name_type);
140 wbc_status = WBC_ERR_INVALID_PARAM;
141 goto failed;
144 if (tevent_req_is_wbcerr(req, &wbc_status)) {
145 goto failed;
148 memcpy(sid, state->sid, sizeof(struct wbcDomainSid));
149 *name_type = state->name_type;
151 failed:
152 tevent_req_received(req);
153 return wbc_status;
157 struct wbc_lookup_sid_state {
158 struct winbindd_request req;
159 char *domain;
160 char *name;
161 enum wbcSidType name_type;
164 static void wbcLookupSid_done(struct tevent_req *subreq);
167 * @brief Request a conversion of a SID to a domain and name
169 * @param mem_ctx talloc context to allocate the request from
170 * @param ev tevent context to use for async operation
171 * @param wb_ctx winbind context to use
172 * @param *sid Pointer to the domain SID to be resolved
174 * @return tevent_req on success, NULL on error
177 struct tevent_req *wbcLookupSid_send(TALLOC_CTX *mem_ctx,
178 struct tevent_context *ev,
179 struct wb_context *wb_ctx,
180 const struct wbcDomainSid *sid)
182 struct tevent_req *req, *subreq;
183 struct wbc_lookup_sid_state *state;
184 char *sid_string;
185 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
187 req = tevent_req_create(mem_ctx, &state, struct wbc_lookup_sid_state);
188 if (req == NULL) {
189 return NULL;
192 ZERO_STRUCT(state->req);
194 state->req.cmd = WINBINDD_LOOKUPSID;
195 wbc_status = wbcSidToString(sid, &sid_string);
196 if (!WBC_ERROR_IS_OK(wbc_status)) {
197 tevent_req_error(req, wbc_status);
198 return tevent_req_post(req, ev);
200 strncpy(state->req.data.sid, sid_string, sizeof(state->req.data.sid)-1);
201 wbcFreeMemory(sid_string);
203 subreq = wb_trans_send(state, ev, wb_ctx, false, &state->req);
204 if (tevent_req_nomem(subreq, req)) {
205 return tevent_req_post(req, ev);
208 tevent_req_set_callback(subreq, wbcLookupSid_done, req);
209 return req;
212 static void wbcLookupSid_done(struct tevent_req *subreq)
214 struct tevent_req *req = tevent_req_callback_data(
215 subreq, struct tevent_req);
216 struct wbc_lookup_sid_state *state = tevent_req_data(
217 req, struct wbc_lookup_sid_state);
218 struct winbindd_response *resp;
219 wbcErr wbc_status;
221 wbc_status = wb_trans_recv(subreq, state, &resp);
222 TALLOC_FREE(subreq);
223 if (!WBC_ERROR_IS_OK(wbc_status)) {
224 tevent_req_error(req, wbc_status);
225 return;
227 state->domain = talloc_strdup(state, resp->data.name.dom_name);
228 if (tevent_req_nomem(state->domain, req)) {
229 return;
232 state->name = talloc_strdup(state, resp->data.name.name);
233 if (tevent_req_nomem(state->name, req)) {
234 return;
237 state->name_type = (enum wbcSidType)resp->data.name.type;
239 TALLOC_FREE(resp);
241 tevent_req_done(req);
245 * @brief Receive a conversion a SID to a domain and name
247 * @param *mem_ctx, talloc context to move results to
248 * @param *pdomain Resolved Domain name (possibly "")
249 * @param *pname Resolved User or group name
250 * @param *pname_type Pointer to the resolved SID type
252 * @return #wbcErr
255 wbcErr wbcLookupSid_recv(struct tevent_req *req,
256 TALLOC_CTX *mem_ctx,
257 char **pdomain,
258 char **pname,
259 enum wbcSidType *pname_type)
261 struct wbc_lookup_sid_state *state = tevent_req_data(
262 req, struct wbc_lookup_sid_state);
263 wbcErr wbc_status;
265 if (tevent_req_is_wbcerr(req, &wbc_status)) {
266 tevent_req_received(req);
267 return wbc_status;
270 if (pdomain != NULL) {
271 *pdomain = talloc_steal(mem_ctx, state->domain);
274 if (pname != NULL) {
275 *pname = talloc_steal(mem_ctx, state->name);
278 if (pname_type != NULL) {
279 *pname_type = state->name_type;
282 tevent_req_received(req);
283 return WBC_ERR_SUCCESS;