|
Packit |
6bd9ab |
/*
|
|
Packit |
6bd9ab |
bsdnss.c - BSD NSS functions
|
|
Packit |
6bd9ab |
This file was part of the nss-pam-ldapd FreeBSD port and part of the
|
|
Packit |
6bd9ab |
nss_ldap FreeBSD port before that.
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
Copyright (C) 2003 Jacques Vidrine
|
|
Packit |
6bd9ab |
Copyright (C) 2006 Artem Kazakov
|
|
Packit |
6bd9ab |
Copyright (C) 2009 Alexander V. Chernikov
|
|
Packit |
6bd9ab |
Copyright (C) 2011-2016 Arthur de Jong
|
|
Packit |
6bd9ab |
Copyright (C) 2011 Tom Judge
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
This library is free software; you can redistribute it and/or
|
|
Packit |
6bd9ab |
modify it under the terms of the GNU Lesser General Public
|
|
Packit |
6bd9ab |
License as published by the Free Software Foundation; either
|
|
Packit |
6bd9ab |
version 2.1 of the License, or (at your option) any later version.
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
This library is distributed in the hope that it will be useful,
|
|
Packit |
6bd9ab |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
6bd9ab |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
6bd9ab |
Lesser General Public License for more details.
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
6bd9ab |
License along with this library; if not, write to the Free Software
|
|
Packit |
6bd9ab |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit |
6bd9ab |
02110-1301 USA
|
|
Packit |
6bd9ab |
*/
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
#include "config.h"
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
#include <errno.h>
|
|
Packit |
6bd9ab |
#include <sys/param.h>
|
|
Packit |
6bd9ab |
#include <netinet/in.h>
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
#include "prototypes.h"
|
|
Packit |
6bd9ab |
#include "common.h"
|
|
Packit |
6bd9ab |
#include "compat/attrs.h"
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
#define BUFFER_SIZE 1024
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_getgrnam_r);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_getgrgid_r);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_getgrent_r);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_setgrent);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_endgrent);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__freebsd_getgroupmembership);
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_getpwnam_r);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_getpwuid_r);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_getpwent_r);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_setpwent);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_endpwent);
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_gethostbyname);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_gethostbyname2);
|
|
Packit |
6bd9ab |
NSS_METHOD_PROTOTYPE(__nss_compat_gethostbyaddr);
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
static ns_mtab methods[] = {
|
|
Packit |
6bd9ab |
{ NSDB_GROUP, "getgrnam_r", __nss_compat_getgrnam_r, (void *)NSS_NAME(getgrnam_r) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP, "getgrgid_r", __nss_compat_getgrgid_r, (void *)NSS_NAME(getgrgid_r) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP, "getgrent_r", __nss_compat_getgrent_r, (void *)NSS_NAME(getgrent_r) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP, "setgrent", __nss_compat_setgrent, (void *)NSS_NAME(setgrent) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP, "endgrent", __nss_compat_endgrent, (void *)NSS_NAME(endgrent) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP, "getgroupmembership", __freebsd_getgroupmembership, NULL },
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD, "getpwnam_r", __nss_compat_getpwnam_r, (void *)NSS_NAME(getpwnam_r) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD, "getpwuid_r", __nss_compat_getpwuid_r, (void *)NSS_NAME(getpwuid_r) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD, "getpwent_r", __nss_compat_getpwent_r, (void *)NSS_NAME(getpwent_r) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD, "setpwent", __nss_compat_setpwent, (void *)NSS_NAME(setpwent) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD, "endpwent", __nss_compat_endpwent, (void *)NSS_NAME(endpwent) },
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
{ NSDB_HOSTS, "gethostbyname", __nss_compat_gethostbyname, (void *)NSS_NAME(gethostbyname_r) },
|
|
Packit |
6bd9ab |
{ NSDB_HOSTS, "gethostbyaddr", __nss_compat_gethostbyaddr, (void *)NSS_NAME(gethostbyaddr_r) },
|
|
Packit |
6bd9ab |
{ NSDB_HOSTS, "gethostbyname2", __nss_compat_gethostbyname2, (void *)NSS_NAME(gethostbyname2_r) },
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
{ NSDB_GROUP_COMPAT, "getgrnam_r", __nss_compat_getgrnam_r, (void *)NSS_NAME(getgrnam_r) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP_COMPAT, "getgrgid_r", __nss_compat_getgrgid_r, (void *)NSS_NAME(getgrgid_r) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP_COMPAT, "getgrent_r", __nss_compat_getgrent_r, (void *)NSS_NAME(getgrent_r) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP_COMPAT, "setgrent", __nss_compat_setgrent, (void *)NSS_NAME(setgrent) },
|
|
Packit |
6bd9ab |
{ NSDB_GROUP_COMPAT, "endgrent", __nss_compat_endgrent, (void *)NSS_NAME(endgrent) },
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD_COMPAT, "getpwnam_r", __nss_compat_getpwnam_r, (void *)NSS_NAME(getpwnam_r) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD_COMPAT, "getpwuid_r", __nss_compat_getpwuid_r, (void *)NSS_NAME(getpwuid_r) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD_COMPAT, "getpwent_r", __nss_compat_getpwent_r, (void *)NSS_NAME(getpwent_r) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD_COMPAT, "setpwent", __nss_compat_setpwent, (void *)NSS_NAME(setpwent) },
|
|
Packit |
6bd9ab |
{ NSDB_PASSWD_COMPAT, "endpwent", __nss_compat_endpwent, (void *)NSS_NAME(endpwent) },
|
|
Packit |
6bd9ab |
};
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
typedef nss_status_t (*gethbn_t)(const char *, struct hostent *, char *, size_t, int *, int *);
|
|
Packit |
6bd9ab |
typedef nss_status_t (*gethba_t)(struct in_addr *, int, int, struct hostent *, char *, size_t, int *, int *);
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
int __nss_compat_gethostbyname(void UNUSED(*retval), void *mdata, va_list ap)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
gethbn_t fn;
|
|
Packit |
6bd9ab |
const char *name;
|
|
Packit |
6bd9ab |
struct hostent *result;
|
|
Packit |
6bd9ab |
char buffer[BUFFER_SIZE];
|
|
Packit |
6bd9ab |
int errnop;
|
|
Packit |
6bd9ab |
int h_errnop;
|
|
Packit |
6bd9ab |
int af;
|
|
Packit |
6bd9ab |
nss_status_t status;
|
|
Packit |
6bd9ab |
fn = (gethbn_t)mdata;
|
|
Packit |
6bd9ab |
name = va_arg(ap, const char *);
|
|
Packit |
6bd9ab |
af = va_arg(ap, int);
|
|
Packit |
6bd9ab |
result = va_arg(ap, struct hostent *);
|
|
Packit |
6bd9ab |
status = fn(name, result, buffer, sizeof(buffer), &errnop, &h_errnop);
|
|
Packit |
6bd9ab |
status = __nss_compat_result(status, errnop);
|
|
Packit |
6bd9ab |
h_errno = h_errnop;
|
|
Packit |
6bd9ab |
return status;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
int __nss_compat_gethostbyname2(void UNUSED(*retval), void *mdata, va_list ap)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
gethbn_t fn;
|
|
Packit |
6bd9ab |
const char *name;
|
|
Packit |
6bd9ab |
struct hostent *result;
|
|
Packit |
6bd9ab |
char buffer[BUFFER_SIZE];
|
|
Packit |
6bd9ab |
int errnop;
|
|
Packit |
6bd9ab |
int h_errnop;
|
|
Packit |
6bd9ab |
int af;
|
|
Packit |
6bd9ab |
nss_status_t status;
|
|
Packit |
6bd9ab |
fn = (gethbn_t)mdata;
|
|
Packit |
6bd9ab |
name = va_arg(ap, const char *);
|
|
Packit |
6bd9ab |
af = va_arg(ap, int);
|
|
Packit |
6bd9ab |
result = va_arg(ap, struct hostent *);
|
|
Packit |
6bd9ab |
status = fn(name, result, buffer, sizeof(buffer), &errnop, &h_errnop);
|
|
Packit |
6bd9ab |
status = __nss_compat_result(status, errnop);
|
|
Packit |
6bd9ab |
h_errno = h_errnop;
|
|
Packit |
6bd9ab |
return status;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
int __nss_compat_gethostbyaddr(void UNUSED(*retval), void *mdata, va_list ap)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
gethba_t fn;
|
|
Packit |
6bd9ab |
struct in_addr *addr;
|
|
Packit |
6bd9ab |
int len;
|
|
Packit |
6bd9ab |
int type;
|
|
Packit |
6bd9ab |
struct hostent *result;
|
|
Packit |
6bd9ab |
char buffer[BUFFER_SIZE];
|
|
Packit |
6bd9ab |
int errnop;
|
|
Packit |
6bd9ab |
int h_errnop;
|
|
Packit |
6bd9ab |
nss_status_t status;
|
|
Packit |
6bd9ab |
fn = (gethba_t)mdata;
|
|
Packit |
6bd9ab |
addr = va_arg(ap, struct in_addr *);
|
|
Packit |
6bd9ab |
len = va_arg(ap, int);
|
|
Packit |
6bd9ab |
type = va_arg(ap, int);
|
|
Packit |
6bd9ab |
result = va_arg(ap, struct hostent *);
|
|
Packit |
6bd9ab |
status = fn(addr, len, type, result, buffer, sizeof(buffer), &errnop, &h_errnop);
|
|
Packit |
6bd9ab |
status = __nss_compat_result(status, errnop);
|
|
Packit |
6bd9ab |
h_errno = h_errnop;
|
|
Packit |
6bd9ab |
return status;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
static int __gr_addgid(gid_t gid, gid_t *groups, int maxgrp, int *groupc)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
int ret, dupc;
|
|
Packit |
6bd9ab |
/* skip duplicates */
|
|
Packit |
6bd9ab |
for (dupc = 0; dupc < MIN(maxgrp, *groupc); dupc++)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
if (groups[dupc] == gid)
|
|
Packit |
6bd9ab |
return 1;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
ret = 1;
|
|
Packit |
6bd9ab |
if (*groupc < maxgrp) /* add this gid */
|
|
Packit |
6bd9ab |
groups[*groupc] = gid;
|
|
Packit |
6bd9ab |
else
|
|
Packit |
6bd9ab |
ret = 0;
|
|
Packit |
6bd9ab |
(*groupc)++;
|
|
Packit |
6bd9ab |
return ret;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
int __freebsd_getgroupmembership(void UNUSED(*retval), void UNUSED(*mdata_),
|
|
Packit |
6bd9ab |
va_list ap)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
int err;
|
|
Packit |
6bd9ab |
nss_status_t s;
|
|
Packit |
6bd9ab |
gid_t group;
|
|
Packit |
6bd9ab |
gid_t *tmpgroups;
|
|
Packit |
6bd9ab |
const char *user;
|
|
Packit |
6bd9ab |
gid_t *groups;
|
|
Packit |
6bd9ab |
int maxgrp, *grpcnt;
|
|
Packit |
6bd9ab |
int i;
|
|
Packit |
6bd9ab |
long int lstart, lsize;
|
|
Packit |
6bd9ab |
user = va_arg(ap, const char *);
|
|
Packit |
6bd9ab |
group = va_arg(ap, gid_t);
|
|
Packit |
6bd9ab |
groups = va_arg(ap, gid_t *);
|
|
Packit |
6bd9ab |
maxgrp = va_arg(ap, int);
|
|
Packit |
6bd9ab |
grpcnt = va_arg(ap, int *);
|
|
Packit |
6bd9ab |
tmpgroups = malloc(maxgrp * sizeof(gid_t));
|
|
Packit |
6bd9ab |
if (tmpgroups == NULL)
|
|
Packit |
6bd9ab |
return NSS_STATUS_UNAVAIL;
|
|
Packit |
6bd9ab |
/* insert primary membership */
|
|
Packit |
6bd9ab |
__gr_addgid(group, groups, maxgrp, grpcnt);
|
|
Packit |
6bd9ab |
lstart = 0;
|
|
Packit |
6bd9ab |
lsize = maxgrp;
|
|
Packit |
6bd9ab |
s = NSS_NAME(initgroups_dyn)(user, group, &lstart, &lsize, &tmpgroups, 0, &err;;
|
|
Packit |
6bd9ab |
if (s == NSS_STATUS_SUCCESS)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
for (i = 0; i < lstart; i++)
|
|
Packit |
6bd9ab |
__gr_addgid(tmpgroups[i], groups, maxgrp, grpcnt);
|
|
Packit |
6bd9ab |
s = NSS_STATUS_NOTFOUND;
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
free(tmpgroups);
|
|
Packit |
6bd9ab |
return __nss_compat_result(s, 0);
|
|
Packit |
6bd9ab |
}
|
|
Packit |
6bd9ab |
|
|
Packit |
6bd9ab |
ns_mtab *nss_module_register(const char UNUSED(*source), unsigned int *mtabsize,
|
|
Packit |
6bd9ab |
nss_module_unregister_fn *unreg)
|
|
Packit |
6bd9ab |
{
|
|
Packit |
6bd9ab |
*mtabsize = sizeof(methods) / sizeof(methods[0]);
|
|
Packit |
6bd9ab |
*unreg = NULL;
|
|
Packit |
6bd9ab |
return methods;
|
|
Packit |
6bd9ab |
}
|