/* common.h - common server code routines This file is part of the nss-pam-ldapd library. Copyright (C) 2006 West Consulting Copyright (C) 2006-2014 Arthur de Jong This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef NSLCD__COMMON_H #define NSLCD__COMMON_H 1 #include #include #include #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ #include #include #include "nslcd.h" #include "common/nslcd-prot.h" #include "common/tio.h" #include "compat/attrs.h" #include "cfg.h" #include "hackers.h" /* macros for basic read and write operations, the following ERROR_OUT* marcos define the action taken on errors the stream is not closed because the caller closes the stream */ #define ERROR_OUT_WRITEERROR(fp) \ do { \ if (errno == EPIPE) \ log_log(LOG_DEBUG, "error writing to client: %s", strerror(errno)); \ else \ log_log(LOG_WARNING, "error writing to client: %s", strerror(errno)); \ return -1; \ } while(0) #define ERROR_OUT_READERROR(fp) \ do { \ log_log(LOG_WARNING, "error reading from client: %s", strerror(errno)); \ return -1; \ } while(0) #define ERROR_OUT_BUFERROR(fp) \ do { \ log_log(LOG_ERR, "client supplied argument %d bytes too large", \ tmpint32); \ return -1; \ } while(0) /* a simple wrapper around snprintf, returns 0 if ok, -1 on error */ int mysnprintf(char *buffer, size_t buflen, const char *format, ...) LIKE_PRINTF(3, 4); /* get a name of a signal with a given signal number */ const char *signame(int signum); /* checks to see if the specified string is a valid user or group name */ MUST_USE int isvalidname(const char *name); /* check whether the nsswitch file should be reloaded */ void nsswitch_check_reload(void); /* check whether the nsswitch.conf file has NSLCD as a naming source for db */ int nsswitch_shadow_uses_nslcd(void); /* start a child process that holds onto the original privileges with the purpose of running external cache invalidation commands */ int invalidator_start(void); /* signal invalidator to invalidate the selected external cache */ void invalidator_do(enum nss_map_selector map); /* common buffer lengths */ #define BUFLEN_NAME 256 /* user, group names and such */ #define BUFLEN_PASSWORD 128 /* passwords */ #define BUFLEN_MESSAGE 1024 /* message strings */ /* these are the different functions that handle the database specific actions, see nslcd.h for the action descriptions */ #include "dispatch.h" /* macros for generating service handling code */ #define NSLCD_HANDLE(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) \ int nslcd_##db##_##fn(TFILE *_handle_fp, struct session *_handle_session) \ NSLCD_HANDLE_BODY(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) #define NSLCD_HANDLE_UID(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) \ int nslcd_##db##_##fn(TFILE *_handle_fp, struct session *_handle_session, uid_t calleruid) \ NSLCD_HANDLE_BODY(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) #define NSLCD_HANDLE_BODY(db, fn, fndecls, fnread, fncheck, tentry, fnsearch, fnwrite, fnclean) \ { \ /* define common variables */ \ tentry *_handle_entry = NULL; \ int _handle_rc = 1; \ bool _handle_more = true; \ fndecls \ __extension__ int read(TFILE *fp) { fnread } \ __extension__ tentry *search(struct session *session, \ int *rcp, bool *more) { fnsearch } \ __extension__ int write(TFILE *fp, tentry *entry) { fnwrite } \ __extension__ void clean() { fnclean } \ /* read request parameters */ \ if ((_handle_rc = read(_handle_fp)) != 0) \ return _handle_rc; \ _handle_rc = 1; \ /* validate request parameters */ \ fncheck \ /* write the response header */ \ WRITE_INT32(_handle_fp, NSLCD_VERSION); \ WRITE_INT32(_handle_fp, NSLCD_ACTION_##db##_##fn); \ /* go over results */ \ while ((_handle_entry = search(_handle_session, &_handle_rc, &_handle_more)) != NULL)\ { \ if ( write(_handle_fp, _handle_entry) ) { \ clean(); \ return -1; \ } \ if (! _handle_more) \ break; \ } \ /* write the final result code */ \ if (_handle_rc == 0) \ { \ WRITE_INT32(_handle_fp, NSLCD_RESULT_END); \ } \ clean(); \ return 0; \ } /* macro to compare strings which uses the ignorecase config option to determine whether or not to do a case-sensitive match */ #define STR_CMP(str1, str2) \ (nslcd_cfg->ignorecase == 1 ? \ strcasecmp(str1, str2) : strcmp(str1, str2)) #endif /* not NSLCD__COMMON_H */