Add a test that shows the difference between Windows and Samba with respect to Delete...
[Samba/gebeck_regimport.git] / nsswitch / libwbclient / wbc_idmap.c
blob04e7d02995e50e0d0c11bf750b4498cb2f1f64a9
1 /*
2 Unix SMB/CIFS implementation.
4 Winbind client API
6 Copyright (C) Gerald (Jerry) Carter 2007
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 /* Convert a Windows SID to a Unix uid, allocating an uid if needed */
29 wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
31 struct winbindd_request request;
32 struct winbindd_response response;
33 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
35 if (!sid || !puid) {
36 wbc_status = WBC_ERR_INVALID_PARAM;
37 BAIL_ON_WBC_ERROR(wbc_status);
40 /* Initialize request */
42 ZERO_STRUCT(request);
43 ZERO_STRUCT(response);
45 wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
47 /* Make request */
49 wbc_status = wbcRequestResponse(WINBINDD_SID_TO_UID,
50 &request,
51 &response);
52 BAIL_ON_WBC_ERROR(wbc_status);
54 *puid = response.data.uid;
56 wbc_status = WBC_ERR_SUCCESS;
58 done:
59 return wbc_status;
62 /* Convert a Windows SID to a Unix uid if there already is a mapping */
63 wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
64 uid_t *puid)
66 return WBC_ERR_NOT_IMPLEMENTED;
69 /* Convert a Unix uid to a Windows SID, allocating a SID if needed */
70 wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid)
72 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
73 struct winbindd_request request;
74 struct winbindd_response response;
76 if (!sid) {
77 wbc_status = WBC_ERR_INVALID_PARAM;
78 BAIL_ON_WBC_ERROR(wbc_status);
81 /* Initialize request */
83 ZERO_STRUCT(request);
84 ZERO_STRUCT(response);
86 request.data.uid = uid;
88 /* Make request */
90 wbc_status = wbcRequestResponse(WINBINDD_UID_TO_SID,
91 &request,
92 &response);
93 BAIL_ON_WBC_ERROR(wbc_status);
95 wbc_status = wbcStringToSid(response.data.sid.sid, sid);
96 BAIL_ON_WBC_ERROR(wbc_status);
98 done:
99 return wbc_status;
102 /* Convert a Unix uid to a Windows SID if there already is a mapping */
103 wbcErr wbcQueryUidToSid(uid_t uid,
104 struct wbcDomainSid *sid)
106 return WBC_ERR_NOT_IMPLEMENTED;
109 /** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
111 * @param *sid Pointer to the domain SID to be resolved
112 * @param *pgid Pointer to the resolved gid_t value
114 * @return #wbcErr
118 wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
120 struct winbindd_request request;
121 struct winbindd_response response;
122 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
124 if (!sid || !pgid) {
125 wbc_status = WBC_ERR_INVALID_PARAM;
126 BAIL_ON_WBC_ERROR(wbc_status);
129 /* Initialize request */
131 ZERO_STRUCT(request);
132 ZERO_STRUCT(response);
134 wbcSidToStringBuf(sid, request.data.sid, sizeof(request.data.sid));
136 /* Make request */
138 wbc_status = wbcRequestResponse(WINBINDD_SID_TO_GID,
139 &request,
140 &response);
141 BAIL_ON_WBC_ERROR(wbc_status);
143 *pgid = response.data.gid;
145 wbc_status = WBC_ERR_SUCCESS;
147 done:
148 return wbc_status;
152 /* Convert a Windows SID to a Unix gid if there already is a mapping */
154 wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
155 gid_t *pgid)
157 return WBC_ERR_NOT_IMPLEMENTED;
161 /* Convert a Unix gid to a Windows SID, allocating a SID if needed */
162 wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid)
164 struct winbindd_request request;
165 struct winbindd_response response;
166 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
168 if (!sid) {
169 wbc_status = WBC_ERR_INVALID_PARAM;
170 BAIL_ON_WBC_ERROR(wbc_status);
173 /* Initialize request */
175 ZERO_STRUCT(request);
176 ZERO_STRUCT(response);
178 request.data.gid = gid;
180 /* Make request */
182 wbc_status = wbcRequestResponse(WINBINDD_GID_TO_SID,
183 &request,
184 &response);
185 BAIL_ON_WBC_ERROR(wbc_status);
187 wbc_status = wbcStringToSid(response.data.sid.sid, sid);
188 BAIL_ON_WBC_ERROR(wbc_status);
190 done:
191 return wbc_status;
194 /* Convert a Unix gid to a Windows SID if there already is a mapping */
195 wbcErr wbcQueryGidToSid(gid_t gid,
196 struct wbcDomainSid *sid)
198 return WBC_ERR_NOT_IMPLEMENTED;
201 /* Obtain a new uid from Winbind */
202 wbcErr wbcAllocateUid(uid_t *puid)
204 struct winbindd_request request;
205 struct winbindd_response response;
206 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
208 if (!puid)
209 return WBC_ERR_INVALID_PARAM;
211 /* Initialise request */
213 ZERO_STRUCT(request);
214 ZERO_STRUCT(response);
216 /* Make request */
218 wbc_status = wbcRequestResponsePriv(WINBINDD_ALLOCATE_UID,
219 &request, &response);
220 BAIL_ON_WBC_ERROR(wbc_status);
222 /* Copy out result */
223 *puid = response.data.uid;
225 wbc_status = WBC_ERR_SUCCESS;
227 done:
228 return wbc_status;
231 /* Obtain a new gid from Winbind */
232 wbcErr wbcAllocateGid(gid_t *pgid)
234 struct winbindd_request request;
235 struct winbindd_response response;
236 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
238 if (!pgid)
239 return WBC_ERR_INVALID_PARAM;
241 /* Initialise request */
243 ZERO_STRUCT(request);
244 ZERO_STRUCT(response);
246 /* Make request */
248 wbc_status = wbcRequestResponsePriv(WINBINDD_ALLOCATE_GID,
249 &request, &response);
250 BAIL_ON_WBC_ERROR(wbc_status);
252 /* Copy out result */
253 *pgid = response.data.gid;
255 wbc_status = WBC_ERR_SUCCESS;
257 done:
258 return wbc_status;
261 /* we can't include smb.h here... */
262 #define _ID_TYPE_UID 1
263 #define _ID_TYPE_GID 2
265 /* Set an user id mapping - not implemented any more */
266 wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid)
268 return WBC_ERR_NOT_IMPLEMENTED;
271 /* Set a group id mapping - not implemented any more */
272 wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid)
274 return WBC_ERR_NOT_IMPLEMENTED;
277 /* Remove a user id mapping - not implemented any more */
278 wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid)
280 return WBC_ERR_NOT_IMPLEMENTED;
283 /* Remove a group id mapping - not implemented any more */
284 wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid)
286 return WBC_ERR_NOT_IMPLEMENTED;
289 /* Set the highwater mark for allocated uids - not implemented any more */
290 wbcErr wbcSetUidHwm(uid_t uid_hwm)
292 return WBC_ERR_NOT_IMPLEMENTED;
295 /* Set the highwater mark for allocated gids - not implemented any more */
296 wbcErr wbcSetGidHwm(gid_t gid_hwm)
298 return WBC_ERR_NOT_IMPLEMENTED;
301 /* Convert a list of SIDs */
302 wbcErr wbcSidsToUnixIds(const struct wbcDomainSid *sids, uint32_t num_sids,
303 struct wbcUnixId *ids)
305 struct winbindd_request request;
306 struct winbindd_response response;
307 wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
308 int buflen, extra_len;
309 uint32_t i;
310 char *sidlist, *p, *extra_data;
312 buflen = num_sids * (WBC_SID_STRING_BUFLEN + 1) + 1;
314 sidlist = (char *)malloc(buflen);
315 if (sidlist == NULL) {
316 return WBC_ERR_NO_MEMORY;
319 p = sidlist;
321 for (i=0; i<num_sids; i++) {
322 int remaining;
323 int len;
325 remaining = buflen - (p - sidlist);
327 len = wbcSidToStringBuf(&sids[i], p, remaining);
328 if (len > remaining) {
329 free(sidlist);
330 return WBC_ERR_UNKNOWN_FAILURE;
333 p += len;
334 *p++ = '\n';
336 *p++ = '\0';
338 ZERO_STRUCT(request);
339 ZERO_STRUCT(response);
341 request.extra_data.data = sidlist;
342 request.extra_len = p - sidlist;
344 wbc_status = wbcRequestResponse(WINBINDD_SIDS_TO_XIDS,
345 &request, &response);
346 free(sidlist);
347 if (!WBC_ERROR_IS_OK(wbc_status)) {
348 return wbc_status;
351 extra_len = response.length - sizeof(struct winbindd_response);
352 extra_data = (char *)response.extra_data.data;
354 if ((extra_len <= 0) || (extra_data[extra_len-1] != '\0')) {
355 goto wbc_err_invalid;
358 p = extra_data;
360 for (i=0; i<num_sids; i++) {
361 struct wbcUnixId *id = &ids[i];
362 char *q;
364 switch (p[0]) {
365 case 'U':
366 id->type = WBC_ID_TYPE_UID;
367 id->id.uid = strtoul(p+1, &q, 10);
368 break;
369 case 'G':
370 id->type = WBC_ID_TYPE_GID;
371 id->id.gid = strtoul(p+1, &q, 10);
372 break;
373 case 'B':
374 id->type = WBC_ID_TYPE_BOTH;
375 id->id.uid = strtoul(p+1, &q, 10);
376 break;
377 default:
378 id->type = WBC_ID_TYPE_NOT_SPECIFIED;
379 q = strchr(p, '\n');
380 break;
382 if (q == NULL || q[0] != '\n') {
383 goto wbc_err_invalid;
385 p = q+1;
387 wbc_status = WBC_ERR_SUCCESS;
388 goto done;
390 wbc_err_invalid:
391 wbc_status = WBC_ERR_INVALID_RESPONSE;
392 done:
393 winbindd_free_response(&response);
394 return wbc_status;