summaryrefslogtreecommitdiff
path: root/source3/nsswitch/winbind_nss_aix.c
diff options
context:
space:
mode:
authorTim Potter <tpot@samba.org>2003-04-02 06:16:15 +0000
committerTim Potter <tpot@samba.org>2003-04-02 06:16:15 +0000
commit759179b1902d2847cce199e2efa1f830ec675427 (patch)
tree1f92544247d7848911e25220ce33d341f8dd5d21 /source3/nsswitch/winbind_nss_aix.c
parent21c4559c84f4599a6b990a18dc3bb781ab5fd8c1 (diff)
downloadsamba-759179b1902d2847cce199e2efa1f830ec675427.tar.gz
samba-759179b1902d2847cce199e2efa1f830ec675427.tar.bz2
samba-759179b1902d2847cce199e2efa1f830ec675427.zip
Merge of winbind nss library cleanup from HEAD.
(This used to be commit a4b5f2c01bae049edc4f385cb0441bbde4fb443b)
Diffstat (limited to 'source3/nsswitch/winbind_nss_aix.c')
-rw-r--r--source3/nsswitch/winbind_nss_aix.c370
1 files changed, 370 insertions, 0 deletions
diff --git a/source3/nsswitch/winbind_nss_aix.c b/source3/nsswitch/winbind_nss_aix.c
index e69de29bb2..c06fbc7d4b 100644
--- a/source3/nsswitch/winbind_nss_aix.c
+++ b/source3/nsswitch/winbind_nss_aix.c
@@ -0,0 +1,370 @@
+
+#include <stdlib.h>
+#include <string.h>
+#include <usersec.h>
+#include <errno.h>
+
+#include "winbind_client.h"
+
+#define MAX_GETPWENT_USERS 250
+#define MAX_GETGRENT_USERS 250
+
+BOOL next_token(char **ptr,char *buff,char *sep, size_t bufsize)
+{
+ char *s;
+ BOOL quoted;
+ size_t len=1;
+
+ if (!ptr) return(False);
+
+ s = *ptr;
+
+ /* default to simple separators */
+ if (!sep) sep = " \t\n\r";
+
+ /* find the first non sep char */
+ while (*s && strchr(sep,*s)) s++;
+
+ /* nothing left? */
+ if (! *s) return(False);
+
+ /* copy over the token */
+ for (quoted = False; len < bufsize && *s && (quoted || !strchr(sep,*s)); s++) {
+ if (*s == '\"') {
+ quoted = !quoted;
+ } else {
+ len++;
+ *buff++ = *s;
+ }
+ }
+
+ *ptr = (*s) ? s+1 : s;
+ *buff = 0;
+
+ return(True);
+}
+
+static struct passwd *fill_pwent(struct winbindd_pw *pw)
+{
+ struct passwd *result;
+
+ if (!(result = malloc(sizeof(struct passwd)))) {
+ return NULL;
+ }
+ memset(result, 0, sizeof(struct passwd));
+
+ /* User name */
+
+ if ((result->pw_name = malloc(strlen(pw->pw_name) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy(result->pw_name, pw->pw_name);
+
+ /* Password */
+
+ if ((result->pw_passwd = malloc(strlen(pw->pw_passwd) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy(result->pw_passwd, pw->pw_passwd);
+
+ /* [ug]id */
+
+ result->pw_uid = pw->pw_uid;
+ result->pw_gid = pw->pw_gid;
+
+ /* GECOS */
+
+ if ((result->pw_gecos = malloc(strlen(pw->pw_gecos) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy(result->pw_gecos, pw->pw_gecos);
+
+ /* Home directory */
+
+ if ((result->pw_dir = malloc(strlen(pw->pw_dir) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy(result->pw_dir, pw->pw_dir);
+
+ /* Logon shell */
+
+ if ((result->pw_shell = malloc(strlen(pw->pw_shell) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy(result->pw_shell, pw->pw_shell);
+
+ return result;
+}
+
+static struct group *fill_grent(struct winbindd_gr *gr, char *gr_mem)
+{
+ fstring name;
+ int i;
+ char *tst;
+ struct group *result;
+
+ if (!(result = malloc(sizeof(struct group)))) {
+ return NULL;
+ }
+ memset(result, 0, sizeof(struct group));
+
+ /* Group name */
+
+ if ((result->gr_name = malloc(strlen(gr->gr_name) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy(result->gr_name, gr->gr_name);
+
+ /* Password */
+
+ if ((result->gr_passwd = malloc(strlen(gr->gr_passwd) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy(result->gr_passwd, gr->gr_passwd);
+
+ /* gid */
+
+ result->gr_gid = gr->gr_gid;
+
+ /* Group membership */
+
+ if ((gr->num_gr_mem < 0) || !gr_mem) {
+ gr->num_gr_mem = 0;
+ }
+
+ if (gr->num_gr_mem == 0) {
+
+ /* Group is empty */
+
+ *(result->gr_mem) = NULL;
+ return result;
+ }
+
+ if ((tst = malloc(((gr->num_gr_mem + 1) * sizeof(char *)))) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+ result->gr_mem = (char **)tst;
+
+ /* Start looking at extra data */
+
+ i = 0;
+
+ while(next_token((char **)&gr_mem, name, ",", sizeof(fstring))) {
+
+ /* Allocate space for member */
+
+ if (((result->gr_mem)[i] =
+ malloc(strlen(name) + 1)) == NULL) {
+
+ /* Out of memory */
+
+ return NULL;
+ }
+
+ strcpy((result->gr_mem)[i], name);
+ i++;
+ }
+
+ /* Terminate list */
+
+ (result->gr_mem)[i] = NULL;
+
+ return result;
+}
+
+
+
+static struct group *
+wb_aix_getgrgid (gid_t gid)
+{
+/* take a group id and return a filled struct group */
+
+ NSS_STATUS ret;
+ struct winbindd_response response;
+ struct winbindd_request request;
+
+ ZERO_STRUCT(response);
+ ZERO_STRUCT(request);
+
+ request.data.gid = gid;
+
+ ret = winbindd_request(WINBINDD_GETGRGID, &request, &response);
+
+ if (ret == NSS_STATUS_SUCCESS) {
+ return fill_grent(&response.data.gr, response.extra_data);
+ }
+ return NULL;
+}
+
+static struct group *
+wb_aix_getgrnam (const char *name)
+{
+/* take a group name and return a filled struct group */
+
+ NSS_STATUS ret;
+ struct winbindd_response response;
+ struct winbindd_request request;
+
+ ZERO_STRUCT(response);
+ ZERO_STRUCT(request);
+
+ strncpy(request.data.groupname, name,
+ sizeof(request.data.groupname));
+ request.data.groupname
+ [sizeof(request.data.groupname) - 1] = '\0';
+
+ ret = winbindd_request(WINBINDD_GETGRNAM, &request, &response);
+
+ if (ret == NSS_STATUS_SUCCESS) {
+ return fill_grent(&response.data.gr, response.extra_data);
+ }
+ return NULL;
+}
+
+static char *
+wb_aix_getgrset (const char *user)
+{
+/* take a username and return a string containing a comma-separated list of
+ group id numbers to which the user belongs */
+
+ NSS_STATUS ret;
+ struct winbindd_response response;
+ struct winbindd_request request;
+
+ char *tmpbuf, *result;
+ int i, idx = 0;
+
+ strncpy(request.data.username, user,
+ sizeof(request.data.username) - 1);
+ request.data.username
+ [sizeof(request.data.username) - 1] = '\0';
+
+ ret = winbindd_request(WINBINDD_GETGROUPS, &request, &response);
+
+ if (ret == NSS_STATUS_SUCCESS) {
+ int num_gids = response.data.num_entries;
+ gid_t *gid_list = (gid_t *)response.extra_data;
+
+ /* allocate a space large enough to contruct the string */
+ if (!(tmpbuf = malloc(num_gids*12))) {
+ return NULL;
+ }
+ idx += sprintf(tmpbuf, "%d", gid_list[0]);
+ for (i = 1; i < num_gids; i++) {
+ tmpbuf[idx++] = ',';
+ idx += sprintf(tmpbuf+idx, "%d", gid_list[i]);
+ }
+ tmpbuf[idx] = '\0';
+ if (!(result = malloc(idx+1))) {
+ /* allocate a string the right size to return, but
+ if that fails may as well return our working buffer
+ because it contains the same thing */
+ return tmpbuf;
+ }
+ strcpy(result, tmpbuf);
+ free(tmpbuf);
+ return result;
+ }
+ return NULL;
+}
+
+static struct passwd *
+wb_aix_getpwuid (uid_t uid)
+{
+/* take a uid and return a filled struct passwd */
+
+ NSS_STATUS ret;
+ struct winbindd_response response;
+ struct winbindd_request request;
+
+ ZERO_STRUCT(response);
+ ZERO_STRUCT(request);
+
+ request.data.uid = uid;
+
+ ret = winbindd_request(WINBINDD_GETPWUID, &request, &response);
+
+ if (ret == NSS_STATUS_SUCCESS) {
+ return fill_pwent(&response.data.pw);
+ }
+ return NULL;
+}
+
+static struct passwd *
+wb_aix_getpwnam (const char *name)
+{
+/* take a username and return a filled struct passwd */
+
+ NSS_STATUS ret;
+ struct winbindd_response response;
+ struct winbindd_request request;
+
+ ZERO_STRUCT(response);
+ ZERO_STRUCT(request);
+
+ strncpy(request.data.username, name,
+ sizeof(request.data.username) - 1);
+ request.data.username
+ [sizeof(request.data.username) - 1] = '\0';
+
+ ret = winbindd_request(WINBINDD_GETPWNAM, &request, &response);
+
+ if (ret == NSS_STATUS_SUCCESS) {
+ return fill_pwent(&response.data.pw);
+ }
+ return NULL;
+}
+
+int
+wb_aix_init (struct secmethod_table *methods)
+{
+ memset(methods, 0, sizeof(*methods));
+
+ /* identification methods */
+
+ methods->method_getgrgid = wb_aix_getgrgid;
+ methods->method_getgrnam = wb_aix_getgrnam;
+ methods->method_getgrset = wb_aix_getgrset;
+ methods->method_getpwnam = wb_aix_getpwnam;
+ methods->method_getpwuid = wb_aix_getpwuid;
+
+ /* support methods
+ methods->method_open = wb_aix_open;
+ methods->method_close = wb_aix_close;
+ */
+
+ return AUTH_SUCCESS;
+}
+
+