a125b04d7d1e8296d375550bc8fc1446bd0c4e28
[amitay/samba.git] / nsswitch / libwbclient / wbc_idmap.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Winbind client API
5
6    Copyright (C) Gerald (Jerry) Carter 2007
7
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.
12
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.
17
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/>.
20 */
21
22 /* Required Headers */
23
24 #include "replace.h"
25 #include "libwbclient.h"
26
27 /* Convert a Windows SID to a Unix uid, allocating an uid if needed */
28 wbcErr wbcSidToUid(const struct wbcDomainSid *sid, uid_t *puid)
29 {
30         struct winbindd_request request;
31         struct winbindd_response response;
32         char *sid_string = NULL;
33         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
34
35         if (!sid || !puid) {
36                 wbc_status = WBC_ERR_INVALID_PARAM;
37                 BAIL_ON_WBC_ERROR(wbc_status);
38         }
39
40         /* Initialize request */
41
42         ZERO_STRUCT(request);
43         ZERO_STRUCT(response);
44
45         wbc_status = wbcSidToString(sid, &sid_string);
46         BAIL_ON_WBC_ERROR(wbc_status);
47
48         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
49         wbcFreeMemory(sid_string);
50
51         /* Make request */
52
53         wbc_status = wbcRequestResponse(WINBINDD_SID_TO_UID,
54                                         &request,
55                                         &response);
56         BAIL_ON_WBC_ERROR(wbc_status);
57
58         *puid = response.data.uid;
59
60         wbc_status = WBC_ERR_SUCCESS;
61
62  done:
63         return wbc_status;
64 }
65
66 /* Convert a Windows SID to a Unix uid if there already is a mapping */
67 wbcErr wbcQuerySidToUid(const struct wbcDomainSid *sid,
68                         uid_t *puid)
69 {
70         return WBC_ERR_NOT_IMPLEMENTED;
71 }
72
73 /* Convert a Unix uid to a Windows SID, allocating a SID if needed */
74 wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid)
75 {
76         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
77         struct winbindd_request request;
78         struct winbindd_response response;
79
80         if (!sid) {
81                 wbc_status = WBC_ERR_INVALID_PARAM;
82                 BAIL_ON_WBC_ERROR(wbc_status);
83         }
84
85         /* Initialize request */
86
87         ZERO_STRUCT(request);
88         ZERO_STRUCT(response);
89
90         request.data.uid = uid;
91
92         /* Make request */
93
94         wbc_status = wbcRequestResponse(WINBINDD_UID_TO_SID,
95                                         &request,
96                                         &response);
97         BAIL_ON_WBC_ERROR(wbc_status);
98
99         wbc_status = wbcStringToSid(response.data.sid.sid, sid);
100         BAIL_ON_WBC_ERROR(wbc_status);
101
102 done:
103         return wbc_status;
104 }
105
106 /* Convert a Unix uid to a Windows SID if there already is a mapping */
107 wbcErr wbcQueryUidToSid(uid_t uid,
108                         struct wbcDomainSid *sid)
109 {
110         return WBC_ERR_NOT_IMPLEMENTED;
111 }
112
113 /** @brief Convert a Windows SID to a Unix gid, allocating a gid if needed
114  *
115  * @param *sid        Pointer to the domain SID to be resolved
116  * @param *pgid       Pointer to the resolved gid_t value
117  *
118  * @return #wbcErr
119  *
120  **/
121
122 wbcErr wbcSidToGid(const struct wbcDomainSid *sid, gid_t *pgid)
123 {
124         struct winbindd_request request;
125         struct winbindd_response response;
126         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
127         char *sid_string = NULL;
128
129         if (!sid || !pgid) {
130                 wbc_status = WBC_ERR_INVALID_PARAM;
131                 BAIL_ON_WBC_ERROR(wbc_status);
132         }
133
134         /* Initialize request */
135
136         ZERO_STRUCT(request);
137         ZERO_STRUCT(response);
138
139         wbc_status = wbcSidToString(sid, &sid_string);
140         BAIL_ON_WBC_ERROR(wbc_status);
141
142         strncpy(request.data.sid, sid_string, sizeof(request.data.sid)-1);
143         wbcFreeMemory(sid_string);
144
145         /* Make request */
146
147         wbc_status = wbcRequestResponse(WINBINDD_SID_TO_GID,
148                                         &request,
149                                         &response);
150         BAIL_ON_WBC_ERROR(wbc_status);
151
152         *pgid = response.data.gid;
153
154         wbc_status = WBC_ERR_SUCCESS;
155
156  done:
157         return wbc_status;
158 }
159
160
161 /* Convert a Windows SID to a Unix gid if there already is a mapping */
162
163 wbcErr wbcQuerySidToGid(const struct wbcDomainSid *sid,
164                         gid_t *pgid)
165 {
166         return WBC_ERR_NOT_IMPLEMENTED;
167 }
168
169
170 /* Convert a Unix gid to a Windows SID, allocating a SID if needed */
171 wbcErr wbcGidToSid(gid_t gid, struct wbcDomainSid *sid)
172 {
173         struct winbindd_request request;
174         struct winbindd_response response;
175         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
176
177         if (!sid) {
178                 wbc_status = WBC_ERR_INVALID_PARAM;
179                 BAIL_ON_WBC_ERROR(wbc_status);
180         }
181
182         /* Initialize request */
183
184         ZERO_STRUCT(request);
185         ZERO_STRUCT(response);
186
187         request.data.gid = gid;
188
189         /* Make request */
190
191         wbc_status = wbcRequestResponse(WINBINDD_GID_TO_SID,
192                                         &request,
193                                         &response);
194         BAIL_ON_WBC_ERROR(wbc_status);
195
196         wbc_status = wbcStringToSid(response.data.sid.sid, sid);
197         BAIL_ON_WBC_ERROR(wbc_status);
198
199 done:
200         return wbc_status;
201 }
202
203 /* Convert a Unix gid to a Windows SID if there already is a mapping */
204 wbcErr wbcQueryGidToSid(gid_t gid,
205                         struct wbcDomainSid *sid)
206 {
207         return WBC_ERR_NOT_IMPLEMENTED;
208 }
209
210 /* Obtain a new uid from Winbind */
211 wbcErr wbcAllocateUid(uid_t *puid)
212 {
213         struct winbindd_request request;
214         struct winbindd_response response;
215         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
216
217         if (!puid)
218                 return WBC_ERR_INVALID_PARAM;
219
220         /* Initialise request */
221
222         ZERO_STRUCT(request);
223         ZERO_STRUCT(response);
224
225         /* Make request */
226
227         wbc_status = wbcRequestResponsePriv(WINBINDD_ALLOCATE_UID,
228                                             &request, &response);
229         BAIL_ON_WBC_ERROR(wbc_status);
230
231         /* Copy out result */
232         *puid = response.data.uid;
233
234         wbc_status = WBC_ERR_SUCCESS;
235
236  done:
237         return wbc_status;
238 }
239
240 /* Obtain a new gid from Winbind */
241 wbcErr wbcAllocateGid(gid_t *pgid)
242 {
243         struct winbindd_request request;
244         struct winbindd_response response;
245         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
246
247         if (!pgid)
248                 return WBC_ERR_INVALID_PARAM;
249
250         /* Initialise request */
251
252         ZERO_STRUCT(request);
253         ZERO_STRUCT(response);
254
255         /* Make request */
256
257         wbc_status = wbcRequestResponsePriv(WINBINDD_ALLOCATE_GID,
258                                             &request, &response);
259         BAIL_ON_WBC_ERROR(wbc_status);
260
261         /* Copy out result */
262         *pgid = response.data.gid;
263
264         wbc_status = WBC_ERR_SUCCESS;
265
266  done:
267         return wbc_status;
268 }
269
270 /* we can't include smb.h here... */
271 #define _ID_TYPE_UID 1
272 #define _ID_TYPE_GID 2
273
274 /* Set an user id mapping */
275 wbcErr wbcSetUidMapping(uid_t uid, const struct wbcDomainSid *sid)
276 {
277         struct winbindd_request request;
278         struct winbindd_response response;
279         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
280         char *sid_string = NULL;
281
282         if (!sid) {
283                 return WBC_ERR_INVALID_PARAM;
284         }
285
286         /* Initialise request */
287
288         ZERO_STRUCT(request);
289         ZERO_STRUCT(response);
290
291         /* Make request */
292
293         request.data.dual_idmapset.id = uid;
294         request.data.dual_idmapset.type = _ID_TYPE_UID;
295
296         wbc_status = wbcSidToString(sid, &sid_string);
297         BAIL_ON_WBC_ERROR(wbc_status);
298
299         strncpy(request.data.dual_idmapset.sid, sid_string,
300                 sizeof(request.data.dual_idmapset.sid)-1);
301         wbcFreeMemory(sid_string);
302
303         wbc_status = wbcRequestResponsePriv(WINBINDD_SET_MAPPING,
304                                             &request, &response);
305         BAIL_ON_WBC_ERROR(wbc_status);
306
307  done:
308         return wbc_status;
309 }
310
311 /* Set a group id mapping */
312 wbcErr wbcSetGidMapping(gid_t gid, const struct wbcDomainSid *sid)
313 {
314         struct winbindd_request request;
315         struct winbindd_response response;
316         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
317         char *sid_string = NULL;
318
319         if (!sid) {
320                 return WBC_ERR_INVALID_PARAM;
321         }
322
323         /* Initialise request */
324
325         ZERO_STRUCT(request);
326         ZERO_STRUCT(response);
327
328         /* Make request */
329
330         request.data.dual_idmapset.id = gid;
331         request.data.dual_idmapset.type = _ID_TYPE_GID;
332
333         wbc_status = wbcSidToString(sid, &sid_string);
334         BAIL_ON_WBC_ERROR(wbc_status);
335
336         strncpy(request.data.dual_idmapset.sid, sid_string,
337                 sizeof(request.data.dual_idmapset.sid)-1);
338         wbcFreeMemory(sid_string);
339
340         wbc_status = wbcRequestResponsePriv(WINBINDD_SET_MAPPING,
341                                             &request, &response);
342         BAIL_ON_WBC_ERROR(wbc_status);
343
344  done:
345         return wbc_status;
346 }
347
348 /* Remove a user id mapping */
349 wbcErr wbcRemoveUidMapping(uid_t uid, const struct wbcDomainSid *sid)
350 {
351         struct winbindd_request request;
352         struct winbindd_response response;
353         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
354         char *sid_string = NULL;
355
356         if (!sid) {
357                 return WBC_ERR_INVALID_PARAM;
358         }
359
360         /* Initialise request */
361
362         ZERO_STRUCT(request);
363         ZERO_STRUCT(response);
364
365         /* Make request */
366
367         request.data.dual_idmapset.id = uid;
368         request.data.dual_idmapset.type = _ID_TYPE_UID;
369
370         wbc_status = wbcSidToString(sid, &sid_string);
371         BAIL_ON_WBC_ERROR(wbc_status);
372
373         strncpy(request.data.dual_idmapset.sid, sid_string,
374                 sizeof(request.data.dual_idmapset.sid)-1);
375         wbcFreeMemory(sid_string);
376
377         wbc_status = wbcRequestResponsePriv(WINBINDD_REMOVE_MAPPING,
378                                             &request, &response);
379         BAIL_ON_WBC_ERROR(wbc_status);
380
381  done:
382         return wbc_status;
383 }
384
385 /* Remove a group id mapping */
386 wbcErr wbcRemoveGidMapping(gid_t gid, const struct wbcDomainSid *sid)
387 {
388         struct winbindd_request request;
389         struct winbindd_response response;
390         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
391         char *sid_string = NULL;
392
393         if (!sid) {
394                 return WBC_ERR_INVALID_PARAM;
395         }
396
397         /* Initialise request */
398
399         ZERO_STRUCT(request);
400         ZERO_STRUCT(response);
401
402         /* Make request */
403
404         request.data.dual_idmapset.id = gid;
405         request.data.dual_idmapset.type = _ID_TYPE_GID;
406
407         wbc_status = wbcSidToString(sid, &sid_string);
408         BAIL_ON_WBC_ERROR(wbc_status);
409
410         strncpy(request.data.dual_idmapset.sid, sid_string,
411                 sizeof(request.data.dual_idmapset.sid)-1);
412         wbcFreeMemory(sid_string);
413
414         wbc_status = wbcRequestResponsePriv(WINBINDD_REMOVE_MAPPING,
415                                             &request, &response);
416         BAIL_ON_WBC_ERROR(wbc_status);
417
418  done:
419         return wbc_status;
420 }
421
422 /* Set the highwater mark for allocated uids. */
423 wbcErr wbcSetUidHwm(uid_t uid_hwm)
424 {
425         struct winbindd_request request;
426         struct winbindd_response response;
427         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
428
429         /* Initialise request */
430
431         ZERO_STRUCT(request);
432         ZERO_STRUCT(response);
433
434         /* Make request */
435
436         request.data.dual_idmapset.id = uid_hwm;
437         request.data.dual_idmapset.type = _ID_TYPE_UID;
438
439         wbc_status = wbcRequestResponsePriv(WINBINDD_SET_HWM,
440                                             &request, &response);
441         BAIL_ON_WBC_ERROR(wbc_status);
442
443  done:
444         return wbc_status;
445 }
446
447 /* Set the highwater mark for allocated gids. */
448 wbcErr wbcSetGidHwm(gid_t gid_hwm)
449 {
450         struct winbindd_request request;
451         struct winbindd_response response;
452         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
453
454         /* Initialise request */
455
456         ZERO_STRUCT(request);
457         ZERO_STRUCT(response);
458
459         /* Make request */
460
461         request.data.dual_idmapset.id = gid_hwm;
462         request.data.dual_idmapset.type = _ID_TYPE_GID;
463
464         wbc_status = wbcRequestResponsePriv(WINBINDD_SET_HWM,
465                                             &request, &response);
466         BAIL_ON_WBC_ERROR(wbc_status);
467
468  done:
469         return wbc_status;
470 }