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