From: Ryan Tandy Date: Wed, 7 Jan 2015 15:45:23 +0000 (-0800) Subject: ITS#8097 nssov: update nss-pam-ldapd files to 0.9.4 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=27a4cfea51def69831647a3b202e1f2a55c4eb08;p=openldap ITS#8097 nssov: update nss-pam-ldapd files to 0.9.4 --- diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/README b/contrib/slapd-modules/nssov/nss-pam-ldapd/README index 39198dd998..4176ad7d63 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/README +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/README @@ -1,4 +1,4 @@ -These files were pulled from the nss-pam-ldapd project version 0.8.12. +These files were pulled from the nss-pam-ldapd project version 0.9.4. Copyright notices are in the individual files. This is not the full distribution of nss-pam-ldapd, and does not @@ -10,6 +10,6 @@ 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 +version 0.9.0. 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 0bc0f30d90..83f1777f22 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/attrs.h +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/attrs.h @@ -1,7 +1,7 @@ /* attrs.h - wrapper macros for the gcc __attribute__(()) directive - Copyright (C) 2007, 2008 Arthur de Jong + Copyright (C) 2007, 2008, 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 @@ -23,7 +23,7 @@ #define COMPAT__ATTRS_H 1 /* macro for testing the version of GCC */ -#define GCC_VERSION(major,minor) \ +#define GCC_VERSION(major, minor) \ ((__GNUC__ > (major)) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))) /* These are macros to use some gcc-specific flags in case the're available @@ -34,7 +34,7 @@ /* this is used to flag function parameters that are not used in the function body. */ -#if GCC_VERSION(3,0) +#if GCC_VERSION(3, 0) #define UNUSED(x) x __attribute__((__unused__)) #else #define UNUSED(x) x @@ -42,16 +42,16 @@ /* this is used to add extra format checking to the function calls as if this was a printf()-like function */ -#if GCC_VERSION(3,0) -#define LIKE_PRINTF(format_idx,arg_idx) \ - __attribute__((__format__(__printf__,format_idx,arg_idx))) +#if GCC_VERSION(3, 0) +#define LIKE_PRINTF(format_idx, arg_idx) \ + __attribute__((__format__(__printf__, format_idx, arg_idx))) #else -#define LIKE_PRINTF(format_idx,arg_idx) /* no attribute */ +#define LIKE_PRINTF(format_idx, arg_idx) /* no attribute */ #endif -/* indicates that the function is "pure": it's result is purely based on +/* indicates that the function is "pure": its result is purely based on the parameters and has no side effects or used static data */ -#if GCC_VERSION(3,0) +#if GCC_VERSION(3, 0) #define PURE __attribute__((__pure__)) #else #define PURE /* no attribute */ @@ -59,21 +59,21 @@ /* the function returns a new data structure that has been freshly allocated */ -#if GCC_VERSION(3,0) +#if GCC_VERSION(3, 0) #define LIKE_MALLOC __attribute__((__malloc__)) #else #define LIKE_MALLOC /* no attribute */ #endif /* the function's return value should be used by the caller */ -#if GCC_VERSION(3,4) +#if GCC_VERSION(3, 4) #define MUST_USE __attribute__((__warn_unused_result__)) #else #define MUST_USE /* no attribute */ #endif /* the function's return value should be used by the caller */ -#if GCC_VERSION(2,5) +#if GCC_VERSION(2, 5) #define NORETURN __attribute__((__noreturn__)) #else #define NORETURN /* no attribute */ 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 1252158c6d..649be890cc 100644 --- a/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd-prot.h +++ b/contrib/slapd-modules/nssov/nss-pam-ldapd/nslcd-prot.h @@ -2,7 +2,7 @@ nslcd-prot.h - helper macros for reading and writing in protocol streams Copyright (C) 2006 West Consulting - Copyright (C) 2006, 2007, 2009 Arthur de Jong + 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 @@ -23,6 +23,9 @@ #ifndef COMMON__NSLCD_PROT_H #define COMMON__NSLCD_PROT_H 1 +#include +#include + #include "tio.h" /* If you use these macros you should define the following macros to @@ -42,11 +45,12 @@ /* define a debugging macro to output logging */ #include #include -#define DEBUG_PRINT(fmt,arg) \ - fprintf(stderr,"%s:%d:%s: " fmt "\n",__FILE__,__LINE__,__PRETTY_FUNCTION__,arg); +#define DEBUG_PRINT(fmt, arg) \ + fprintf(stderr, "%s:%d:%s: " fmt "\n", __FILE__, __LINE__, \ + __PRETTY_FUNCTION__, arg); #else /* DEBUG_PROT */ /* define an empty debug macro to disable logging */ -#define DEBUG_PRINT(fmt,arg) +#define DEBUG_PRINT(fmt, arg) #endif /* not DEBUG_PROT */ #ifdef DEBUG_PROT_DUMP @@ -54,19 +58,19 @@ #ifdef HAVE_STDINT_H #include #endif /* HAVE_STDINT_H */ -static void debug_dump(const void *ptr,size_t size) +static void debug_dump(const void *ptr, size_t size) { int i; - for (i=0;i0) \ - { WRITE(fp,(str),tmpint32); } \ +#define WRITE_INT32(fp, i) \ + DEBUG_PRINT("WRITE_INT32 : var="__STRING(i)" int32=%08x", (int)i); \ + tmpint32 = htonl((int32_t)(i)); \ + WRITE(fp, &tmpint32, sizeof(int32_t)) + +#define WRITE_STRING(fp, str) \ + DEBUG_PRINT("WRITE_STRING: var="__STRING(str)" string=\"%s\"", (str)); \ + if ((str) == NULL) \ + { \ + WRITE_INT32(fp, 0); \ + } \ + else \ + { \ + WRITE_INT32(fp, strlen(str)); \ + tmpint32 = ntohl(tmpint32); \ + if (tmpint32 > 0) \ + { \ + WRITE(fp, (str), tmpint32); \ + } \ } -#define WRITE_STRINGLIST(fp,arr) \ - if ((arr)==NULL) \ - { \ - DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d",0); \ - WRITE_INT32(fp,0); \ - } \ - else \ - { \ - /* first determin length of array */ \ - for (tmp3int32=0;(arr)[tmp3int32]!=NULL;tmp3int32++) \ - /*noting*/ ; \ - /* write number of strings */ \ - DEBUG_PRINT("WRITE_STRLST: var="__STRING(arr)" num=%d",(int)tmp3int32); \ - WRITE_TYPE(fp,tmp3int32,int32_t); \ - /* write strings */ \ - for (tmp2int32=0;tmp2int32=sizeof(buffer)) \ - { \ - /* will not fit */ \ - tmpint32=(tmpint32-sizeof(buffer))+1; \ - DEBUG_PRINT("READ : buffer %d bytes too small",tmpint32); \ - ERROR_OUT_BUFERROR(fp); \ - } \ - /* read string from the stream */ \ - if (tmpint32>0) \ - { READ(fp,buffer,(size_t)tmpint32); } \ - /* null-terminate string in buffer */ \ - buffer[tmpint32]='\0'; \ - DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" string=\"%s\"",buffer); +#define READ_STRING(fp, buffer) \ + /* read the size of the string */ \ + READ(fp, &tmpint32, sizeof(int32_t)); \ + tmpint32 = ntohl(tmpint32); \ + DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" strlen=%d", tmpint32); \ + /* check if read would fit */ \ + if (((size_t)tmpint32) >= sizeof(buffer)) \ + { \ + /* will not fit */ \ + tmpint32 = (tmpint32 - sizeof(buffer)) + 1; \ + DEBUG_PRINT("READ : buffer %d bytes too small", tmpint32); \ + ERROR_OUT_BUFERROR(fp); \ + } \ + /* read string from the stream */ \ + if (tmpint32 > 0) \ + { \ + READ(fp, buffer, (size_t)tmpint32); \ + } \ + /* null-terminate string in buffer */ \ + buffer[tmpint32] = '\0'; \ + DEBUG_PRINT("READ_STRING: var="__STRING(buffer)" string=\"%s\"", buffer); /* READ BUF macros that read data into a pre-allocated buffer. @@ -202,116 +207,123 @@ static void debug_dump(const void *ptr,size_t size) */ /* current position in the buffer */ -#define BUF_CUR \ - (buffer+bufptr) +#define BUF_CUR \ + (buffer + bufptr) /* check that the buffer has sz bytes left in it */ -#define BUF_CHECK(fp,sz) \ - if ((bufptr+(size_t)(sz))>buflen) \ - { \ - /* will not fit */ \ - tmpint32=bufptr+(sz)-(buflen); \ - DEBUG_PRINT("READ : buffer %d bytes too small",tmpint32); \ - ERROR_OUT_BUFERROR(fp); \ +#define BUF_CHECK(fp, sz) \ + if ((bufptr + (size_t)(sz)) > buflen) \ + { \ + /* will not fit */ \ + tmpint32 = bufptr + (sz) - (buflen); \ + DEBUG_PRINT("READ : buffer %d bytes too small", tmpint32); \ + ERROR_OUT_BUFERROR(fp); \ } /* move the buffer pointer */ -#define BUF_SKIP(sz) \ - bufptr+=(size_t)(sz); +#define BUF_SKIP(sz) \ + bufptr += (size_t)(sz); /* move BUF_CUR foreward so that it is aligned to the specified type width */ -#define BUF_ALIGN(fp,type) \ - /* figure out number of bytes to skip foreward */ \ - tmp2int32=(sizeof(type)-((BUF_CUR-(char *)NULL)%sizeof(type)))%sizeof(type); \ - /* check and skip */ \ - BUF_CHECK(fp,tmp2int32); \ +#define BUF_ALIGN(fp, type) \ + /* figure out number of bytes to skip foreward */ \ + tmp2int32 = (sizeof(type) - ((BUF_CUR - (char *)NULL) % sizeof(type))) \ + % sizeof(type); \ + /* check and skip */ \ + BUF_CHECK(fp, tmp2int32); \ BUF_SKIP(tmp2int32); /* allocate a piece of the buffer to store an array in */ -#define BUF_ALLOC(fp,ptr,type,num) \ - /* align to the specified type width */ \ - BUF_ALIGN(fp,type); \ - /* check that we have enough room */ \ - BUF_CHECK(fp,(size_t)(num)*sizeof(type)); \ - /* store the pointer */ \ - (ptr)=(type *)BUF_CUR; \ - /* reserve the space */ \ - BUF_SKIP((size_t)(num)*sizeof(type)); +#define BUF_ALLOC(fp, ptr, type, num) \ + /* align to the specified type width */ \ + BUF_ALIGN(fp, type); \ + /* check that we have enough room */ \ + BUF_CHECK(fp, (size_t)(num) * sizeof(type)); \ + /* store the pointer */ \ + (ptr) = (type *)BUF_CUR; \ + /* reserve the space */ \ + BUF_SKIP((size_t)(num) * sizeof(type)); /* read a binary blob into the buffer */ -#define READ_BUF(fp,ptr,sz) \ - /* check that there is enough room and read */ \ - BUF_CHECK(fp,sz); \ - READ(fp,BUF_CUR,(size_t)sz); \ - /* store pointer and skip */ \ - (ptr)=BUF_CUR; \ +#define READ_BUF(fp, ptr, sz) \ + /* check that there is enough room and read */ \ + BUF_CHECK(fp, sz); \ + READ(fp, BUF_CUR, (size_t)sz); \ + /* store pointer and skip */ \ + (ptr) = BUF_CUR; \ BUF_SKIP(sz); /* read string in the buffer (using buffer, buflen and bufptr) and store the actual location of the string in field */ -#define READ_BUF_STRING(fp,field) \ - /* read the size of the string */ \ - READ_TYPE(fp,tmpint32,int32_t); \ - DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" strlen=%d",tmpint32); \ - /* check if read would fit */ \ - BUF_CHECK(fp,tmpint32+1); \ - /* read string from the stream */ \ - if (tmpint32>0) \ - { READ(fp,BUF_CUR,(size_t)tmpint32); } \ - /* null-terminate string in buffer */ \ - BUF_CUR[tmpint32]='\0'; \ - DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" string=\"%s\"",BUF_CUR); \ - /* prepare result */ \ - (field)=BUF_CUR; \ - BUF_SKIP(tmpint32+1); +#define READ_BUF_STRING(fp, field) \ + /* read the size of the string */ \ + READ(fp, &tmpint32, sizeof(int32_t)); \ + tmpint32 = ntohl(tmpint32); \ + DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" strlen=%d", tmpint32); \ + /* check if read would fit */ \ + BUF_CHECK(fp, tmpint32 + 1); \ + /* read string from the stream */ \ + if (tmpint32 > 0) \ + { \ + READ(fp, BUF_CUR, (size_t)tmpint32); \ + } \ + /* null-terminate string in buffer */ \ + BUF_CUR[tmpint32] = '\0'; \ + DEBUG_PRINT("READ_BUF_STRING: var="__STRING(field)" string=\"%s\"", BUF_CUR); \ + /* prepare result */ \ + (field) = BUF_CUR; \ + BUF_SKIP(tmpint32 + 1); /* read an array from a stram and store it as a null-terminated array list (size for the array is allocated) */ -#define READ_BUF_STRINGLIST(fp,arr) \ - /* read the number of entries */ \ - READ_TYPE(fp,tmp3int32,int32_t); \ - DEBUG_PRINT("READ_STRLST: var="__STRING(arr)" num=%d",(int)tmp3int32); \ - /* allocate room for *char[num+1] */ \ - BUF_ALLOC(fp,arr,char *,tmp3int32+1); \ - /* read all entries */ \ - for (tmp2int32=0;tmp2int32 #include #include +#include #include "tio.h" @@ -76,124 +76,117 @@ struct tio_fileinfo { #endif /* DEBUG_TIO_STATS */ }; -/* build a timeval for comparison to when the operation should be finished */ -static inline void tio_get_deadline(struct timeval *deadline,int timeout) -{ - if (gettimeofday(deadline,NULL)) - { - /* just blank it in case of errors */ - deadline->tv_sec=0; - deadline->tv_usec=0; - return; - } - deadline->tv_sec+=timeout/1000; - deadline->tv_sec+=(timeout%1000)*1000; -} +/* some older versions of Solaris don't provide CLOCK_MONOTONIC but do have + a CLOCK_HIGHRES that has the same properties we need */ +#ifndef CLOCK_MONOTONIC +#ifdef CLOCK_HIGHRES +#define CLOCK_MONOTONIC CLOCK_HIGHRES +#endif /* CLOCK_HIGHRES */ +#endif /* not CLOCK_MONOTONIC */ -/* 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_time_remaining(const struct timeval *deadline) +/* update the timeout to the value that is remaining before the deadline + returns the number of milliseconds before the deadline (or a negative + value of the deadline has expired) */ +static inline int tio_time_remaining(struct timespec *deadline, int timeout) { - struct timeval tv; - /* get the current time */ - if (gettimeofday(&tv,NULL)) + struct timespec tv; + /* if this is the first call, set the deadline and return the full time */ + if ((deadline->tv_sec == 0) && (deadline->tv_nsec == 0)) { - /* 1 second default if gettimeofday() is broken */ - return 1000; + if (clock_gettime(CLOCK_MONOTONIC, deadline) == 0) + { + deadline->tv_sec += timeout / 1000; + deadline->tv_nsec += (timeout % 1000) * 1000000; + } + return timeout; } - /* calculate time remaining in miliseconds */ - return (deadline->tv_sec-tv.tv_sec)*1000 + (deadline->tv_usec-tv.tv_usec)/1000; + /* get the current time (fall back to full time on error) */ + if (clock_gettime(CLOCK_MONOTONIC, &tv)) + return timeout; + /* calculate time remaining in milliseconds */ + return (deadline->tv_sec - tv.tv_sec) * 1000 + + (deadline->tv_nsec - tv.tv_nsec) / 1000000; } /* open a new TFILE based on the file descriptor */ -TFILE *tio_fdopen(int fd,int readtimeout,int writetimeout, - size_t initreadsize,size_t maxreadsize, - size_t initwritesize,size_t maxwritesize) +TFILE *tio_fdopen(int fd, int readtimeout, int writetimeout, + size_t initreadsize, size_t maxreadsize, + size_t initwritesize, size_t maxwritesize) { struct tio_fileinfo *fp; - fp=(struct tio_fileinfo *)malloc(sizeof(struct tio_fileinfo)); - if (fp==NULL) + fp = (struct tio_fileinfo *)malloc(sizeof(struct tio_fileinfo)); + if (fp == NULL) return NULL; - fp->fd=fd; + fp->fd = fd; /* initialize read buffer */ - fp->readbuffer.buffer=(uint8_t *)malloc(initreadsize); - if (fp->readbuffer.buffer==NULL) + fp->readbuffer.buffer = (uint8_t *)malloc(initreadsize); + if (fp->readbuffer.buffer == NULL) { free(fp); return NULL; } - fp->readbuffer.size=initreadsize; - fp->readbuffer.maxsize=maxreadsize; - fp->readbuffer.start=0; - fp->readbuffer.len=0; + fp->readbuffer.size = initreadsize; + fp->readbuffer.maxsize = maxreadsize; + fp->readbuffer.start = 0; + fp->readbuffer.len = 0; /* initialize write buffer */ - fp->writebuffer.buffer=(uint8_t *)malloc(initwritesize); - if (fp->writebuffer.buffer==NULL) + fp->writebuffer.buffer = (uint8_t *)malloc(initwritesize); + if (fp->writebuffer.buffer == NULL) { free(fp->readbuffer.buffer); free(fp); return NULL; } - fp->writebuffer.size=initwritesize; - fp->writebuffer.maxsize=maxwritesize; - fp->writebuffer.start=0; - fp->writebuffer.len=0; + fp->writebuffer.size = initwritesize; + fp->writebuffer.maxsize = maxwritesize; + fp->writebuffer.start = 0; + fp->writebuffer.len = 0; /* initialize other attributes */ - fp->readtimeout=readtimeout; - fp->writetimeout=writetimeout; - fp->read_resettable=0; + fp->readtimeout = readtimeout; + fp->writetimeout = writetimeout; + fp->read_resettable = 0; #ifdef DEBUG_TIO_STATS - fp->byteswritten=0; - fp->bytesread=0; + fp->byteswritten = 0; + fp->bytesread = 0; #endif /* DEBUG_TIO_STATS */ return fp; } /* wait for any activity on the specified file descriptor using the specified deadline */ -static int tio_wait(TFILE *fp,int readfd,const struct timeval *deadline) +static int tio_wait(int fd, short events, int timeout, + struct timespec *deadline) { - int timeout; + int t; struct pollfd fds[1]; int rv; while (1) { + fds[0].fd = fd; + fds[0].events = events; /* figure out the time we need to wait */ - if ((timeout=tio_time_remaining(deadline))<0) + if ((t = tio_time_remaining(deadline, timeout)) < 0) { - errno=ETIME; + errno = ETIME; return -1; } + /* sanitiy check for moving clock */ + if (t > timeout) + t = timeout; /* wait for activity */ - if (readfd) - { - fds[0].fd=fp->fd; - fds[0].events=POLLIN; - /* santiy check for moving clock */ - if (timeout>fp->readtimeout) - timeout=fp->readtimeout; - } - else - { - fds[0].fd=fp->fd; - fds[0].events=POLLOUT; - /* santiy check for moving clock */ - if (timeout>fp->writetimeout) - timeout=fp->writetimeout; - } - rv=poll(fds,1,timeout); - if (rv>0) + rv = poll(fds, 1, t); + if (rv > 0) return 0; /* we have activity */ - else if (rv==0) + else if (rv == 0) { /* no file descriptors were available within the specified time */ - errno=ETIME; + errno = ETIME; return -1; } - else if (errno!=EINTR) + else if ((errno != EINTR) && (errno != EAGAIN)) /* some error ocurred */ return -1; - /* we just try again on EINTR */ + /* we just try again on EINTR or EAGAIN */ } } @@ -201,93 +194,92 @@ static int tio_wait(TFILE *fp,int readfd,const struct timeval *deadline) if no data was read in the specified time an error is returned */ int tio_read(TFILE *fp, void *buf, size_t count) { - struct timeval deadline; + struct timespec deadline = {0, 0}; 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 */ - tio_get_deadline(&deadline,fp->readtimeout); + uint8_t *ptr = (uint8_t *)buf; /* loop until we have returned all the needed data */ while (1) { /* check if we have enough data in the buffer */ if (fp->readbuffer.len >= count) { - if (count>0) + if (count > 0) { - if (ptr!=NULL) - memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,count); + if (ptr != NULL) + memcpy(ptr, fp->readbuffer.buffer + fp->readbuffer.start, count); /* adjust buffer position */ - fp->readbuffer.start+=count; - fp->readbuffer.len-=count; + fp->readbuffer.start += count; + fp->readbuffer.len -= count; } return 0; } /* empty what we have and continue from there */ - if (fp->readbuffer.len>0) + if (fp->readbuffer.len > 0) { - if (ptr!=NULL) + if (ptr != NULL) { - memcpy(ptr,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.len); - ptr+=fp->readbuffer.len; + memcpy(ptr, fp->readbuffer.buffer + fp->readbuffer.start, + fp->readbuffer.len); + ptr += fp->readbuffer.len; } - count-=fp->readbuffer.len; - fp->readbuffer.start+=fp->readbuffer.len; - fp->readbuffer.len=0; + count -= fp->readbuffer.len; + fp->readbuffer.start += fp->readbuffer.len; + fp->readbuffer.len = 0; } /* after this point until the read fp->readbuffer.len is 0 */ if (!fp->read_resettable) { /* the stream is not resettable, re-use the buffer */ - fp->readbuffer.start=0; + fp->readbuffer.start = 0; } - else if (fp->readbuffer.start>=(fp->readbuffer.size-4)) + else if (fp->readbuffer.start >= (fp->readbuffer.size - 4)) { /* buffer is running empty, try to grow buffer */ - if (fp->readbuffer.sizereadbuffer.maxsize) + if (fp->readbuffer.size < fp->readbuffer.maxsize) { - newsz=fp->readbuffer.size*2; - if (newsz>fp->readbuffer.maxsize) - newsz=fp->readbuffer.maxsize; - tmp=realloc(fp->readbuffer.buffer,newsz); - if (tmp!=NULL) + newsz = fp->readbuffer.size * 2; + if (newsz > fp->readbuffer.maxsize) + newsz = fp->readbuffer.maxsize; + tmp = realloc(fp->readbuffer.buffer, newsz); + if (tmp != NULL) { - fp->readbuffer.buffer=tmp; - fp->readbuffer.size=newsz; + fp->readbuffer.buffer = tmp; + fp->readbuffer.size = newsz; } } /* if buffer still does not contain enough room, clear resettable */ - if (fp->readbuffer.start>=(fp->readbuffer.size-4)) + if (fp->readbuffer.start >= (fp->readbuffer.size - 4)) { - fp->readbuffer.start=0; - fp->read_resettable=0; + fp->readbuffer.start = 0; + fp->read_resettable = 0; } } /* wait until we have input */ - if (tio_wait(fp,1,&deadline)) + if (tio_wait(fp->fd, POLLIN, fp->readtimeout, &deadline)) return -1; /* read the input in the buffer */ - len=fp->readbuffer.size-fp->readbuffer.start; + len = fp->readbuffer.size - fp->readbuffer.start; #ifdef SSIZE_MAX - if (len>SSIZE_MAX) - len=SSIZE_MAX; + if (len > SSIZE_MAX) + len = SSIZE_MAX; #endif /* SSIZE_MAX */ - rv=read(fp->fd,fp->readbuffer.buffer+fp->readbuffer.start,len); + rv = read(fp->fd, fp->readbuffer.buffer + fp->readbuffer.start, len); /* check for errors */ - if (rv==0) + if (rv == 0) { - errno=ECONNRESET; + 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; + else if ((rv < 0) && (errno != EINTR) && (errno != EAGAIN)) + return -1; /* something went wrong with the read */ + else if (rv > 0) + fp->readbuffer.len = rv; /* skip the read part in the buffer */ #ifdef DEBUG_TIO_STATS - fp->bytesread+=rv; + fp->bytesread += rv; #endif /* DEBUG_TIO_STATS */ } } @@ -295,45 +287,37 @@ 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) { - return tio_read(fp,NULL,count); + return tio_read(fp, NULL, count); } /* Read all available data from the stream and empty the read buffer. */ -int tio_skipall(TFILE *fp) +int tio_skipall(TFILE *fp, int timeout) { - struct pollfd fds[1]; + struct timespec deadline = {0, 0}; int rv; size_t len; /* clear the read buffer */ - fp->readbuffer.start=0; - fp->readbuffer.len=0; - fp->read_resettable=0; + fp->readbuffer.start = 0; + fp->readbuffer.len = 0; + fp->read_resettable = 0; /* read until we can't read no more */ - len=fp->readbuffer.size; + len = fp->readbuffer.size; #ifdef SSIZE_MAX - if (len>SSIZE_MAX) - len=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 */ + /* wait until we have input */ + if (tio_wait(fp->fd, POLLIN, timeout, &deadline)) + return -1; /* read data from the stream */ - rv=read(fp->fd,fp->readbuffer.buffer,len); - if (rv==0) + rv = read(fp->fd, fp->readbuffer.buffer, len); + if (rv == 0) return 0; /* end-of-file */ - if ((rv<0)&&(errno==EWOULDBLOCK)) + if ((rv < 0) && (errno == EWOULDBLOCK)) return 0; /* we've ready everything we can without blocking */ - if ((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN)) + if ((rv < 0) && (errno != EINTR) && (errno != EAGAIN)) return -1; /* something went wrong with the read */ } } @@ -345,46 +329,50 @@ static int tio_writebuf(TFILE *fp) int rv; /* write the buffer */ #ifdef MSG_NOSIGNAL - rv=send(fp->fd,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len,MSG_NOSIGNAL); + rv = send(fp->fd, fp->writebuffer.buffer + fp->writebuffer.start, + fp->writebuffer.len, MSG_NOSIGNAL); #else /* not MSG_NOSIGNAL */ /* on platforms that cannot use send() with masked signals, we change the signal mask and change it back after the write (note that there is a race condition here) */ - struct sigaction act,oldact; + struct sigaction act, oldact; /* set up sigaction */ - memset(&act,0,sizeof(struct sigaction)); - act.sa_sigaction=NULL; - act.sa_handler=SIG_IGN; + memset(&act, 0, sizeof(struct sigaction)); + act.sa_sigaction = NULL; + act.sa_handler = SIG_IGN; sigemptyset(&act.sa_mask); - act.sa_flags=SA_RESTART; + act.sa_flags = SA_RESTART; /* ignore SIGPIPE */ - if (sigaction(SIGPIPE,&act,&oldact)!=0) + if (sigaction(SIGPIPE, &act, &oldact) != 0) return -1; /* error setting signal handler */ /* write the buffer */ - rv=write(fp->fd,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len); + rv = write(fp->fd, fp->writebuffer.buffer + fp->writebuffer.start, + fp->writebuffer.len); /* restore the old handler for SIGPIPE */ - if (sigaction(SIGPIPE,&oldact,NULL)!=0) + if (sigaction(SIGPIPE, &oldact, NULL) != 0) return -1; /* error restoring signal handler */ #endif /* check for errors */ - if ((rv==0)||((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN))) + if ((rv == 0) || ((rv < 0) && (errno != EINTR) && (errno != EAGAIN))) return -1; /* something went wrong with the write */ /* skip the written part in the buffer */ - if (rv>0) + if (rv > 0) { - fp->writebuffer.start+=rv; - fp->writebuffer.len-=rv; + fp->writebuffer.start += rv; + fp->writebuffer.len -= rv; #ifdef DEBUG_TIO_STATS - fp->byteswritten+=rv; + fp->byteswritten += rv; #endif /* DEBUG_TIO_STATS */ /* reset start if len is 0 */ - if (fp->writebuffer.len==0) - fp->writebuffer.start=0; + if (fp->writebuffer.len == 0) + fp->writebuffer.start = 0; /* move contents of the buffer to the front if it will save enough room */ - if (fp->writebuffer.start>=(fp->writebuffer.size/4)) + if (fp->writebuffer.start >= (fp->writebuffer.size / 4)) { - memmove(fp->writebuffer.buffer,fp->writebuffer.buffer+fp->writebuffer.start,fp->writebuffer.len); - fp->writebuffer.start=0; + memmove(fp->writebuffer.buffer, + fp->writebuffer.buffer + fp->writebuffer.start, + fp->writebuffer.len); + fp->writebuffer.start = 0; } } return 0; @@ -393,14 +381,12 @@ static int tio_writebuf(TFILE *fp) /* write all the data in the buffer to the stream */ int tio_flush(TFILE *fp) { - struct timeval deadline; - /* build a time by which we should be finished */ - tio_get_deadline(&deadline,fp->writetimeout); + struct timespec deadline = {0, 0}; /* loop until we have written our buffer */ while (fp->writebuffer.len > 0) { /* wait until we can write */ - if (tio_wait(fp,0,&deadline)) + if (tio_wait(fp->fd, POLLOUT, fp->writetimeout, &deadline)) return -1; /* write one block */ if (tio_writebuf(fp)) @@ -415,16 +401,16 @@ static int tio_flush_nonblock(TFILE *fp) { struct pollfd fds[1]; int rv; - /* wait for activity */ - fds[0].fd=fp->fd; - fds[0].events=POLLOUT; - rv=poll(fds,1,0); + /* see if we can write without blocking */ + 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))) + if ((rv == 0) || ((rv < 0) && ((errno == EINTR) || (errno == EAGAIN)))) return 0; /* any other errors? */ - if (rv<0) + if (rv < 0) return -1; /* so file descriptor will accept writes */ return tio_writebuf(fp); @@ -435,44 +421,46 @@ int tio_write(TFILE *fp, const void *buf, size_t count) size_t fr; uint8_t *tmp; size_t newsz; - const uint8_t *ptr=(const uint8_t *)buf; + const uint8_t *ptr = (const uint8_t *)buf; /* keep filling the buffer until we have bufferred everything */ - while (count>0) + while (count > 0) { /* figure out free size in buffer */ - fr=fp->writebuffer.size-(fp->writebuffer.start+fp->writebuffer.len); + fr = fp->writebuffer.size - (fp->writebuffer.start + fp->writebuffer.len); if (count <= fr) { /* the data fits in the buffer */ - memcpy(fp->writebuffer.buffer+fp->writebuffer.start+fp->writebuffer.len,ptr,count); - fp->writebuffer.len+=count; + memcpy(fp->writebuffer.buffer + fp->writebuffer.start + + fp->writebuffer.len, ptr, count); + fp->writebuffer.len += count; return 0; } else if (fr > 0) { /* fill the buffer with data that will fit */ - memcpy(fp->writebuffer.buffer+fp->writebuffer.start+fp->writebuffer.len,ptr,fr); - fp->writebuffer.len+=fr; - ptr+=fr; - count-=fr; + memcpy(fp->writebuffer.buffer + fp->writebuffer.start + + fp->writebuffer.len, ptr, fr); + fp->writebuffer.len += fr; + ptr += fr; + count -= fr; } /* try to flush some of the data that is in the buffer */ if (tio_flush_nonblock(fp)) return -1; /* if we have room now, try again */ - if (fp->writebuffer.size>(fp->writebuffer.start+fp->writebuffer.len)) + if (fp->writebuffer.size > (fp->writebuffer.start + fp->writebuffer.len)) continue; /* try to grow the buffer */ - if (fp->writebuffer.sizewritebuffer.maxsize) + if (fp->writebuffer.size < fp->writebuffer.maxsize) { - newsz=fp->writebuffer.size*2; - if (newsz>fp->writebuffer.maxsize) - newsz=fp->writebuffer.maxsize; - tmp=realloc(fp->writebuffer.buffer,newsz); - if (tmp!=NULL) + newsz = fp->writebuffer.size * 2; + if (newsz > fp->writebuffer.maxsize) + newsz = fp->writebuffer.maxsize; + tmp = realloc(fp->writebuffer.buffer, newsz); + if (tmp != NULL) { - fp->writebuffer.buffer=tmp; - fp->writebuffer.size=newsz; + fp->writebuffer.buffer = tmp; + fp->writebuffer.size = newsz; continue; /* try again */ } } @@ -487,15 +475,18 @@ int tio_close(TFILE *fp) { int retv; /* write any buffered data */ - retv=tio_flush(fp); + retv = tio_flush(fp); #ifdef DEBUG_TIO_STATS /* dump statistics to stderr */ - fprintf(stderr,"DEBUG_TIO_STATS READ=%d WRITTEN=%d\n",fp->bytesread,fp->byteswritten); + fprintf(stderr, "DEBUG_TIO_STATS READ=%d WRITTEN=%d\n", fp->bytesread, + fp->byteswritten); #endif /* DEBUG_TIO_STATS */ /* close file descriptor */ if (close(fp->fd)) - retv=-1; + retv = -1; /* free any allocated buffers */ + memset(fp->readbuffer.buffer, 0, fp->readbuffer.size); + memset(fp->writebuffer.buffer, 0, fp->writebuffer.size); free(fp->readbuffer.buffer); free(fp->writebuffer.buffer); /* free the tio struct itself */ @@ -507,13 +498,14 @@ int tio_close(TFILE *fp) void tio_mark(TFILE *fp) { /* move any data in the buffer to the start of the buffer */ - if ((fp->readbuffer.start>0)&&(fp->readbuffer.len>0)) + if ((fp->readbuffer.start > 0) && (fp->readbuffer.len > 0)) { - memmove(fp->readbuffer.buffer,fp->readbuffer.buffer+fp->readbuffer.start,fp->readbuffer.len); - fp->readbuffer.start=0; + memmove(fp->readbuffer.buffer, + fp->readbuffer.buffer + fp->readbuffer.start, fp->readbuffer.len); + fp->readbuffer.start = 0; } /* mark the stream as resettable */ - fp->read_resettable=1; + fp->read_resettable = 1; } int tio_reset(TFILE *fp) @@ -522,7 +514,7 @@ int tio_reset(TFILE *fp) if (!fp->read_resettable) return -1; /* reset the buffer */ - fp->readbuffer.len+=fp->readbuffer.start; - fp->readbuffer.start=0; + fp->readbuffer.len += fp->readbuffer.start; + fp->readbuffer.start = 0; return 0; } diff --git a/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.h b/contrib/slapd-modules/nssov/nss-pam-ldapd/tio.h index eaebf88a2d..95f981255c 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, 2010, 2012 Arthur de Jong + Copyright (C) 2007, 2008, 2010, 2012, 2013 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 @@ -47,22 +47,22 @@ typedef struct tio_fileinfo TFILE; /* Open a new TFILE based on the file descriptor. The timeout is set for any 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) +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; /* Read the specified number of bytes from the stream. */ -int tio_read(TFILE *fp,void *buf,size_t count); +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); +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); +int tio_skipall(TFILE *fp, int timeout); /* Write the specified buffer to the stream. */ -int tio_write(TFILE *fp,const void *buf,size_t count); +int tio_write(TFILE *fp, const void *buf, size_t count); /* Write out all buffered data to the stream. */ int tio_flush(TFILE *fp);