libwbclient: Add placeholder function for WINBINDD_GETGRLST
[samba.git] / source3 / nsswitch / libwbclient / wbc_pwd.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 "libwbclient.h"
26
27 /**
28  *
29  **/
30
31 static struct passwd *copy_passwd_entry(struct winbindd_pw *p)
32 {
33         struct passwd *pwd = NULL;
34         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
35
36         pwd = talloc(NULL, struct passwd);
37         BAIL_ON_PTR_ERROR(pwd, wbc_status);
38
39         pwd->pw_name = talloc_strdup(pwd,p->pw_name);
40         BAIL_ON_PTR_ERROR(pwd->pw_name, wbc_status);
41
42         pwd->pw_passwd = talloc_strdup(pwd, p->pw_passwd);
43         BAIL_ON_PTR_ERROR(pwd->pw_passwd, wbc_status);
44
45         pwd->pw_gecos = talloc_strdup(pwd, p->pw_gecos);
46         BAIL_ON_PTR_ERROR(pwd->pw_gecos, wbc_status);
47
48         pwd->pw_shell = talloc_strdup(pwd, p->pw_shell);
49         BAIL_ON_PTR_ERROR(pwd->pw_shell, wbc_status);
50
51         pwd->pw_dir = talloc_strdup(pwd, p->pw_dir);
52         BAIL_ON_PTR_ERROR(pwd->pw_dir, wbc_status);
53
54         pwd->pw_uid = p->pw_uid;
55         pwd->pw_gid = p->pw_gid;
56
57 done:
58         if (!WBC_ERROR_IS_OK(wbc_status)) {
59                 talloc_free(pwd);
60                 pwd = NULL;
61         }
62
63         return pwd;
64 }
65
66 /**
67  *
68  **/
69
70 static struct group *copy_group_entry(struct winbindd_gr *g,
71                                       char *mem_buf)
72 {
73         struct group *grp = NULL;
74         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
75         int i;
76         char *mem_p, *mem_q;
77
78         grp = talloc(NULL, struct group);
79         BAIL_ON_PTR_ERROR(grp, wbc_status);
80
81         grp->gr_name = talloc_strdup(grp, g->gr_name);
82         BAIL_ON_PTR_ERROR(grp->gr_name, wbc_status);
83
84         grp->gr_passwd = talloc_strdup(grp, g->gr_passwd);
85         BAIL_ON_PTR_ERROR(grp->gr_passwd, wbc_status);
86
87         grp->gr_gid = g->gr_gid;
88
89         grp->gr_mem = talloc_array(grp, char*, g->num_gr_mem+1);
90
91         mem_p = mem_q = mem_buf;
92         for (i=0; i<g->num_gr_mem && mem_p; i++) {
93                 if ((mem_q = strchr(mem_p, ',')) != NULL) {
94                         *mem_q = '\0';
95                 }
96
97                 grp->gr_mem[i] = talloc_strdup(grp, mem_p);
98                 BAIL_ON_PTR_ERROR(grp->gr_mem[i], wbc_status);
99
100                 if (mem_q == NULL) {
101                         i += 1;
102                         break;
103                 }
104                 mem_p = mem_q + 1;
105         }
106         grp->gr_mem[i] = NULL;
107
108         wbc_status = WBC_ERR_SUCCESS;
109
110 done:
111         if (!WBC_ERROR_IS_OK(wbc_status)) {
112                 talloc_free(grp);
113                 grp = NULL;
114         }
115
116         return grp;
117 }
118
119 /** @brief Fill in a struct passwd* for a domain user based
120  *   on username
121  *
122  * @param *name     Username to lookup
123  * @param **pwd     Pointer to resulting struct passwd* from the query.
124  *
125  * @return #wbcErr
126  **/
127
128 wbcErr wbcGetpwnam(const char *name, struct passwd **pwd)
129 {
130         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
131         struct winbindd_request request;
132         struct winbindd_response response;
133
134         if (!name || !pwd) {
135                 wbc_status = WBC_ERR_INVALID_PARAM;
136                 BAIL_ON_WBC_ERROR(wbc_status);
137         }
138
139         /* Initialize request */
140
141         ZERO_STRUCT(request);
142         ZERO_STRUCT(response);
143
144         /* dst is already null terminated from the memset above */
145
146         strncpy(request.data.username, name, sizeof(request.data.username)-1);
147
148         wbc_status = wbcRequestResponse(WINBINDD_GETPWNAM,
149                                         &request,
150                                         &response);
151         BAIL_ON_WBC_ERROR(wbc_status);
152
153         *pwd = copy_passwd_entry(&response.data.pw);
154         BAIL_ON_PTR_ERROR(*pwd, wbc_status);
155
156  done:
157         return wbc_status;
158 }
159
160 /** @brief Fill in a struct passwd* for a domain user based
161  *   on uid
162  *
163  * @param uid       Uid to lookup
164  * @param **pwd     Pointer to resulting struct passwd* from the query.
165  *
166  * @return #wbcErr
167  **/
168
169 wbcErr wbcGetpwuid(uid_t uid, struct passwd **pwd)
170 {
171         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
172         struct winbindd_request request;
173         struct winbindd_response response;
174
175         if (!pwd) {
176                 wbc_status = WBC_ERR_INVALID_PARAM;
177                 BAIL_ON_WBC_ERROR(wbc_status);
178         }
179
180         /* Initialize request */
181
182         ZERO_STRUCT(request);
183         ZERO_STRUCT(response);
184
185         request.data.uid = uid;
186
187         wbc_status = wbcRequestResponse(WINBINDD_GETPWUID,
188                                         &request,
189                                         &response);
190         BAIL_ON_WBC_ERROR(wbc_status);
191
192         *pwd = copy_passwd_entry(&response.data.pw);
193         BAIL_ON_PTR_ERROR(*pwd, wbc_status);
194
195  done:
196         return wbc_status;
197 }
198
199 /** @brief Fill in a struct passwd* for a domain user based
200  *   on username
201  *
202  * @param *name     Username to lookup
203  * @param **grp     Pointer to resulting struct group* from the query.
204  *
205  * @return #wbcErr
206  **/
207
208 wbcErr wbcGetgrnam(const char *name, struct group **grp)
209 {
210         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
211         struct winbindd_request request;
212         struct winbindd_response response;
213
214         /* Initialize request */
215
216         ZERO_STRUCT(request);
217         ZERO_STRUCT(response);
218
219         if (!name || !grp) {
220                 wbc_status = WBC_ERR_INVALID_PARAM;
221                 BAIL_ON_WBC_ERROR(wbc_status);
222         }
223
224         /* dst is already null terminated from the memset above */
225
226         strncpy(request.data.groupname, name, sizeof(request.data.groupname)-1);
227
228         wbc_status = wbcRequestResponse(WINBINDD_GETGRNAM,
229                                         &request,
230                                         &response);
231         BAIL_ON_WBC_ERROR(wbc_status);
232
233         *grp = copy_group_entry(&response.data.gr,
234                                 (char*)response.extra_data.data);
235         BAIL_ON_PTR_ERROR(*grp, wbc_status);
236
237  done:
238         if (response.extra_data.data)
239                 free(response.extra_data.data);
240
241         return wbc_status;
242 }
243
244 /** @brief Fill in a struct passwd* for a domain user based
245  *   on uid
246  *
247  * @param gid       Uid to lookup
248  * @param **grp     Pointer to resulting struct group* from the query.
249  *
250  * @return #wbcErr
251  **/
252
253 wbcErr wbcGetgrgid(gid_t gid, struct group **grp)
254 {
255         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
256         struct winbindd_request request;
257         struct winbindd_response response;
258
259         /* Initialize request */
260
261         ZERO_STRUCT(request);
262         ZERO_STRUCT(response);
263
264         if (!grp) {
265                 wbc_status = WBC_ERR_INVALID_PARAM;
266                 BAIL_ON_WBC_ERROR(wbc_status);
267         }
268
269         request.data.gid = gid;
270
271         wbc_status = wbcRequestResponse(WINBINDD_GETGRGID,
272                                         &request,
273                                         &response);
274         BAIL_ON_WBC_ERROR(wbc_status);
275
276         *grp = copy_group_entry(&response.data.gr,
277                                 (char*)response.extra_data.data);
278         BAIL_ON_PTR_ERROR(*grp, wbc_status);
279
280  done:
281         if (response.extra_data.data)
282                 free(response.extra_data.data);
283
284         return wbc_status;
285 }
286
287 /** @brief Reset the passwd iterator
288  *
289  * @return #wbcErr
290  **/
291
292 wbcErr wbcSetpwent(void)
293 {
294         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
295
296         wbc_status = wbcRequestResponse(WINBINDD_SETPWENT,
297                                         NULL, NULL);
298         BAIL_ON_WBC_ERROR(wbc_status);
299
300  done:
301         return wbc_status;
302 }
303
304 /** @brief Close the passwd iterator
305  *
306  * @return #wbcErr
307  **/
308
309 wbcErr wbcEndpwent(void)
310 {
311         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
312
313         wbc_status = wbcRequestResponse(WINBINDD_ENDPWENT,
314                                         NULL, NULL);
315         BAIL_ON_WBC_ERROR(wbc_status);
316
317  done:
318         return wbc_status;
319 }
320
321 /** @brief Return the next struct passwd* entry from the pwent iterator
322  *
323  * @param **pwd       Pointer to resulting struct group* from the query.
324  *
325  * @return #wbcErr
326  **/
327
328 wbcErr wbcGetpwent(struct passwd **pwd)
329 {
330         return WBC_ERR_NOT_IMPLEMENTED;
331 }
332
333 /** @brief Reset the group iterator
334  *
335  * @return #wbcErr
336  **/
337
338 wbcErr wbcSetgrent(void)
339 {
340         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
341
342         wbc_status = wbcRequestResponse(WINBINDD_SETGRENT,
343                                         NULL, NULL);
344         BAIL_ON_WBC_ERROR(wbc_status);
345
346  done:
347         return wbc_status;
348 }
349
350 /** @brief Close the group iterator
351  *
352  * @return #wbcErr
353  **/
354
355 wbcErr wbcEndgrent(void)
356 {
357         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
358
359         wbc_status = wbcRequestResponse(WINBINDD_ENDGRENT,
360                                         NULL, NULL);
361         BAIL_ON_WBC_ERROR(wbc_status);
362
363  done:
364         return wbc_status;
365 }
366
367 /** @brief Return the next struct passwd* entry from the pwent iterator
368  *
369  * @param **grp       Pointer to resulting struct group* from the query.
370  *
371  * @return #wbcErr
372  **/
373
374 wbcErr wbcGetgrent(struct group **grp)
375 {
376         return WBC_ERR_NOT_IMPLEMENTED;
377 }
378
379 /** @brief Return the next struct group* entry from the pwent iterator
380  *
381  * This is similar to #wbcGetgrent, just that the member list is empty
382  *
383  * @param **grp       Pointer to resulting struct group* from the query.
384  *
385  * @return #wbcErr
386  **/
387
388 wbcErr wbcGetgrlist(struct group **grp)
389 {
390         return WBC_ERR_NOT_IMPLEMENTED;
391 }
392
393 /** @brief Return the unix group array belonging to the given user
394  *
395  * @param *account       The given user name
396  * @param *num_groups    Number of elements returned in the groups array
397  * @param **_groups      Pointer to resulting gid_t array.
398  *
399  * @return #wbcErr
400  **/
401 wbcErr wbcGetGroups(const char *account,
402                     uint32_t *num_groups,
403                     gid_t **_groups)
404 {
405         wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
406         struct winbindd_request request;
407         struct winbindd_response response;
408         uint32_t i;
409         gid_t *groups = NULL;
410
411         /* Initialize request */
412
413         ZERO_STRUCT(request);
414         ZERO_STRUCT(response);
415
416         if (!account) {
417                 wbc_status = WBC_ERR_INVALID_PARAM;
418                 BAIL_ON_WBC_ERROR(wbc_status);
419         }
420
421         /* Send request */
422
423         strncpy(request.data.username, account, sizeof(request.data.username)-1);
424
425         wbc_status = wbcRequestResponse(WINBINDD_GETGROUPS,
426                                         &request,
427                                         &response);
428         BAIL_ON_WBC_ERROR(wbc_status);
429
430         groups = talloc_array(NULL, gid_t, response.data.num_entries);
431         BAIL_ON_PTR_ERROR(groups, wbc_status);
432
433         for (i = 0; i < response.data.num_entries; i++) {
434                 groups[i] = ((gid_t *)response.extra_data.data)[i];
435         }
436
437         *num_groups = response.data.num_entries;
438         *_groups = groups;
439         groups = NULL;
440
441         wbc_status = WBC_ERR_SUCCESS;
442
443  done:
444         if (response.extra_data.data) {
445                 free(response.extra_data.data);
446         }
447         if (groups) {
448                 talloc_free(groups);
449         }
450
451         return wbc_status;
452 }