/* 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, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) \ int nslcd_##db##_##fn(TFILE *_fp, struct session *_session) \ NSLCD_HANDLE_BODY(db, fn, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) #define NSLCD_HANDLE_UID(db, fn, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) \ int nslcd_##db##_##fn(TFILE *_fp, struct session *_session, uid_t calleruid) \ NSLCD_HANDLE_BODY(db, fn, type_request, type_searchdat, type_entry, fnread, fncheck, fnsearch, fnwrite, fnclean) #define NSLCD_HANDLE_BODY(_db, _fn, _type_request, _type_searchdat, _type_entry, _fnread, _fncheck, _fnsearch, _fnwrite, _fnclean) \ { \ /* define common variables */ \ int _rc = 1; \ _type_request _request; memset(&_request, 0, sizeof(_request)); \ _type_searchdat _searchdat; memset(&_searchdat, 0, sizeof(_searchdat)); \ _type_entry *_entry = NULL; \ __extension__ int _read(TFILE *fp, __typeof__(_request) *req) \ { _fnread } \ __extension__ int _check(__typeof__(_request) *req) \ { _fncheck } \ __extension__ int _search(struct session *session, \ __typeof__(_request) *req, \ __typeof__(_searchdat) *searchdat, \ __typeof__(_entry) *entry) \ { _fnsearch } \ __extension__ int _write(TFILE *fp, __typeof__(_entry) entry) \ { _fnwrite } \ __extension__ void _clean(__typeof__(_request) *req, \ __typeof__(_searchdat) *searchdat) \ { _fnclean } \ /* read request parameters */ \ if ((_rc = _read(_fp, &_request)) != 0) \ return _rc; \ /* validate request parameters */ \ if ((_rc = _check(&_request)) != 0) \ return _rc; \ /* write the response header */ \ WRITE_INT32(_fp, NSLCD_VERSION); \ WRITE_INT32(_fp, NSLCD_ACTION_##_db##_##_fn); \ /* go over results */ \ do { \ _rc = _search(_session, &_request, &_searchdat, &_entry); \ if (_entry != NULL) { \ /* write the response */ \ WRITE_INT32(_fp, NSLCD_RESULT_BEGIN); \ if ( _write(_fp, _entry) != 0 ) { \ _clean(&_request, &_searchdat); \ return -1; \ } \ } \ } while (_rc == 0 && _entry != NULL ); \ if (_rc == 0) \ WRITE_INT32(_fp, NSLCD_RESULT_END); \ _clean(&_request, &_searchdat); \ 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 */