|
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 */
|