From 33fc2b54a52d8d902ff53c5d3c9279c0b316a625 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 23 Apr 2013 12:49:25 -0700 Subject: [PATCH] ITS#7518 resync nss-pam-ldapd files Also note minimum version required. --- .../slapd-modules/nssov/nss-pam-ldapd/README | 10 +- .../slapd-modules/nssov/nss-pam-ldapd/attrs.h | 6 +- .../nssov/nss-pam-ldapd/nslcd-prot.h | 12 +- .../slapd-modules/nssov/nss-pam-ldapd/nslcd.h | 19 +- .../slapd-modules/nssov/nss-pam-ldapd/tio.c | 164 ++++++++++-------- .../slapd-modules/nssov/nss-pam-ldapd/tio.h | 16 +- 6 files changed, 137 insertions(+), 90 deletions(-) diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/README b/contrib/slapd-modules/nssov/nss-pam-ldapd/README index 1c56e2015e..39198dd998 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/README +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/README @@ -1,7 +1,15 @@ -These files were pulled from the nss-pam-ldapd project version 0.7.3. Copyright notices are in the individual files. +These files were pulled from the nss-pam-ldapd project version 0.8.12. +Copyright notices are in the individual files. This is not the full distribution of nss-pam-ldapd, and does not include the client-side stub libraries. Get the latest release of nss-pam-ldapd from http://arthurdejong.org/nss-pam-ldapd/ to use this overlay. +If your system already has the nss-pam-ldapd stub libraries +installed, make sure the versions match the version number +shown above. Otherwise, there may be incompatible differences in +the protocols being used. Currently nssov requires at least +version 0.8.11. If your system's version is older, you will need +to install the client-side stubs from source. + diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/attrs.h b/contrib/slapd-modules/nssov/nss-pam-ldapd/attrs.h index 492f45c2ea..0bc0f30d90 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/attrs.h +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/attrs.h @@ -19,8 +19,8 @@ 02110-1301 USA */ -#ifndef _COMPAT_ATTRS_H -#define _COMPAT_ATTRS_H 1 +#ifndef COMPAT__ATTRS_H +#define COMPAT__ATTRS_H 1 /* macro for testing the version of GCC */ #define GCC_VERSION(major,minor) \ @@ -88,4 +88,4 @@ #endif /* not __STDC__ */ #endif /* not __STRING */ -#endif /* not _COMPAT_ATTRS_H */ +#endif /* not COMPAT__ATTRS_H */ diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd-prot.h b/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd-prot.h index abfb4cb45d..1252158c6d 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd-prot.h +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd-prot.h @@ -20,8 +20,8 @@ 02110-1301 USA */ -#ifndef _NSLCD_PROT_H -#define _NSLCD_PROT_H 1 +#ifndef COMMON__NSLCD_PROT_H +#define COMMON__NSLCD_PROT_H 1 #include "tio.h" @@ -180,7 +180,8 @@ static void debug_dump(const void *ptr,size_t size) if (((size_t)tmpint32)>=sizeof(buffer)) \ { \ /* will not fit */ \ - DEBUG_PRINT("READ : buffer error: %d bytes too large",(tmpint32-sizeof(buffer))+1); \ + tmpint32=(tmpint32-sizeof(buffer))+1; \ + DEBUG_PRINT("READ : buffer %d bytes too small",tmpint32); \ ERROR_OUT_BUFERROR(fp); \ } \ /* read string from the stream */ \ @@ -209,7 +210,8 @@ static void debug_dump(const void *ptr,size_t size) if ((bufptr+(size_t)(sz))>buflen) \ { \ /* will not fit */ \ - DEBUG_PRINT("READ : buffer error: %d bytes too small",(bufptr+(sz)-(buflen))); \ + tmpint32=bufptr+(sz)-(buflen); \ + DEBUG_PRINT("READ : buffer %d bytes too small",tmpint32); \ ERROR_OUT_BUFERROR(fp); \ } @@ -353,4 +355,4 @@ TFILE *nslcd_client_open(void) if (tmpint32!=(int32_t)NSLCD_RESULT_BEGIN) \ { ERROR_OUT_NOSUCCESS(fp) } -#endif /* not _NSLCD_PROT_H */ +#endif /* not COMMON__NSLCD_PROT_H */ diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd.h b/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd.h index daaf1b1a59..ebbba7471e 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd.h +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd.h @@ -2,7 +2,7 @@ nslcd.h - file describing client/server protocol Copyright (C) 2006 West Consulting - Copyright (C) 2006, 2007, 2009, 2010 Arthur de Jong + Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012 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 @@ -71,6 +71,16 @@ 1.0 release of nss-pam-ldapd is made. */ #define NSLCD_VERSION 1 +/* Get a NSLCD configuration option. There is one request parameter: + INT32 NSLCD_CONFIG_* + the result value is: + STRING value, interpretation depending on request */ +#define NSLCD_ACTION_CONFIG_GET 20006 + +/* return the message, if any, that is presented to the user when password + modification through PAM is prohibited */ +#define NSLCD_CONFIG_PAM_PASSWORD_PROHIBIT_MESSAGE 852 + /* Email alias (/etc/aliases) NSS requests. The result values for a single entry are: STRING alias name @@ -187,7 +197,10 @@ STRING service name all requests, except the SESSION requests start the result value with: STRING user name (cannonical name) - STRING DN (can be used to speed up requests) */ + STRING DN (can be used to speed up requests) + Some functions may return an authorisation message. This message, if + supplied will be used by the PAM module instead of a message that is + generated by the PAM module itself. */ /* PAM authentication check request. The extra request values are: STRING password @@ -249,8 +262,10 @@ #define NSLCD_PAM_NEW_AUTHTOK_REQD 12 /* Password expired */ #define NSLCD_PAM_ACCT_EXPIRED 13 /* Account expired */ #define NSLCD_PAM_SESSION_ERR 14 /* Cannot make/remove session record */ +#define NSLCD_PAM_AUTHTOK_ERR 20 /* Authentication token manipulation error */ #define NSLCD_PAM_AUTHTOK_DISABLE_AGING 23 /* Password aging disabled */ #define NSLCD_PAM_IGNORE 25 /* Ignore module */ #define NSLCD_PAM_ABORT 26 /* Fatal error */ +#define NSLCD_PAM_AUTHTOK_EXPIRED 27 /* authentication token has expired */ #endif /* not _NSLCD_H */ diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.c b/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.c index 6db920ea89..31764c707c 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.c +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.c @@ -2,7 +2,7 @@ tio.c - timed io functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008 Arthur de Jong + Copyright (C) 2007, 2008, 2010, 2011, 2012 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 @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include "tio.h" @@ -63,8 +65,8 @@ struct tio_fileinfo { int fd; struct tio_buffer readbuffer; struct tio_buffer writebuffer; - struct timeval readtimeout; - struct timeval writetimeout; + int readtimeout; + int writetimeout; int read_resettable; /* whether the tio_reset() function can be called */ #ifdef DEBUG_TIO_STATS /* this is used to collect statistics on the use of the streams @@ -74,21 +76,8 @@ struct tio_fileinfo { #endif /* DEBUG_TIO_STATS */ }; -/* add the second timeval to the first modifing the first */ -static inline void tio_tv_add(struct timeval *tv1, const struct timeval *tv2) -{ - /* BUG: we hope that this does not overflow */ - tv1->tv_usec+=tv2->tv_usec; - if (tv1->tv_usec>1000000) - { - tv1->tv_usec-=1000000; - tv1->tv_sec+=1; - } - tv1->tv_sec+=tv2->tv_sec; -} - /* build a timeval for comparison to when the operation should be finished */ -static inline void tio_tv_prepare(struct timeval *deadline, const struct timeval *timeout) +static inline void tio_get_deadline(struct timeval *deadline,int timeout) { if (gettimeofday(deadline,NULL)) { @@ -97,39 +86,27 @@ static inline void tio_tv_prepare(struct timeval *deadline, const struct timeval deadline->tv_usec=0; return; } - tio_tv_add(deadline,timeout); + deadline->tv_sec+=timeout/1000; + deadline->tv_sec+=(timeout%1000)*1000; } -/* update the timeval to the value that is remaining before deadline +/* update the timeout to the value that is remaining before deadline returns non-zero if there is no more time before the deadline */ -static inline int tio_tv_remaining(struct timeval *tv, const struct timeval *deadline) +static inline int tio_time_remaining(const struct timeval *deadline) { + struct timeval tv; /* get the current time */ - if (gettimeofday(tv,NULL)) + if (gettimeofday(&tv,NULL)) { /* 1 second default if gettimeofday() is broken */ - tv->tv_sec=1; - tv->tv_usec=0; - return 0; + return 1000; } - /* check if we're too late */ - if ( (tv->tv_sec>deadline->tv_sec) || - ( (tv->tv_sec==deadline->tv_sec) && (tv->tv_usec>deadline->tv_usec) ) ) - return -1; - /* update tv */ - tv->tv_sec=deadline->tv_sec-tv->tv_sec; - if (tv->tv_usectv_usec) - tv->tv_usec=deadline->tv_usec-tv->tv_usec; - else - { - tv->tv_sec--; - tv->tv_usec=1000000+deadline->tv_usec-tv->tv_usec; - } - return 0; + /* calculate time remaining in miliseconds */ + return (deadline->tv_sec-tv.tv_sec)*1000 + (deadline->tv_usec-tv.tv_usec)/1000; } /* open a new TFILE based on the file descriptor */ -TFILE *tio_fdopen(int fd,struct timeval *readtimeout,struct timeval *writetimeout, +TFILE *tio_fdopen(int fd,int readtimeout,int writetimeout, size_t initreadsize,size_t maxreadsize, size_t initwritesize,size_t maxwritesize) { @@ -162,10 +139,8 @@ TFILE *tio_fdopen(int fd,struct timeval *readtimeout,struct timeval *writetimeou fp->writebuffer.start=0; fp->writebuffer.len=0; /* initialize other attributes */ - fp->readtimeout.tv_sec=readtimeout->tv_sec; - fp->readtimeout.tv_usec=readtimeout->tv_usec; - fp->writetimeout.tv_sec=writetimeout->tv_sec; - fp->writetimeout.tv_usec=writetimeout->tv_usec; + fp->readtimeout=readtimeout; + fp->writetimeout=writetimeout; fp->read_resettable=0; #ifdef DEBUG_TIO_STATS fp->byteswritten=0; @@ -176,18 +151,15 @@ TFILE *tio_fdopen(int fd,struct timeval *readtimeout,struct timeval *writetimeou /* wait for any activity on the specified file descriptor using the specified deadline */ -static int tio_select(TFILE *fp, int readfd, const struct timeval *deadline) +static int tio_wait(TFILE *fp,int readfd,const struct timeval *deadline) { - struct timeval tv; - fd_set fdset; + int timeout; + struct pollfd fds[1]; int rv; while (1) { - /* prepare our filedescriptorset */ - FD_ZERO(&fdset); - FD_SET(fp->fd,&fdset); /* figure out the time we need to wait */ - if (tio_tv_remaining(&tv,deadline)) + if ((timeout=tio_time_remaining(deadline))<0) { errno=ETIME; return -1; @@ -195,18 +167,21 @@ static int tio_select(TFILE *fp, int readfd, const struct timeval *deadline) /* wait for activity */ if (readfd) { + fds[0].fd=fp->fd; + fds[0].events=POLLIN; /* santiy check for moving clock */ - if (tv.tv_sec>fp->readtimeout.tv_sec) - tv.tv_sec=fp->readtimeout.tv_sec; - rv=select(FD_SETSIZE,&fdset,NULL,NULL,&tv); + if (timeout>fp->readtimeout) + timeout=fp->readtimeout; } else { + fds[0].fd=fp->fd; + fds[0].events=POLLOUT; /* santiy check for moving clock */ - if (tv.tv_sec>fp->writetimeout.tv_sec) - tv.tv_sec=fp->writetimeout.tv_sec; - rv=select(FD_SETSIZE,NULL,&fdset,NULL,&tv); + if (timeout>fp->writetimeout) + timeout=fp->writetimeout; } + rv=poll(fds,1,timeout); if (rv>0) return 0; /* we have activity */ else if (rv==0) @@ -230,11 +205,11 @@ int tio_read(TFILE *fp, void *buf, size_t count) int rv; uint8_t *tmp; size_t newsz; + size_t len; /* have a more convenient storage type for the buffer */ uint8_t *ptr=(uint8_t *)buf; /* build a time by which we should be finished */ - /* TODO: probably only set up deadline if we have to do select() */ - tio_tv_prepare(&deadline,&(fp->readtimeout)); + tio_get_deadline(&deadline,fp->readtimeout); /* loop until we have returned all the needed data */ while (1) { @@ -292,12 +267,22 @@ int tio_read(TFILE *fp, void *buf, size_t count) } } /* wait until we have input */ - if (tio_select(fp,1,&deadline)) + if (tio_wait(fp,1,&deadline)) return -1; /* read the input in the buffer */ - rv=read(fp->fd,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.size-fp->readbuffer.start); + len=fp->readbuffer.size-fp->readbuffer.start; +#ifdef SSIZE_MAX + if (len>SSIZE_MAX) + len=SSIZE_MAX; +#endif /* SSIZE_MAX */ + rv=read(fp->fd,fp->readbuffer.buffer+fp->readbuffer.start,len); /* check for errors */ - if ((rv==0)||((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN))) + if (rv==0) + { + errno=ECONNRESET; + return -1; + } + else if ((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN)) return -1; /* something went wrong with the read */ /* skip the read part in the buffer */ fp->readbuffer.len=rv; @@ -313,6 +298,46 @@ int tio_skip(TFILE *fp, size_t count) return tio_read(fp,NULL,count); } +/* Read all available data from the stream and empty the read buffer. */ +int tio_skipall(TFILE *fp) +{ + struct pollfd fds[1]; + int rv; + size_t len; + /* clear the read buffer */ + fp->readbuffer.start=0; + fp->readbuffer.len=0; + fp->read_resettable=0; + /* read until we can't read no more */ + len=fp->readbuffer.size; +#ifdef SSIZE_MAX + if (len>SSIZE_MAX) + len=SSIZE_MAX; +#endif /* SSIZE_MAX */ + while (1) + { + /* see if any data is available */ + fds[0].fd=fp->fd; + fds[0].events=POLLIN; + rv=poll(fds,1,0); + /* check the poll() result */ + if (rv==0) + return 0; /* no file descriptor ready */ + if ((rv<0)&&((errno==EINTR)||(errno==EAGAIN))) + continue; /* interrupted, try again */ + if (rv<0) + return -1; /* something went wrong */ + /* read data from the stream */ + rv=read(fp->fd,fp->readbuffer.buffer,len); + if (rv==0) + return 0; /* end-of-file */ + if ((rv<0)&&(errno==EWOULDBLOCK)) + return 0; /* we've ready everything we can without blocking */ + if ((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN)) + return -1; /* something went wrong with the read */ + } +} + /* the caller has assured us that we can write to the file descriptor and we give it a shot */ static int tio_writebuf(TFILE *fp) @@ -370,12 +395,12 @@ int tio_flush(TFILE *fp) { struct timeval deadline; /* build a time by which we should be finished */ - tio_tv_prepare(&deadline,&(fp->writetimeout)); + tio_get_deadline(&deadline,fp->writetimeout); /* loop until we have written our buffer */ while (fp->writebuffer.len > 0) { /* wait until we can write */ - if (tio_select(fp,0,&deadline)) + if (tio_wait(fp,0,&deadline)) return -1; /* write one block */ if (tio_writebuf(fp)) @@ -388,17 +413,12 @@ int tio_flush(TFILE *fp) will accept data */ static int tio_flush_nonblock(TFILE *fp) { - struct timeval tv; - fd_set fdset; + struct pollfd fds[1]; int rv; - /* prepare our filedescriptorset */ - FD_ZERO(&fdset); - FD_SET(fp->fd,&fdset); - /* set the timeout to 0 to poll */ - tv.tv_sec=0; - tv.tv_usec=0; /* wait for activity */ - rv=select(FD_SETSIZE,NULL,&fdset,NULL,&tv); + fds[0].fd=fp->fd; + fds[0].events=POLLOUT; + rv=poll(fds,1,0); /* check if any file descriptors were ready (timeout) or we were interrupted */ if ((rv==0)||((rv<0)&&(errno==EINTR))) diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.h b/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.h index f577b63a7a..eaebf88a2d 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.h +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.h @@ -2,7 +2,7 @@ tio.h - timed io functions This file is part of the nss-pam-ldapd library. - Copyright (C) 2007, 2008 Arthur de Jong + Copyright (C) 2007, 2008, 2010, 2012 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 @@ -33,8 +33,8 @@ */ -#ifndef _TIO_H -#define _TIO_H +#ifndef COMMON__TIO_H +#define COMMON__TIO_H #include #include @@ -46,9 +46,8 @@ typedef struct tio_fileinfo TFILE; /* Open a new TFILE based on the file descriptor. The timeout is set for any - operation. The timeout value is copied so may be dereferenced after the - call. */ -TFILE *tio_fdopen(int fd,struct timeval *readtimeout,struct timeval *writetimeout, + operation (value in milliseconds). */ +TFILE *tio_fdopen(int fd,int readtimeout,int writetimeout, size_t initreadsize,size_t maxreadsize, size_t initwritesize,size_t maxwritesize) LIKE_MALLOC MUST_USE; @@ -59,6 +58,9 @@ int tio_read(TFILE *fp,void *buf,size_t count); /* Read and discard the specified number of bytes from the stream. */ int tio_skip(TFILE *fp,size_t count); +/* Read all available data from the stream and empty the read buffer. */ +int tio_skipall(TFILE *fp); + /* Write the specified buffer to the stream. */ int tio_write(TFILE *fp,const void *buf,size_t count); @@ -78,4 +80,4 @@ void tio_mark(TFILE *fp); were full). */ int tio_reset(TFILE *fp); -#endif /* _TIO_H */ +#endif /* COMMON__TIO_H */ -- 2.39.5