1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00
samba-mirror/source3/nsswitch/winbind_nss_aix.c

371 lines
7.0 KiB
C
Raw Normal View History

#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;
}