Commit 0dfb5095 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Changes:

    Fixed liblutil getpeereid replacement function
    Fixed liblber 64bit len/tag bug
    Updated liblber ber_get_stringbv handling
    Build Environment
        Updated NT build environment w/ slurpd support
        Updated test suite
parent cf2ae725
......@@ -2,6 +2,12 @@ OpenLDAP 2.1 Change Log
OpenLDAP 2.1.15 Engineering
Fixed slapd saslauthz null backend crash
Fixed liblutil getpeereid replacement function
Fixed liblber 64bit len/tag bug
Updated liblber ber_get_stringbv handling
Build Environment
Updated NT build environment w/ slurpd support
Updated test suite
OpenLDAP 2.1.14 Release
Fixed slapd schema_check name check crash (ITS#2330)
......
......@@ -1216,3 +1216,16 @@ AC_DEFUN([OL_SASL_COMPAT],
#endif
], [ol_cv_sasl_compat=yes], [ol_cv_sasl_compat=no])])
])
dnl ====================================================================
dnl check for msg_accrights in msghdr
AC_DEFUN(OL_MSGHDR_MSG_ACCRIGHTS,
[AC_CACHE_CHECK(for msg_accrights in msghdr, ol_cv_msghdr_msg_accrights,
[AC_TRY_COMPILE([#include <sys/socket.h>],
[struct msghdr m; m.msg_accrightslen=0],
ol_cv_msghdr_msg_accrights=yes, ol_cv_msghdr_msg_accrights=no)
])
if test $ol_cv_msghdr_msg_accrights = "yes" ; then
AC_DEFINE(HAVE_MSGHDR_MSG_ACCRIGHTS,1,
[define if struct msghdr has msg_accrights])
fi
])dnl
This diff is collapsed.
......@@ -808,10 +808,12 @@ AC_CHECK_HEADERS( \
sys/resource.h \
sys/select.h \
sys/socket.h \
sys/stat.h \
sys/syslog.h \
sys/time.h \
sys/types.h \
sys/ucred.h \
sys/uio.h \
syslog.h \
termios.h \
unistd.h \
......@@ -2438,6 +2440,7 @@ if test "$ac_cv_func_getopt" != yes; then
LIBSRCS="$LIBSRCS getopt.c"
fi
if test "$ac_cv_func_getpeereid" != yes; then
OL_MSGHDR_MSG_ACCRIGHTS
LIBSRCS="$LIBSRCS getpeereid.c"
fi
if test "$ac_cv_func_snprintf" != yes -o "$ac_cv_func_vsnprintf" != yes; then
......
# $OpenLDAP$
## Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
## Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
##
## include Makefile.in for OpenLDAP
......@@ -43,10 +43,6 @@ ldap_config.h: $(LDAP_CONFIG) Makefile
$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
localstatedir=`cygpath -w $(localstatedir) | \
$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
editor=`cygpath -w $(EDITOR) | \
$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
sendmail=`cygpath -w $(SENDMAIL) | \
$(SED) -e 's/\\\\/\\\\\\\\\\\\\\\\/g'`; \
else \
sysconfdir=$(sysconfdir); \
datadir=$(datadir); \
......@@ -54,8 +50,6 @@ ldap_config.h: $(LDAP_CONFIG) Makefile
sbindir=$(sbindir); \
libexecdir=$(libexecdir); \
localstatedir=$(localstatedir); \
editor=$(EDITOR); \
sendmail=$(SENDMAIL); \
fi; \
$(SED) \
-e "s;%SYSCONFDIR%;$$sysconfdir;" \
......@@ -64,8 +58,6 @@ ldap_config.h: $(LDAP_CONFIG) Makefile
-e "s;%SBINDIR%;$$sbindir;" \
-e "s;%LIBEXECDIR%;$$libexecdir;" \
-e "s;%RUNDIR%;$$localstatedir;" \
-e "s;%EDITOR%;$$editor;" \
-e "s;%SENDMAIL%;$$sendmail;" \
$(LDAP_CONFIG) >> $@; \
$(CHMOD) 444 $@
......
......@@ -162,12 +162,35 @@ LDAP_LUTIL_V (ldap_pvt_thread_cond_t) started_event;
/* macros are different between Windows and Mingw */
#if defined(_WINSVC_H) || defined(_WINSVC_)
LDAP_LUTIL_V (SERVICE_STATUS) SLAPDServiceStatus;
LDAP_LUTIL_V (SERVICE_STATUS_HANDLE) hSLAPDServiceStatus;
LDAP_LUTIL_V (SERVICE_STATUS) lutil_ServiceStatus;
LDAP_LUTIL_V (SERVICE_STATUS_HANDLE) hlutil_ServiceStatus;
#endif /* _WINSVC_H */
LDAP_LUTIL_F (void)
lutil_CommenceStartupProcessing( char *serverName, void (*stopper)(int)) ;
LDAP_LUTIL_F (void)
lutil_ReportShutdownComplete( void );
LDAP_LUTIL_F (void *)
lutil_getRegParam( char *svc, char *value );
LDAP_LUTIL_F (int)
lutil_srv_install( char* service, char * displayName, char* filename,
int auto_start );
LDAP_LUTIL_F (int)
lutil_srv_remove ( char* service, char* filename );
#endif /* HAVE_NT_SERVICE_MANAGER */
#ifdef HAVE_NT_EVENT_LOG
LDAP_LUTIL_F (void)
lutil_LogStartedEvent( char *svc, int slap_debug, char *configfile, char *urls );
LDAP_LUTIL_F (void)
lutil_LogStoppedEvent( char *svc );
#endif
#ifdef HAVE_EBCDIC
/* Generally this has only been used to put '\n' to stdout. We need to
* make sure it is output in EBCDIC.
......
......@@ -539,6 +539,9 @@
/* Define if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
/* Define if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define if you have the <sys/syslog.h> header file. */
#undef HAVE_SYS_SYSLOG_H
......@@ -551,6 +554,9 @@
/* Define if you have the <sys/ucred.h> header file. */
#undef HAVE_SYS_UCRED_H
/* Define if you have the <sys/uio.h> header file. */
#undef HAVE_SYS_UIO_H
/* Define if you have the <sys/un.h> header file. */
#undef HAVE_SYS_UN_H
......@@ -878,6 +884,9 @@
/* define to vsnprintf routine */
#undef vsnprintf
/* define if struct msghdr has msg_accrights */
#undef HAVE_MSGHDR_MSG_ACCRIGHTS
/* define to snprintf routine */
#undef snprintf
......
......@@ -282,7 +282,7 @@ ber_get_stringb(
return tag;
}
/* Definitions for recursive get_string
/* Definitions for get_string vector
*
* ChArray, BvArray, and BvVec are self-explanatory.
* BvOff is a struct berval embedded in an array of larger structures
......@@ -296,9 +296,6 @@ enum bgbvc { ChArray, BvArray, BvVec, BvOff };
typedef struct bgbvr {
enum bgbvc choice;
BerElement *ber;
ber_tag_t tag;
ber_len_t len;
char *last;
int alloc;
ber_len_t siz;
ber_len_t off;
......@@ -309,74 +306,74 @@ typedef struct bgbvr {
} res;
} bgbvr;
/* Recursive get_string, for decoding a vector of strings. The number
* of elements in the vector is limited only by available stack space.
* Each invocation consumes 24 bytes of stack on a 32-bit machine.
*/
static ber_tag_t
ber_get_stringbvr( bgbvr *b, int n )
ber_get_stringbvl( bgbvr *b, ber_len_t *rlen )
{
int i = 0, n;
ber_tag_t tag;
ber_len_t len;
char *last, *orig;
struct berval bv, *bvp = NULL;
if ( n )
b->tag = ber_next_element( b->ber, &b->len, b->last );
else
b->tag = ber_first_element( b->ber, &b->len, &b->last );
if ( b->tag == LBER_DEFAULT )
{
b->len = n;
orig = b->ber->ber_ptr;
if ( n == 0 ) {
*b->res.c = NULL;
return 0;
}
/* Allocate the result vector */
switch (b->choice) {
case ChArray:
*b->res.c = LBER_MALLOC( (n+1) * sizeof( char * ));
if ( *b->res.c == NULL )
return LBER_DEFAULT;
(*b->res.c)[n] = NULL;
break;
case BvArray:
*b->res.ba = LBER_MALLOC( (n+1) * sizeof( struct berval ));
if ( *b->res.ba == NULL )
return LBER_DEFAULT;
(*b->res.ba)[n].bv_val = NULL;
break;
case BvVec:
*b->res.bv = LBER_MALLOC( (n+1) * sizeof( struct berval *));
if ( *b->res.bv == NULL )
return LBER_DEFAULT;
(*b->res.bv)[n] = NULL;
break;
case BvOff:
*b->res.ba = LBER_MALLOC( (n+1) * b->siz );
if ( *b->res.ba == NULL )
return LBER_DEFAULT;
((struct berval *)((long)(*b->res.ba) + n*b->siz +
b->off))->bv_val = NULL;
break;
tag = ber_first_element( b->ber, &len, &last );
if ( tag != LBER_DEFAULT ) {
for ( ; b->ber->ber_ptr < last; i++ )
{
tag = ber_skip_tag( b->ber, &len );
if (tag == LBER_DEFAULT) break;
b->ber->ber_ptr += len;
}
return 0;
}
/* Do all local allocs before the recursion. Then there
* cannot possibly be any failures on the return trip.
*/
if ( b->choice == BvVec )
bvp = LBER_MALLOC( sizeof( struct berval ));
if ( rlen ) *rlen = i;
if ( ber_get_stringbv( b->ber, &bv, b->alloc ) == LBER_DEFAULT ) {
if ( bvp ) LBER_FREE( bvp );
return LBER_DEFAULT;
if ( i == 0 )
{
*b->res.c = NULL;
return 0;
}
b->tag = ber_get_stringbvr( b, n+1 );
n = i;
/* Allocate the result vector */
switch (b->choice) {
case ChArray:
*b->res.c = LBER_MALLOC( (n+1) * sizeof( char * ));
if ( *b->res.c == NULL )
return LBER_DEFAULT;
(*b->res.c)[n] = NULL;
break;
case BvArray:
*b->res.ba = LBER_MALLOC( (n+1) * sizeof( struct berval ));
if ( *b->res.ba == NULL )
return LBER_DEFAULT;
(*b->res.ba)[n].bv_val = NULL;
break;
case BvVec:
*b->res.bv = LBER_MALLOC( (n+1) * sizeof( struct berval *));
if ( *b->res.bv == NULL )
return LBER_DEFAULT;
(*b->res.bv)[n] = NULL;
break;
case BvOff:
*b->res.ba = LBER_MALLOC( (n+1) * b->siz );
if ( *b->res.ba == NULL )
return LBER_DEFAULT;
((struct berval *)((long)(*b->res.ba) + n*b->siz +
b->off))->bv_val = NULL;
break;
}
b->ber->ber_ptr = orig;
ber_skip_tag( b->ber, &len );
if ( b->tag == 0 )
for (n=0; n<i; n++)
{
tag = ber_next_element( b->ber, &len, last );
if ( ber_get_stringbv( b->ber, &bv, b->alloc ) == LBER_DEFAULT )
goto nomem;
/* store my result */
switch (b->choice) {
case ChArray:
......@@ -386,20 +383,36 @@ ber_get_stringbvr( bgbvr *b, int n )
(*b->res.ba)[n] = bv;
break;
case BvVec:
bvp = LBER_MALLOC( sizeof( struct berval ));
if ( !bvp ) {
LBER_FREE(bv.bv_val);
goto nomem;
}
(*b->res.bv)[n] = bvp;
*bvp = bv;
break;
case BvOff:
*(BerVarray)((long)(*b->res.ba)+n*b->siz+b->off) = bv;
break;
}
}
return tag;
nomem:
if (b->alloc || b->choice == BvVec)
{
for (--n; n>=0; n--)
{
switch(b->choice) {
case ChArray: LBER_FREE((*b->res.c)[n]); break;
case BvArray: LBER_FREE((*b->res.ba)[n].bv_val); break;
case BvVec: LBER_FREE((*b->res.bv)[n]->bv_val);
LBER_FREE((*b->res.bv)[n]); break;
}
}
} else {
/* Failure will propagate up and free in reverse
* order, which is actually ideal.
*/
if ( b->alloc ) LBER_FREE( bv.bv_val );
if ( bvp ) LBER_FREE( bvp );
}
return b->tag;
LBER_FREE(*b->res.c);
*b->res.c = NULL;
return LBER_DEFAULT;
}
ber_tag_t
......@@ -723,7 +736,7 @@ ber_scanf ( BerElement *ber,
cookie.ber = ber;
cookie.res.c = va_arg( ap, char *** );
cookie.alloc = 1;
rc = ber_get_stringbvr( &cookie, 0 );
rc = ber_get_stringbvl( &cookie, NULL );
break;
}
......@@ -733,7 +746,7 @@ ber_scanf ( BerElement *ber,
cookie.ber = ber;
cookie.res.bv = va_arg( ap, struct berval *** );
cookie.alloc = 1;
rc = ber_get_stringbvr( &cookie, 0 );
rc = ber_get_stringbvl( &cookie, NULL );
break;
}
......@@ -743,7 +756,7 @@ ber_scanf ( BerElement *ber,
cookie.ber = ber;
cookie.res.ba = va_arg( ap, struct berval ** );
cookie.alloc = 1;
rc = ber_get_stringbvr( &cookie, 0 );
rc = ber_get_stringbvl( &cookie, NULL );
break;
}
......@@ -760,8 +773,7 @@ ber_scanf ( BerElement *ber,
l = va_arg( ap, ber_len_t * );
cookie.siz = *l;
cookie.off = va_arg( ap, ber_len_t );
rc = ber_get_stringbvr( &cookie, 0 );
*l = cookie.len;
rc = ber_get_stringbvl( &cookie, l );
break;
}
......
......@@ -456,6 +456,8 @@ ber_reset( BerElement *ber, int was_writing )
* a full packet is read.
*/
#define LENSIZE 4
ber_tag_t
ber_get_next(
Sockbuf *sb,
......@@ -486,6 +488,15 @@ ber_get_next(
* 1) small tags (less than 128)
* 2) definite lengths
* 3) primitive encodings used whenever possible
*
* The code also handles multi-byte tags. The first few bytes
* of the message are read to check for multi-byte tags and
* lengths. These bytes are temporarily stored in the ber_tag,
* ber_len, and ber_usertag fields of the berelement until
* tag/len parsing is complete. After this parsing, any leftover
* bytes and the rest of the message are copied into the ber_buf.
*
* We expect tag and len to be at most 32 bits wide.
*/
if (ber->ber_rwptr == NULL) {
......@@ -499,13 +510,13 @@ ber_get_next(
}
while (ber->ber_rwptr > (char *)&ber->ber_tag && ber->ber_rwptr <
(char *)(&ber->ber_usertag + 1)) {
(char *)&ber->ber_len + LENSIZE*2) {
ber_slen_t sblen;
char buf[sizeof(ber->ber_len)-1];
char buf[LENSIZE-1];
ber_len_t tlen = 0;
sblen=ber_int_sb_read( sb, ber->ber_rwptr,
(char *)(&ber->ber_usertag+1)-ber->ber_rwptr);
((char *)&ber->ber_len + LENSIZE*2)-ber->ber_rwptr);
if (sblen<=0) return LBER_DEFAULT;
ber->ber_rwptr += sblen;
......@@ -563,11 +574,11 @@ ber_get_next(
}
/* Are there leftover data bytes inside ber->ber_len? */
if (ber->ber_ptr < (char *)&ber->ber_usertag) {
if (ber->ber_rwptr < (char *)&ber->ber_usertag)
if (ber->ber_ptr < (char *)&ber->ber_len+LENSIZE) {
if (ber->ber_rwptr < (char *)&ber->ber_len+LENSIZE)
sblen = ber->ber_rwptr - ber->ber_ptr;
else
sblen = (char *)&ber->ber_usertag - ber->ber_ptr;
sblen = ((char *)&ber->ber_len+LENSIZE) - ber->ber_ptr;
AC_MEMCPY(buf, ber->ber_ptr, sblen);
ber->ber_ptr += sblen;
} else {
......
......@@ -25,8 +25,12 @@
#include <ac/time.h>
#include <ac/unistd.h>
/* XXX non-portable */
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#ifdef HAVE_IO_H
#include <io.h>
......@@ -131,7 +135,9 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s)
}
#undef TRACE
#if !defined(HAVE_GETPEEREID) && !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && defined(HAVE_SENDMSG)
#if !defined(HAVE_GETPEEREID) && \
!defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \
defined(HAVE_SENDMSG) && defined(HAVE_MSGHDR_MSG_ACCRIGHTS)
#define DO_SENDMSG
#endif
......@@ -163,9 +169,13 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s, struct sockaddr_un *sa, int async)
/* Send a dummy message with access rights. Remote side will
* obtain our uid/gid by fstat'ing this descriptor.
*/
sendcred: {
sendcred:
{
int fds[2];
struct iovec iov = {(char *)fds, sizeof(int)};
/* Abandon, noop, has no reply */
char txt[] = {LDAP_TAG_MESSAGE, 6,
LDAP_TAG_MSGID, 1, 0, LDAP_REQ_ABANDON, 1, 0};
struct iovec iov = {txt, sizeof(txt)};
struct msghdr msg = {0};
if (pipe(fds) == 0) {
msg.msg_iov = &iov;
......@@ -173,7 +183,7 @@ sendcred: {
msg.msg_accrights = (char *)fds;
msg.msg_accrightslen = sizeof(int);
sendmsg( s, &msg, 0 );
close(fds[0]);
close(fds[0]);
close(fds[1]);
}
}
......
......@@ -13,13 +13,18 @@
#include <ac/unistd.h>
#include <ac/socket.h>
#include <ac/errno.h>
#if HAVE_SYS_UCRED_H
#include <sys/ucred.h>
#endif
#if !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && defined(HAVE_SENDMSG)
#if !defined(SO_PEERCRED) && !defined(LOCAL_PEERCRED) && \
defined(HAVE_SENDMSG) && defined(HAVE_MSGHDR_MSG_ACCRIGHTS)
#define DO_SENDMSG
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif
#include <sys/stat.h>
#endif
......@@ -53,14 +58,14 @@ int getpeereid( int s, uid_t *euid, gid_t *egid )
}
#elif defined( DO_SENDMSG )
int dummy, fd[2];
struct iovec iov = {(char *)&dummy, sizeof(dummy)};
struct iovec iov = {(char *)&dummy, 1};
struct msghdr msg = {0};
struct stat st;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_accrights = (char *)fd;
msg.msg_accrightslen = sizeof(fd);
if( recvmsg( s, &msg, 0) >= 0 && msg.msg_accrightslen == sizeof(int) )
if( recvmsg( s, &msg, MSG_PEEK) >= 0 && msg.msg_accrightslen == sizeof(int) )
{
/* We must receive a valid descriptor, it must be a pipe,
* and it must only be accessible by its owner.
......@@ -76,9 +81,9 @@ int getpeereid( int s, uid_t *euid, gid_t *egid )
}
}
#endif
#endif
#endif /* LDAP_PF_LOCAL */
return -1;
}
#endif
#endif /* HAVE_GETPEEREID */
......@@ -6,7 +6,6 @@
/*
* NT Service manager utilities for OpenLDAP services
* these should NOT be slapd specific, but are
*/
#include "portable.h"
......@@ -23,17 +22,6 @@
#include <ldap.h>
/*
* The whole debug implementation is a bit of a hack.
* We have to define this LDAP_SLAPD_V macro here since the slap.h
* header file isn't included (and really shouldn't be).
* TODO: re-implement debug functions so that the debug level can
* be passed around instead of having to count on the existence of
* ldap_debug, slap_debug, etc.
*/
#define ldap_debug slap_debug
LDAP_SLAPD_V (int) slap_debug;
#include "ldap_log.h"
#include "ldap_pvt_thread.h"
......@@ -45,11 +33,10 @@ LDAP_SLAPD_V (int) slap_debug;
#define SCM_NOTIFICATION_INTERVAL 5000
#define THIRTY_SECONDS (30 * 1000)
int is_NT_Service = 1; /* assume this is an NT service until determined that */
/* startup was from the command line */
int is_NT_Service; /* is this is an NT service? */
SERVICE_STATUS SLAPDServiceStatus;
SERVICE_STATUS_HANDLE hSLAPDServiceStatus;
SERVICE_STATUS lutil_ServiceStatus;
SERVICE_STATUS_HANDLE hlutil_ServiceStatus;
ldap_pvt_thread_cond_t started_event, stopped_event;
ldap_pvt_thread_t start_status_tid, stop_status_tid;
......@@ -58,14 +45,17 @@ void (*stopfunc)(int);
static char *GetLastErrorString( void );
int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
LPCTSTR lpszBinaryPathName, BOOL auto_start)
int lutil_srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
LPCTSTR lpszBinaryPathName, int auto_start)
{
HKEY hKey;
DWORD dwValue, dwDisposition;
SC_HANDLE schSCManager, schService;
char *sp = strchr( lpszBinaryPathName, ' ');
if ( sp ) *sp = '\0';
fprintf( stderr, "The install path is %s.\n", lpszBinaryPathName );
if ( sp ) *sp = ' ';
if ((schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT|SC_MANAGER_CREATE_SERVICE ) ) != NULL )
{
if ((schService = CreateService(
......@@ -96,6 +86,7 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
RegCloseKey(hKey);
return(0);
}
if ( sp ) *sp = '\0';
if ( RegSetValueEx(hKey, "EventMessageFile", 0, REG_EXPAND_SZ, lpszBinaryPathName, strlen(lpszBinaryPathName) + 1) != ERROR_SUCCESS)
{
fprintf( stderr, "RegSetValueEx(EventMessageFile) failed. GetLastError=%lu (%s)\n", GetLastError(), GetLastErrorString() );
......@@ -126,7 +117,7 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
}
int srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
int lutil_srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
{
SC_HANDLE schSCManager, schService;
......@@ -159,6 +150,7 @@ int srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
}
#if 0 /* unused */