Blame nslcd/common.h

Packit 6bd9ab
/*
Packit 6bd9ab
   common.h - common server code routines
Packit 6bd9ab
   This file is part of the nss-pam-ldapd library.
Packit 6bd9ab
Packit 6bd9ab
   Copyright (C) 2006 West Consulting
Packit 6bd9ab
   Copyright (C) 2006-2018 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
#ifndef NSLCD__COMMON_H
Packit 6bd9ab
#define NSLCD__COMMON_H 1
Packit 6bd9ab
Packit 6bd9ab
#include <errno.h>
Packit 6bd9ab
#include <limits.h>
Packit 6bd9ab
#ifdef HAVE_STDINT_H
Packit 6bd9ab
#include <stdint.h>
Packit 6bd9ab
#endif /* HAVE_STDINT_H */
Packit 6bd9ab
#include <sys/types.h>
Packit 6bd9ab
Packit 6bd9ab
#include "nslcd.h"
Packit 6bd9ab
#include "common/nslcd-prot.h"
Packit 6bd9ab
#include "common/tio.h"
Packit 6bd9ab
#include "compat/attrs.h"
Packit 6bd9ab
#include "myldap.h"
Packit 6bd9ab
#include "cfg.h"
Packit 6bd9ab
Packit 6bd9ab
/* macros for basic read and write operations, the following
Packit 6bd9ab
   ERROR_OUT* marcos define the action taken on errors
Packit 6bd9ab
   the stream is not closed because the caller closes the
Packit 6bd9ab
   stream */
Packit 6bd9ab
Packit 6bd9ab
#define ERROR_OUT_WRITEERROR(fp)                                            \
Packit 6bd9ab
  if (errno == EPIPE)                                                       \
Packit 6bd9ab
    log_log(LOG_DEBUG, "error writing to client: %s", strerror(errno));     \
Packit 6bd9ab
  else                                                                      \
Packit 6bd9ab
    log_log(LOG_WARNING, "error writing to client: %s", strerror(errno));   \
Packit 6bd9ab
  return -1;
Packit 6bd9ab
Packit 6bd9ab
#define ERROR_OUT_READERROR(fp)                                             \
Packit 6bd9ab
  log_log(LOG_WARNING, "error reading from client: %s", strerror(errno));   \
Packit 6bd9ab
  return -1;
Packit 6bd9ab
Packit 6bd9ab
#define ERROR_OUT_BUFERROR(fp)                                              \
Packit 6bd9ab
  log_log(LOG_ERR, "client supplied argument %d bytes too large",           \
Packit 6bd9ab
          tmpint32);                                                        \
Packit 6bd9ab
  return -1;
Packit 6bd9ab
Packit 6bd9ab
/* a simple wrapper around snprintf,
Packit 6bd9ab
   returns 0 if ok, -1 on error */
Packit 6bd9ab
int mysnprintf(char *buffer, size_t buflen, const char *format, ...)
Packit 6bd9ab
  LIKE_PRINTF(3, 4);
Packit 6bd9ab
Packit 6bd9ab
/* get a name of a signal with a given signal number */
Packit 6bd9ab
const char *signame(int signum);
Packit 6bd9ab
Packit 6bd9ab
/* return the fully qualified domain name of the current host
Packit 6bd9ab
   the returned value does not need to be freed but is re-used for every
Packit 6bd9ab
   call */
Packit 6bd9ab
MUST_USE const char *getfqdn(void);
Packit 6bd9ab
Packit 6bd9ab
/* This tries to get the user password attribute from the entry.
Packit 6bd9ab
   It will try to return an encrypted password as it is used in /etc/passwd,
Packit 6bd9ab
   /etc/group or /etc/shadow depending upon what is in the directory.
Packit 6bd9ab
   This function will return NULL if no passwd is found and will return the
Packit 6bd9ab
   literal value in the directory if conversion is not possible. */
Packit 6bd9ab
const char *get_userpassword(MYLDAP_ENTRY *entry, const char *attr,
Packit 6bd9ab
                             char *buffer, size_t buflen);
Packit 6bd9ab
Packit 6bd9ab
/* write out an address, parsing the addr value */
Packit 6bd9ab
int write_address(TFILE *fp, MYLDAP_ENTRY *entry, const char *attr,
Packit 6bd9ab
                  const char *addr);
Packit 6bd9ab
Packit 6bd9ab
/* a helper macro to write out addresses and bail out on errors */
Packit 6bd9ab
#define WRITE_ADDRESS(fp, entry, attr, addr)                                \
Packit 6bd9ab
  if (write_address(fp, entry, attr, addr))                                 \
Packit 6bd9ab
    return -1;
Packit 6bd9ab
Packit 6bd9ab
/* read an address from the stream */
Packit 6bd9ab
int read_address(TFILE *fp, char *addr, int *addrlen, int *af);
Packit 6bd9ab
Packit 6bd9ab
/* helper macro to read an address from the stream */
Packit 6bd9ab
#define READ_ADDRESS(fp, addr, len, af)                                     \
Packit 6bd9ab
  len = (int)sizeof(addr);                                                  \
Packit 6bd9ab
  if (read_address(fp, addr, &(len), &(af)))                                \
Packit 6bd9ab
    return -1;
Packit 6bd9ab
Packit 6bd9ab
/* convert the provided string representation of a sid
Packit 6bd9ab
   (e.g. S-1-5-21-1936905831-823966427-12391542-23578)
Packit 6bd9ab
   to a format that can be used to search the objectSid property with */
Packit 6bd9ab
MUST_USE char *sid2search(const char *sid);
Packit 6bd9ab
Packit 6bd9ab
/* return the last security identifier of the binary sid */
Packit 6bd9ab
MUST_USE unsigned long int binsid2id(const char *binsid);
Packit 6bd9ab
Packit 6bd9ab
/* checks to see if the specified string is a valid user or group name */
Packit 6bd9ab
MUST_USE int isvalidname(const char *name);
Packit 6bd9ab
Packit 6bd9ab
/* Perform an LDAP lookup to translate the DN into a uid.
Packit 6bd9ab
   This function either returns NULL or a strdup()ed string. */
Packit 6bd9ab
MUST_USE char *lookup_dn2uid(MYLDAP_SESSION *session, const char *dn,
Packit 6bd9ab
                             int *rcp, char *buf, size_t buflen);
Packit 6bd9ab
Packit 6bd9ab
/* transforms the DN info a uid doing an LDAP lookup if needed */
Packit 6bd9ab
MUST_USE char *dn2uid(MYLDAP_SESSION *session, const char *dn, char *buf,
Packit 6bd9ab
                      size_t buflen);
Packit 6bd9ab
Packit 6bd9ab
/* use the user id to lookup an LDAP entry */
Packit 6bd9ab
MYLDAP_ENTRY *uid2entry(MYLDAP_SESSION *session, const char *uid, int *rcp);
Packit 6bd9ab
Packit 6bd9ab
/* transforms the uid into a DN by doing an LDAP lookup */
Packit 6bd9ab
MUST_USE char *uid2dn(MYLDAP_SESSION *session, const char *uid, char *buf,
Packit 6bd9ab
                      size_t buflen);
Packit 6bd9ab
Packit 6bd9ab
/* use the user id to lookup an LDAP entry with the shadow attributes
Packit 6bd9ab
   requested */
Packit 6bd9ab
MYLDAP_ENTRY *shadow_uid2entry(MYLDAP_SESSION *session, const char *username,
Packit 6bd9ab
                               int *rcp);
Packit 6bd9ab
Packit 6bd9ab
/* return shadow information */
Packit 6bd9ab
void get_shadow_properties(MYLDAP_ENTRY *entry, long *lastchangedate,
Packit 6bd9ab
                           long *mindays, long *maxdays, long *warndays,
Packit 6bd9ab
                           long *inactdays, long *expiredate,
Packit 6bd9ab
                           unsigned long *flag);
Packit 6bd9ab
Packit 6bd9ab
Packit 6bd9ab
/* check whether the nsswitch file should be reloaded */
Packit 6bd9ab
void nsswitch_check_reload(void);
Packit 6bd9ab
Packit 6bd9ab
/* check whether the nsswitch.conf file has LDAP as a naming source for db */
Packit 6bd9ab
int nsswitch_shadow_uses_ldap(void);
Packit 6bd9ab
Packit 6bd9ab
/* start a child process that holds onto the original privileges with the
Packit 6bd9ab
   purpose of running external cache invalidation commands */
Packit 6bd9ab
int invalidator_start(void);
Packit 6bd9ab
Packit 6bd9ab
/* signal invalidator to invalidate the selected external cache */
Packit 6bd9ab
void invalidator_do(enum ldap_map_selector map);
Packit 6bd9ab
Packit 6bd9ab
/* common buffer lengths */
Packit 6bd9ab
#define BUFLEN_NAME         256  /* user, group names and such */
Packit 6bd9ab
#define BUFLEN_SAFENAME     300  /* escaped name */
Packit 6bd9ab
#define BUFLEN_PASSWORD     128  /* passwords */
Packit 6bd9ab
#define BUFLEN_PASSWORDHASH 256  /* passwords hashes */
Packit 6bd9ab
#define BUFLEN_DN           512  /* distinguished names */
Packit 6bd9ab
#define BUFLEN_SAFEDN       600  /* escapedd dn */
Packit 6bd9ab
#define BUFLEN_FILTER      4096  /* search filters */
Packit 6bd9ab
#define BUFLEN_HOSTNAME     256  /* host names or FQDN (and safe version) */
Packit 6bd9ab
#define BUFLEN_MESSAGE     1024  /* message strings */
Packit 6bd9ab
Packit Service 574307
Packit Service 574307
uint32_t strtoid(const char *nptr,char **endptr,int base);
Packit Service 574307
#define strtouid (uid_t)strtoid
Packit Service 574307
#define strtogid (gid_t)strtoid
Packit 6bd9ab
Packit 6bd9ab
#ifdef WANT_STRTOUI
Packit 6bd9ab
/* provide a strtoui() if it is needed */
Packit 6bd9ab
unsigned int strtoui(const char *nptr, char **endptr, int base);
Packit 6bd9ab
#endif /* WANT_STRTOUI */
Packit 6bd9ab
Packit 6bd9ab
/* these are the functions for initialising the database specific
Packit 6bd9ab
   modules */
Packit 6bd9ab
void alias_init(void);
Packit 6bd9ab
void ether_init(void);
Packit 6bd9ab
void group_init(void);
Packit 6bd9ab
void host_init(void);
Packit 6bd9ab
void netgroup_init(void);
Packit 6bd9ab
void network_init(void);
Packit 6bd9ab
void passwd_init(void);
Packit 6bd9ab
void protocol_init(void);
Packit 6bd9ab
void rpc_init(void);
Packit 6bd9ab
void service_init(void);
Packit 6bd9ab
void shadow_init(void);
Packit 6bd9ab
Packit 6bd9ab
/* these are the different functions that handle the database
Packit 6bd9ab
   specific actions, see nslcd.h for the action descriptions */
Packit 6bd9ab
int nslcd_config_get(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_alias_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_alias_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_ether_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_ether_byether(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_ether_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_group_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_group_bygid(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_group_bymember(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_group_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_host_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_host_byaddr(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_host_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_netgroup_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_netgroup_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_network_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_network_byaddr(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_network_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_passwd_byname(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
int nslcd_passwd_byuid(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
int nslcd_passwd_all(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
int nslcd_protocol_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_protocol_bynumber(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_protocol_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_rpc_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_rpc_bynumber(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_rpc_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_service_byname(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_service_bynumber(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_service_all(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_shadow_byname(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
int nslcd_shadow_all(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
int nslcd_pam_authc(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
int nslcd_pam_authz(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_pam_sess_o(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_pam_sess_c(TFILE *fp, MYLDAP_SESSION *session);
Packit 6bd9ab
int nslcd_pam_pwmod(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
int nslcd_usermod(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid);
Packit 6bd9ab
Packit 6bd9ab
/* macros for generating service handling code */
Packit 6bd9ab
#define NSLCD_HANDLE(db, fn, action, readfn, mkfilter, writefn)             \
Packit 6bd9ab
  int nslcd_##db##_##fn(TFILE *fp, MYLDAP_SESSION *session)                 \
Packit 6bd9ab
  NSLCD_HANDLE_BODY(db, fn, action, readfn, mkfilter, writefn)
Packit 6bd9ab
#define NSLCD_HANDLE_UID(db, fn, action, readfn, mkfilter, writefn)         \
Packit 6bd9ab
  int nslcd_##db##_##fn(TFILE *fp, MYLDAP_SESSION *session, uid_t calleruid) \
Packit 6bd9ab
  NSLCD_HANDLE_BODY(db, fn, action, readfn, mkfilter, writefn)
Packit 6bd9ab
#define NSLCD_HANDLE_BODY(db, fn, action, readfn, mkfilter, writefn)        \
Packit 6bd9ab
  {                                                                         \
Packit 6bd9ab
    /* define common variables */                                           \
Packit 6bd9ab
    int32_t tmpint32;                                                       \
Packit 6bd9ab
    MYLDAP_SEARCH *search;                                                  \
Packit 6bd9ab
    MYLDAP_ENTRY *entry;                                                    \
Packit 6bd9ab
    const char *base;                                                       \
Packit 6bd9ab
    int rc, i;                                                              \
Packit 6bd9ab
    /* read request parameters */                                           \
Packit 6bd9ab
    readfn;                                                                 \
Packit 6bd9ab
    /* write the response header */                                         \
Packit 6bd9ab
    WRITE_INT32(fp, NSLCD_VERSION);                                         \
Packit 6bd9ab
    WRITE_INT32(fp, action);                                                \
Packit 6bd9ab
    /* prepare the search filter */                                         \
Packit 6bd9ab
    if (mkfilter)                                                           \
Packit 6bd9ab
    {                                                                       \
Packit 6bd9ab
      log_log(LOG_ERR, "nslcd_" __STRING(db) "_" __STRING(fn)               \
Packit 6bd9ab
              "(): filter buffer too small");                               \
Packit 6bd9ab
      return -1;                                                            \
Packit 6bd9ab
    }                                                                       \
Packit 6bd9ab
    /* perform a search for each search base */                             \
Packit 6bd9ab
    for (i = 0; (base = db##_bases[i]) != NULL; i++)                        \
Packit 6bd9ab
    {                                                                       \
Packit 6bd9ab
      /* do the LDAP search */                                              \
Packit 6bd9ab
      search = myldap_search(session, base, db##_scope, filter,             \
Packit 6bd9ab
                             db##_attrs, NULL);                             \
Packit 6bd9ab
      if (search == NULL)                                                   \
Packit 6bd9ab
        return -1;                                                          \
Packit 6bd9ab
      /* go over results */                                                 \
Packit 6bd9ab
      while ((entry = myldap_get_entry(search, &rc)) != NULL)               \
Packit 6bd9ab
      {                                                                     \
Packit 6bd9ab
        if (writefn)                                                        \
Packit 6bd9ab
          return -1;                                                        \
Packit 6bd9ab
      }                                                                     \
Packit 6bd9ab
    }                                                                       \
Packit 6bd9ab
    /* write the final result code */                                       \
Packit 6bd9ab
    if (rc == LDAP_SUCCESS)                                                 \
Packit 6bd9ab
    {                                                                       \
Packit 6bd9ab
      WRITE_INT32(fp, NSLCD_RESULT_END);                                    \
Packit 6bd9ab
    }                                                                       \
Packit 6bd9ab
    return 0;                                                               \
Packit 6bd9ab
  }
Packit 6bd9ab
Packit 6bd9ab
/* macro to compare strings which uses the ignorecase config option to
Packit 6bd9ab
   determine whether or not to do a case-sensitive match */
Packit 6bd9ab
#define STR_CMP(str1, str2)                                                 \
Packit 6bd9ab
  (nslcd_cfg->ignorecase == 1 ?                                             \
Packit 6bd9ab
    strcasecmp(str1, str2) : strcmp(str1, str2))
Packit 6bd9ab
Packit 6bd9ab
#endif /* not NSLCD__COMMON_H */