Blame nslcd/netgroup.c

Packit 6bd9ab
/*
Packit 6bd9ab
   netgroup.c - netgroup lookup routines
Packit 6bd9ab
   Parts of this file were part of the nss_ldap library (as ldap-netgrp.c)
Packit 6bd9ab
   which has been forked into the nss-pam-ldapd library.
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 1997-2005 Luke Howard
Packit 6bd9ab
   Copyright (C) 2006 West Consulting
Packit 6bd9ab
   Copyright (C) 2006-2014 Arthur de Jong
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 <stdio.h>
Packit 6bd9ab
#include <stdlib.h>
Packit 6bd9ab
#include <stdarg.h>
Packit 6bd9ab
#include <ctype.h>
Packit 6bd9ab
#include <sys/types.h>
Packit 6bd9ab
#include <sys/param.h>
Packit 6bd9ab
#include <string.h>
Packit 6bd9ab
Packit 6bd9ab
#include "common.h"
Packit 6bd9ab
#include "log.h"
Packit 6bd9ab
#include "myldap.h"
Packit 6bd9ab
#include "cfg.h"
Packit 6bd9ab
#include "attmap.h"
Packit 6bd9ab
Packit 6bd9ab
/* ( nisSchema.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL
Packit 6bd9ab
 *   DESC 'Abstraction of a netgroup. May refer to other netgroups'
Packit 6bd9ab
 *   MUST cn
Packit 6bd9ab
 *   MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
Packit 6bd9ab
 */
Packit 6bd9ab
Packit 6bd9ab
/* the search base for searches */
Packit 6bd9ab
const char *netgroup_bases[NSS_LDAP_CONFIG_MAX_BASES] = { NULL };
Packit 6bd9ab
Packit 6bd9ab
/* the search scope for searches */
Packit 6bd9ab
int netgroup_scope = LDAP_SCOPE_DEFAULT;
Packit 6bd9ab
Packit 6bd9ab
/* the basic search filter for searches */
Packit 6bd9ab
const char *netgroup_filter = "(objectClass=nisNetgroup)";
Packit 6bd9ab
Packit 6bd9ab
/* the attributes to request with searches */
Packit 6bd9ab
const char *attmap_netgroup_cn                = "cn";
Packit 6bd9ab
const char *attmap_netgroup_nisNetgroupTriple = "nisNetgroupTriple";
Packit 6bd9ab
const char *attmap_netgroup_memberNisNetgroup = "memberNisNetgroup";
Packit 6bd9ab
Packit 6bd9ab
/* the attribute list to request with searches */
Packit 6bd9ab
static const char *netgroup_attrs[4];
Packit 6bd9ab
Packit 6bd9ab
static int mkfilter_netgroup_byname(const char *name,
Packit 6bd9ab
                                    char *buffer, size_t buflen)
Packit 6bd9ab
{
Packit 6bd9ab
  char safename[BUFLEN_SAFENAME];
Packit 6bd9ab
  /* escape attribute */
Packit 6bd9ab
  if (myldap_escape(name, safename, sizeof(safename)))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_ERR, "mkfilter_netgroup_byname(): safename buffer too small");
Packit 6bd9ab
    return -1;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* build filter */
Packit 6bd9ab
  return mysnprintf(buffer, buflen, "(&%s(%s=%s))",
Packit 6bd9ab
                    netgroup_filter, attmap_netgroup_cn, safename);
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
void netgroup_init(void)
Packit 6bd9ab
{
Packit 6bd9ab
  int i;
Packit 6bd9ab
  /* set up search bases */
Packit 6bd9ab
  if (netgroup_bases[0] == NULL)
Packit 6bd9ab
    for (i = 0; i < NSS_LDAP_CONFIG_MAX_BASES; i++)
Packit 6bd9ab
      netgroup_bases[i] = nslcd_cfg->bases[i];
Packit 6bd9ab
  /* set up scope */
Packit 6bd9ab
  if (netgroup_scope == LDAP_SCOPE_DEFAULT)
Packit 6bd9ab
    netgroup_scope = nslcd_cfg->scope;
Packit 6bd9ab
  /* set up attribute list */
Packit 6bd9ab
  netgroup_attrs[0] = attmap_netgroup_cn;
Packit 6bd9ab
  netgroup_attrs[1] = attmap_netgroup_nisNetgroupTriple;
Packit 6bd9ab
  netgroup_attrs[2] = attmap_netgroup_memberNisNetgroup;
Packit 6bd9ab
  netgroup_attrs[3] = NULL;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static int write_string_stripspace_len(TFILE *fp, const char *str, int len)
Packit 6bd9ab
{
Packit 6bd9ab
  int32_t tmpint32;
Packit 6bd9ab
  int i, j;
Packit 6bd9ab
  DEBUG_PRINT("WRITE_STRING: var=" __STRING(str) " string=\"%s\"", str);
Packit 6bd9ab
  /* skip leading spaces */
Packit 6bd9ab
  for (i = 0; (str[i] != '\0') && (isspace(str[i])); i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  /* skip trailing spaces */
Packit 6bd9ab
  for (j = len; (j > i) && (isspace(str[j - 1])); j--)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  /* write length of string */
Packit 6bd9ab
  WRITE_INT32(fp, j - i);
Packit 6bd9ab
  /* write string itself */
Packit 6bd9ab
  if (j > i)
Packit 6bd9ab
  {
Packit 6bd9ab
    WRITE(fp, str + i, j - i);
Packit 6bd9ab
  }
Packit 6bd9ab
  /* we're done */
Packit 6bd9ab
  return 0;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
#define WRITE_STRING_STRIPSPACE_LEN(fp, str, len)                           \
Packit 6bd9ab
  if (write_string_stripspace_len(fp, str, len))                            \
Packit 6bd9ab
    return -1;
Packit 6bd9ab
Packit 6bd9ab
#define WRITE_STRING_STRIPSPACE(fp, str)                                    \
Packit 6bd9ab
  WRITE_STRING_STRIPSPACE_LEN(fp, str, strlen(str))
Packit 6bd9ab
Packit 6bd9ab
static int write_netgroup_triple(TFILE *fp, MYLDAP_ENTRY *entry,
Packit 6bd9ab
                                 const char *triple)
Packit 6bd9ab
{
Packit 6bd9ab
  int32_t tmpint32;
Packit 6bd9ab
  int i;
Packit 6bd9ab
  int hostb, hoste, userb, usere, domainb, domaine;
Packit 6bd9ab
  /* skip leading spaces */
Packit 6bd9ab
  for (i = 0; (triple[i] != '\0') && (isspace(triple[i])); i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  /* we should have a bracket now */
Packit 6bd9ab
  if (triple[i] != '(')
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_WARNING, "%s: %s: does not begin with '('",
Packit 6bd9ab
            myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  }
Packit 6bd9ab
  i++;
Packit 6bd9ab
  hostb = i;
Packit 6bd9ab
  /* find comma (end of host string) */
Packit 6bd9ab
  for (; (triple[i] != '\0') && (triple[i] != ','); i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  hoste = i;
Packit 6bd9ab
  if (triple[i++] != ',')
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_WARNING, "%s: %s: missing ','",
Packit 6bd9ab
            myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  }
Packit 6bd9ab
  userb = i;
Packit 6bd9ab
  /* find comma (end of user string) */
Packit 6bd9ab
  for (; (triple[i] != '\0') && (triple[i] != ','); i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  usere = i;
Packit 6bd9ab
  if (triple[i++] != ',')
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_WARNING, "%s: %s: missing ','",
Packit 6bd9ab
            myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  }
Packit 6bd9ab
  domainb = i;
Packit 6bd9ab
  /* find closing bracket (end of domain string) */
Packit 6bd9ab
  for (; (triple[i] != '\0') && (triple[i] != ')'); i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  domaine=i;
Packit 6bd9ab
  if (triple[i++] != ')')
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_WARNING, "%s: %s: missing ')'",
Packit 6bd9ab
            myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* skip trailing spaces */
Packit 6bd9ab
  for (; (triple[i] != '\0') && (isspace(triple[i])); i++)
Packit 6bd9ab
    /* nothing */ ;
Packit 6bd9ab
  /* if anything is left in the string we have a problem */
Packit 6bd9ab
  if (triple[i] != '\0')
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_WARNING, "%s: %s: contains trailing data",
Packit 6bd9ab
            myldap_get_dn(entry), attmap_netgroup_nisNetgroupTriple);
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* write strings */
Packit 6bd9ab
  WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_TRIPLE);
Packit 6bd9ab
  WRITE_STRING_STRIPSPACE_LEN(fp, triple + hostb, hoste - hostb)
Packit 6bd9ab
  WRITE_STRING_STRIPSPACE_LEN(fp, triple + userb, usere - userb)
Packit 6bd9ab
  WRITE_STRING_STRIPSPACE_LEN(fp, triple + domainb, domaine - domainb)
Packit 6bd9ab
  /* we're done */
Packit 6bd9ab
  return 0;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
static int write_netgroup(TFILE *fp, MYLDAP_ENTRY *entry, const char *reqname)
Packit 6bd9ab
{
Packit 6bd9ab
  int32_t tmpint32;
Packit 6bd9ab
  int i, j;
Packit 6bd9ab
  const char **names;
Packit 6bd9ab
  const char **triples;
Packit 6bd9ab
  const char **members;
Packit 6bd9ab
  /* get the netgroup name */
Packit 6bd9ab
  names = myldap_get_values(entry, attmap_netgroup_cn);
Packit 6bd9ab
  if ((names == NULL) || (names[0] == NULL))
Packit 6bd9ab
  {
Packit 6bd9ab
    log_log(LOG_WARNING, "%s: %s: missing",
Packit 6bd9ab
            myldap_get_dn(entry), attmap_netgroup_cn);
Packit 6bd9ab
    return 0;
Packit 6bd9ab
  }
Packit 6bd9ab
  /* get the netgroup triples and member */
Packit 6bd9ab
  triples = myldap_get_values(entry, attmap_netgroup_nisNetgroupTriple);
Packit 6bd9ab
  members = myldap_get_values(entry, attmap_netgroup_memberNisNetgroup);
Packit 6bd9ab
  /* write the entries */
Packit 6bd9ab
  for (i = 0; names[i] != NULL; i++)
Packit 6bd9ab
    if ((reqname == NULL) || (STR_CMP(reqname, names[i]) == 0))
Packit 6bd9ab
    {
Packit 6bd9ab
      /* write first part of result */
Packit 6bd9ab
      WRITE_INT32(fp, NSLCD_RESULT_BEGIN);
Packit 6bd9ab
      WRITE_STRING(fp, names[i]);
Packit 6bd9ab
      /* write the netgroup triples */
Packit 6bd9ab
      if (triples != NULL)
Packit 6bd9ab
        for (j = 0; triples[j] != NULL; j++)
Packit 6bd9ab
          if (write_netgroup_triple(fp, entry, triples[j]))
Packit 6bd9ab
            return -1;
Packit 6bd9ab
      /* write netgroup members */
Packit 6bd9ab
      if (members != NULL)
Packit 6bd9ab
        for (j = 0; members[j] != NULL; j++)
Packit 6bd9ab
        {
Packit 6bd9ab
          /* write triple indicator */
Packit 6bd9ab
          WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_NETGROUP);
Packit 6bd9ab
          /* write netgroup name */
Packit 6bd9ab
          WRITE_STRING_STRIPSPACE(fp, members[j]);
Packit 6bd9ab
        }
Packit 6bd9ab
      /* write end of result marker */
Packit 6bd9ab
      WRITE_INT32(fp, NSLCD_NETGROUP_TYPE_END);
Packit 6bd9ab
    }
Packit 6bd9ab
  /* we're done */
Packit 6bd9ab
  return 0;
Packit 6bd9ab
}
Packit 6bd9ab
Packit 6bd9ab
NSLCD_HANDLE(
Packit 6bd9ab
  netgroup, byname, NSLCD_ACTION_NETGROUP_BYNAME,
Packit 6bd9ab
  char name[BUFLEN_NAME];
Packit 6bd9ab
  char filter[BUFLEN_FILTER];
Packit 6bd9ab
  READ_STRING(fp, name);
Packit 6bd9ab
  log_setrequest("netgroup=\"%s\"", name);,
Packit 6bd9ab
  mkfilter_netgroup_byname(name, filter, sizeof(filter)),
Packit 6bd9ab
  write_netgroup(fp, entry, name)
Packit 6bd9ab
)
Packit 6bd9ab
Packit 6bd9ab
NSLCD_HANDLE(
Packit 6bd9ab
  netgroup, all, NSLCD_ACTION_NETGROUP_ALL,
Packit 6bd9ab
  const char *filter;
Packit 6bd9ab
  log_setrequest("netgroup(all)");,
Packit 6bd9ab
  (filter = netgroup_filter, 0),
Packit 6bd9ab
  write_netgroup(fp, entry, NULL)
Packit 6bd9ab
)