2 Unix SMB/CIFS implementation.
4 AIX loadable authentication module, providing identification
5 routines against Samba winbind/Windows NT Domain
7 Copyright (C) Tim Potter 2003
8 Copyright (C) Steve Roylance 2003
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Library General Public
12 License as published by the Free Software Foundation; either
13 version 2 of the License, or (at your option) any later version.
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Library General Public License for more details.
20 You should have received a copy of the GNU Library General Public
21 License along with this library; if not, write to the
22 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 Boston, MA 02111-1307, USA.
31 #include "winbind_client.h"
33 #define MAX_GETPWENT_USERS 250
34 #define MAX_GETGRENT_USERS 250
36 static struct passwd *fill_pwent(struct winbindd_pw *pw)
38 struct passwd *result;
40 if (!(result = malloc(sizeof(struct passwd))))
47 if ((result->pw_name = malloc(strlen(pw->pw_name) + 1)) == NULL)
50 strcpy(result->pw_name, pw->pw_name);
54 if ((result->pw_passwd = malloc(strlen(pw->pw_passwd) + 1)) == NULL)
57 strcpy(result->pw_passwd, pw->pw_passwd);
61 result->pw_uid = pw->pw_uid;
62 result->pw_gid = pw->pw_gid;
66 if ((result->pw_gecos = malloc(strlen(pw->pw_gecos) + 1)) == NULL)
69 strcpy(result->pw_gecos, pw->pw_gecos);
73 if ((result->pw_dir = malloc(strlen(pw->pw_dir) + 1)) == NULL)
76 strcpy(result->pw_dir, pw->pw_dir);
80 if ((result->pw_shell = malloc(strlen(pw->pw_shell) + 1)) == NULL)
83 strcpy(result->pw_shell, pw->pw_shell);
87 /* A memory allocation failed, undo succesfull allocations and
92 SAFE_FREE(result->pw_dir);
93 SAFE_FREE(result->pw_gecos);
94 SAFE_FREE(result->pw_passwd);
95 SAFE_FREE(result->pw_name);
101 static BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
107 if (!ptr) return(False);
111 /* default to simple separators */
112 if (!sep) sep = " \t\n\r";
114 /* find the first non sep char */
115 while (*s && strchr(sep,*s)) s++;
118 if (! *s) return(False);
120 /* copy over the token */
121 for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
130 *ptr = (*s) ? s+1 : s;
136 static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem)
141 struct group *result;
143 if (!(result = malloc(sizeof(struct group))))
146 ZERO_STRUCTP(result);
150 if ((result->gr_name = malloc(strlen(gr->gr_name) + 1)) == NULL)
153 strcpy(result->gr_name, gr->gr_name);
157 if ((result->gr_passwd = malloc(strlen(gr->gr_passwd) + 1)) == NULL)
160 strcpy(result->gr_passwd, gr->gr_passwd);
164 result->gr_gid = gr->gr_gid;
166 /* Group membership */
168 if ((gr->num_gr_mem < 0) || !gr_mem) {
172 if (gr->num_gr_mem == 0) {
176 *(result->gr_mem) = NULL;
180 if ((tst = malloc(((gr->num_gr_mem + 1) * sizeof(char *)))) == NULL)
183 result->gr_mem = (char **)tst;
185 /* Start looking at extra data */
189 while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) {
191 /* Allocate space for member */
193 if (((result->gr_mem)[i] =
194 malloc(strlen(name) + 1)) == NULL) {
195 for ( i -= 1; i >= 0; i--)
196 SAFE_FREE((result->gr_mem)[i]);
201 strcpy((result->gr_mem)[i], name);
206 (result->gr_mem)[i] = NULL;
210 /* A memory allocation failed, undo succesfull allocations and
216 SAFE_FREE(result->gr_passwd);
217 SAFE_FREE(result->gr_name);
225 static struct group *
226 wb_aix_getgrgid (gid_t gid)
228 /* take a group id and return a filled struct group */
230 struct winbindd_response response;
231 struct winbindd_request request;
234 ZERO_STRUCT(response);
235 ZERO_STRUCT(request);
237 request.data.gid = gid;
239 ret = winbindd_request(WINBINDD_GETGRGID, &request, &response);
241 if (ret == NSS_STATUS_SUCCESS) {
242 return fill_grent(&response.data.gr, response.extra_data);
243 } else if (ret == NSS_STATUS_NOTFOUND) {
252 static struct group *
253 wb_aix_getgrnam (const char *name)
255 /* take a group name and return a filled struct group */
257 struct winbindd_response response;
258 struct winbindd_request request;
261 ZERO_STRUCT(response);
262 ZERO_STRUCT(request);
264 strncpy(request.data.groupname, name,
265 sizeof(request.data.groupname));
266 request.data.groupname
267 [sizeof(request.data.groupname) - 1] = '\0';
269 ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response);
271 if (ret == NSS_STATUS_SUCCESS) {
272 return fill_grent(&response.data.gr, response.extra_data);
273 } else if (ret == NSS_STATUS_NOTFOUND) {
283 wb_aix_getgrset (const char *user)
285 /* take a username and return a string containing a comma-separated list of
286 group id numbers to which the user belongs */
288 struct winbindd_response response;
289 struct winbindd_request request;
292 strncpy(request.data.username, user,
293 sizeof(request.data.username) - 1);
294 request.data.username
295 [sizeof(request.data.username) - 1] = '\0';
297 ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
298 if (ret == NSS_STATUS_SUCCESS ) {
300 char *tmpbuf, *result;
302 int num_gids = response.data.num_entries;
303 gid_t *gid_list = (gid_t *)response.extra_data;
306 /* allocate a space large enough to contruct the string */
307 if (!(tmpbuf = malloc(num_gids*12))) {
311 idx += sprintf(tmpbuf, "%d", gid_list[0]);
312 for (i = 1; i < num_gids; i++) {
314 idx += sprintf(tmpbuf+idx, "%d", gid_list[i]);
317 if (!(result = malloc(idx+1))) {
318 /* allocate a string the right size to return, but
319 if that fails may as well return our working buffer
320 because it contains the same thing */
323 strcpy(result, tmpbuf);
326 } else if (ret == NSS_STATUS_NOTFOUND) {
335 static struct passwd *
336 wb_aix_getpwuid (uid_t uid)
338 /* take a uid and return a filled struct passwd */
340 struct winbindd_response response;
341 struct winbindd_request request;
344 ZERO_STRUCT(response);
345 ZERO_STRUCT(request);
347 request.data.uid = uid;
349 ret = winbindd_request(WINBINDD_GETPWUID, &request, &response);
351 if (ret == NSS_STATUS_SUCCESS) {
352 return fill_pwent(&response.data.pw);
353 } else if (ret == NSS_STATUS_NOTFOUND ) {
362 static struct passwd *
363 wb_aix_getpwnam (const char *name)
365 /* take a username and return a filled struct passwd */
367 struct winbindd_response response;
368 struct winbindd_request request;
371 ZERO_STRUCT(response);
372 ZERO_STRUCT(request);
374 strncpy(request.data.username, name,
375 sizeof(request.data.username) - 1);
376 request.data.username
377 [sizeof(request.data.username) - 1] = '\0';
379 ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response);
381 if (ret == NSS_STATUS_SUCCESS ) {
382 return fill_pwent(&response.data.pw);
383 } else if (ret == NSS_STATUS_NOTFOUND) {
393 wb_aix_init (struct secmethod_table *methods)
395 memset(methods, 0, sizeof(*methods));
397 /* identification methods, this is the minimum requried for a
400 methods->method_getgrgid = wb_aix_getgrgid;
401 methods->method_getgrnam = wb_aix_getgrnam;
402 methods->method_getgrset = wb_aix_getgrset;
403 methods->method_getpwnam = wb_aix_getpwnam;
404 methods->method_getpwuid = wb_aix_getpwuid;