r3220: merging current 3.0 code to release branch
[Samba.git] / source / nsswitch / winbind_nss_aix.c
blobc90dc2f3f100b76e81d133d0b3e827ba3583509c
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(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);
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(WINBINDD_GETGRNAM, &request, &response);
315 HANDLE_ERRORS(ret);
317 grp = fill_grent(&response.data.gr, response.extra_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 STRCPY_RETNULL(request.data.username, r_user);
365 if (*user == WB_AIX_ENCODED) {
366 free(r_user);
369 ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
371 HANDLE_ERRORS(ret);
373 num_gids = response.data.num_entries;
374 gid_list = (gid_t *)response.extra_data;
376 /* allocate a space large enough to contruct the string */
377 tmpbuf = malloc(num_gids*12);
378 if (!tmpbuf) {
379 return NULL;
382 for (idx=i=0; i < num_gids-1; i++) {
383 idx += sprintf(tmpbuf+idx, "%u,", gid_list[i]);
385 idx += sprintf(tmpbuf+idx, "%u", gid_list[i]);
387 free_response(&response);
389 return tmpbuf;
393 /* take a uid and return a filled struct passwd */
394 static struct passwd *wb_aix_getpwuid(uid_t uid)
396 struct winbindd_response response;
397 struct winbindd_request request;
398 NSS_STATUS ret;
399 struct passwd *pwd;
401 logit("getpwuid '%d'\n", uid);
403 ZERO_STRUCT(response);
404 ZERO_STRUCT(request);
406 request.data.uid = uid;
408 ret = winbindd_request(WINBINDD_GETPWUID, &request, &response);
410 HANDLE_ERRORS(ret);
412 pwd = fill_pwent(&response.data.pw);
414 free_response(&response);
416 logit("getpwuid gave ptr %p\n", pwd);
418 return pwd;
422 /* take a username and return a filled struct passwd */
423 static struct passwd *wb_aix_getpwnam(const char *name)
425 struct winbindd_response response;
426 struct winbindd_request request;
427 NSS_STATUS ret;
428 struct passwd *pwd;
430 if (*name == WB_AIX_ENCODED) {
431 return wb_aix_getpwuid(decode_id(name));
434 logit("getpwnam '%s'\n", name);
436 ZERO_STRUCT(response);
437 ZERO_STRUCT(request);
439 STRCPY_RETNULL(request.data.username, name);
441 ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response);
443 HANDLE_ERRORS(ret);
445 pwd = fill_pwent(&response.data.pw);
447 free_response(&response);
449 logit("getpwnam gave ptr %p\n", pwd);
451 return pwd;
455 list users
457 static int wb_aix_lsuser(char *attributes[], attrval_t results[], int size)
459 NSS_STATUS ret;
460 struct winbindd_request request;
461 struct winbindd_response response;
462 int len;
463 char *s;
465 if (size != 1 || strcmp(attributes[0], S_USERS) != 0) {
466 logit("invalid lsuser op\n");
467 errno = EINVAL;
468 return -1;
471 ZERO_STRUCT(request);
472 ZERO_STRUCT(response);
474 ret = winbindd_request(WINBINDD_LIST_USERS, &request, &response);
475 if (ret != 0) {
476 errno = EINVAL;
477 return -1;
480 len = strlen(response.extra_data);
482 s = malloc(len+2);
483 if (!s) {
484 free_response(&response);
485 errno = ENOMEM;
486 return -1;
489 memcpy(s, response.extra_data, len+1);
491 replace_commas(s);
493 results[0].attr_un.au_char = s;
494 results[0].attr_flag = 0;
496 free_response(&response);
498 return 0;
503 list groups
505 static int wb_aix_lsgroup(char *attributes[], attrval_t results[], int size)
507 NSS_STATUS ret;
508 struct winbindd_request request;
509 struct winbindd_response response;
510 int len;
511 char *s;
513 if (size != 1 || strcmp(attributes[0], S_GROUPS) != 0) {
514 logit("invalid lsgroup op\n");
515 errno = EINVAL;
516 return -1;
519 ZERO_STRUCT(request);
520 ZERO_STRUCT(response);
522 ret = winbindd_request(WINBINDD_LIST_GROUPS, &request, &response);
523 if (ret != 0) {
524 errno = EINVAL;
525 return -1;
528 len = strlen(response.extra_data);
530 s = malloc(len+2);
531 if (!s) {
532 free_response(&response);
533 errno = ENOMEM;
534 return -1;
537 memcpy(s, response.extra_data, len+1);
539 replace_commas(s);
541 results[0].attr_un.au_char = s;
542 results[0].attr_flag = 0;
544 free_response(&response);
546 return 0;
550 static attrval_t pwd_to_group(struct passwd *pwd)
552 attrval_t r;
553 struct group *grp = wb_aix_getgrgid(pwd->pw_gid);
555 if (!grp) {
556 r.attr_flag = EINVAL;
557 } else {
558 r.attr_flag = 0;
559 r.attr_un.au_char = strdup(grp->gr_name);
560 free_grp(grp);
563 return r;
566 static attrval_t pwd_to_groupsids(struct passwd *pwd)
568 attrval_t r;
569 char *s, *p;
571 s = wb_aix_getgrset(pwd->pw_name);
572 if (!s) {
573 r.attr_flag = EINVAL;
574 return r;
577 p = malloc(strlen(s)+2);
578 if (!p) {
579 r.attr_flag = ENOMEM;
580 return r;
583 strcpy(p, s);
584 replace_commas(p);
585 free(s);
587 r.attr_un.au_char = p;
589 return r;
592 static attrval_t pwd_to_sid(struct passwd *pwd)
594 struct winbindd_request request;
595 struct winbindd_response response;
596 attrval_t r;
598 ZERO_STRUCT(request);
599 ZERO_STRUCT(response);
601 request.data.uid = pwd->pw_uid;
603 if (winbindd_request(WINBINDD_UID_TO_SID, &request, &response) !=
604 NSS_STATUS_SUCCESS) {
605 r.attr_flag = ENOENT;
606 } else {
607 r.attr_flag = 0;
608 r.attr_un.au_char = strdup(response.data.sid.sid);
611 return r;
614 static int wb_aix_user_attrib(const char *key, char *attributes[],
615 attrval_t results[], int size)
617 struct passwd *pwd;
618 int i;
620 pwd = wb_aix_getpwnam(key);
621 if (!pwd) {
622 errno = ENOENT;
623 return -1;
626 for (i=0;i<size;i++) {
627 results[i].attr_flag = 0;
629 if (strcmp(attributes[i], S_ID) == 0) {
630 results[i].attr_un.au_int = pwd->pw_uid;
631 } else if (strcmp(attributes[i], S_PWD) == 0) {
632 results[i].attr_un.au_char = strdup(pwd->pw_passwd);
633 } else if (strcmp(attributes[i], S_HOME) == 0) {
634 results[i].attr_un.au_char = strdup(pwd->pw_dir);
635 } else if (strcmp(attributes[0], S_SHELL) == 0) {
636 results[i].attr_un.au_char = strdup(pwd->pw_shell);
637 } else if (strcmp(attributes[0], S_REGISTRY) == 0) {
638 results[i].attr_un.au_char = strdup("WINBIND");
639 } else if (strcmp(attributes[0], S_GECOS) == 0) {
640 results[i].attr_un.au_char = strdup(pwd->pw_gecos);
641 } else if (strcmp(attributes[0], S_PGRP) == 0) {
642 results[i] = pwd_to_group(pwd);
643 } else if (strcmp(attributes[0], S_GECOS) == 0) {
644 results[i].attr_un.au_char = strdup(pwd->pw_gecos);
645 } else if (strcmp(attributes[0], S_GROUPSIDS) == 0) {
646 results[i] = pwd_to_groupsids(pwd);
647 } else if (strcmp(attributes[0], "SID") == 0) {
648 results[i] = pwd_to_sid(pwd);
649 } else {
650 logit("Unknown user attribute '%s'\n", attributes[i]);
651 results[i].attr_flag = EINVAL;
655 free_pwd(pwd);
657 return 0;
660 static int wb_aix_group_attrib(const char *key, char *attributes[],
661 attrval_t results[], int size)
663 struct group *grp;
664 int i;
666 grp = wb_aix_getgrnam(key);
667 if (!grp) {
668 errno = ENOENT;
669 return -1;
672 for (i=0;i<size;i++) {
673 results[i].attr_flag = 0;
675 if (strcmp(attributes[i], S_PWD) == 0) {
676 results[i].attr_un.au_char = strdup(grp->gr_passwd);
677 } else if (strcmp(attributes[i], S_ID) == 0) {
678 results[i].attr_un.au_int = grp->gr_gid;
679 } else {
680 logit("Unknown group attribute '%s'\n", attributes[i]);
681 results[i].attr_flag = EINVAL;
685 free_grp(grp);
687 return 0;
692 called for user/group enumerations
694 static int wb_aix_getentry(char *key, char *table, char *attributes[],
695 attrval_t results[], int size)
697 logit("Got getentry with key='%s' table='%s' size=%d attributes[0]='%s'\n",
698 key, table, size, attributes[0]);
700 if (strcmp(key, "ALL") == 0 &&
701 strcmp(table, "user") == 0) {
702 return wb_aix_lsuser(attributes, results, size);
705 if (strcmp(key, "ALL") == 0 &&
706 strcmp(table, "group") == 0) {
707 return wb_aix_lsgroup(attributes, results, size);
710 if (strcmp(table, "user") == 0) {
711 return wb_aix_user_attrib(key, attributes, results, size);
714 if (strcmp(table, "group") == 0) {
715 return wb_aix_group_attrib(key, attributes, results, size);
718 logit("Unknown getentry operation key='%s' table='%s'\n", key, table);
720 errno = ENOSYS;
721 return -1;
727 called to start the backend
729 static void *wb_aix_open(const char *name, const char *domain, int mode, char *options)
731 if (strstr(options, "debug")) {
732 debug_enabled = 1;
734 logit("open name='%s' mode=%d domain='%s' options='%s'\n", name, domain,
735 mode, options);
736 return NULL;
739 static void wb_aix_close(void *token)
741 logit("close\n");
742 return;
745 #ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_ATTRLIST
747 return a list of additional attributes supported by the backend
749 static attrlist_t **wb_aix_attrlist(void)
751 attrlist_t **ret;
752 logit("method attrlist called\n");
753 ret = malloc(2*sizeof(attrlist_t *) + sizeof(attrlist_t));
754 if (!ret) {
755 errno = ENOMEM;
756 return NULL;
759 ret[0] = (attrlist_t *)(ret+2);
761 /* just one extra attribute - the windows SID */
762 ret[0]->al_name = strdup("SID");
763 ret[0]->al_flags = AL_USERATTR;
764 ret[0]->al_type = SEC_CHAR;
765 ret[1] = NULL;
767 return ret;
769 #endif
773 turn a long username into a short one. Needed to cope with the 8 char
774 username limit in AIX 5.2 and below
776 static int wb_aix_normalize(char *longname, char *shortname)
778 struct passwd *pwd;
780 logit("normalize '%s'\n", longname);
782 /* automatically cope with AIX 5.3 with longer usernames
783 when it comes out */
784 if (S_NAMELEN > strlen(longname)) {
785 strcpy(shortname, longname);
786 return 1;
789 pwd = wb_aix_getpwnam(longname);
790 if (!pwd) {
791 errno = ENOENT;
792 return 0;
795 sprintf(shortname, "%c%07u", WB_AIX_ENCODED, pwd->pw_uid);
797 free_pwd(pwd);
799 return 1;
804 authenticate a user
806 static int wb_aix_authenticate(char *user, char *pass,
807 int *reenter, char **message)
809 struct winbindd_request request;
810 struct winbindd_response response;
811 NSS_STATUS result;
812 char *r_user = user;
814 logit("authenticate '%s' response='%s'\n", user, pass);
816 *reenter = 0;
817 *message = NULL;
819 /* Send off request */
820 ZERO_STRUCT(request);
821 ZERO_STRUCT(response);
823 if (*user == WB_AIX_ENCODED) {
824 r_user = decode_user(r_user);
825 if (!r_user) {
826 return AUTH_NOTFOUND;
830 STRCPY_RET(request.data.auth.user, r_user);
831 STRCPY_RET(request.data.auth.pass, pass);
833 if (*user == WB_AIX_ENCODED) {
834 free(r_user);
837 result = winbindd_request(WINBINDD_PAM_AUTH, &request, &response);
839 free_response(&response);
841 logit("auth result %d for '%s'\n", result, user);
843 if (result == NSS_STATUS_SUCCESS) {
844 errno = 0;
845 return AUTH_SUCCESS;
848 return AUTH_FAILURE;
853 change a user password
855 static int wb_aix_chpass(char *user, char *oldpass, char *newpass, char **message)
857 struct winbindd_request request;
858 struct winbindd_response response;
859 NSS_STATUS result;
860 char *r_user = user;
862 if (*user == WB_AIX_ENCODED) {
863 r_user = decode_user(r_user);
864 if (!r_user) {
865 errno = ENOENT;
866 return -1;
870 logit("chpass '%s' old='%s' new='%s'\n", r_user, oldpass, newpass);
872 *message = NULL;
874 /* Send off request */
875 ZERO_STRUCT(request);
876 ZERO_STRUCT(response);
878 STRCPY_RET(request.data.chauthtok.user, r_user);
879 STRCPY_RET(request.data.chauthtok.oldpass, oldpass);
880 STRCPY_RET(request.data.chauthtok.newpass, newpass);
882 if (*user == WB_AIX_ENCODED) {
883 free(r_user);
886 result = winbindd_request(WINBINDD_PAM_CHAUTHTOK, &request, &response);
888 free_response(&response);
890 if (result == NSS_STATUS_SUCCESS) {
891 errno = 0;
892 return 0;
895 errno = EINVAL;
896 return -1;
900 don't do any password strength testing for now
902 static int wb_aix_passwdrestrictions(char *user, char *newpass, char *oldpass,
903 char **message)
905 logit("passwdresrictions called for '%s'\n", user);
906 return 0;
910 static int wb_aix_passwdexpired(char *user, char **message)
912 logit("passwdexpired '%s'\n", user);
913 /* we should check the account bits here */
914 return 0;
919 we can't return a crypt() password
921 static char *wb_aix_getpasswd(char *user)
923 logit("getpasswd '%s'\n", user);
924 errno = ENOSYS;
925 return NULL;
929 this is called to update things like the last login time. We don't
930 currently pass this onto the DC
932 static int wb_aix_putentry(char *key, char *table, char *attributes[],
933 attrval_t values[], int size)
935 logit("putentry key='%s' table='%s' attrib='%s'\n",
936 key, table, size>=1?attributes[0]:"<null>");
937 errno = ENOSYS;
938 return -1;
941 static int wb_aix_commit(char *key, char *table)
943 logit("commit key='%s' table='%s'\n");
944 errno = ENOSYS;
945 return -1;
948 static int wb_aix_getgrusers(char *group, void *result, int type, int *size)
950 logit("getgrusers group='%s'\n", group);
951 errno = ENOSYS;
952 return -1;
956 #define DECL_METHOD(x) \
957 int method_ ## x(void) \
959 logit("UNIMPLEMENTED METHOD '%s'\n", #x); \
960 errno = EINVAL; \
961 return -1; \
964 #if LOG_UNIMPLEMENTED_CALLS
965 DECL_METHOD(delgroup);
966 DECL_METHOD(deluser);
967 DECL_METHOD(newgroup);
968 DECL_METHOD(newuser);
969 DECL_METHOD(putgrent);
970 DECL_METHOD(putgrusers);
971 DECL_METHOD(putpwent);
972 DECL_METHOD(lock);
973 DECL_METHOD(unlock);
974 DECL_METHOD(getcred);
975 DECL_METHOD(setcred);
976 DECL_METHOD(deletecred);
977 #endif
979 int wb_aix_init(struct secmethod_table *methods)
981 ZERO_STRUCTP(methods);
983 #ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_VERSION
984 methods->method_version = SECMETHOD_VERSION_520;
985 #endif
987 methods->method_getgrgid = wb_aix_getgrgid;
988 methods->method_getgrnam = wb_aix_getgrnam;
989 methods->method_getgrset = wb_aix_getgrset;
990 methods->method_getpwnam = wb_aix_getpwnam;
991 methods->method_getpwuid = wb_aix_getpwuid;
992 methods->method_getentry = wb_aix_getentry;
993 methods->method_open = wb_aix_open;
994 methods->method_close = wb_aix_close;
995 methods->method_normalize = wb_aix_normalize;
996 methods->method_passwdexpired = wb_aix_passwdexpired;
997 methods->method_putentry = wb_aix_putentry;
998 methods->method_getpasswd = wb_aix_getpasswd;
999 methods->method_authenticate = wb_aix_authenticate;
1000 methods->method_commit = wb_aix_commit;
1001 methods->method_chpass = wb_aix_chpass;
1002 methods->method_passwdrestrictions = wb_aix_passwdrestrictions;
1003 methods->method_getgracct = wb_aix_getgracct;
1004 methods->method_getgrusers = wb_aix_getgrusers;
1005 #ifdef HAVE_STRUCT_SECMETHOD_TABLE_METHOD_ATTRLIST
1006 methods->method_attrlist = wb_aix_attrlist;
1007 #endif
1009 #if LOG_UNIMPLEMENTED_CALLS
1010 methods->method_delgroup = method_delgroup;
1011 methods->method_deluser = method_deluser;
1012 methods->method_newgroup = method_newgroup;
1013 methods->method_newuser = method_newuser;
1014 methods->method_putgrent = method_putgrent;
1015 methods->method_putgrusers = method_putgrusers;
1016 methods->method_putpwent = method_putpwent;
1017 methods->method_lock = method_lock;
1018 methods->method_unlock = method_unlock;
1019 methods->method_getcred = method_getcred;
1020 methods->method_setcred = method_setcred;
1021 methods->method_deletecred = method_deletecred;
1022 #endif
1024 return AUTH_SUCCESS;