Blame nss/bsdnss.c

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
}