Commit 76ed17f7 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Merge in latest from -current.

parent 58ea169c
......@@ -2,6 +2,18 @@ OpenLDAP Change Log
Changes included in OpenLDAP Stable
CVS Tag: OPENLDAP_STABLE
Updated README, INSTALL files
Updated Linux platform defaults
Updated FreeBSD 2 & 3 platform defaults
Added SCHED_YIELD_MISSING flag
Added LDAP_ALLOW_NULL_SEARCH_BASE flag
Added core removal to tests/Make-template
Fixed slapd/acl debug trace problem
Fixed ud/auth.c bound_dn problem
Fixed back-ldbm/idl.c CLDAP include <sys/socket.h> problem.
Fixed Makefile $(CC) problem
Fixed LIBEXEC/SBIN creation problem
Fixed gmake RUNDIR not defaulting problem
Changes included in OpenLDAP Stable
CVS Tag: OPENLDAP_STABLE_980929
......
......@@ -12,7 +12,7 @@ these steps:
1. untar the distribution and cd to the top:
% tar xfz ldap-stable.tgz
% tar xfz openldap-VERSION.tgz
% cd ldap
If you are reading this file, you probably have already done this!
......
#ifdef KERBEROS
#if defined(KERBEROS) && !defined(openbsd)
/*
* $Source: /usr/local/src/ldap/clients/ud/RCS/string_to_key.c,v $
* $Author: lsloan $
* $Source: /repo/OpenLDAP/pkg/ldap/clients/ud/string_to_key.c,v $
* $Author: kurt $
*
* Copyright 1985, 1986, 1987, 1988, 1989 by the Massachusetts Institute
* of Technology.
......@@ -24,18 +24,24 @@
* spm 8/85 MIT project athena
*/
#ifndef lint
static char rcsid_string_to_key_c[] =
"$Id: string_to_key.c,v 1.5 1995/11/09 20:29:55 lsloan Exp $";
#endif
#ifdef KERBEROS_V
#include <kerberosIV/mit-copyright.h>
#include <kerberosIV/des.h>
#else
#include <mit-copyright.h>
#include <stdio.h>
#include <des.h>
#endif /* KERBEROS_V */
#include <stdio.h>
/* #include "des_internal.h" */
#if 1
#ifdef KERBEROS_V
#include <kerberosIV/krb.h>
#else
#include <krb.h>
#endif
#endif /* KERBEROS_V */
#endif /* 1 */
extern int des_debug;
extern int des_debug_print();
......@@ -46,6 +52,7 @@ extern void des_fixup_key_parity();
#endif
#if defined(WORLDPEACEINOURTIME) /* Use original, not ifs version */
#ifndef KERBEROS_V
/*
* convert an arbitrary length string to a DES key
*/
......@@ -132,6 +139,7 @@ des_string_to_key(str,key)
*((unsigned long *) key+1));
}
#endif /* KERBEROS_V */
#else /* Use ifs version */
#if 0
......
......@@ -4,8 +4,8 @@
LIBRARY = liblthread.a
XSRCS = version.c
SRCS = thread.c stack.c
OBJS = thread.o stack.o
SRCS = rdwr.c thread.c stack.c
OBJS = rdwr.o thread.o stack.o
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
......
/*
** This basic implementation of Reader/Writer locks does not
** protect writers from starvation. That is, if a writer is
** currently waiting on a reader, any new reader will get
** the lock before the writer.
*/
/********************************************************
* An example source module to accompany...
*
* "Using POSIX Threads: Programming with Pthreads"
* by Brad nichols, Dick Buttlar, Jackie Farrell
* O'Reilly & Associates, Inc.
*
********************************************************
* rdwr.c --
*
* Library of functions implementing reader/writer locks
*/
#define DISABLE_BRIDGE
#include <portable.h>
#include <stdlib.h>
#include <lthread.h>
#include <lthread_rdwr.h>
int pthread_rdwr_init_np(pthread_rdwr_t *rdwrp, pthread_rdwrattr_t *attrp)
{
rdwrp->readers_reading = 0;
rdwrp->writer_writing = 0;
pthread_mutex_init(&(rdwrp->mutex), NULL);
pthread_cond_init(&(rdwrp->lock_free), NULL);
return 0;
}
int pthread_rdwr_rlock_np(pthread_rdwr_t *rdwrp){
pthread_mutex_lock(&(rdwrp->mutex));
while(rdwrp->writer_writing) {
pthread_cond_wait(&(rdwrp->lock_free), &(rdwrp->mutex));
}
rdwrp->readers_reading++;
pthread_mutex_unlock(&(rdwrp->mutex));
return 0;
}
int pthread_rdwr_runlock_np(pthread_rdwr_t *rdwrp)
{
pthread_mutex_lock(&(rdwrp->mutex));
if (rdwrp->readers_reading == 0) {
pthread_mutex_unlock(&(rdwrp->mutex));
return -1;
}
else {
rdwrp->readers_reading--;
if (rdwrp->readers_reading == 0) {
pthread_cond_signal(&(rdwrp->lock_free));
}
pthread_mutex_unlock(&(rdwrp->mutex));
return 0;
}
}
int pthread_rdwr_wlock_np(pthread_rdwr_t *rdwrp)
{
pthread_mutex_lock(&(rdwrp->mutex));
while(rdwrp->writer_writing || rdwrp->readers_reading) {
pthread_cond_wait(&(rdwrp->lock_free), &(rdwrp->mutex));
}
rdwrp->writer_writing++;
pthread_mutex_unlock(&(rdwrp->mutex));
return 0;
}
int pthread_rdwr_wunlock_np(pthread_rdwr_t *rdwrp)
{
pthread_mutex_lock(&(rdwrp->mutex));
if (rdwrp->writer_writing == 0) {
pthread_mutex_unlock(&(rdwrp->mutex));
return -1;
}
else {
rdwrp->writer_writing = 0;
pthread_cond_broadcast(&(rdwrp->lock_free));
pthread_mutex_unlock(&(rdwrp->mutex));
return 0;
}
}
#ifdef LDAP_DEBUG
/* just for testing,
* return 0 if false, suitable for assert(pthread_rdwr_Xchk(rdwr))
*
* Currently they don't check if the calling thread is the one
* that has the lock, just that there is a reader or writer.
*
* Basically sufficent for testing that places that should have
* a lock are caught.
*/
int pthread_rdwr_rchk_np(pthread_rdwr_t *rdwrp)
{
return(rdwrp->readers_reading!=0);
}
int pthread_rdwr_wchk_np(pthread_rdwr_t *rdwrp)
{
return(rdwrp->writer_writing!=0);
}
int pthread_rdwr_rwchk_np(pthread_rdwr_t *rdwrp)
{
return(pthread_rdwr_rchk_np(rdwrp) || pthread_rdwr_wchk_np(rdwrp));
}
#endif /* LDAP_DEBUG */
......@@ -504,6 +504,7 @@ void pthread_yield( void )
{
sched_yield();
}
#endif /* HAVE_SCHED_YIELD */
#endif /* posix threads */
......
......@@ -6,15 +6,11 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#ifdef sunos5
#include "regexpr.h"
#else
#include "regex.h"
#endif
#include <regex.h>
#include "slap.h"
extern Attribute *attr_find();
extern char *re_comp();
extern struct acl *global_acl;
extern int global_default_access;
extern char *access2str();
......@@ -26,7 +22,9 @@ struct acl *acl_get_applicable();
static int regex_matches();
extern pthread_mutex_t regex_mutex;
static string_expand(char *newbuf, int bufsiz, char *pattern,
char *match, regmatch_t *matches);
/*
* access_allowed - check whether dn is allowed the requested access
......@@ -51,15 +49,57 @@ access_allowed(
int access
)
{
int rc;
struct acl *a;
int rc;
struct acl *a;
char *edn;
regmatch_t matches[MAXREMATCHES];
int i;
int n;
if ( be == NULL ) {
return( 0 );
}
a = acl_get_applicable( be, op, e, attr );
rc = acl_access_allowed( a, be, conn, e, val, op, access );
edn = dn_normalize_case( strdup( e->e_dn ) );
Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: entry (%s) attr (%s)\n",
e->e_dn, attr, 0 );
/* the lastmod attributes are ignored by ACL checking */
if ( strcasecmp( attr, "modifiersname" ) == 0 ||
strcasecmp( attr, "modifytimestamp" ) == 0 ||
strcasecmp( attr, "creatorsname" ) == 0 ||
strcasecmp( attr, "createtimestamp" ) == 0 )
{
Debug( LDAP_DEBUG_ACL, "LASTMOD attribute: %s access allowed\n",
attr, 0, 0 );
free( edn );
return(1);
}
memset(matches, 0, sizeof(matches));
a = acl_get_applicable( be, op, e, attr, edn, MAXREMATCHES, matches );
if (a) {
for (i = 0; i < MAXREMATCHES && matches[i].rm_so > 0; i++) {
Debug( LDAP_DEBUG_ARGS, "=> match[%d]: %d %d ",
i, matches[i].rm_so, matches[i].rm_eo );
if( matches[i].rm_so <= matches[0].rm_eo ) {
for ( n = matches[i].rm_so; n < matches[i].rm_eo; n++) {
Debug( LDAP_DEBUG_ARGS, "%c", edn[n], 0, 0 );
}
}
Debug( LDAP_DEBUG_ARGS, "\n", 0, 0, 0 );
}
}
rc = acl_access_allowed( a, be, conn, e, val, op, access, edn, matches );
free( edn );
Debug( LDAP_DEBUG_ACL, "\n=> access_allowed: exit (%s) attr (%s)\n",
e->e_dn, attr, 0);
return( rc );
}
......@@ -75,15 +115,17 @@ acl_get_applicable(
Backend *be,
Operation *op,
Entry *e,
char *attr
char *attr,
char *edn,
int nmatch,
regmatch_t *matches
)
{
int i;
int i, j;
struct acl *a;
char *edn;
Debug( LDAP_DEBUG_ACL, "=> acl_get: entry (%s) attr (%s)\n", e->e_dn,
attr, 0 );
Debug( LDAP_DEBUG_ACL, "\n=> acl_get: entry (%s) attr (%s)\n",
e->e_dn, attr, 0 );
if ( be_isroot( be, op->o_dn ) ) {
Debug( LDAP_DEBUG_ACL,
......@@ -92,55 +134,73 @@ acl_get_applicable(
return( NULL );
}
Debug( LDAP_DEBUG_ARGS, "=> acl_get: edn %s\n", edn, 0, 0 );
/* check for a backend-specific acl that matches the entry */
for ( i = 1, a = be->be_acl; a != NULL; a = a->acl_next, i++ ) {
if ( a->acl_dnpat != NULL ) {
edn = dn_normalize_case( strdup( e->e_dn ) );
if ( ! regex_matches( a->acl_dnpat, edn ) ) {
free( edn );
if (a->acl_dnpat != NULL) {
Debug( LDAP_DEBUG_TRACE, "=> dnpat: [%d] %s nsub: %d\n",
i, a->acl_dnpat, a->acl_dnre.re_nsub);
if (regexec(&a->acl_dnre, edn, nmatch, matches, 0))
continue;
}
free( edn );
else
Debug( LDAP_DEBUG_TRACE, "=> acl_get:[%d] backend ACL match\n",
i, 0, 0);
}
if ( a->acl_filter != NULL ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter )
!= 0 ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
continue;
}
}
Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr %s\n", i, attr, 0);
if ( attr == NULL || a->acl_attrs == NULL ||
charray_inlist( a->acl_attrs, attr ) ) {
Debug( LDAP_DEBUG_ACL, "<= acl_get: backend acl #%d\n",
i, e->e_dn, attr );
charray_inlist( a->acl_attrs, attr ) )
{
Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] backend acl %s attr: %s\n",
i, e->e_dn, attr );
return( a );
}
matches[0].rm_so = matches[0].rm_eo = -1;
}
/* check for a global acl that matches the entry */
for ( i = 1, a = global_acl; a != NULL; a = a->acl_next, i++ ) {
if ( a->acl_dnpat != NULL ) {
edn = dn_normalize_case( strdup( e->e_dn ) );
if ( ! regex_matches( a->acl_dnpat, edn ) ) {
free( edn );
if (a->acl_dnpat != NULL) {
Debug( LDAP_DEBUG_TRACE, "=> dnpat: [%d] %s nsub: %d\n",
i, a->acl_dnpat, a->acl_dnre.re_nsub);
if (regexec(&a->acl_dnre, edn, nmatch, matches, 0)) {
continue;
} else {
Debug( LDAP_DEBUG_TRACE, "=> acl_get: [%d] global ACL match\n",
i, 0, 0);
}
free( edn );
}
if ( a->acl_filter != NULL ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter )
!= 0 ) {
if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
continue;
}
}
if ( attr == NULL || a->acl_attrs == NULL || charray_inlist(
a->acl_attrs, attr ) ) {
Debug( LDAP_DEBUG_ACL, "<= acl_get: global acl #%d\n",
i, e->e_dn, attr );
Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr\n", i, 0, 0);
if ( attr == NULL || a->acl_attrs == NULL ||
charray_inlist( a->acl_attrs, attr ) )
{
Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] global acl %s attr: %s\n",
i, e->e_dn, attr );
return( a );
}
matches[0].rm_so = matches[0].rm_eo = -1;
}
Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
return( NULL );
}
......@@ -161,31 +221,40 @@ acl_access_allowed(
Entry *e,
struct berval *val,
Operation *op,
int access
int access,
char *edn,
regmatch_t *matches
)
{
int i;
char *edn, *odn;
char *odn;
struct access *b;
Attribute *at;
struct berval bv;
int default_access;
Debug( LDAP_DEBUG_ACL, "=> acl: %s access to value \"%s\" by \"%s\"\n",
access2str( access ), val ? val->bv_val : "any", op->o_dn ?
op->o_dn : "" );
Debug( LDAP_DEBUG_ACL,
"\n=> acl_access_allowed: %s access to entry \"%s\"\n",
access2str( access ), e->e_dn, 0 );
Debug( LDAP_DEBUG_ACL,
"\n=> acl_access_allowed: %s access to value \"%s\" by \"%s\"\n",
access2str( access ),
val ? val->bv_val : "any",
op->o_dn ? op->o_dn : "" );
if ( be_isroot( be, op->o_dn ) ) {
Debug( LDAP_DEBUG_ACL, "<= acl: granted to database root\n",
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: granted to database root\n",
0, 0, 0 );
return( 1 );
}
default_access = be->be_dfltaccess ? be->be_dfltaccess :
global_default_access;
default_access = be->be_dfltaccess ? be->be_dfltaccess : global_default_access;
if ( a == NULL ) {
Debug( LDAP_DEBUG_ACL,
"<= acl: %s by default (no matching to)\n",
"<= acl_access_allowed: %s by default (no matching to)\n",
default_access >= access ? "granted" : "denied", 0, 0 );
return( default_access >= access );
}
......@@ -198,76 +267,78 @@ acl_access_allowed(
}
for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
if ( b->a_dnpat != NULL ) {
Debug( LDAP_DEBUG_TRACE, "<= check a_dnpat: %s\n",
b->a_dnpat, 0, 0);
/*
* if access applies to the entry itself, and the
* user is bound as somebody in the same namespace as
* the entry, OR the given dn matches the dn pattern
*/
if ( strcasecmp( b->a_dnpat, "self" ) == 0 && op->o_dn
!= NULL && *(op->o_dn) && e->e_dn != NULL ) {
edn = dn_normalize_case( strdup( e->e_dn ) );
if ( strcasecmp( b->a_dnpat, "self" ) == 0 &&
op->o_dn != NULL && *(op->o_dn) && e->e_dn != NULL )
{
if ( strcasecmp( edn, op->o_dn ) == 0 ) {
free( edn );
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >=
access ? "granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF)
>= access );
if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
free( edn );
} else {
if ( regex_matches( b->a_dnpat, odn ) ) {
if ( odn ) free( odn );
if ( regex_matches( b->a_dnpat, odn, edn, matches ) ) {
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
return( (b->a_access & ~ACL_SELF)
>= access );
if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
}
}
if ( b->a_addrpat != NULL ) {
if ( regex_matches( b->a_addrpat, conn->c_addr ) ) {
if ( odn ) free( odn );
if ( regex_matches( b->a_addrpat, conn->c_addr, edn, matches ) ) {
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
}
if ( b->a_domainpat != NULL ) {
if ( regex_matches( b->a_domainpat, conn->c_domain ) ) {
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ARGS, "<= check a_domainpath: %s\n",
b->a_domainpat, 0, 0 );
if ( regex_matches( b->a_domainpat, conn->c_domain, edn, matches ) )
{
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
"<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
}
if ( b->a_dnattr != NULL && op->o_dn != NULL ) {
Debug( LDAP_DEBUG_ARGS, "<= check a_dnattr: %s\n",
b->a_dnattr, 0, 0);
/* see if asker is listed in dnattr */
if ( (at = attr_find( e->e_attrs, b->a_dnattr ))
!= NULL && value_find( at->a_vals, &bv,
at->a_syntax, 3 ) == 0 )
if ( (at = attr_find( e->e_attrs, b->a_dnattr )) != NULL &&
value_find( at->a_vals, &bv, at->a_syntax, 3 ) == 0 )
{
if ( (b->a_access & ACL_SELF) && (val == NULL
|| value_cmp( &bv, val, at->a_syntax,
2 )) ) {
if ( (b->a_access & ACL_SELF) &&
(val == NULL || value_cmp( &bv, val, at->a_syntax, 2 )) )
{
continue;
}
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d access %s\n",
"<= acl_acces_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
......@@ -276,22 +347,49 @@ acl_access_allowed(
/* asker not listed in dnattr - check for self access */
if ( ! (b->a_access & ACL_SELF) || val == NULL ||
value_cmp( &bv, val, at->a_syntax, 2 ) != 0 ) {
value_cmp( &bv, val, at->a_syntax, 2 ) != 0 )
{
continue;
}
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
"<= acl: matched by clause #%d (self) access %s\n",
"<= acl_access_allowed: matched by clause #%d (self) access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ? "granted"
: "denied", 0 );
return( (b->a_access & ~ACL_SELF) >= access );
}
#ifdef ACLGROUP
if ( b->a_group != NULL && op->o_dn != NULL ) {
char buf[512];
/* b->a_group is an unexpanded entry name, expanded it should be an