Commit 8d5ef331 authored by Quanah Gibson-Mount's avatar Quanah Gibson-Mount
Browse files

Merge remote-tracking branch 'origin/master' into OPENLDAP_REL_ENG_2_5

parents b518a597 fcc1410f
......@@ -24399,6 +24399,7 @@ fi
 
for ac_func in \
bcopy \
clock_gettime \
closesocket \
chroot \
endgrent \
......
......@@ -2368,6 +2368,7 @@ fi
AC_CHECK_FUNCS( \
bcopy \
clock_gettime \
closesocket \
chroot \
endgrent \
......
......@@ -289,7 +289,7 @@ static int k5key_chk(
struct lutil_tm tm;
struct lutil_timet tt;
if ( lutil_parsetime( a->a_vals[0].bv_val, &tm ) == 0 &&
lutil_tm2time( &tm, &tt ) == 0 && tt.tt_usec < op->o_time ) {
lutil_tm2time( &tm, &tt ) == 0 && tt.tt_sec < op->o_time ) {
/* Account is expired */
rc = LUTIL_PASSWD_ERR;
break;
......
......@@ -1171,7 +1171,7 @@ First, create a directory to serve as the hosting DB and create the structure:
> cp /usr/local/etc/openldap/slapd.d/cn=config.ldif ./recovery/cn=recovery
> cp -r /usr/local/etc/openldap/slapd.d/cn=config ./recovery/cn=recovery
Or, if you have already backed up your old configration, you can symlink it
Or, if you have already backed up your old configuration, you can symlink it
into place:
> mkdir ./recovery
......
......@@ -74,12 +74,23 @@ It has no effect on any other operations.
Dynamic List.
This overlay allows expansion of dynamic groups and more.
.TP
.B homedir
Home Directory Provisioning.
This overlay manages creation/deletion of home directories for LDAP-based
Unix accounts.
.TP
.B memberof
MemberOf.
This overlay maintains automatic reverse group membership values,
typically stored in an attribute called memberOf. This overlay
is deprecated and should be replaced with dynlist.
.TP
.B otp_2fa
Two factor authentication module.
This module allows time-based one-time password, AKA "authenticator-style",
and HMAC-based one-time password authentication to be used in applications
that use LDAP for authentication.
.TP
.B pbind
Proxybind.
This overlay forwards simple bind requests on a local database to a
......
......@@ -4,7 +4,7 @@
.\" Portions Copyright 2018 by Ondřej Kuzník, Symas Corp. All rights reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
slapo-otp \- Two factor authentication module
slapo-otp_2fa \- Two factor authentication module
.SH SYNOPSIS
.B moduleload
.I otp_2fa.la
......
......@@ -29,4 +29,11 @@
# include <time.h>
#endif
#if defined(_WIN32) && !defined(HAVE_CLOCK_GETTIME)
struct timespec {
time_t tv_sec;
int tv_nsec;
};
#endif
#endif /* _AC_TIME_H */
......@@ -131,6 +131,13 @@ ldap_pvt_gettime LDAP_P(( struct lutil_tm * ));
struct timeval;
LDAP_F( int )
ldap_pvt_gettimeofday LDAP_P(( struct timeval *tv, void *unused ));
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
#endif
#define clock_gettime(clkid,tv) ldap_pvt_clock_gettime(clkid,tv)
struct timespec;
LDAP_F( int )
ldap_pvt_clock_gettime LDAP_P(( int clkid, struct timespec *tv ));
#endif
/* use this macro to allocate buffer for ldap_pvt_csnstr */
......
......@@ -172,7 +172,7 @@ typedef struct lutil_tm {
int tm_mday; /* day 1-31 */
int tm_mon; /* month 0-11 */
int tm_year; /* year - 1900 */
int tm_usec; /* microseconds */
int tm_nsec; /* nanoseconds */
int tm_usub; /* submicro */
} lutil_tm;
......@@ -180,7 +180,7 @@ typedef struct lutil_timet {
unsigned int tt_sec; /* seconds since epoch, 0000 or 1970 */
int tt_gsec; /* seconds since epoch, high 7 bits, maybe sign-flipped */
/* sign flipped to sort properly as unsigned ints */
unsigned int tt_usec; /* microseconds */
unsigned int tt_nsec; /* nanoseconds */
} lutil_timet;
/* Parse a timestamp string into a structure */
......
......@@ -105,6 +105,9 @@
/* Define to 1 if you have the `chroot' function. */
#undef HAVE_CHROOT
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
/* Define to 1 if you have the `closesocket' function. */
#undef HAVE_CLOSESOCKET
......
......@@ -20,7 +20,6 @@
#include <ac/stdarg.h>
#include <ac/stdlib.h>
#include <ac/string.h>
#include <ac/time.h>
#include <ac/ctype.h>
#ifdef LDAP_SYSLOG
......@@ -32,12 +31,8 @@
#include "lber.h"
#include "ldap_pvt.h"
static FILE *log_file = NULL;
static int debug_lastc = '\n';
int lutil_debug_file( FILE *file )
{
log_file = file;
ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, file );
return 0;
......@@ -47,41 +42,13 @@ void (lutil_debug)( int debug, int level, const char *fmt, ... )
{
char buffer[4096];
va_list vl;
int len, off;
if ( !(level & debug ) ) return;
#ifdef HAVE_WINSOCK
if( log_file == NULL ) {
log_file = fopen( LDAP_RUNDIR LDAP_DIRSEP "openldap.log", "w" );
if ( log_file == NULL ) {
log_file = fopen( "openldap.log", "w" );
if ( log_file == NULL ) return;
}
ber_set_option( NULL, LBER_OPT_LOG_PRINT_FILE, log_file );
}
#endif
if (debug_lastc == '\n') {
sprintf(buffer, "%08x ", (unsigned) time(0L));
off = 9;
} else {
off = 0;
}
va_start( vl, fmt );
len = vsnprintf( buffer+off, sizeof(buffer)-off, fmt, vl );
if (len > sizeof(buffer)-off)
len = sizeof(buffer)-off;
debug_lastc = buffer[len+off-1];
buffer[sizeof(buffer)-1] = '\0';
if( log_file != NULL ) {
fputs( buffer, log_file );
fflush( log_file );
}
fputs( buffer, stderr );
vsnprintf( buffer, sizeof(buffer), fmt, vl );
va_end( vl );
ber_pvt_log_print( buffer );
}
#if defined(HAVE_EBCDIC) && defined(LDAP_SYSLOG)
......
......@@ -66,6 +66,10 @@ ber_get_option(
case LBER_OPT_LOG_PRINT_FILE:
*((FILE**)outvalue) = (FILE*)ber_pvt_err_file;
return LBER_OPT_SUCCESS;
case LBER_OPT_LOG_PRINT_FN:
*(BER_LOG_PRINT_FN *)outvalue = ber_pvt_log_print;
return LBER_OPT_SUCCESS;
}
ber_errno = LBER_ERROR_PARAM;
......
......@@ -178,7 +178,7 @@ static int _ldap_pvt_gt_subs;
#ifdef _WIN32
/* Windows SYSTEMTIME only has 10 millisecond resolution, so we
* also need to use a high resolution timer to get microseconds.
* also need to use a high resolution timer to get nanoseconds.
* This is pretty clunky.
*/
static LARGE_INTEGER _ldap_pvt_gt_freq;
......@@ -187,9 +187,10 @@ static int _ldap_pvt_gt_offset;
#define SEC_TO_UNIX_EPOCH 11644473600LL
#define TICKS_PER_SECOND 10000000
#define BILLION 1000000000L
static int
ldap_pvt_gettimeusec(int *sec)
ldap_pvt_gettimensec(int *sec)
{
LARGE_INTEGER count;
......@@ -200,7 +201,7 @@ ldap_pvt_gettimeusec(int *sec)
*/
LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
/* We assume Windows has at least a vague idea of
* when a second begins. So we align our microsecond count
* when a second begins. So we align our nanosecond count
* with the Windows millisecond count using this offset.
* We retain the submillisecond portion of our own count.
*
......@@ -214,7 +215,7 @@ ldap_pvt_gettimeusec(int *sec)
ULARGE_INTEGER ut;
FILETIME ft0, ft1;
long long t;
int usec;
int nsec;
/* Initialize our offset */
QueryPerformanceFrequency( &_ldap_pvt_gt_freq );
......@@ -232,13 +233,13 @@ ldap_pvt_gettimeusec(int *sec)
/* get second and fraction portion of counter */
t = c2.QuadPart % (_ldap_pvt_gt_freq.QuadPart*10);
/* convert to microseconds */
t *= 1000000;
usec = t / _ldap_pvt_gt_freq.QuadPart;
/* convert to nanoseconds */
t *= BILLION;
nsec = t / _ldap_pvt_gt_freq.QuadPart;
ut.QuadPart /= 10;
ut.QuadPart %= 10000000;
_ldap_pvt_gt_offset = usec - ut.QuadPart;
ut.QuadPart %= (10 * BILLION);
_ldap_pvt_gt_offset = nsec - ut.QuadPart;
count = c2;
}
if ( count.QuadPart <= _ldap_pvt_gt_prev.QuadPart ) {
......@@ -249,28 +250,28 @@ ldap_pvt_gettimeusec(int *sec)
}
LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );
/* convert to microseconds */
/* convert to nanoseconds */
count.QuadPart %= _ldap_pvt_gt_freq.QuadPart*10;
count.QuadPart *= 1000000;
count.QuadPart *= BILLION;
count.QuadPart /= _ldap_pvt_gt_freq.QuadPart;
count.QuadPart -= _ldap_pvt_gt_offset;
/* We've extracted the 1s and microseconds.
* The 1sec digit is used to detect wraparound in microsecnds.
/* We've extracted the 1s and nanoseconds.
* The 1sec digit is used to detect wraparound in nanosecnds.
*/
if (count.QuadPart < 0)
count.QuadPart += 10000000;
else if (count.QuadPart >= 10000000)
count.QuadPart -= 10000000;
count.QuadPart += (10 * BILLION);
else if (count.QuadPart >= (10 * BILLION))
count.QuadPart -= (10 * BILLION);
*sec = count.QuadPart / 1000000;
return count.QuadPart % 1000000;
*sec = count.QuadPart / BILLION;
return count.QuadPart % BILLION;
}
/* emulate POSIX gettimeofday */
/* emulate POSIX clock_gettime */
int
ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
ldap_pvt_clock_gettime( int clk_id, struct timespec *tv )
{
FILETIME ft;
ULARGE_INTEGER ut;
......@@ -280,11 +281,11 @@ ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
ut.LowPart = ft.dwLowDateTime;
ut.HighPart = ft.dwHighDateTime;
/* convert to usec */
ut.QuadPart /= (TICKS_PER_SECOND / 1000000);
/* convert to sec */
ut.QuadPart /= TICKS_PER_SECOND;
tv->tv_usec = ldap_pvt_gettimeusec(&sec);
tv->tv_sec = ut.QuadPart / 1000000 - SEC_TO_UNIX_EPOCH;
tv->tv_nsec = ldap_pvt_gettimensec(&sec);
tv->tv_sec = ut.QuadPart - SEC_TO_UNIX_EPOCH;
/* check for carry from microseconds */
sec0 = tv->tv_sec % 10;
......@@ -294,7 +295,20 @@ ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
return 0;
}
/* return a broken out time, with microseconds
/* emulate POSIX gettimeofday */
int
ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
int
{
struct timespec ts;
ldap_pvt_clock_gettime( 0, &ts );
tv->tv_sec = ts.tv_spec;
tv->tv_usec = ts.tv_nsec / 1000;
return 0;
}
/* return a broken out time, with nanoseconds
*/
void
ldap_pvt_gettime( struct lutil_tm *tm )
......@@ -305,10 +319,10 @@ ldap_pvt_gettime( struct lutil_tm *tm )
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
GetSystemTime( &st );
tm->tm_usec = ldap_pvt_gettimeusec(&sec);
tm->tm_nsec = ldap_pvt_gettimensec(&sec);
tm->tm_usub = _ldap_pvt_gt_subs;
/* any difference larger than microseconds is
/* any difference larger than nanoseconds is
* already reflected in st
*/
tm->tm_sec = st.wSecond;
......@@ -318,7 +332,7 @@ ldap_pvt_gettime( struct lutil_tm *tm )
tm->tm_mon = st.wMonth - 1;
tm->tm_year = st.wYear - 1900;
/* check for carry from microseconds */
/* check for carry from nanoseconds */
sec0 = tm->tm_sec % 10;
if (sec0 < sec || (sec0 == 9 && !sec)) {
tm->tm_sec++;
......@@ -357,23 +371,36 @@ ldap_pvt_gettime( struct lutil_tm *tm )
}
#else
#ifdef HAVE_CLOCK_GETTIME
static struct timespec _ldap_pvt_gt_prevTv;
#else
static struct timeval _ldap_pvt_gt_prevTv;
#endif
void
ldap_pvt_gettime( struct lutil_tm *ltm )
{
struct timeval tv;
struct tm tm;
time_t t;
#ifdef HAVE_CLOCK_GETTIME
#define FRAC tv_nsec
#define NSECS(x) x
struct timespec tv;
clock_gettime( CLOCK_REALTIME, &tv );
#else
#define FRAC tv_usec
#define NSECS(x) x * 1000
struct timeval tv;
gettimeofday( &tv, NULL );
#endif
t = tv.tv_sec;
LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
if ( tv.tv_sec < _ldap_pvt_gt_prevTv.tv_sec
|| ( tv.tv_sec == _ldap_pvt_gt_prevTv.tv_sec
&& tv.tv_usec <= _ldap_pvt_gt_prevTv.tv_usec )) {
&& tv.FRAC <= _ldap_pvt_gt_prevTv.FRAC )) {
_ldap_pvt_gt_subs++;
} else {
_ldap_pvt_gt_subs = 0;
......@@ -391,7 +418,7 @@ ldap_pvt_gettime( struct lutil_tm *ltm )
ltm->tm_mday = tm.tm_mday;
ltm->tm_mon = tm.tm_mon;
ltm->tm_year = tm.tm_year;
ltm->tm_usec = tv.tv_usec;
ltm->tm_nsec = NSECS(tv.FRAC);
}
#endif
......@@ -406,7 +433,7 @@ ldap_pvt_csnstr(char *buf, size_t len, unsigned int replica, unsigned int mod)
n = snprintf( buf, len,
"%4d%02d%02d%02d%02d%02d.%06dZ#%06x#%03x#%06x",
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
tm.tm_min, tm.tm_sec, tm.tm_usec, tm.tm_usub, replica, mod );
tm.tm_min, tm.tm_sec, tm.tm_nsec / 1000, tm.tm_usub, replica, mod );
if( n < 0 ) return 0;
return ( (size_t) n < len ) ? n : 0;
......
......@@ -159,7 +159,7 @@ int lutil_tm2time( struct lutil_tm *tm, struct lutil_timet *tt )
273, 304, 334 };
int sec;
tt->tt_usec = tm->tm_usec;
tt->tt_nsec = tm->tm_nsec;
/* special case 0000/01/01+00:00:00 is returned as zero */
if ( tm->tm_year == -1900 && tm->tm_mon == 0 && tm->tm_mday == 1 &&
......@@ -226,7 +226,7 @@ int lutil_tm2gtime( struct lutil_tm *tm, struct lutil_timet *tt )
int sec, year;
long tmp;
tt->tt_usec = tm->tm_usec;
tt->tt_nsec = tm->tm_nsec;
/* tm->tm_year is years since 1900 */
/* calculate days from 0000 */
......@@ -350,13 +350,13 @@ int lutil_parsetime( char *atm, struct lutil_tm *tm )
i*=10; i+= *ptr++ - '0';
fracs++;
}
tm->tm_usec = i;
tm->tm_nsec = i;
if (i) {
for (i = fracs; i<6; i++)
tm->tm_usec *= 10;
for (i = fracs; i<9; i++)
tm->tm_nsec *= 10;
}
} else {
tm->tm_usec = 0;
tm->tm_nsec = 0;
}
tm->tm_usub = 0;
......
......@@ -377,6 +377,28 @@ usage( char *name )
);
}
typedef void (BER_logger)(const char *buf);
static BER_logger *ber_logger;
static void debug_print( const char *data )
{
char buf[4136]; /* 4096 + 40 */
#ifdef HAVE_CLOCK_GETTIME
struct timespec tv;
#define TS "%08x"
#define Tfrac tv.tv_nsec
clock_gettime( CLOCK_REALTIME, &tv );
#else
struct timeval tv;
#define TS "%05x"
#define Tfrac tv.tv_usec
gettimeofday( &tv, NULL );
#endif
buf[sizeof(buf)-1] = '\0';
snprintf( buf, sizeof(buf)-1, "%lx." TS " %p %s",
(long)tv.tv_sec, Tfrac, (void *)ldap_pvt_thread_self(), data );
ber_logger( buf );
}
#ifdef HAVE_NT_SERVICE_MANAGER
void WINAPI ServiceMain( DWORD argc, LPTSTR *argv )
......@@ -720,6 +742,8 @@ unhandled_option:;
if ( optind != argc )
goto unhandled_option;
ber_get_option(NULL, LBER_OPT_LOG_PRINT_FN, &ber_logger);
ber_set_option(NULL, LBER_OPT_LOG_PRINT_FN, debug_print);
ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug);
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug);
ldif_debug = slap_debug;
......@@ -843,6 +867,8 @@ unhandled_option:;
debug_unknowns = NULL;
if ( rc )
goto destroy;
ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &slap_debug );
ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &slap_debug );
}
if ( syslog_unknowns ) {
rc = parse_debug_unknowns( syslog_unknowns, &ldap_syslog );
......
......@@ -415,8 +415,8 @@ matching_rule_use_init( void )
mru->smru_names = mr->smr_names;
mru->smru_desc = mr->smr_desc;
Debug( LDAP_DEBUG_TRACE, " %s (%s): ",
mru->smru_oid,
Debug( LDAP_DEBUG_TRACE, " %s (%s):\n",
mru->smru_oid,
mru->smru_names ? mru->smru_names[ 0 ] : "" );
at = NULL;
......@@ -437,7 +437,7 @@ matching_rule_use_init( void )
mru->smru_applies_oids = applies_oids;
{
char *str = ldap_matchingruleuse2str( &mru->smru_mruleuse );
Debug( LDAP_DEBUG_TRACE, "matchingRuleUse: %s\n", str );
Debug( LDAP_DEBUG_TRACE, " matchingRuleUse: %s\n", str );
ldap_memfree( str );
}
......
......@@ -1500,7 +1500,7 @@ ppolicy_bind_response( Operation *op, SlapReply *rs )
strcpy(nowstr_usec, nowstr);
timestamp_usec.bv_val = nowstr_usec;
timestamp_usec.bv_len = timestamp.bv_len;
snprintf( timestamp_usec.bv_val + timestamp_usec.bv_len-1, sizeof(".123456Z"), ".%06dZ", now_usec.tt_usec );
snprintf( timestamp_usec.bv_val + timestamp_usec.bv_len-1, sizeof(".123456Z"), ".%06dZ", now_usec.tt_nsec / 1000 );
timestamp_usec.bv_len += STRLENOF(".123456");
if ( rs->sr_err == LDAP_INVALID_CREDENTIALS && ppb->pp.pwdMaxRecordedFailure ) {
......
......@@ -118,9 +118,8 @@ do_search(
goto return_results;
}
Debug( LDAP_DEBUG_ARGS, "SRCH \"%s\" %d %d",
base.bv_val, op->ors_scope, op->ors_deref );
Debug( LDAP_DEBUG_ARGS, " %d %d %d\n",
Debug( LDAP_DEBUG_ARGS, "SRCH \"%s\" %d %d %d %d %d\n",
base.bv_val, op->ors_scope, op->ors_deref,
op->ors_slimit, op->ors_tlimit, op->ors_attrsonly);
/* filter - returns a "normalized" version */
......@@ -198,16 +197,37 @@ do_search(
goto return_results;
}
Debug( LDAP_DEBUG_ARGS, " attrs:" );
if (LogTest( LDAP_DEBUG_ARGS ) ) {
char abuf[BUFSIZ/2], *ptr = abuf;
unsigned len = 0, alen;
if ( siz != 0 ) {
if ( !siz ) {
len = 1;
abuf[0] = '\0';
}
for ( i = 0; i<siz; i++ ) {
Debug( LDAP_DEBUG_ARGS, " %s", op->ors_attrs[i].an_name.bv_val );
alen = op->ors_attrs[i].an_name.bv_len;
if (alen >= sizeof(abuf)) {
alen = sizeof(abuf)-1;
}
if (len && (len + 1 + alen >= sizeof(abuf))) {
Debug( LDAP_DEBUG_ARGS, " attrs: %s\n", abuf );
len = 0;
ptr = abuf;
}
if (len) {
*ptr++ = ' ';
len++;
}
ptr = lutil_strncopy(ptr, op->ors_attrs[i].an_name.bv_val, alen);
len += alen;
*ptr = '\0';
}
if (len) {
Debug( LDAP_DEBUG_ARGS, " attrs: %s\n", abuf );
}
}
Debug( LDAP_DEBUG_ARGS, "\n" );
if (LogTest( LDAP_DEBUG_STATS ) ) {
char abuf[BUFSIZ/2], *ptr = abuf;
unsigned len = 0, alen;
......
......@@ -425,7 +425,7 @@ void get_csns(
if (j < numservers) {
ber_bvreplace( &c->vals[j], &bvs[i] );
lutil_parsetime(bvs[i].bv_val, &tm);
c->tvs[j].tv_usec = tm.tm_usec;
c->tvs[j].tv_usec = tm.tm_nsec / 1000;
lutil_tm2time( &tm, &tt );
c->tvs[j].tv_sec = tt.tt_sec;
}
......
......@@ -313,18 +313,12 @@ FIRST=$CNT
# queries 2-6,8-10 are cacheable
CACHEABILITY=0111110111
grep CACHEABLE $LOG2 | awk '{
if ($3 == "NOT")
printf "Query %d not cacheable\n",NR
else
printf "Query %d cacheable\n",NR
}'
CACHED=`grep CACHEABLE $LOG2 | awk '{
if ($3 == "NOT")
printf "0"
else
printf "1"
}'`
grep CACHEABLE $LOG2 | awk '
/NOT CACHEABLE/{printf "Query %d not cacheable\n",NR}
/QUERY CACHEABLE/{printf "Query %d cacheable\n",NR}'