r17727: Start pulling in changes for 3.0.23c
[Samba/gbeck.git] / source / nsswitch / winbind_nss_aix.c
blob5b3aaeb8d7731c7e1f820577b76bb4da893676b3
1 /*
2 Unix SMB/CIFS implementation.
4 AIX loadable authentication module, providing identification and
5 authentication routines against Samba winbind/Windows NT Domain
7 Copyright (C) Tim Potter 2003
8 Copyright (C) Steve Roylance 2003
9 Copyright (C) Andrew Tridgell 2003-2004
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Library General Public
13 License as published by the Free Software Foundation; either
14 version 2 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Library General Public License for more details.
21 You should have received a copy of the GNU Library General Public
22 License along with this library; if not, write to the
23 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 Boston, MA 02111-1307, USA.
29 To install this module copy nsswitch/WINBIND to /usr/lib/security and add
30 "WINBIND" in /usr/lib/security/methods.cfg and /etc/security/user
32 Note that this module also provides authentication and password
33 changing routines, so you do not need to install the winbind PAM
34 module.
36 see
37 http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/aixprggd/kernextc/sec_load_mod.htm
38 for some information in the interface that this module implements
40 Many thanks to Julianne Haugh for explaining some of the finer
41 details of this interface.
43 To debug this module use uess_test.c (which you can get from tridge)
44 or set "options=debug" in /usr/lib/security/methods.cfg
48 #include <stdlib.h>
49 #include <string.h>
50 #include <usersec.h>
51 #include <errno.h>
52 #include <stdarg.h>
54 #include "winbind_client.h"
56 #define WB_AIX_ENCODED '_'
58 static int debug_enabled;
61 static void logit(const char *format, ...)
63 va_list ap;
64 FILE *f;
65 if (!debug_enabled) {
66 return;
68 f = fopen("/tmp/WINBIND_DEBUG.log", "a");
69 if (!f) return;
70 va_start(ap, format);
71 vfprintf(f, format, ap);
72 va_end(ap);
73 fclose(f);
77 #define HANDLE_ERRORS(ret) do { \
78 if ((ret) == NSS_STATUS_NOTFOUND) { \
79 errno = ENOENT; \
80 return NULL; \
81 } else if ((ret) != NSS_STATUS_SUCCESS) { \
82 errno = EIO; \
83 return NULL; \
84 } \
85 } while (0)
87 #define STRCPY_RET(dest, src) \
88 do { \
89 if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return -1; } \
90 strcpy(dest, src); \
91 } while (0)
93 #define STRCPY_RETNULL(dest, src) \
94 do { \
95 if (strlen(src)+1 > sizeof(dest)) { errno = EINVAL; return NULL; } \
96 strcpy(dest, src); \
97 } while (0)
100 /* free a passwd structure */
101 static void free_pwd(struct passwd *pwd)
103 free(pwd->pw_name);
104 free(pwd->pw_passwd);
105 free(pwd->pw_gecos);
106 free(pwd->pw_dir);
107 free(pwd->pw_shell);
108 free(pwd);
111 /* free a group structure */
112 static void free_grp(struct group *grp)
114 int i;
116 free(grp->gr_name);
117 free(grp->gr_passwd);
119 if (!grp->gr_mem) {
120 free(grp);
121 return;
124 for (i=0; grp->gr_mem[i]; i++) {
125 free(grp->gr_mem[i]);
128 free(grp->gr_mem);
129 free(grp);
133 /* replace commas with nulls, and null terminate */
134 static void replace_commas(char *s)
136 char *p, *p0=s;
137 for (p=strchr(s, ','); p; p = strchr(p+1, ',')) {
138 *p=0;
139 p0 = p+1;
142 p0[strlen(p0)+1] = 0;
146 /* the decode_*() routines are used to cope with the fact that AIX 5.2
147 and below cannot handle user or group names longer than 8
148 characters in some interfaces. We use the normalize method to
149 provide a mapping to a username that fits, by using the form '_UID'
150 or '_GID'.
152 this only works if you can guarantee that the WB_AIX_ENCODED char
153 is not used as the first char of any other username
155 static unsigned decode_id(const char *name)
157 unsigned id;
158 sscanf(name+1, "%u", &id);
159 return id;
162 static struct passwd *wb_aix_getpwuid(uid_t uid);
164 static char *decode_user(const char *name)
166 struct passwd *pwd;
167 unsigned id;
168 char *ret;
170 sscanf(name+1, "%u", &id);
171 pwd = wb_aix_getpwuid(id);
172 if (!pwd) {
173 return NULL;
175 ret = strdup(pwd->pw_name);
177 free_pwd(pwd);
179 logit("decoded '%s' -> '%s'\n", name, ret);
181 return ret;
186 fill a struct passwd from a winbindd_pw struct, allocating as a single block
188 static struct passwd *fill_pwent(struct winbindd_pw *pw)
190 struct passwd *result;
192 result = calloc(1, sizeof(struct passwd));
193 if (!result) {
194 errno = ENOMEM;
195 return NULL;
198 result->pw_uid = pw->pw_uid;
199 result->pw_gid = pw->pw_gid;
200 result->pw_name = strdup(pw->pw_name);
201 result->pw_passwd = strdup(pw->pw_passwd);
202 result->pw_gecos = strdup(pw->pw_gecos);
203 result->pw_dir = strdup(pw->pw_dir);
204 result->pw_shell = strdup(pw->pw_shell);
206 return result;
211 fill a struct group from a winbindd_pw struct, allocating as a single block
213 static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem)
215 int i;
216 struct group *result;
217 char *p, *name;
219 result = calloc(1, sizeof(struct group));
220 if (!result) {
221 errno = ENOMEM;
222 return NULL;
225 result->gr_gid = gr->gr_gid;
227 result->gr_name = strdup(gr->gr_name);
228 result->gr_passwd = strdup(gr->gr_passwd);
230 /* Group membership */
231 if ((gr->num_gr_mem < 0) || !gr_mem) {
232 gr->num_gr_mem = 0;
235 if (gr->num_gr_mem == 0) {
236 /* Group is empty */
237 return result;
240 result->gr_mem = (char **)malloc(sizeof(char *) * (gr->num_gr_mem+1));
241 if (!result->gr_mem) {
242 errno = ENOMEM;
243 return NULL;
246 /* Start looking at extra data */
247 i=0;
248 for (name = strtok_r(gr_mem, ",", &p);
249 name;
250 name = strtok_r(NULL, ",", &p)) {
251 if (i == gr->num_gr_mem) {
252 break;
254 result->gr_mem[i] = strdup(name);
255 i++;
258 /* Terminate list */
259 result->gr_mem[i] = NULL;
261 return result;
266 /* take a group id and return a filled struct group */
267 static struct group *wb_aix_getgrgid(gid_t gid)
269 struct winbindd_response response;
270 struct winbindd_request request;
271 struct group *grp;
272 NSS_STATUS ret;
274 logit("getgrgid %d\n", gid);
276 ZERO_STRUCT(response);
277 ZERO_STRUCT(request);
279 request.data.gid = gid;
281 ret = winbindd_request_response(WINBINDD_GETGRGID, &request, &response);
283 logit("getgrgid ret=%d\n", ret);
285 HANDLE_ERRORS(ret);
287 grp = fill_grent(&response.data.gr, response.extra_data.data);
289 free_response(&response);
291 return grp;
294 /* take a group name and return a filled struct group */
295 static struct group *wb_aix_getgrnam(const char *name)
297 struct winbindd_response response;
298 struct winbindd_request request;
299 NSS_STATUS ret;
300 struct group *grp;
302 if (*name == WB_AIX_ENCODED) {
303 return wb_aix_getgrgid(decode_id(name));
306 logit("getgrnam '%s'\n", name);
308 ZERO_STRUCT(response);
309 ZERO_STRUCT(request);
311 STRCPY_RETNULL(request.data.groupname, name);
313 ret = winbindd_request_response(WINBINDD_GETGRNAM, &request, &response);
315 HANDLE_ERRORS(ret);
317 grp = fill_grent(&response.data.gr, response.extra_data.data);
319 free_response(&response);
321 return grp;
325 /* this call doesn't have to fill in the gr_mem, but we do anyway
326 for simplicity */
327 static struct group *wb_aix_getgracct(void *id, int type)
329 if (type == 1) {
330 return wb_aix_getgrnam((char *)id);
332 if (type == 0) {
333 return wb_aix_getgrgid(*(int *)id);
335 errno = EINVAL;
336 return NULL;
340 /* take a username and return a string containing a comma-separated
341 list of group id numbers to which the user belongs */
342 static char *wb_aix_getgrset(char *user)
344 struct winbindd_response response;
345 struct winbindd_request request;
346 NSS_STATUS ret;
347 int i, idx;
348 char *tmpbuf;
349 int num_gids;
350 gid_t *gid_list;
351 char *r_user = user;
353 if (*user == WB_AIX_ENCODED) {
354 r_user = decode_user(r_user);
355 if (!r_user) {
356 errno = ENOENT;
357 return NULL;
361 logit("getgrset '%s'\n", r_user);
363 ZERO_STRUCT(response);
364 ZERO_STRUCT(request);
366 STRCPY_RETNULL(request.data.username, r_user);
368 if (*user == WB_AIX_ENCODED) {
369 free(r_user);
372 ret = winbindd_request_response(WINBINDD_GETGROUPS, &request, &response);
374 HANDLE_ERRORS(ret);
376 num_gids = response.data.num_entries;
377 gid_list = (gid_t *)response.extra_data.data;
379 /* allocate a space large enough to contruct the string */
380 tmpbuf = malloc(num_gids*12);
381 if (!tmpbuf) {
382 return NULL;
385 for (idx=i=0; i < num_gids-1; i++) {
386 idx += sprintf(tmpbuf+idx, "%u,", gid_list[i]);
388 idx += sprintf(tmpbuf+idx, "%u", gid_list[i]);
390 free_response(&response);
392 return tmpbuf;
396 /* take a uid and return a filled struct passwd */
397 static struct passwd *wb_aix_getpwuid(uid_t uid)
399 struct winbindd_response response;
400 struct winbindd_request request;
401 NSS_STATUS ret;
402 struct passwd *pwd;
404 logit("getpwuid '%d'\n", uid);
406 ZERO_STRUCT(response);
407 ZERO_STRUCT(request);
409 request.data.uid = uid;
411 ret = winbindd_request_response(WINBINDD_GETPWUID, &request, &response);
413 HANDLE_ERRORS(ret);
415 pwd = fill_pwent(&response.data.pw);
417 free_response(&response);
419 logit("getpwuid gave ptr %p\n", pwd);
421 return pwd;
425 /* take a username and return a filled struct passwd */
426 static struct passwd *wb_aix_getpwnam(const char *name)
428 struct winbindd_response response;
429 struct winbindd_request request;
430 NSS_STATUS ret;
431 struct passwd *pwd;
433 if (*name == WB_AIX_ENCODED) {
434 return wb_aix_getpwuid(decode_id(name));
437 logit("getpwnam '%s'\n", name);
439 ZERO_STRUCT(response);
440 ZERO_STRUCT(request);
442 STRCPY_RETNULL(request.data.username, name);
444 ret = winbindd_request_response(WINBINDD_GETPWNAM, &request, &response);
446 HANDLE_ERRORS(ret);
448 pwd = fill_pwent(&response.data.pw);
450 free_response(&response);
452 logit("getpwnam gave ptr %p\n", pwd);
454 return pwd;
458 list users
460 static int wb_aix_lsuser(char *attributes[], attrval_t results[], int size)
462 NSS_STATUS ret;
463 struct winbindd_request request;
464 struct winbindd_response response;
465 int len;
466 char *s;
468 if (size != 1 || strcmp(attributes[0], S_USERS) != 0) {
469 logit("invalid lsuser op\n");
470 errno = EINVAL;
471 return -1;
474 ZERO_STRUCT(request);
475 ZERO_STRUCT(response);
477 ret = winbindd_request_response(WINBINDD_LIST_USERS, &request, &response);
478 if (ret != 0) {
479 errno = EINVAL;
480 return -1;
483 len = strlen(response.extra_data.data);
485 s = malloc(len+2);
486 if (!s) {
487 free_response(&response);
488 errno = ENOMEM;
489 return -1;
492 memcpy(s, response.extra_data.data, len+1);
494 replace_commas(s);
496 results[0].attr_un.au_char = s;
497 results[0].attr_flag = 0;
499 free_response(&response);
501 return 0;
506 list groups
508 static int wb_aix_lsgroup(char *attributes[], attrval_t results[], int size)
510 NSS_STATUS ret;
511 struct winbindd_request request;
512 struct winbindd_response response;
513 int len;
514 char *s;
516 if (size != 1 || strcmp(attributes[0], S_GROUPS) != 0) {
517 logit("invalid lsgroup op\n");
518 errno = EINVAL;
519 return -1;
522 ZERO_STRUCT(request);
523 ZERO_STRUCT(response);
525 ret = winbindd_request_response(WINBINDD_LIST_GROUPS, &request, &response);
526 if (ret != 0) {
527 errno = EINVAL;
528 return -1;
531 len = strlen(response.extra_data.data);
533 s = malloc(len+2);
534 if (!s) {
535 free_response(&response);
536 errno = ENOMEM;
537 return -1;
540 memcpy(s, response.extra_data.data, len+1);
542 replace_commas(s);
544 results[0].attr_un.au_char = s;
545 results[0].attr_flag = 0;
547 free_response(&response);
549 return 0;
553 static attrval_t pwd_to_group(struct passwd *pwd)
555 attrval_t r;
556 struct group *grp = wb_aix_getgrgid(pwd->pw_gid);
558 if (!grp) {
559 r.attr_flag = EINVAL;
560 } else {
561 r.attr_flag = 0;
562 r.attr_un.au_char = strdup(grp->gr_name);
563 free_grp(grp);
566 return r;
569 static attrval_t pwd_to_groupsids(struct passwd *pwd)
571 attrval_t r;
572 char *s, *p;
574 s = wb_aix_getgrset(pwd->pw_name);
575 if (!s) {
576 r.attr_flag = EINVAL;
577 return r;
580 p = malloc(strlen(s)+2);
581 if (!p) {
582 r.attr_flag = ENOMEM;
583 return r;
586 strcpy(p, s);
587 replace_commas(p);
588 free(s);
590 r.attr_un.au_char = p;
592 return r;
595 static attrval_t pwd_to_sid(struct passwd *pwd)
597 struct winbindd_request request;
598 struct winbindd_response response;
599 attrval_t r;
601 ZERO_STRUCT(request);
602 ZERO_STRUCT(response);
604 request.data.uid = pwd->pw_uid;
606 if (winbindd_request_response(WINBINDD_UID_TO_SID, &request, &response) !=
607 NSS_STATUS_SUCCESS) {
608 r.attr_flag = ENOENT;
609 } else {
610 r.attr_flag = 0;
611 r.attr_un.au_char = strdup(response.data.sid.sid);
614 return r;
617 static int wb_aix_user_attrib(const char *key, char *attributes[],
618 attrval_t results[], int size)
620 struct passwd *pwd;
621 int i;
623 pwd = wb_aix_getpwnam(key);
624 if (!pwd) {
625 errno = ENOENT;
626 return -1;
629 for (i=0;i<size;i++) {
630 results[i].attr_flag = 0;
632 if (strcmp(attributes[i], S_ID) == 0) {
633 results[i].attr_un.au_int = pwd->pw_uid;
634 } else if (strcmp(attributes[i], S_PWD) == 0) {
635 results[i].attr_un.au_char = strdup(pwd->pw_passwd);
636 } else if (strcmp(attributes[i], S_HOME) == 0) {
637 results[i].attr_un.au_char = strdup(pwd->pw_dir);
638 } else if (strcmp(attributes[i], S_SHELL) == 0) {
639 results[i].attr_un.au_char = strdup(pwd->pw_shell);
640 } else if (strcmp(attributes[i], S_REGISTRY) == 0) {
641 results[i].attr_un.au_char = strdup("WINBIND");
642 } else if (strcmp(attributes[i], S_GECOS) == 0) {
643 results[i].attr_un.au_char = strdup(pwd->pw_gecos);
644 } else if (strcmp(attributes[i], S_PGRP) == 0) {
645 results[i] = pwd_to_group(pwd);
646 } else if (strcmp(attributes[i], S_GROUPS) == 0) {
647 results[i] = pwd_to_groupsids(pwd);
648 } else if (strcmp(attributes[i], "SID") == 0) {
649 results[i] = pwd_to_sid(pwd);
650 } else {
651 logit("Unknown user attribute '%s'\n", attributes[i]);
652 results[i].attr_flag = EINVAL;
656 free_pwd(pwd);
658 return 0;
661 static int wb_aix_group_attrib(const char *key, char *attributes[],
662 attrval_t results[], int size)
664 struct group *grp;
665 int i;
667 grp = wb_aix_getgrnam(key);
668 if (!grp) {
669 errno = ENOENT;
670 return -1;
673 for (i=0;i<size;i++) {
674 results[i].attr_flag = 0;
676 if (strcmp(attributes[i], S_PWD) == 0) {
677 results[i].attr_un.au_char = strdup(grp->gr_passwd);
678 } else if (strcmp(attributes[i], S_ID) == 0) {
679 results[i].attr_un.au_int = grp->gr_gid;
680 } else {
681 logit("Unknown group attribute '%s'\n", attributes[i]);
682 results[i].attr_flag = EINVAL;
686 free_grp(grp);
688 return 0;
693 called for user/group enumerations
695 static int wb_aix_getentry(char *key, char *table, char *attributes[],
696 attrval_t results[], int size)
698 logit("Got getentry with key='%s' table='%s' size=%d attributes[0]='%s'\n",
699 key, table, size, attributes[0]);
701 if (strcmp(key, "ALL") == 0 &&
702 strcmp(table, "user") == 0) {
703 return wb_aix_lsuser(attributes, results, size);
706 if (strcmp(key, "ALL") == 0 &&
707 strcmp(table, "group") == 0) {
708 return wb_aix_lsgroup(attributes, results, size);
711 if (strcmp(table, "user") == 0) {
712 return wb_aix_user_attrib(key, attributes, results, size);
715 if (strcmp(table, "group") == 0) {
716 return wb_aix_group_attrib(key, attributes, results, size);
719 logit("Unknown getentry operation key='%s' table='%s'\n", key, table);
721 errno = ENOSYS;
722 return -1;
728 called to start the backend
730 static void *wb_aix_open(const char *name, const char *domain, int mode, char *options)
732 if (strstr(options, "debug")) {
733 debug_enabled = 1;
735 logit("open name='%s' mode=%d domain='%s' options='%s'\n", name, domain,
736 mode, options);
737 return NULL;
740 static void wb_aix_close(void *token)
742 logit("close\n");
743 return;
746 #ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_ATTRLIST
748 return a list of additional attributes supported by the backend
750 static attrlist_t **wb_aix_attrlist(void)
752 attrlist_t **ret;
753 logit("method attrlist called\n");
754 ret = malloc(2*sizeof(attrlist_t *) + sizeof(attrlist_t));
755 if (!ret) {
756 errno = ENOMEM;
757 return NULL;
760 ret[0] = (attrlist_t *)(ret+2);
762 /* just one extra attribute - the windows SID */
763 ret[0]->al_name = strdup("SID");
764 ret[0]->al_flags = AL_USERATTR;
765 ret[0]->al_type = SEC_CHAR;
766 ret[1] = NULL;
768 return ret;
770 #endif
774 turn a long username into a short one. Needed to cope with the 8 char
775 username limit in AIX 5.2 and below
777 static int wb_aix_normalize(char *longname, char *shortname)
779 struct passwd *pwd;
781 logit("normalize '%s'\n", longname);
783 /* automatically cope with AIX 5.3 with longer usernames
784 when it comes out */
785 if (S_NAMELEN > strlen(longname)) {
786 strcpy(shortname, longname);
787 return 1;
790 pwd = wb_aix_getpwnam(longname);
791 if (!pwd) {
792 errno = ENOENT;
793 return 0;
796 sprintf(shortname, "%c%07u", WB_AIX_ENCODED, pwd->pw_uid);
798 free_pwd(pwd);
800 return 1;
805 authenticate a user
807 static int wb_aix_authenticate(char *user, char *pass,
808 int *reenter, char **message)
810 struct winbindd_request request;
811 struct winbindd_response response;
812 NSS_STATUS result;
813 char *r_user = user;
815 logit("authenticate '%s' response='%s'\n", user, pass);
817 *reenter = 0;
818 *message = NULL;
820 /* Send off request */
821 ZERO_STRUCT(request);
822 ZERO_STRUCT(response);
824 if (*user == WB_AIX_ENCODED) {
825 r_user = decode_user(r_user);
826 if (!r_user) {
827 return AUTH_NOTFOUND;
831 STRCPY_RET(request.data.auth.user, r_user);
832 STRCPY_RET(request.data.auth.pass, pass);
834 if (*user == WB_AIX_ENCODED) {
835 free(r_user);
838 result = winbindd_request_response(WINBINDD_PAM_AUTH, &request, &response);
840 free_response(&response);
842 logit("auth result %d for '%s'\n", result, user);
844 if (result == NSS_STATUS_SUCCESS) {
845 errno = 0;
846 return AUTH_SUCCESS;
849 return AUTH_FAILURE;
854 change a user password
856 static int wb_aix_chpass(char *user, char *oldpass, char *newpass, char **message)
858 struct winbindd_request request;
859 struct winbindd_response response;
860 NSS_STATUS result;
861 char *r_user = user;
863 if (*user == WB_AIX_ENCODED) {
864 r_user = decode_user(r_user);
865 if (!r_user) {
866 errno = ENOENT;
867 return -1;
871 logit("chpass '%s' old='%s' new='%s'\n", r_user, oldpass, newpass);
873 *message = NULL;
875 /* Send off request */
876 ZERO_STRUCT(request);
877 ZERO_STRUCT(response);
879 STRCPY_RET(request.data.chauthtok.user, r_user);
880 STRCPY_RET(request.data.chauthtok.oldpass, oldpass);
881 STRCPY_RET(request.data.chauthtok.newpass, newpass);
883 if (*user == WB_AIX_ENCODED) {
884 free(r_user);
887 result = winbindd_request_response(WINBINDD_PAM_CHAUTHTOK, &request, &response);
889 free_response(&response);
891 if (result == NSS_STATUS_SUCCESS) {
892 errno = 0;
893 return 0;
896 errno = EINVAL;
897 return -1;
901 don't do any password strength testing for now
903 static int wb_aix_passwdrestrictions(char *user, char *newpass, char *oldpass,
904 char **message)
906 logit("passwdresrictions called for '%s'\n", user);
907 return 0;
911 static int wb_aix_passwdexpired(char *user, char **message)
913 logit("passwdexpired '%s'\n", user);
914 /* we should check the account bits here */
915 return 0;
920 we can't return a crypt() password
922 static char *wb_aix_getpasswd(char *user)
924 logit("getpasswd '%s'\n", user);
925 errno = ENOSYS;
926 return NULL;
930 this is called to update things like the last login time. We don't
931 currently pass this onto the DC
933 static int wb_aix_putentry(char *key, char *table, char *attributes[],
934 attrval_t values[], int size)
936 logit("putentry key='%s' table='%s' attrib='%s'\n",
937 key, table, size>=1?attributes[0]:"<null>");
938 errno = ENOSYS;
939 return -1;
942 static int wb_aix_commit(char *key, char *table)
944 logit("commit key='%s' table='%s'\n");
945 errno = ENOSYS;
946 return -1;
949 static int wb_aix_getgrusers(char *group, void *result, int type, int *size)
951 logit("getgrusers group='%s'\n", group);
952 errno = ENOSYS;
953 return -1;
957 #define DECL_METHOD(x) \
958 int method_ ## x(void) \
960 logit("UNIMPLEMENTED METHOD '%s'\n", #x); \
961 errno = EINVAL; \
962 return -1; \
965 #if LOG_UNIMPLEMENTED_CALLS
966 DECL_METHOD(delgroup);
967 DECL_METHOD(deluser);
968 DECL_METHOD(newgroup);
969 DECL_METHOD(newuser);
970 DECL_METHOD(putgrent);
971 DECL_METHOD(putgrusers);
972 DECL_METHOD(putpwent);
973 DECL_METHOD(lock);
974 DECL_METHOD(unlock);
975 DECL_METHOD(getcred);
976 DECL_METHOD(setcred);
977 DECL_METHOD(deletecred);
978 #endif
980 int wb_aix_init(struct secmethod_table *methods)
982 ZERO_STRUCTP(methods);
984 #ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_VERSION
985 methods->method_version = SECMETHOD_VERSION_520;
986 #endif
988 methods->method_getgrgid = wb_aix_getgrgid;
989 methods->method_getgrnam = wb_aix_getgrnam;
990 methods->method_getgrset = wb_aix_getgrset;
991 methods->method_getpwnam = wb_aix_getpwnam;
992 methods->method_getpwuid = wb_aix_getpwuid;
993 methods->method_getentry = wb_aix_getentry;
994 methods->method_open = wb_aix_open;
995 methods->method_close = wb_aix_close;
996 methods->method_normalize = wb_aix_normalize;
997 methods->method_passwdexpired = wb_aix_passwdexpired;
998 methods->method_putentry = wb_aix_putentry;
999 methods->method_getpasswd = wb_aix_getpasswd;
1000 methods->method_authenticate = wb_aix_authenticate;
1001 methods->method_commit = wb_aix_commit;
1002 methods->method_chpass = wb_aix_chpass;
1003 methods->method_passwdrestrictions = wb_aix_passwdrestrictions;
1004 methods->method_getgracct = wb_aix_getgracct;
1005 methods->method_getgrusers = wb_aix_getgrusers;
1006 #ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_ATTRLIST
1007 methods->method_attrlist = wb_aix_attrlist;
1008 #endif
1010 #if LOG_UNIMPLEMENTED_CALLS
1011 methods->method_delgroup = method_delgroup;
1012 methods->method_deluser = method_deluser;
1013 methods->method_newgroup = method_newgroup;
1014 methods->method_newuser = method_newuser;
1015 methods->method_putgrent = method_putgrent;
1016 methods->method_putgrusers = method_putgrusers;
1017 methods->method_putpwent = method_putpwent;
1018 methods->method_lock = method_lock;
1019 methods->method_unlock = method_unlock;
1020 methods->method_getcred = method_getcred;
1021 methods->method_setcred = method_setcred;
1022 methods->method_deletecred = method_deletecred;
1023 #endif
1025 return AUTH_SUCCESS;