Working ACLs!

This commit is contained in:
Kurt Zeilenga 1998-08-21 05:51:28 +00:00
parent 59a6663312
commit 4d9941b0f2
24 changed files with 756 additions and 2412 deletions

View file

@ -6,11 +6,41 @@
#
# add any platform-specific overrides below here
#
EXTRACFLAGS=-O -g
LDBMBACKEND=-DLDBM_USE_DBBTREE
LDBMINCLUDE=-I/usr/include
EDITOR=/usr/bin/vi
FINGER=/usr/bin/finger
SENDMAIL=/usr/sbin/sendmail
LDAP_RUNDIR=/var/run
MANCOMPRESS=gzip
MANCOMPRESSSUFFIX=.gz
#
# LDAP has a problem with the idea of implicit vs. explicit yields
# in call conversion threading packages, like the MIT pthreads
# package. Rather than resolve this globally, I have marked the
# threading as "preeemptive", even though it is technically not.
#
# This means that the implicit-yield threading is topologically
# equivalent to preemptive threading.
#
THREADS= -DPOSIX_THREADS -D_THREAD_SAFE -DPTHREAD_PREEMPTIVE
# use special gcc flag to include libc_r.a
THREADSLIB= -pthread
#THREADSLIB= -lc_r
# crypt(3) is in a separate library
LDAP_CRYPT_LIB= -lcrypt
#
# -------------------------------------------------------------------------
# you will probably not need to edit anything below this point
# -------------------------------------------------------------------------
CC = gcc
PLATFORMCFLAGS= -Dfreebsd

View file

@ -17,13 +17,13 @@ LDAPSRC = ../..
SRCS = bind.c open.c result.c error.c compare.c search.c \
modify.c add.c modrdn.c delete.c abandon.c ufn.c cache.c \
getfilter.c regex.c sbind.c kbind.c unbind.c friendly.c cldap.c \
getfilter.c sbind.c kbind.c unbind.c friendly.c cldap.c \
free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
getdn.c getentry.c getattr.c getvalues.c addentry.c \
request.c getdxbyname.c os-ip.c url.c charset.c
OBJS = bind.o open.o result.o error.o compare.o search.o \
modify.o add.o modrdn.o delete.o abandon.o ufn.o cache.o \
getfilter.o regex.o sbind.o kbind.o unbind.o friendly.o cldap.o \
getfilter.o sbind.o kbind.o unbind.o friendly.o cldap.o \
free.o disptmpl.o srchpref.o dsparse.o tmplout.o sort.o \
getdn.o getentry.o getattr.o getvalues.o addentry.o \
request.o getdxbyname.o os-ip.o url.o charset.o
@ -31,8 +31,7 @@ OBJS = bind.o open.o result.o error.o compare.o search.o \
HDIR = ../../include
INCLUDES= -I$(HDIR) $(KRBINCLUDEFLAG)
DEFINES = $(DEFS) -DFILTERFILE="\"$(RUNTIMEETCDIR)/ldapfilter.conf\"" \
-DTEMPLATEFILE="\"$(RUNTIMEETCDIR)/ldaptemplates.conf\""
DEFINES = $(DEFS)
CFLAGS = $(INCLUDES) $(DEFINES) $(ACFLAGS)
LIBS = -L. -L../liblber -lldap -llber $(KRBLIBFLAG) $(KRBLIBS) $(ALIBS)
@ -62,20 +61,20 @@ version.c: $(OBJS)
< Version.c > $@)
install: libldap.a ldapfilter.conf ldapfriendly ldaptemplates.conf ldapsearchprefs.conf FORCE
-$(MKDIR) -p $(LIBDIR)
$(INSTALL) $(INSTALLFLAGS) -m 644 libldap.a $(LIBDIR)
-$(MKDIR) -p $(LDAP_LIBDIR) $(LDAP_ETCDIR)
$(INSTALL) $(INSTALLFLAGS) -m 644 libldap.a $(LDAP_LIBDIR)
@if [ ! -z "$(RANLIB)" ]; then \
(cd /tmp; $(RANLIB) $(LIBDIR)/libldap.a) \
(cd /tmp; $(RANLIB) $(LDAP_LIBDIR)/libldap.a) \
fi
-$(MKDIR) -p $(ETCDIR)
-$(MV) $(ETCDIR)/ldapfriendly $(ETCDIR)/ldapfriendly-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldapfriendly $(ETCDIR)
-$(MV) $(ETCDIR)/ldapfilter.conf $(ETCDIR)/ldapfilter.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldapfilter.conf $(ETCDIR)
-$(MV) $(ETCDIR)/ldaptemplates.conf $(ETCDIR)/ldaptemplates.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldaptemplates.conf $(ETCDIR)
-$(MV) $(ETCDIR)/ldapsearchprefs.conf $(ETCDIR)/ldapsearchprefs.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldapsearchprefs.conf $(ETCDIR)
-$(MKDIR) -p $(LDAP_ETCDIR)
-$(MV) $(LDAP_ETCDIR)/ldapfriendly $(LDAP_ETCDIR)/ldapfriendly-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldapfriendly $(LDAP_ETCDIR)
-$(MV) $(LDAP_ETCDIR)/ldapfilter.conf $(LDAP_ETCDIR)/ldapfilter.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldapfilter.conf $(LDAP_ETCDIR)
-$(MV) $(LDAP_ETCDIR)/ldaptemplates.conf $(LDAP_ETCDIR)/ldaptemplates.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldaptemplates.conf $(LDAP_ETCDIR)
-$(MV) $(LDAP_ETCDIR)/ldapsearchprefs.conf $(LDAP_ETCDIR)/ldapsearchprefs.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 ldapsearchprefs.conf $(LDAP_ETCDIR)
lint: FORCE
$(LINT) $(INCLUDES) $(DEFINES) $(SRCS)
@ -93,51 +92,3 @@ links:
@$(LN) .src/*.[ch] .src/ldapfriendly .src/ldapfilter.conf \
.src/ldaptemplates.conf .src/ldapsearchprefs.conf .
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
bind.o: bind.c ../../include/lber.h ../../include/ldap.h
open.o: open.c ../../include/lber.h ../../include/ldap.h ldap-int.h
result.o: result.c ../../include/portable.h ../../include/lber.h
result.o: ../../include/ldap.h ldap-int.h
error.o: error.c ../../include/lber.h ../../include/ldap.h
compare.o: compare.c ../../include/lber.h ../../include/ldap.h ldap-int.h
search.o: search.c ../../include/lber.h ../../include/ldap.h ldap-int.h
modify.o: modify.c ../../include/lber.h ../../include/ldap.h ldap-int.h
add.o: add.c ../../include/lber.h ../../include/ldap.h ldap-int.h
modrdn.o: modrdn.c ../../include/lber.h ../../include/ldap.h ldap-int.h
delete.o: delete.c ../../include/lber.h ../../include/ldap.h ldap-int.h
abandon.o: abandon.c ../../include/lber.h ../../include/ldap.h ldap-int.h
ufn.o: ufn.c ../../include/lber.h ../../include/ldap.h
cache.o: cache.c ../../include/lber.h ../../include/ldap.h ldap-int.h
getfilter.o: getfilter.c ../../include/lber.h ../../include/ldap.h
getfilter.o: ../../include/regex.h
regex.o: regex.c ../../include/portable.h
sbind.o: sbind.c ../../include/lber.h ../../include/ldap.h ldap-int.h
kbind.o: kbind.c ../../include/lber.h ../../include/ldap.h ldap-int.h
unbind.o: unbind.c ../../include/lber.h ../../include/ldap.h ldap-int.h
friendly.o: friendly.c ../../include/lber.h ../../include/ldap.h
cldap.o: cldap.c ../../include/lber.h ../../include/ldap.h ldap-int.h
free.o: free.c ../../include/lber.h ../../include/ldap.h
disptmpl.o: disptmpl.c ../../include/lber.h ../../include/ldap.h
disptmpl.o: ../../include/disptmpl.h
srchpref.o: srchpref.c ../../include/lber.h ../../include/ldap.h
srchpref.o: ../../include/srchpref.h
dsparse.o: dsparse.c ../../include/lber.h ../../include/ldap.h
tmplout.o: tmplout.c ../../include/lber.h ../../include/ldap.h
tmplout.o: ../../include/disptmpl.h
sort.o: sort.c ../../include/lber.h ../../include/ldap.h
getdn.o: getdn.c ../../include/lber.h ../../include/ldap.h
getentry.o: getentry.c ../../include/lber.h ../../include/ldap.h
getattr.o: getattr.c ../../include/lber.h ../../include/ldap.h ldap-int.h
getvalues.o: getvalues.c ../../include/lber.h ../../include/ldap.h
addentry.o: addentry.c ../../include/lber.h ../../include/ldap.h
request.o: request.c ../../include/portable.h ../../include/lber.h
request.o: ../../include/ldap.h ldap-int.h
getdxbyname.o: getdxbyname.c
os-ip.o: os-ip.c ../../include/portable.h ../../include/lber.h
os-ip.o: ../../include/ldap.h
url.o: url.c ../../include/lber.h ../../include/ldap.h ldap-int.h
charset.o: charset.c
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY

View file

@ -10,13 +10,13 @@ static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#if defined(NeXT)
#include <sys/types.h>
#include <regex.h>
#endif
#ifdef MACOS
#include <stdlib.h>
#include "macos.h"
#else /* MACOS */
#ifdef DOS
@ -25,7 +25,6 @@ static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of
#else /* DOS */
#include <sys/types.h>
#include <sys/file.h>
#include <stdlib.h>
#include <sys/errno.h>
#ifndef VMS
#include <unistd.h>
@ -35,7 +34,6 @@ static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of
#include "lber.h"
#include "ldap.h"
#include "regex.h"
#ifdef NEEDPROTOS
static int break_into_words( char *str, char *delims, char ***wordsp );
@ -49,7 +47,6 @@ void free_strarray();
#if !defined( MACOS ) && !defined( DOS )
extern int errno;
extern char *re_comp();
#endif
#define FILT_MAX_LINE_LEN 1024
@ -107,8 +104,10 @@ ldap_init_getfilter_buf( char *buf, long buflen )
LDAPFiltDesc *lfdp;
LDAPFiltList *flp, *nextflp;
LDAPFiltInfo *fip, *nextfip;
char *tag, **tok;
int tokcnt, i;
char *tag, **tok;
int tokcnt, i;
int rc;
regex_t re;
if (( lfdp = (LDAPFiltDesc *)calloc( 1, sizeof( LDAPFiltDesc))) == NULL ) {
return( NULL );
@ -138,11 +137,13 @@ ldap_init_getfilter_buf( char *buf, long buflen )
}
nextflp->lfl_tag = strdup( tag );
nextflp->lfl_pattern = tok[ 0 ];
if ( re_comp( nextflp->lfl_pattern ) != NULL ) {
if ( (rc = regcomp( &re, nextflp->lfl_pattern, 0 )) != 0 ) {
#ifndef NO_USERINTERFACE
char error[512];
regerror(rc, &re, error, sizeof(error));
ldap_getfilter_free( lfdp );
fprintf( stderr, "bad regular expresssion %s\n",
nextflp->lfl_pattern );
fprintf( stderr, "bad regular expresssion %s, %s\n",
nextflp->lfl_pattern, error );
#if !defined( MACOS ) && !defined( DOS )
errno = EINVAL;
#endif
@ -150,6 +151,7 @@ ldap_init_getfilter_buf( char *buf, long buflen )
free_strarray( tok );
return( NULL );
}
regfree(&re);
nextflp->lfl_delims = tok[ 1 ];
nextflp->lfl_ilist = NULL;
@ -247,6 +249,8 @@ LDAPFiltInfo *
ldap_getfirstfilter( LDAPFiltDesc *lfdp, char *tagpat, char *value )
{
LDAPFiltList *flp;
int rc;
regex_t re;
if ( lfdp->lfd_curvalcopy != NULL ) {
free( lfdp->lfd_curvalcopy );
@ -256,13 +260,30 @@ ldap_getfirstfilter( LDAPFiltDesc *lfdp, char *tagpat, char *value )
lfdp->lfd_curval = value;
lfdp->lfd_curfip = NULL;
for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = flp->lfl_next ) {
if ( re_comp( tagpat ) == NULL && re_exec( flp->lfl_tag ) == 1
&& re_comp( flp->lfl_pattern ) == NULL
&& re_exec( lfdp->lfd_curval ) == 1 ) {
lfdp->lfd_curfip = flp->lfl_ilist;
break;
}
for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = flp->lfl_next ) {
/* compile tagpat, continue if we fail */
if (regcomp(&re, tagpat, 0) != 0)
continue;
/* match tagpatern and tag, continue if we fail */
rc = regexec(&re, flp->lfl_tag, 0, NULL, 0);
regfree(&re);
if (rc != 0)
continue;
/* compile flp->ifl_pattern, continue if we fail */
if (regcomp(&re, flp->lfl_pattern, 0) != 0)
continue;
/* match ifl_pattern and lfd_curval, continue if we fail */
rc = regexec(&re, lfdp->lfd_curval, 0, NULL, 0);
regfree(&re);
if (rc != 0)
continue;
/* we successfully compiled both patterns and matched both values */
lfdp->lfd_curfip = flp->lfl_ilist;
break;
}
if ( lfdp->lfd_curfip == NULL ) {

View file

@ -1,906 +0,0 @@
#include "portable.h"
#if defined( MACOS ) || defined( DOS ) || defined( _WIN32 ) || defined( NEED_BSDREGEX )
#include "regex.h"
/*
* regex - Regular expression pattern matching and replacement
*
* By: Ozan S. Yigit (oz)
* Dept. of Computer Science
* York University
*
* These routines are the PUBLIC DOMAIN equivalents of regex
* routines as found in 4.nBSD UN*X, with minor extensions.
*
* These routines are derived from various implementations found
* in software tools books, and Conroy's grep. They are NOT derived
* from licensed/restricted software.
* For more interesting/academic/complicated implementations,
* see Henry Spencer's regexp routines, or GNU Emacs pattern
* matching module.
*
* Modification history:
*
* $Log: regex.c,v $
* Revision 1.12 1996/04/25 16:20:59 mcs
* make re_exec() match "" with ".*" and similar patterns
* hopefully this change doesn't break anything else!
*
* Revision 1.11 1994/12/14 21:33:45 mcs
* use new NEED_BSDREGEX
* fix pmatch() prototype
*
* Revision 1.10 1994/12/12 18:16:39 mcs
* use on NetBSD
*
* Revision 1.9 1994/11/15 19:16:35 mcs
* add (CHAR) cast to make VisualC++ happy
*
* Revision 1.8 1994/11/08 21:14:32 mcs
* WIN32 changes
*
* Revision 1.7 1994/07/23 19:51:24 mcs
* use ANSI-style inline function parameters
*
* Revision 1.6 1993/10/18 01:52:32 tim
* include for VMS
*
* Revision 1.5 1993/09/28 21:37:54 mcs
* HP/UX needs the regex we include (not in its libc)
*
* Revision 1.4 1993/08/27 15:59:52 mcs
* use CHAR for deftab
*
* Revision 1.3 1993/08/27 15:49:47 mcs
* added missing 0 to octal constants
* use unsigned char for CHAR under DOS
*
* Revision 1.2 1993/08/27 14:57:48 mcs
* add proto. for pmatch
*
* Revision 1.1 1993/08/18 21:20:02 mcs
* Initial revision
*
* Revision 1.4 1991/10/17 03:56:42 oz
* miscellaneous changes, small cleanups etc.
*
* Revision 1.3 1989/04/01 14:18:09 oz
* Change all references to a dfa: this is actually an nfa.
*
* Revision 1.2 88/08/28 15:36:04 oz
* Use a complement bitmap to represent NCL.
* This removes the need to have seperate
* code in the pmatch case block - it is
* just CCL code now.
*
* Use the actual CCL code in the CLO
* section of pmatch. No need for a recursive
* pmatch call.
*
* Use a bitmap table to set char bits in an
* 8-bit chunk.
*
* Interfaces:
* re_comp: compile a regular expression into a NFA.
*
* char *re_comp(s)
* char *s;
*
* re_exec: execute the NFA to match a pattern.
*
* int re_exec(s)
* char *s;
*
* re_modw change re_exec's understanding of what a "word"
* looks like (for \< and \>) by adding into the
* hidden word-syntax table.
*
* void re_modw(s)
* char *s;
*
* re_subs: substitute the matched portions in a new string.
*
* int re_subs(src, dst)
* char *src;
* char *dst;
*
* re_fail: failure routine for re_exec.
*
* void re_fail(msg, op)
* char *msg;
* char op;
*
* Regular Expressions:
*
* [1] char matches itself, unless it is a special
* character (metachar): . \ [ ] * + ^ $
*
* [2] . matches any character.
*
* [3] \ matches the character following it, except
* when followed by a left or right round bracket,
* a digit 1 to 9 or a left or right angle bracket.
* (see [7], [8] and [9])
* It is used as an escape character for all
* other meta-characters, and itself. When used
* in a set ([4]), it is treated as an ordinary
* character.
*
* [4] [set] matches one of the characters in the set.
* If the first character in the set is "^",
* it matches a character NOT in the set, i.e.
* complements the set. A shorthand S-E is
* used to specify a set of characters S upto
* E, inclusive. The special characters "]" and
* "-" have no special meaning if they appear
* as the first chars in the set.
* examples: match:
*
* [a-z] any lowercase alpha
*
* [^]-] any char except ] and -
*
* [^A-Z] any char except uppercase
* alpha
*
* [a-zA-Z] any alpha
*
* [5] * any regular expression form [1] to [4], followed by
* closure char (*) matches zero or more matches of
* that form.
*
* [6] + same as [5], except it matches one or more.
*
* [7] a regular expression in the form [1] to [10], enclosed
* as \(form\) matches what form matches. The enclosure
* creates a set of tags, used for [8] and for
* pattern substution. The tagged forms are numbered
* starting from 1.
*
* [8] a \ followed by a digit 1 to 9 matches whatever a
* previously tagged regular expression ([7]) matched.
*
* [9] \< a regular expression starting with a \< construct
* \> and/or ending with a \> construct, restricts the
* pattern matching to the beginning of a word, and/or
* the end of a word. A word is defined to be a character
* string beginning and/or ending with the characters
* A-Z a-z 0-9 and _. It must also be preceded and/or
* followed by any character outside those mentioned.
*
* [10] a composite regular expression xy where x and y
* are in the form [1] to [10] matches the longest
* match of x followed by a match for y.
*
* [11] ^ a regular expression starting with a ^ character
* $ and/or ending with a $ character, restricts the
* pattern matching to the beginning of the line,
* or the end of line. [anchors] Elsewhere in the
* pattern, ^ and $ are treated as ordinary characters.
*
*
* Acknowledgements:
*
* HCR's Hugh Redelmeier has been most helpful in various
* stages of development. He convinced me to include BOW
* and EOW constructs, originally invented by Rob Pike at
* the University of Toronto.
*
* References:
* Software tools Kernighan & Plauger
* Software tools in Pascal Kernighan & Plauger
* Grep [rsx-11 C dist] David Conroy
* ed - text editor Un*x Programmer's Manual
* Advanced editing on Un*x B. W. Kernighan
* RegExp routines Henry Spencer
*
* Notes:
*
* This implementation uses a bit-set representation for character
* classes for speed and compactness. Each character is represented
* by one bit in a 128-bit block. Thus, CCL always takes a
* constant 16 bytes in the internal nfa, and re_exec does a single
* bit comparison to locate the character in the set.
*
* Examples:
*
* pattern: foo*.*
* compile: CHR f CHR o CLO CHR o END CLO ANY END END
* matches: fo foo fooo foobar fobar foxx ...
*
* pattern: fo[ob]a[rz]
* compile: CHR f CHR o CCL bitset CHR a CCL bitset END
* matches: fobar fooar fobaz fooaz
*
* pattern: foo\\+
* compile: CHR f CHR o CHR o CHR \ CLO CHR \ END END
* matches: foo\ foo\\ foo\\\ ...
*
* pattern: \(foo\)[1-3]\1 (same as foo[1-3]foo)
* compile: BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END
* matches: foo1foo foo2foo foo3foo
*
* pattern: \(fo.*\)-\1
* compile: BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END
* matches: foo-foo fo-fo fob-fob foobar-foobar ...
*/
#define MAXNFA 1024
#define MAXTAG 10
#define OKP 1
#define NOP 0
#define CHR 1
#define ANY 2
#define CCL 3
#define BOL 4
#define EOL 5
#define BOT 6
#define EOT 7
#define BOW 8
#define EOW 9
#define REF 10
#define CLO 11
#define END 0
/*
* The following defines are not meant to be changeable.
* They are for readability only.
*/
#define MAXCHR 128
#define CHRBIT 8
#define BITBLK MAXCHR/CHRBIT
#define BLKIND 0170
#define BITIND 07
#define ASCIIB 0177
#if defined( DOS ) || defined( _WIN32 )
typedef unsigned char CHAR;
#else /* DOS */
typedef /*unsigned*/ char CHAR;
#endif /* DOS */
static int tagstk[MAXTAG]; /* subpat tag stack..*/
static CHAR nfa[MAXNFA]; /* automaton.. */
static int sta = NOP; /* status of lastpat */
static CHAR bittab[BITBLK]; /* bit table for CCL */
/* pre-set bits... */
static CHAR bitarr[] = {1,2,4,8,16,32,64,128};
static void
chset(CHAR c)
{
bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND];
}
#define badpat(x) (*nfa = END, x)
#define store(x) *mp++ = x
char *
re_comp( char *pat )
{
register char *p; /* pattern pointer */
register CHAR *mp=nfa; /* nfa pointer */
register CHAR *lp; /* saved pointer.. */
register CHAR *sp=nfa; /* another one.. */
register int tagi = 0; /* tag stack index */
register int tagc = 1; /* actual tag count */
register int n;
register CHAR mask; /* xor mask -CCL/NCL */
int c1, c2;
if (!pat || !*pat)
if (sta)
return 0;
else
return badpat("No previous regular expression");
sta = NOP;
for (p = pat; *p; p++) {
lp = mp;
switch(*p) {
case '.': /* match any char.. */
store(ANY);
break;
case '^': /* match beginning.. */
if (p == pat)
store(BOL);
else {
store(CHR);
store(*p);
}
break;
case '$': /* match endofline.. */
if (!*(p+1))
store(EOL);
else {
store(CHR);
store(*p);
}
break;
case '[': /* match char class..*/
store(CCL);
if (*++p == '^') {
mask = 0377;
p++;
}
else
mask = 0;
if (*p == '-') /* real dash */
chset(*p++);
if (*p == ']') /* real brac */
chset(*p++);
while (*p && *p != ']') {
if (*p == '-' && *(p+1) && *(p+1) != ']') {
p++;
c1 = *(p-2) + 1;
c2 = *p++;
while (c1 <= c2)
chset((CHAR)c1++);
}
#ifdef EXTEND
else if (*p == '\\' && *(p+1)) {
p++;
chset(*p++);
}
#endif
else
chset(*p++);
}
if (!*p)
return badpat("Missing ]");
for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
store(mask ^ bittab[n]);
break;
case '*': /* match 0 or more.. */
case '+': /* match 1 or more.. */
if (p == pat)
return badpat("Empty closure");
lp = sp; /* previous opcode */
if (*lp == CLO) /* equivalence.. */
break;
switch(*lp) {
case BOL:
case BOT:
case EOT:
case BOW:
case EOW:
case REF:
return badpat("Illegal closure");
default:
break;
}
if (*p == '+')
for (sp = mp; lp < sp; lp++)
store(*lp);
store(END);
store(END);
sp = mp;
while (--mp > lp)
*mp = mp[-1];
store(CLO);
mp = sp;
break;
case '\\': /* tags, backrefs .. */
switch(*++p) {
case '(':
if (tagc < MAXTAG) {
tagstk[++tagi] = tagc;
store(BOT);
store(tagc++);
}
else
return badpat("Too many \\(\\) pairs");
break;
case ')':
if (*sp == BOT)
return badpat("Null pattern inside \\(\\)");
if (tagi > 0) {
store(EOT);
store(tagstk[tagi--]);
}
else
return badpat("Unmatched \\)");
break;
case '<':
store(BOW);
break;
case '>':
if (*sp == BOW)
return badpat("Null pattern inside \\<\\>");
store(EOW);
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = *p-'0';
if (tagi > 0 && tagstk[tagi] == n)
return badpat("Cyclical reference");
if (tagc > n) {
store(REF);
store(n);
}
else
return badpat("Undetermined reference");
break;
#ifdef EXTEND
case 'b':
store(CHR);
store('\b');
break;
case 'n':
store(CHR);
store('\n');
break;
case 'f':
store(CHR);
store('\f');
break;
case 'r':
store(CHR);
store('\r');
break;
case 't':
store(CHR);
store('\t');
break;
#endif
default:
store(CHR);
store(*p);
}
break;
default : /* an ordinary char */
store(CHR);
store(*p);
break;
}
sp = lp;
}
if (tagi > 0)
return badpat("Unmatched \\(");
store(END);
sta = OKP;
return 0;
}
static char *bol;
char *bopat[MAXTAG];
char *eopat[MAXTAG];
#ifdef NEEDPROTOS
static char *pmatch( char *lp, CHAR *ap );
#else /* NEEDPROTOS */
static char *pmatch();
#endif /* NEEDPROTOS */
/*
* re_exec:
* execute nfa to find a match.
*
* special cases: (nfa[0])
* BOL
* Match only once, starting from the
* beginning.
* CHR
* First locate the character without
* calling pmatch, and if found, call
* pmatch for the remaining string.
* END
* re_comp failed, poor luser did not
* check for it. Fail fast.
*
* If a match is found, bopat[0] and eopat[0] are set
* to the beginning and the end of the matched fragment,
* respectively.
*
*/
int
re_exec( char *lp )
{
register char c;
register char *ep = 0;
register CHAR *ap = nfa;
bol = lp;
bopat[0] = 0;
bopat[1] = 0;
bopat[2] = 0;
bopat[3] = 0;
bopat[4] = 0;
bopat[5] = 0;
bopat[6] = 0;
bopat[7] = 0;
bopat[8] = 0;
bopat[9] = 0;
switch(*ap) {
case BOL: /* anchored: match from BOL only */
ep = pmatch(lp,ap);
break;
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
while (*lp && *lp != c)
lp++;
if (!*lp) /* if EOS, fail, else fall thru. */
return 0;
default: /* regular matching all the way. */
do {
if ((ep = pmatch(lp,ap)))
break;
lp++;
} while (*lp);
break;
case END: /* munged automaton. fail always */
return 0;
}
if (!ep)
return 0;
bopat[0] = lp;
eopat[0] = ep;
return 1;
}
/*
* pmatch: internal routine for the hard part
*
* This code is partly snarfed from an early grep written by
* David Conroy. The backref and tag stuff, and various other
* innovations are by oz.
*
* special case optimizations: (nfa[n], nfa[n+1])
* CLO ANY
* We KNOW .* will match everything upto the
* end of line. Thus, directly go to the end of
* line, without recursive pmatch calls. As in
* the other closure cases, the remaining pattern
* must be matched by moving backwards on the
* string recursively, to find a match for xy
* (x is ".*" and y is the remaining pattern)
* where the match satisfies the LONGEST match for
* x followed by a match for y.
* CLO CHR
* We can again scan the string forward for the
* single char and at the point of failure, we
* execute the remaining nfa recursively, same as
* above.
*
* At the end of a successful match, bopat[n] and eopat[n]
* are set to the beginning and end of subpatterns matched
* by tagged expressions (n = 1 to 9).
*
*/
#ifndef re_fail
extern void re_fail();
#endif /* re_fail */
/*
* character classification table for word boundary operators BOW
* and EOW. the reason for not using ctype macros is that we can
* let the user add into our own table. see re_modw. This table
* is not in the bitset form, since we may wish to extend it in the
* future for other character classifications.
*
* TRUE for 0-9 A-Z a-z _
*/
static char chrtyp[MAXCHR] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0
};
#define inascii(x) (0177&(x))
#define iswordc(x) chrtyp[inascii(x)]
#define isinset(x,y) ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND])
/*
* skip values for CLO XXX to skip past the closure
*/
#define ANYSKIP 2 /* [CLO] ANY END ... */
#define CHRSKIP 3 /* [CLO] CHR chr END ... */
#define CCLSKIP 18 /* [CLO] CCL 16bytes END ... */
static char *
pmatch( char *lp, CHAR *ap)
{
register int op, c, n;
register char *e; /* extra pointer for CLO */
register char *bp; /* beginning of subpat.. */
register char *ep; /* ending of subpat.. */
char *are; /* to save the line ptr. */
while ((op = *ap++) != END)
switch(op) {
case CHR:
if (*lp++ != *ap++)
return 0;
break;
case ANY:
if (!*lp++)
return 0;
break;
case CCL:
c = *lp++;
if (!isinset(ap,c))
return 0;
ap += BITBLK;
break;
case BOL:
if (lp != bol)
return 0;
break;
case EOL:
if (*lp)
return 0;
break;
case BOT:
bopat[*ap++] = lp;
break;
case EOT:
eopat[*ap++] = lp;
break;
case BOW:
if (lp!=bol && iswordc(lp[-1]) || !iswordc(*lp))
return 0;
break;
case EOW:
if (lp==bol || !iswordc(lp[-1]) || iswordc(*lp))
return 0;
break;
case REF:
n = *ap++;
bp = bopat[n];
ep = eopat[n];
while (bp < ep)
if (*bp++ != *lp++)
return 0;
break;
case CLO:
are = lp;
switch(*ap) {
case ANY:
while (*lp)
lp++;
n = ANYSKIP;
break;
case CHR:
c = *(ap+1);
while (*lp && c == *lp)
lp++;
n = CHRSKIP;
break;
case CCL:
while ((c = *lp) && isinset(ap+1,c))
lp++;
n = CCLSKIP;
break;
default:
re_fail("closure: bad nfa.", *ap);
return 0;
}
ap += n;
while (lp >= are) {
if (e = pmatch(lp, ap))
return e;
--lp;
}
return 0;
default:
re_fail("re_exec: bad nfa.", op);
return 0;
}
return lp;
}
/*
* re_modw:
* add new characters into the word table to change re_exec's
* understanding of what a word should look like. Note that we
* only accept additions into the word definition.
*
* If the string parameter is 0 or null string, the table is
* reset back to the default containing A-Z a-z 0-9 _. [We use
* the compact bitset representation for the default table]
*/
static CHAR deftab[16] = {
0, 0, 0, 0, 0, 0, 0377, 003, 0376, 0377, 0377, 0207,
0376, 0377, 0377, 007
};
void
re_modw( char *s )
{
register int i;
if (!s || !*s) {
for (i = 0; i < MAXCHR; i++)
if (!isinset(deftab,i))
iswordc(i) = 0;
}
else
while(*s)
iswordc(*s++) = 1;
}
/*
* re_subs:
* substitute the matched portions of the src in dst.
*
* & substitute the entire matched pattern.
*
* \digit substitute a subpattern, with the given tag number.
* Tags are numbered from 1 to 9. If the particular
* tagged subpattern does not exist, null is substituted.
*/
int
re_subs( char *src, char *dst)
{
register char c;
register int pin;
register char *bp;
register char *ep;
if (!*src || !bopat[0])
return 0;
while (c = *src++) {
switch(c) {
case '&':
pin = 0;
break;
case '\\':
c = *src++;
if (c >= '0' && c <= '9') {
pin = c - '0';
break;
}
default:
*dst++ = c;
continue;
}
if ((bp = bopat[pin]) && (ep = eopat[pin])) {
while (*bp && bp < ep)
*dst++ = *bp++;
if (bp < ep)
return 0;
}
}
*dst = (char) 0;
return 1;
}
#ifdef DEBUG
/*
* symbolic - produce a symbolic dump of the nfa
*/
symbolic( char *s )
{
printf("pattern: %s\n", s);
printf("nfacode:\n");
nfadump(nfa);
}
static
nfadump( CHAR *ap)
{
register int n;
while (*ap != END)
switch(*ap++) {
case CLO:
printf("CLOSURE");
nfadump(ap);
switch(*ap) {
case CHR:
n = CHRSKIP;
break;
case ANY:
n = ANYSKIP;
break;
case CCL:
n = CCLSKIP;
break;
}
ap += n;
break;
case CHR:
printf("\tCHR %c\n",*ap++);
break;
case ANY:
printf("\tANY .\n");
break;
case BOL:
printf("\tBOL -\n");
break;
case EOL:
printf("\tEOL -\n");
break;
case BOT:
printf("BOT: %d\n",*ap++);
break;
case EOT:
printf("EOT: %d\n",*ap++);
break;
case BOW:
printf("BOW\n");
break;
case EOW:
printf("EOW\n");
break;
case REF:
printf("REF: %d\n",*ap++);
break;
case CCL:
printf("\tCCL [");
for (n = 0; n < MAXCHR; n++)
if (isinset(ap,(CHAR)n)) {
if (n < ' ')
printf("^%c", n ^ 0x040);
else
printf("%c", n);
}
printf("]\n");
ap += BITBLK;
break;
default:
printf("bad nfa. opcode %o\n", ap[-1]);
exit(1);
break;
}
}
#endif
#endif /* MACOS or DOS or NEED_BSDREGEX */

View file

@ -21,23 +21,24 @@ SRCS = main.c daemon.c connection.c search.c filter.c add.c charray.c \
attr.c entry.c config.c backend.c result.c operation.c \
dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
value.c ava.c bind.c unbind.c abandon.c filterentry.c \
phonetic.c regex.c acl.c str2filter.c aclparse.c init.c \
phonetic.c acl.c str2filter.c aclparse.c init.c \
detach.c strdup.c tempnam.c repl.c lock.c \
schema.c schemaparse.c monitor.c configinfo.c
OBJS = main.o daemon.o connection.o search.o filter.o add.o charray.o \
attr.o entry.o config.o backend.o result.o operation.o \
dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
value.o ava.o bind.o unbind.o abandon.o filterentry.o \
phonetic.o regex.o acl.o str2filter.o aclparse.o init.o \
phonetic.o acl.o str2filter.o aclparse.o init.o \
detach.o strdup.o tempnam.o repl.o lock.o \
schema.o schemaparse.o monitor.o configinfo.o
INCLUDES= -I. -I$(HDIR) $(KRBINCLUDEFLAG)
DEFINES = $(DEFS) $(SERVERDEFS)
DEFINES = $(DEFS) $(LDAP_CRYPT) $(LDAP_TCP_WRAPPERS) $(SERVERDEFS)
CFLAGS = $(INCLUDES) $(THREADSINCLUDE) $(DEFINES) $(ACFLAGS) $(THREADS)
LDFLAGS = -L$(LDIR) $(KRBLIBFLAG)
LIBS = $(KRBLIBS) -llber -lldbm -lavl -llthread -lldif $(THREADSLIB) \
$(LDBMLIB) $(ALIBS)
LIBS = $(KRBLIBS) -llber -lldbm -lavl -llthread -lldif \
$(REGEXLIB) $(THREADSLIB) \
$(LDBMLIB) $(LDAP_CRYPT_LIB) $(LDAP_TCP_WRAPPERS_LIB) $(ALIBS)
all: FORCE
@if [ -z "$(MAKESLAPD)" ]; then \
@ -100,26 +101,27 @@ version.c: libbackends.a $(OBJS) $(LDIR)/liblber/liblber.a \
-e "s|%VERSION%|$${v}|" \
< Version.c > $@)
install: all $(ETCDIR) $(ETCDIR)/slapd $(ETCDIR)/slapd.conf \
$(ETCDIR)/slapd.at.conf $(ETCDIR)/slapd.oc.conf \
install: all $(LDAP_LIBEXECDIR) $(LDAP_LIBEXECDIR)/slapd \
$(LDAP_ETCDIR) $(LDAP_ETCDIR)/slapd.conf \
$(LDAP_ETCDIR)/slapd.at.conf $(LDAP_ETCDIR)/slapd.oc.conf \
install-tools
$(ETCDIR)/slapd: slapd
$(INSTALL) $(INSTALLFLAGS) -m 755 slapd $(ETCDIR)
$(LDAP_LIBEXECDIR)/slapd: slapd
$(INSTALL) $(INSTALLFLAGS) -m 755 slapd $(LDAP_LIBEXECDIR)
$(ETCDIR)/slapd.conf: slapd.conf
$(SED) -e 's;%ETCDIR%;$(RUNTIMEETCDIR);' slapd.conf > /tmp/slapd.$$
-$(MV) $(ETCDIR)/slapd.conf $(ETCDIR)/slapd.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 /tmp/slapd.$$ $(ETCDIR)/slapd.conf
$(LDAP_ETCDIR)/slapd.conf: slapd.conf
$(SED) -e 's;%ETCDIR%;$(LDAP_ETCDIR);' slapd.conf > /tmp/slapd.$$
-$(MV) $(LDAP_ETCDIR)/slapd.conf $(LDAP_ETCDIR)/slapd.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 /tmp/slapd.$$ $(LDAP_ETCDIR)/slapd.conf
$(RM) -f /tmp/slapd.$$
$(ETCDIR)/slapd.at.conf: slapd.at.conf
-$(MV) $(ETCDIR)/slapd.at.conf $(ETCDIR)/slapd.at.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 slapd.at.conf $(ETCDIR)
$(LDAP_ETCDIR)/slapd.at.conf: slapd.at.conf
-$(MV) $(LDAP_ETCDIR)/slapd.at.conf $(LDAP_ETCDIR)/slapd.at.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 slapd.at.conf $(LDAP_ETCDIR)
$(ETCDIR)/slapd.oc.conf: slapd.oc.conf
-$(MV) $(ETCDIR)/slapd.oc.conf $(ETCDIR)/slapd.oc.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 slapd.oc.conf $(ETCDIR)
$(LDAP_ETCDIR)/slapd.oc.conf: slapd.oc.conf
-$(MV) $(LDAP_ETCDIR)/slapd.oc.conf $(LDAP_ETCDIR)/slapd.oc.conf-
$(INSTALL) $(INSTALLFLAGS) -m 644 slapd.oc.conf $(LDAP_ETCDIR)
install-tools: FORCE
(cd tools; $(MAKE) $(MFLAGS) install)
@ -164,103 +166,3 @@ links:
fi; \
done;
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
main.o: main.c ../../include/portable.h slap.h ../../include/avl.h
main.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
main.o: ../../include/ldif.h ../../include/ldapconfig.h
daemon.o: daemon.c slap.h ../../include/avl.h ../../include/lber.h
daemon.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
daemon.o: ../../include/portable.h ../../include/ldapconfig.h
connection.o: connection.c ../../include/portable.h slap.h ../../include/avl.h
connection.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
connection.o: ../../include/ldif.h
search.o: search.c slap.h ../../include/avl.h ../../include/lber.h
search.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
search.o: ../../include/ldapconfig.h
filter.o: filter.c slap.h ../../include/avl.h ../../include/lber.h
filter.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
add.o: add.c slap.h ../../include/avl.h ../../include/lber.h
add.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
charray.o: charray.c slap.h ../../include/avl.h ../../include/lber.h
charray.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
attr.o: attr.c ../../include/portable.h slap.h ../../include/avl.h
attr.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
attr.o: ../../include/ldif.h
entry.o: entry.c slap.h ../../include/avl.h ../../include/lber.h
entry.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
config.o: config.c slap.h ../../include/avl.h ../../include/lber.h
config.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
config.o: ../../include/ldapconfig.h
backend.o: backend.c slap.h ../../include/avl.h ../../include/lber.h
backend.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
result.o: result.c ../../include/portable.h slap.h ../../include/avl.h
result.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
result.o: ../../include/ldif.h
operation.o: operation.c slap.h ../../include/avl.h ../../include/lber.h
operation.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
dn.o: dn.c ../../include/portable.h slap.h ../../include/avl.h
dn.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
dn.o: ../../include/ldif.h
compare.o: compare.c slap.h ../../include/avl.h ../../include/lber.h
compare.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
modify.o: modify.c slap.h ../../include/avl.h ../../include/lber.h
modify.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
delete.o: delete.c slap.h ../../include/avl.h ../../include/lber.h
delete.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
modrdn.o: modrdn.c slap.h ../../include/avl.h ../../include/lber.h
modrdn.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
ch_malloc.o: ch_malloc.c slap.h ../../include/avl.h ../../include/lber.h
ch_malloc.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
value.o: value.c ../../include/portable.h slap.h ../../include/avl.h
value.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
value.o: ../../include/ldif.h
ava.o: ava.c slap.h ../../include/avl.h ../../include/lber.h
ava.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
bind.o: bind.c slap.h ../../include/avl.h ../../include/lber.h
bind.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
unbind.o: unbind.c slap.h ../../include/avl.h ../../include/lber.h
unbind.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
abandon.o: abandon.c slap.h ../../include/avl.h ../../include/lber.h
abandon.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
filterentry.o: filterentry.c ../../include/regex.h slap.h ../../include/avl.h
filterentry.o: ../../include/lber.h ../../include/ldap.h
filterentry.o: ../../include/lthread.h ../../include/ldif.h
phonetic.o: phonetic.c ../../include/portable.h slap.h ../../include/avl.h
phonetic.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
phonetic.o: ../../include/ldif.h
regex.o: regex.c ../../include/portable.h
acl.o: acl.c ../../include/regex.h slap.h ../../include/avl.h
acl.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
acl.o: ../../include/ldif.h
str2filter.o: str2filter.c slap.h ../../include/avl.h ../../include/lber.h
str2filter.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
aclparse.o: aclparse.c ../../include/regex.h slap.h ../../include/avl.h
aclparse.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
aclparse.o: ../../include/ldif.h ../../include/portable.h
init.o: init.c ../../include/portable.h slap.h ../../include/avl.h
init.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
init.o: ../../include/ldif.h
detach.o: detach.c ../../include/portable.h
strdup.o: strdup.c
tempnam.o: tempnam.c
repl.o: repl.c slap.h ../../include/avl.h ../../include/lber.h
repl.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
lock.o: lock.c ../../include/portable.h slap.h ../../include/avl.h
lock.o: ../../include/lber.h ../../include/ldap.h ../../include/lthread.h
lock.o: ../../include/ldif.h
schema.o: schema.c slap.h ../../include/avl.h ../../include/lber.h
schema.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
schemaparse.o: schemaparse.c slap.h ../../include/avl.h ../../include/lber.h
schemaparse.o: ../../include/ldap.h ../../include/lthread.h
schemaparse.o: ../../include/ldif.h
monitor.o: monitor.c slap.h ../../include/avl.h ../../include/lber.h
monitor.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
monitor.o: ../../include/ldapconfig.h
configinfo.o: configinfo.c slap.h ../../include/avl.h ../../include/lber.h
configinfo.o: ../../include/ldap.h ../../include/lthread.h ../../include/ldif.h
configinfo.o: ../../include/ldapconfig.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY

View file

@ -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,10 @@ 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);
extern Entry * be_dn2entry(Backend *be, char *bdn, char **matched);
/*
* access_allowed - check whether dn is allowed the requested access
@ -51,15 +50,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 +116,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 +135,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 );
}
}
Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
matches[0].rm_so = matches[0].rm_eo = -1;
}
Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
return( NULL );
}
@ -161,31 +222,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 +268,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 );
}
free( edn );
} else {
if ( regex_matches( b->a_dnpat, odn ) ) {
if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
} else {
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 +348,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
* entry with objectclass group* and we test to see if odn is one of
* the values in the attribute uniquegroup
*/
Debug( LDAP_DEBUG_ARGS, "<= check a_group: %s\n",
b->a_group, 0, 0);
Debug( LDAP_DEBUG_ARGS, "<= check a_group: odn: %s\n",
odn, 0, 0);
/* see if asker is listed in dnattr */
string_expand(buf, sizeof(buf), b->a_group, edn, matches);
if (be_group(be, buf, odn) == 0) {
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: matched by clause #%d (group) access granted\n",
i, 0, 0 );
if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
}
#endif /* ACLGROUP */
}
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL, "<= acl: %s by default (no matching by)\n",
Debug( LDAP_DEBUG_ACL,
"<= acl_access_allowed: %s by default (no matching by)\n",
default_access >= access ? "granted" : "denied", 0, 0 );
return( default_access >= access );
@ -316,14 +415,26 @@ acl_check_mods(
{
int i;
struct acl *a;
char *edn;
edn = dn_normalize_case( strdup( e->e_dn ) );
for ( ; mods != NULL; mods = mods->mod_next ) {
regmatch_t matches[MAXREMATCHES];
/* the lastmod attributes are ignored by ACL checking */
if ( strcasecmp( mods->mod_type, "modifiersname" ) == 0 ||
strcasecmp( mods->mod_type, "modifytimestamp" ) == 0 ) {
strcasecmp( mods->mod_type, "modifytimestamp" ) == 0 ||
strcasecmp( mods->mod_type, "creatorsname" ) == 0 ||
strcasecmp( mods->mod_type, "createtimestamp" ) == 0 )
{
Debug( LDAP_DEBUG_ACL, "LASTMOD attribute: %s access allowed\n",
mods->mod_type, 0, 0 );
continue;
}
a = acl_get_applicable( be, op, e, mods->mod_type );
a = acl_get_applicable( be, op, e, mods->mod_type, edn,
MAXREMATCHES, matches );
switch ( mods->mod_op & ~LDAP_MOD_BVALUES ) {
case LDAP_MOD_REPLACE:
@ -332,8 +443,10 @@ acl_check_mods(
break;
}
for ( i = 0; mods->mod_bvalues[i] != NULL; i++ ) {
if ( ! acl_access_allowed( a, be, conn, e,
mods->mod_bvalues[i], op, ACL_WRITE ) ) {
if ( ! acl_access_allowed( a, be, conn, e, mods->mod_bvalues[i],
op, ACL_WRITE, edn, matches) )
{
free(edn);
return( LDAP_INSUFFICIENT_ACCESS );
}
}
@ -342,14 +455,18 @@ acl_check_mods(
case LDAP_MOD_DELETE:
if ( mods->mod_bvalues == NULL ) {
if ( ! acl_access_allowed( a, be, conn, e,
NULL, op, ACL_WRITE ) ) {
NULL, op, ACL_WRITE, edn, matches) )
{
free(edn);
return( LDAP_INSUFFICIENT_ACCESS );
}
break;
}
for ( i = 0; mods->mod_bvalues[i] != NULL; i++ ) {
if ( ! acl_access_allowed( a, be, conn, e,
mods->mod_bvalues[i], op, ACL_WRITE ) ) {
if ( ! acl_access_allowed( a, be, conn, e, mods->mod_bvalues[i],
op, ACL_WRITE, edn, matches) )
{
free(edn);
return( LDAP_INSUFFICIENT_ACCESS );
}
}
@ -357,48 +474,95 @@ acl_check_mods(
}
}
free(edn);
return( LDAP_SUCCESS );
}
#ifdef sunos5
static int
regex_matches( char *pat, char *str )
static string_expand(
char *newbuf,
int bufsiz,
char *pat,
char *match,
regmatch_t *matches)
{
char *e;
int rc;
int size;
char *sp;
char *dp;
int flag;
if ( (e = compile( pat, NULL, NULL )) == NULL ) {
Debug( LDAP_DEBUG_ANY,
"compile( \"%s\", \"%s\") failed\n", pat, str, 0 );
return( 0 );
size = 0;
newbuf[0] = '\0';
flag = 0;
for ( dp = newbuf, sp = pat; size < 512 && *sp ; sp++) {
/* did we previously see a $ */
if (flag) {
if (*sp == '$') {
*dp++ = '$';
size++;
} else if (*sp >= '0' && *sp <= '9' ) {
int n;
int i;
char *ep;
int l;
n = *sp - '0';
*dp = '\0';
i = matches[n].rm_so;
l = matches[n].rm_eo;
for ( ; size < 512 && i < l; size++, i++ ) {
*dp++ = match[i];
size++;
}
*dp = '\0';
}
flag = 0;
} else {
if (*sp == '$') {
flag = 1;
} else {
*dp++ = *sp;
size++;
}
}
}
rc = step( str ? str : "", e );
free( e );
*dp = '\0';
return( rc );
Debug( LDAP_DEBUG_TRACE, "=> string_expand: pattern: %s\n", pat, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "=> string_expand: expanded: %s\n", newbuf, 0, 0 );
}
#else /* sunos5 */
static int
regex_matches( char *pat, char *str )
regex_matches(
char *pat, /* pattern to expand and match against */
char *str, /* string to match against pattern */
char *buf, /* buffer with $N expansion variables */
regmatch_t *matches /* offsets in buffer for $N expansion variables */
)
{
char *e;
regex_t re;
char newbuf[512];
int rc;
pthread_mutex_lock( &regex_mutex );
if ( (e = re_comp( pat )) != NULL ) {
string_expand(newbuf, sizeof(newbuf), pat, buf, matches);
if (( rc = regcomp(&re, newbuf, REG_EXTENDED|REG_ICASE))) {
char error[512];
regerror(rc, &re, error, sizeof(error));
Debug( LDAP_DEBUG_ANY,
"re_comp( \"%s\", \"%s\") failed because (%s)\n", pat, str,
e );
pthread_mutex_unlock( &regex_mutex );
"compile( \"%s\", \"%s\") failed %s\n",
pat, str, error );
return( 0 );
}
rc = re_exec( str ? str : "" );
pthread_mutex_unlock( &regex_mutex );
return( rc == 1 );
rc = regexec(&re, str, 0, NULL, 0);
regfree( &re );
Debug( LDAP_DEBUG_ANY,
"=> regex_matches: string: %s\n", str, 0, 0 );
Debug( LDAP_DEBUG_ANY,
"=> regex_matches: rc: %d %s\n",
rc, !rc ? "matches" : "no matches", 0 );
return( !rc );
}
#endif /* sunos5 */

View file

@ -7,12 +7,13 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include "regex.h"
#include <unistd.h>
#include <regex.h>
#include "slap.h"
#include "portable.h"
extern Filter *str2filter();
extern char *re_comp();
extern struct acl *global_acl;
extern char **str2charray();
extern char *dn_upcase();
@ -26,6 +27,62 @@ static void print_acl();
static void print_access();
#endif
int
regtest(char *fname, int lineno, char *pat) {
int e;
regex_t re;
char buf[512];
int size;
char *sp;
char *dp;
int flag;
sp = pat;
dp = buf;
size = 0;
buf[0] = '\0';
for (size = 0, flag = 0; (size < sizeof(buf)) && *sp; sp++) {
if (flag) {
if (*sp == '$'|| (*sp >= '0' && *sp <= '9')) {
*dp++ = *sp;
size++;
}
flag = 0;
} else {
if (*sp == '$') {
flag = 1;
} else {
*dp++ = *sp;
size++;
}
}
}
*dp = '\0';
if ( size >= (sizeof(buf)-1) ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" too large\n",
fname, lineno, pat, 0 );
acl_usage();
}
if ((e = regcomp(&re, buf, REG_EXTENDED|REG_ICASE))) {
char error[512];
regerror(e, &re, error, sizeof(error));
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, pat, error );
acl_usage();
return(0);
}
regfree(&re);
return(1);
}
void
parse_acl(
Backend *be,
@ -58,6 +115,17 @@ parse_acl(
}
if ( strcasecmp( argv[i], "*" ) == 0 ) {
int e;
if ((e = regcomp( &a->acl_dnre, ".*",
REG_EXTENDED|REG_ICASE)))
{
char buf[512];
regerror(e, &a->acl_dnre, buf, sizeof(buf));
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, right, buf );
acl_usage();
}
a->acl_dnpat = strdup( ".*" );
continue;
}
@ -79,14 +147,19 @@ parse_acl(
acl_usage();
}
} else if ( strcasecmp( left, "dn" ) == 0 ) {
if ( (e = re_comp( right )) != NULL ) {
int e;
if ((e = regcomp(&a->acl_dnre, right,
REG_EXTENDED|REG_ICASE))) {
char buf[512];
regerror(e, &a->acl_dnre, buf, sizeof(buf));
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, right, e );
"%s: line %d: regular expression \"%s\" bad because of %s\n",
fname, lineno, right, buf );
acl_usage();
} else {
a->acl_dnpat = dn_upcase(strdup( right ));
}
a->acl_dnpat = dn_upcase( strdup(
right ) );
} else if ( strncasecmp( left, "attr", 4 )
== 0 ) {
char **alist;
@ -96,7 +169,7 @@ parse_acl(
free( alist );
} else {
fprintf( stderr,
"%s: line %d: expecting <what> got \"%s\"\n",
"%s: line %d: expecting <what> got \"%s\"\n",
fname, lineno, left );
acl_usage();
}
@ -106,7 +179,7 @@ parse_acl(
} else if ( strcasecmp( argv[i], "by" ) == 0 ) {
if ( a == NULL ) {
fprintf( stderr,
"%s: line %d: to clause required before by clause in access line\n",
"%s: line %d: to clause required before by clause in access line\n",
fname, lineno );
acl_usage();
}
@ -131,38 +204,27 @@ parse_acl(
} else if ( strcasecmp( argv[i], "self" ) == 0 ) {
b->a_dnpat = strdup( "self" );
} else if ( strcasecmp( left, "dn" ) == 0 ) {
if ( (e = re_comp( right )) != NULL ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad: %s\n",
fname, lineno, right, e );
acl_usage();
}
regtest(fname, lineno, right);
b->a_dnpat = dn_upcase( strdup( right ) );
} else if ( strcasecmp( left, "dnattr" )
== 0 ) {
} else if ( strcasecmp( left, "dnattr" ) == 0 ) {
b->a_dnattr = strdup( right );
} else if ( strcasecmp( left, "domain" )
== 0 ) {
char *s;
if ( (e = re_comp( right )) != NULL ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad: %s\n",
fname, lineno, right, e );
acl_usage();
}
#ifdef ACLGROUP
} else if ( strcasecmp( left, "group" ) == 0 ) {
regtest(fname, lineno, right);
b->a_group = dn_upcase(strdup( right ));
#endif /* ACLGROUP */
} else if ( strcasecmp( left, "domain" ) == 0 ) {
char *s;
regtest(fname, lineno, right);
b->a_domainpat = strdup( right );
/* normalize the domain */
for ( s = b->a_domainpat; *s; s++ ) {
*s = TOLOWER( *s );
}
} else if ( strcasecmp( left, "addr" ) == 0 ) {
if ( (e = re_comp( right )) != NULL ) {
fprintf( stderr,
"%s: line %d: regular expression \"%s\" bad: %s\n",
fname, lineno, right, e );
acl_usage();
}
regtest(fname, lineno, right);
b->a_addrpat = strdup( right );
} else {
fprintf( stderr,
@ -198,16 +260,15 @@ parse_acl(
/* if we have no real access clause, complain and do nothing */
if ( a == NULL ) {
fprintf( stderr,
"%s: line %d: warning: no access clause(s) specified in access line\n",
"%s: line %d: warning: no access clause(s) specified in access line\n",
fname, lineno );
} else {
if ( a->acl_access == NULL ) {
fprintf( stderr,
"%s: line %d: warning: no by clause(s) specified in access line\n",
"%s: line %d: warning: no by clause(s) specified in access line\n",
fname, lineno );
}
@ -373,4 +434,4 @@ print_acl( struct acl *a )
}
}
#endif
#endif /* LDAP_DEBUG */

View file

@ -20,21 +20,21 @@ VERSIONFILE = $(LDAPSRC)/build/version
SRCS = idl.c add.c search.c cache.c dbcache.c dn2id.c id2entry.c \
index.c id2children.c nextid.c abandon.c compare.c \
modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
filterindex.c unbind.c kerberos.c close.c
filterindex.c unbind.c kerberos.c close.c group.c
OBJS = idl.o add.o search.o cache.o dbcache.o dn2id.o id2entry.o \
index.o id2children.o nextid.o abandon.o compare.o \
modify.o modrdn.o delete.o init.o config.o bind.o attr.o \
filterindex.o unbind.o kerberos.o close.o
filterindex.o unbind.o kerberos.o close.o group.o
INCLUDES= -I. -I.. -I$(HDIR) $(KRBINCLUDEFLAG)
DEFINES = $(DEFS) $(THREADS)
DEFINES = $(DEFS) $(LDAP_CRYPT) $(THREADS)
CFLAGS = $(INCLUDES) $(THREADSINCLUDE) $(DEFINES) $(ACFLAGS)
LDFLAGS = -L$(LDIR) $(KRBLIBFLAG)
LDFLAGS = -L$(LDIR) $(KRBLIBFLAG) $(LDAP_CRYPT_LIB)
all: FORCE
-@echo "$(SLAPD_BACKENDS)" | grep LDAP_LDBM 2>&1 > /dev/null; \
if [ $$? = 0 ]; then \
$(MAKE) $(MFLAGS) CC=$(CC) libback-ldbm.a; \
$(MAKE) $(MFLAGS) CC="$(CC)" libback-ldbm.a; \
else \
echo "Include -DLDAP_LDBM in SLAPD_BACKENDS in the"; \
echo "Make-common file to build the ldbm backend"; \
@ -69,80 +69,4 @@ depend: FORCE
links:
@$(LN) .src/*.[ch] .
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
idl.o: idl.c ../slap.h ../../../include/avl.h ../../../include/lber.h
idl.o: ../../../include/ldap.h ../../../include/lthread.h
idl.o: ../../../include/ldif.h ../../../include/ldapconfig.h back-ldbm.h
idl.o: ../../../include/ldbm.h
add.o: add.c ../slap.h ../../../include/avl.h ../../../include/lber.h
add.o: ../../../include/ldap.h ../../../include/lthread.h
add.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
search.o: search.c ../slap.h ../../../include/avl.h ../../../include/lber.h
search.o: ../../../include/ldap.h ../../../include/lthread.h
search.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
cache.o: cache.c ../slap.h ../../../include/avl.h ../../../include/lber.h
cache.o: ../../../include/ldap.h ../../../include/lthread.h
cache.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
dbcache.o: dbcache.c ../../../include/portable.h ../slap.h
dbcache.o: ../../../include/avl.h ../../../include/lber.h
dbcache.o: ../../../include/ldap.h ../../../include/lthread.h
dbcache.o: ../../../include/ldif.h ../../../include/ldapconfig.h back-ldbm.h
dbcache.o: ../../../include/ldbm.h
dn2id.o: dn2id.c ../slap.h ../../../include/avl.h ../../../include/lber.h
dn2id.o: ../../../include/ldap.h ../../../include/lthread.h
dn2id.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
id2entry.o: id2entry.c ../slap.h ../../../include/avl.h ../../../include/lber.h
id2entry.o: ../../../include/ldap.h ../../../include/lthread.h
id2entry.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
index.o: index.c ../slap.h ../../../include/avl.h ../../../include/lber.h
index.o: ../../../include/ldap.h ../../../include/lthread.h
index.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
id2children.o: id2children.c ../slap.h ../../../include/avl.h
id2children.o: ../../../include/lber.h ../../../include/ldap.h
id2children.o: ../../../include/lthread.h ../../../include/ldif.h back-ldbm.h
id2children.o: ../../../include/ldbm.h
nextid.o: nextid.c ../slap.h ../../../include/avl.h ../../../include/lber.h
nextid.o: ../../../include/ldap.h ../../../include/lthread.h
nextid.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
abandon.o: abandon.c
compare.o: compare.c ../slap.h ../../../include/avl.h ../../../include/lber.h
compare.o: ../../../include/ldap.h ../../../include/lthread.h
compare.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
modify.o: modify.c ../slap.h ../../../include/avl.h ../../../include/lber.h
modify.o: ../../../include/ldap.h ../../../include/lthread.h
modify.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
modrdn.o: modrdn.c ../slap.h ../../../include/avl.h ../../../include/lber.h
modrdn.o: ../../../include/ldap.h ../../../include/lthread.h
modrdn.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
delete.o: delete.c ../slap.h ../../../include/avl.h ../../../include/lber.h
delete.o: ../../../include/ldap.h ../../../include/lthread.h
delete.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
init.o: init.c ../slap.h ../../../include/avl.h ../../../include/lber.h
init.o: ../../../include/ldap.h ../../../include/lthread.h
init.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
config.o: config.c ../slap.h ../../../include/avl.h ../../../include/lber.h
config.o: ../../../include/ldap.h ../../../include/lthread.h
config.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
bind.o: bind.c ../slap.h ../../../include/avl.h ../../../include/lber.h
bind.o: ../../../include/ldap.h ../../../include/lthread.h
bind.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
attr.o: attr.c ../slap.h ../../../include/avl.h ../../../include/lber.h
attr.o: ../../../include/ldap.h ../../../include/lthread.h
attr.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
filterindex.o: filterindex.c ../slap.h ../../../include/avl.h
filterindex.o: ../../../include/lber.h ../../../include/ldap.h
filterindex.o: ../../../include/lthread.h ../../../include/ldif.h back-ldbm.h
filterindex.o: ../../../include/ldbm.h
unbind.o: unbind.c ../slap.h ../../../include/avl.h ../../../include/lber.h
unbind.o: ../../../include/ldap.h ../../../include/lthread.h
unbind.o: ../../../include/ldif.h
kerberos.o: kerberos.c ../slap.h ../../../include/avl.h ../../../include/lber.h
kerberos.o: ../../../include/ldap.h ../../../include/lthread.h
kerberos.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
close.o: close.c ../slap.h ../../../include/avl.h ../../../include/lber.h
close.o: ../../../include/ldap.h ../../../include/lthread.h
close.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY

View file

@ -0,0 +1,90 @@
/* compare.c - ldbm backend compare routine */
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "slap.h"
#include "back-ldbm.h"
extern Entry *dn2entry();
extern Attribute *attr_find();
#ifdef ACLGROUP
/* return 0 IFF edn is a value in uniqueMember attribute
* of entry with bdn AND that entry has an objectClass
* value of groupOfUniqueNames
*/
int
ldbm_back_group(
Backend *be,
char *bdn,
char *edn
)
{
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
Entry *e;
char *matched;
Attribute *objectClass;
Attribute *uniqueMember;
int rc;
Debug( LDAP_DEBUG_TRACE, "ldbm_back_group: bdn: %s\n", bdn, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "ldbm_back_group: edn: %s\n", edn, 0, 0 );
/* can we find bdn entry */
if ((e = dn2entry(be, bdn, &matched )) == NULL) {
Debug( LDAP_DEBUG_TRACE, "ldbm_back_group: cannot find bdn: %s matched: %x\n", bdn, matched, 0 );
if (matched != NULL)
free(matched);
return( 1 );
}
Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: found bdn: %s matched: %x\n", bdn, matched, 0 );
/* find it's objectClass and uniqueMember attribute values
* make sure this is a group entry
* finally test if we can find edn in the uniqueMember attribute value list *
*/
rc = 1;
if ((objectClass = attr_find(e->e_attrs, "objectclass")) == NULL) {
Debug( LDAP_DEBUG_TRACE, "ldbm_back_group: failed to find objectClass\n", 0, 0, 0 );
}
else if ((uniqueMember = attr_find(e->e_attrs, "uniquemember")) == NULL) {
Debug( LDAP_DEBUG_TRACE, "ldbm_back_group: failed to find uniqueMember\n", 0, 0, 0 );
}
else {
struct berval bvObjectClass;
struct berval bvUniqueMembers;
Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: found objectClass and uniqueMembers\n", 0, 0, 0 );
bvObjectClass.bv_val = "groupofuniquenames";
bvObjectClass.bv_len = strlen( bvObjectClass.bv_val );
bvUniqueMembers.bv_val = edn;
bvUniqueMembers.bv_len = strlen( edn );
if (value_find(objectClass->a_vals, &bvObjectClass, SYNTAX_CIS, 1) != 0) {
Debug( LDAP_DEBUG_TRACE, "ldbm_back_group: failed to find objectClass in groupOfUniqueNames\n",
0, 0, 0 );
}
else if (value_find(uniqueMember->a_vals, &bvUniqueMembers, SYNTAX_CIS, 1) != 0) {
Debug( LDAP_DEBUG_ACL, "ldbm_back_group: %s not in %s: groupOfUniqueNames\n",
edn, bdn, 0 );
}
else {
Debug( LDAP_DEBUG_ACL, "ldbm_back_group: %s is in %s: groupOfUniqueNames\n",
edn, bdn, 0 );
rc = 0;
}
}
/* free e */
cache_return_entry( &li->li_cache, e );
Debug( LDAP_DEBUG_ARGS, "ldbm_back_group: rc: %d\n", rc, 0, 0 );
return(rc);
}
#endif

View file

@ -2,7 +2,6 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "slap.h"
#include "ldapconfig.h"
#include "back-ldbm.h"
@ -164,15 +163,18 @@ idl_store(
IDList *idl
)
{
int rc;
int rc, flags;
Datum data;
struct ldbminfo *li = (struct ldbminfo *) be->be_private;
/* Debug( LDAP_DEBUG_TRACE, "=> idl_store\n", 0, 0, 0 ); */
data.dptr = (char *) idl;
data.dsize = (2 + idl->b_nmax) * sizeof(ID);
rc = ldbm_cache_store( db, key, data, LDBM_REPLACE );
flags = LDBM_REPLACE;
if( li->li_flush_wrt ) flags |= LDBM_SYNC;
rc = ldbm_cache_store( db, key, data, flags );
/* Debug( LDAP_DEBUG_TRACE, "<= idl_store %d\n", rc, 0, 0 ); */
return( rc );
@ -726,12 +728,9 @@ idl_notin(
if ( a == NULL ) {
return( NULL );
}
if ( b == NULL ) {
if ( b == NULL || ALLIDS( b )) {
return( idl_dup( a ) );
}
if ( ALLIDS( b ) ) {
return( NULL );
}
if ( ALLIDS( a ) ) {
n = idl_alloc( SLAPD_LDBM_MIN_MAXIDS );

View file

@ -21,6 +21,7 @@ extern int ldbm_back_abandon();
extern int ldbm_back_config();
extern int ldbm_back_init();
extern int ldbm_back_close();
extern int ldbm_back_group();
#endif
#ifdef LDAP_PASSWD
@ -86,6 +87,9 @@ new_backend(
be->be_config = ldbm_back_config;
be->be_init = ldbm_back_init;
be->be_close = ldbm_back_close;
#ifdef ACLGROUP
be->be_group = ldbm_back_group;
#endif
be->be_type = "ldbm";
foundit = 1;
}
@ -105,6 +109,9 @@ new_backend(
be->be_config = passwd_back_config;
be->be_init = NULL;
be->be_close = NULL;
#ifdef ACLGROUP
be->be_group = NULL;
#endif
be->be_type = "passwd";
foundit = 1;
}
@ -124,6 +131,9 @@ new_backend(
be->be_config = shell_back_config;
be->be_init = shell_back_init;
be->be_close = NULL;
#ifdef ACLGROUP
be->be_group = NULL;
#endif
be->be_type = "shell";
foundit = 1;
}
@ -231,3 +241,14 @@ be_unbind(
}
}
}
#ifdef ACLGROUP
int
be_group(Backend *be, char *bdn, char *edn)
{
if (be->be_group)
return(be->be_group(be, bdn, edn));
else
return(1);
}
#endif

View file

@ -4,22 +4,13 @@
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef sunos5
#include "regexpr.h"
#else
#include "regex.h"
#endif
#include <regex.h>
#include "slap.h"
extern Attribute *attr_find();
extern char *first_word();
extern char *next_word();
extern char *phonetic();
extern char *re_comp();
#ifndef sunos5
extern pthread_mutex_t regex_mutex;
#endif
static int test_filter_list();
static int test_substring_filter();
@ -223,11 +214,12 @@ test_approx_filter(
w2 = next_word( w2 ) ) {
c2 = phonetic( w2 );
if ( strcmp( c1, c2 ) == 0 ) {
free( c2 );
break;
}
free( c2 );
}
free( c1 );
free( c2 );
/*
* if we stopped because we ran out of words
@ -322,6 +314,7 @@ test_substring_filter(
char pat[BUFSIZ];
char buf[BUFSIZ];
struct berval *val;
regex_t re;
Debug( LDAP_DEBUG_FILTER, "begin test_substring_filter\n", 0, 0, 0 );
@ -389,19 +382,16 @@ test_substring_filter(
}
/* compile the regex */
#ifdef sunos5
if ( (p = compile( pat, NULL, NULL )) == NULL ) {
Debug( LDAP_DEBUG_ANY, "compile failed (%s)\n", p, 0, 0 );
Debug( LDAP_DEBUG_FILTER, "test_substring_filter: regcomp pat: %s\n",
pat, 0, 0 );
if ((rc = regcomp(&re, pat, 0))) {
char error[512];
regerror(rc, &re, error, sizeof(error));
Debug( LDAP_DEBUG_ANY, "regcomp failed (%s) %s\n",
p, error, 0 );
return( -1 );
}
#else /* sunos5 */
pthread_mutex_lock( &regex_mutex );
if ( (p = re_comp( pat )) != 0 ) {
Debug( LDAP_DEBUG_ANY, "re_comp failed (%s)\n", p, 0, 0 );
pthread_mutex_unlock( &regex_mutex );
return( -1 );
}
#endif /* sunos5 */
/* for each value in the attribute see if regex matches */
for ( i = 0; a->a_vals[i] != NULL; i++ ) {
@ -417,29 +407,18 @@ test_substring_filter(
}
value_normalize( realval, a->a_syntax );
#ifdef sunos5
rc = step( realval, p );
#else /* sunos5 */
rc = re_exec( realval );
#endif /* sunos5 */
rc = !regexec(&re, realval, 0, NULL, 0);
if ( tmp != NULL ) {
free( tmp );
}
if ( rc == 1 ) {
#ifdef sunos5
free( p );
#else /* sunos5 */
pthread_mutex_unlock( &regex_mutex );
#endif /* sunos5 */
regfree(&re);
return( 0 );
}
}
#ifdef sunos5
free( p );
#else /* sunos5 */
pthread_mutex_unlock( &regex_mutex );
#endif /* sunos5 */
regfree(&re);
Debug( LDAP_DEBUG_FILTER, "end test_substring_filter 1\n", 0, 0, 0 );
return( 1 );

View file

@ -18,9 +18,6 @@ extern pthread_mutex_t entry2str_mutex;
extern pthread_mutex_t replog_mutex;
extern pthread_mutex_t ops_mutex;
extern pthread_mutex_t num_sent_mutex;
#ifndef sunos5
extern pthread_mutex_t regex_mutex;
#endif
init()
{
@ -31,7 +28,4 @@ init()
pthread_mutex_init( &replog_mutex, pthread_mutexattr_default );
pthread_mutex_init( &ops_mutex, pthread_mutexattr_default );
pthread_mutex_init( &num_sent_mutex, pthread_mutexattr_default );
#ifndef sunos5
pthread_mutex_init( &regex_mutex, pthread_mutexattr_default );
#endif
}

View file

@ -10,16 +10,17 @@
#include "slap.h"
#include "ldapconfig.h"
extern void daemon();
extern void slapd_daemon();
extern int lber_debug;
extern char Versionstr[];
/*
* read-only global variables or variables only written by the listener
* thread (after they are initialized) - no need to protect them with a mutex.
*/
int ldap_debug;
int ldap_debug = 0;
#ifdef LDAP_DEBUG
int ldap_syslog = LDAP_DEBUG_STATS;
#else
@ -55,15 +56,12 @@ pthread_mutex_t num_sent_mutex;
*/
pthread_mutex_t entry2str_mutex;
pthread_mutex_t replog_mutex;
#ifndef sunos5
pthread_mutex_t regex_mutex;
#endif
static
usage( name )
char *name;
{
fprintf( stderr, "usage: %s [-d debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]\n", name );
fprintf( stderr, "usage: %s [-d ?|debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]\n", name );
}
main( argc, argv )
@ -105,19 +103,19 @@ main( argc, argv )
LDAP_DEBUG_CONFIG );
printf( "\tLDAP_DEBUG_ACL\t\t%d\n",
LDAP_DEBUG_ACL );
printf( "\tLDAP_DEBUG_STATS\t\t%d\n",
printf( "\tLDAP_DEBUG_STATS\t%d\n",
LDAP_DEBUG_STATS );
printf( "\tLDAP_DEBUG_STATS2\t\t%d\n",
printf( "\tLDAP_DEBUG_STATS2\t%d\n",
LDAP_DEBUG_STATS2 );
printf( "\tLDAP_DEBUG_SHELL\t\t%d\n",
printf( "\tLDAP_DEBUG_SHELL\t%d\n",
LDAP_DEBUG_SHELL );
printf( "\tLDAP_DEBUG_PARSE\t\t%d\n",
printf( "\tLDAP_DEBUG_PARSE\t%d\n",
LDAP_DEBUG_PARSE );
printf( "\tLDAP_DEBUG_ANY\t\t%d\n",
LDAP_DEBUG_ANY );
exit( 0 );
} else {
ldap_debug = atoi( optarg );
ldap_debug |= atoi( optarg );
lber_debug = (ldap_debug & LDAP_DEBUG_BER);
}
break;
@ -184,12 +182,27 @@ main( argc, argv )
pthread_attr_init( &attr );
pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_DETACHED );
if ( pthread_create( &listener_tid, attr, (void *) daemon,
#ifndef THREAD_MIT_PTHREADS
/* POSIX_THREADS or compatible
* This is a draft 10 or standard pthreads implementation
*/
if ( pthread_create( &listener_tid, &attr, (void *) slapd_daemon,
(void *) port ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"listener pthread_create failed\n", 0, 0, 0 );
exit( 1 );
}
#else /* !THREAD_MIT_PTHREADS */
/*
* This is a draft 4 or earlier pthreads implementation
*/
if ( pthread_create( &listener_tid, attr, (void *) slapd_daemon,
(void *) port ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"listener pthread_create failed\n", 0, 0, 0 );
exit( 1 );
}
#endif /* !THREAD_MIT_PTHREADS */
pthread_attr_destroy( &attr );
pthread_join( listener_tid, (void *) &status );
pthread_exit( 0 );

View file

@ -7,10 +7,13 @@
int access_allowed( Backend *be, Connection *conn, Operation *op, Entry *e,
char *attr, struct berval *val, char *dn, int access );
struct acl * acl_get_applicable( Backend *be, Operation *op, Entry *e,
char *attr );
char *attr, char *edn, int nmatches, regmatch_t *matches );
int acl_access_allowed( struct acl *a, Backend *be, Connection *conn, Entry *e,
struct berval *val, Operation *op, int access );
struct berval *val, Operation *op, int access, char *edn,
regmatch_t *matches );
int acl_check_mods( Backend *be, Connection *conn, Operation *op, Entry *e,
LDAPMod *mods );

View file

@ -1,909 +0,0 @@
#include "portable.h"
#if defined( MACOS ) || defined( DOS ) || defined( _WIN32 ) || defined( NEED_BSDREGEX )
#include "regex.h"
/*
* regex - Regular expression pattern matching and replacement
*
* By: Ozan S. Yigit (oz)
* Dept. of Computer Science
* York University
*
* These routines are the PUBLIC DOMAIN equivalents of regex
* routines as found in 4.nBSD UN*X, with minor extensions.
*
* These routines are derived from various implementations found
* in software tools books, and Conroy's grep. They are NOT derived
* from licensed/restricted software.
* For more interesting/academic/complicated implementations,
* see Henry Spencer's regexp routines, or GNU Emacs pattern
* matching module.
*
* Modification history:
*
* $Log: regex.c,v $
* Revision 1.2 1996/04/25 16:24:11 mcs
* make re_exec() match "" with ".*" and similar patterns
* hopefully this change doesn't break anything else!
*
* Revision 1.1 1995/02/03 15:56:52 tim
* Initial revision
*
* Revision 1.11 1994/12/14 21:33:45 mcs
* use new NEED_BSDREGEX
* fix pmatch() prototype
*
* Revision 1.10 1994/12/12 18:16:39 mcs
* use on NetBSD
*
* Revision 1.9 1994/11/15 19:16:35 mcs
* add (CHAR) cast to make VisualC++ happy
*
* Revision 1.8 1994/11/08 21:14:32 mcs
* WIN32 changes
*
* Revision 1.7 1994/07/23 19:51:24 mcs
* use ANSI-style inline function parameters
*
* Revision 1.6 1993/10/18 01:52:32 tim
* include for VMS
*
* Revision 1.5 1993/09/28 21:37:54 mcs
* HP/UX needs the regex we include (not in its libc)
*
* Revision 1.4 1993/08/27 15:59:52 mcs
* use CHAR for deftab
*
* Revision 1.3 1993/08/27 15:49:47 mcs
* added missing 0 to octal constants
* use unsigned char for CHAR under DOS
*
* Revision 1.2 1993/08/27 14:57:48 mcs
* add proto. for pmatch
*
* Revision 1.1 1993/08/18 21:20:02 mcs
* Initial revision
*
* Revision 1.4 1991/10/17 03:56:42 oz
* miscellaneous changes, small cleanups etc.
*
* Revision 1.3 1989/04/01 14:18:09 oz
* Change all references to a dfa: this is actually an nfa.
*
* Revision 1.2 88/08/28 15:36:04 oz
* Use a complement bitmap to represent NCL.
* This removes the need to have seperate
* code in the pmatch case block - it is
* just CCL code now.
*
* Use the actual CCL code in the CLO
* section of pmatch. No need for a recursive
* pmatch call.
*
* Use a bitmap table to set char bits in an
* 8-bit chunk.
*
* Interfaces:
* re_comp: compile a regular expression into a NFA.
*
* char *re_comp(s)
* char *s;
*
* re_exec: execute the NFA to match a pattern.
*
* int re_exec(s)
* char *s;
*
* re_modw change re_exec's understanding of what a "word"
* looks like (for \< and \>) by adding into the
* hidden word-syntax table.
*
* void re_modw(s)
* char *s;
*
* re_subs: substitute the matched portions in a new string.
*
* int re_subs(src, dst)
* char *src;
* char *dst;
*
* re_fail: failure routine for re_exec.
*
* void re_fail(msg, op)
* char *msg;
* char op;
*
* Regular Expressions:
*
* [1] char matches itself, unless it is a special
* character (metachar): . \ [ ] * + ^ $
*
* [2] . matches any character.
*
* [3] \ matches the character following it, except
* when followed by a left or right round bracket,
* a digit 1 to 9 or a left or right angle bracket.
* (see [7], [8] and [9])
* It is used as an escape character for all
* other meta-characters, and itself. When used
* in a set ([4]), it is treated as an ordinary
* character.
*
* [4] [set] matches one of the characters in the set.
* If the first character in the set is "^",
* it matches a character NOT in the set, i.e.
* complements the set. A shorthand S-E is
* used to specify a set of characters S upto
* E, inclusive. The special characters "]" and
* "-" have no special meaning if they appear
* as the first chars in the set.
* examples: match:
*
* [a-z] any lowercase alpha
*
* [^]-] any char except ] and -
*
* [^A-Z] any char except uppercase
* alpha
*
* [a-zA-Z] any alpha
*
* [5] * any regular expression form [1] to [4], followed by
* closure char (*) matches zero or more matches of
* that form.
*
* [6] + same as [5], except it matches one or more.
*
* [7] a regular expression in the form [1] to [10], enclosed
* as \(form\) matches what form matches. The enclosure
* creates a set of tags, used for [8] and for
* pattern substution. The tagged forms are numbered
* starting from 1.
*
* [8] a \ followed by a digit 1 to 9 matches whatever a
* previously tagged regular expression ([7]) matched.
*
* [9] \< a regular expression starting with a \< construct
* \> and/or ending with a \> construct, restricts the
* pattern matching to the beginning of a word, and/or
* the end of a word. A word is defined to be a character
* string beginning and/or ending with the characters
* A-Z a-z 0-9 and _. It must also be preceded and/or
* followed by any character outside those mentioned.
*
* [10] a composite regular expression xy where x and y
* are in the form [1] to [10] matches the longest
* match of x followed by a match for y.
*
* [11] ^ a regular expression starting with a ^ character
* $ and/or ending with a $ character, restricts the
* pattern matching to the beginning of the line,
* or the end of line. [anchors] Elsewhere in the
* pattern, ^ and $ are treated as ordinary characters.
*
*
* Acknowledgements:
*
* HCR's Hugh Redelmeier has been most helpful in various
* stages of development. He convinced me to include BOW
* and EOW constructs, originally invented by Rob Pike at
* the University of Toronto.
*
* References:
* Software tools Kernighan & Plauger
* Software tools in Pascal Kernighan & Plauger
* Grep [rsx-11 C dist] David Conroy
* ed - text editor Un*x Programmer's Manual
* Advanced editing on Un*x B. W. Kernighan
* RegExp routines Henry Spencer
*
* Notes:
*
* This implementation uses a bit-set representation for character
* classes for speed and compactness. Each character is represented
* by one bit in a 128-bit block. Thus, CCL always takes a
* constant 16 bytes in the internal nfa, and re_exec does a single
* bit comparison to locate the character in the set.
*
* Examples:
*
* pattern: foo*.*
* compile: CHR f CHR o CLO CHR o END CLO ANY END END
* matches: fo foo fooo foobar fobar foxx ...
*
* pattern: fo[ob]a[rz]
* compile: CHR f CHR o CCL bitset CHR a CCL bitset END
* matches: fobar fooar fobaz fooaz
*
* pattern: foo\\+
* compile: CHR f CHR o CHR o CHR \ CLO CHR \ END END
* matches: foo\ foo\\ foo\\\ ...
*
* pattern: \(foo\)[1-3]\1 (same as foo[1-3]foo)
* compile: BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END
* matches: foo1foo foo2foo foo3foo
*
* pattern: \(fo.*\)-\1
* compile: BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END
* matches: foo-foo fo-fo fob-fob foobar-foobar ...
*/
#define MAXNFA 1024
#define MAXTAG 10
#define OKP 1
#define NOP 0
#define CHR 1
#define ANY 2
#define CCL 3
#define BOL 4
#define EOL 5
#define BOT 6
#define EOT 7
#define BOW 8
#define EOW 9
#define REF 10
#define CLO 11
#define END 0
/*
* The following defines are not meant to be changeable.
* They are for readability only.
*/
#define MAXCHR 128
#define CHRBIT 8
#define BITBLK MAXCHR/CHRBIT
#define BLKIND 0170
#define BITIND 07
#define ASCIIB 0177
#if defined( DOS ) || defined( _WIN32 )
typedef unsigned char CHAR;
#else /* DOS */
typedef /*unsigned*/ char CHAR;
#endif /* DOS */
static int tagstk[MAXTAG]; /* subpat tag stack..*/
static CHAR nfa[MAXNFA]; /* automaton.. */
static int sta = NOP; /* status of lastpat */
static CHAR bittab[BITBLK]; /* bit table for CCL */
/* pre-set bits... */
static CHAR bitarr[] = {1,2,4,8,16,32,64,128};
static void
chset(CHAR c)
{
bittab[((c) & BLKIND) >> 3] |= bitarr[(c) & BITIND];
}
#define badpat(x) (*nfa = END, x)
#define store(x) *mp++ = x
char *
re_comp( char *pat )
{
register char *p; /* pattern pointer */
register CHAR *mp=nfa; /* nfa pointer */
register CHAR *lp; /* saved pointer.. */
register CHAR *sp=nfa; /* another one.. */
register int tagi = 0; /* tag stack index */
register int tagc = 1; /* actual tag count */
register int n;
register CHAR mask; /* xor mask -CCL/NCL */
int c1, c2;
if (!pat || !*pat)
if (sta)
return 0;
else
return badpat("No previous regular expression");
sta = NOP;
for (p = pat; *p; p++) {
lp = mp;
switch(*p) {
case '.': /* match any char.. */
store(ANY);
break;
case '^': /* match beginning.. */
if (p == pat)
store(BOL);
else {
store(CHR);
store(*p);
}
break;
case '$': /* match endofline.. */
if (!*(p+1))
store(EOL);
else {
store(CHR);
store(*p);
}
break;
case '[': /* match char class..*/
store(CCL);
if (*++p == '^') {
mask = 0377;
p++;
}
else
mask = 0;
if (*p == '-') /* real dash */
chset(*p++);
if (*p == ']') /* real brac */
chset(*p++);
while (*p && *p != ']') {
if (*p == '-' && *(p+1) && *(p+1) != ']') {
p++;
c1 = *(p-2) + 1;
c2 = *p++;
while (c1 <= c2)
chset((CHAR)c1++);
}
#ifdef EXTEND
else if (*p == '\\' && *(p+1)) {
p++;
chset(*p++);
}
#endif
else
chset(*p++);
}
if (!*p)
return badpat("Missing ]");
for (n = 0; n < BITBLK; bittab[n++] = (char) 0)
store(mask ^ bittab[n]);
break;
case '*': /* match 0 or more.. */
case '+': /* match 1 or more.. */
if (p == pat)
return badpat("Empty closure");
lp = sp; /* previous opcode */
if (*lp == CLO) /* equivalence.. */
break;
switch(*lp) {
case BOL:
case BOT:
case EOT:
case BOW:
case EOW:
case REF:
return badpat("Illegal closure");
default:
break;
}
if (*p == '+')
for (sp = mp; lp < sp; lp++)
store(*lp);
store(END);
store(END);
sp = mp;
while (--mp > lp)
*mp = mp[-1];
store(CLO);
mp = sp;
break;
case '\\': /* tags, backrefs .. */
switch(*++p) {
case '(':
if (tagc < MAXTAG) {
tagstk[++tagi] = tagc;
store(BOT);
store(tagc++);
}
else
return badpat("Too many \\(\\) pairs");
break;
case ')':
if (*sp == BOT)
return badpat("Null pattern inside \\(\\)");
if (tagi > 0) {
store(EOT);
store(tagstk[tagi--]);
}
else
return badpat("Unmatched \\)");
break;
case '<':
store(BOW);
break;
case '>':
if (*sp == BOW)
return badpat("Null pattern inside \\<\\>");
store(EOW);
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = *p-'0';
if (tagi > 0 && tagstk[tagi] == n)
return badpat("Cyclical reference");
if (tagc > n) {
store(REF);
store(n);
}
else
return badpat("Undetermined reference");
break;
#ifdef EXTEND
case 'b':
store(CHR);
store('\b');
break;
case 'n':
store(CHR);
store('\n');
break;
case 'f':
store(CHR);
store('\f');
break;
case 'r':
store(CHR);
store('\r');
break;
case 't':
store(CHR);
store('\t');
break;
#endif
default:
store(CHR);
store(*p);
}
break;
default : /* an ordinary char */
store(CHR);
store(*p);
break;
}
sp = lp;
}
if (tagi > 0)
return badpat("Unmatched \\(");
store(END);
sta = OKP;
return 0;
}
static char *bol;
char *bopat[MAXTAG];
char *eopat[MAXTAG];
#ifdef NEEDPROTOS
static char *pmatch( char *lp, CHAR *ap );
#else /* NEEDPROTOS */
static char *pmatch();
#endif /* NEEDPROTOS */
/*
* re_exec:
* execute nfa to find a match.
*
* special cases: (nfa[0])
* BOL
* Match only once, starting from the
* beginning.
* CHR
* First locate the character without
* calling pmatch, and if found, call
* pmatch for the remaining string.
* END
* re_comp failed, poor luser did not
* check for it. Fail fast.
*
* If a match is found, bopat[0] and eopat[0] are set
* to the beginning and the end of the matched fragment,
* respectively.
*
*/
int
re_exec( char *lp )
{
register char c;
register char *ep = 0;
register CHAR *ap = nfa;
bol = lp;
bopat[0] = 0;
bopat[1] = 0;
bopat[2] = 0;
bopat[3] = 0;
bopat[4] = 0;
bopat[5] = 0;
bopat[6] = 0;
bopat[7] = 0;
bopat[8] = 0;
bopat[9] = 0;
switch(*ap) {
case BOL: /* anchored: match from BOL only */
ep = pmatch(lp,ap);
break;
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
while (*lp && *lp != c)
lp++;
if (!*lp) /* if EOS, fail, else fall thru. */
return 0;
default: /* regular matching all the way. */
do {
if ((ep = pmatch(lp,ap)))
break;
lp++;
} while (*lp);
break;
case END: /* munged automaton. fail always */
return 0;
}
if (!ep)
return 0;
bopat[0] = lp;
eopat[0] = ep;
return 1;
}
/*
* pmatch: internal routine for the hard part
*
* This code is partly snarfed from an early grep written by
* David Conroy. The backref and tag stuff, and various other
* innovations are by oz.
*
* special case optimizations: (nfa[n], nfa[n+1])
* CLO ANY
* We KNOW .* will match everything upto the
* end of line. Thus, directly go to the end of
* line, without recursive pmatch calls. As in
* the other closure cases, the remaining pattern
* must be matched by moving backwards on the
* string recursively, to find a match for xy
* (x is ".*" and y is the remaining pattern)
* where the match satisfies the LONGEST match for
* x followed by a match for y.
* CLO CHR
* We can again scan the string forward for the
* single char and at the point of failure, we
* execute the remaining nfa recursively, same as
* above.
*
* At the end of a successful match, bopat[n] and eopat[n]
* are set to the beginning and end of subpatterns matched
* by tagged expressions (n = 1 to 9).
*
*/
#ifndef re_fail
extern void re_fail();
#endif /* re_fail */
/*
* character classification table for word boundary operators BOW
* and EOW. the reason for not using ctype macros is that we can
* let the user add into our own table. see re_modw. This table
* is not in the bitset form, since we may wish to extend it in the
* future for other character classifications.
*
* TRUE for 0-9 A-Z a-z _
*/
static char chrtyp[MAXCHR] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0
};
#define inascii(x) (0177&(x))
#define iswordc(x) chrtyp[inascii(x)]
#define isinset(x,y) ((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND])
/*
* skip values for CLO XXX to skip past the closure
*/
#define ANYSKIP 2 /* [CLO] ANY END ... */
#define CHRSKIP 3 /* [CLO] CHR chr END ... */
#define CCLSKIP 18 /* [CLO] CCL 16bytes END ... */
static char *
pmatch( char *lp, CHAR *ap)
{
register int op, c, n;
register char *e; /* extra pointer for CLO */
register char *bp; /* beginning of subpat.. */
register char *ep; /* ending of subpat.. */
char *are; /* to save the line ptr. */
while ((op = *ap++) != END)
switch(op) {
case CHR:
if (*lp++ != *ap++)
return 0;
break;
case ANY:
if (!*lp++)
return 0;
break;
case CCL:
c = *lp++;
if (!isinset(ap,c))
return 0;
ap += BITBLK;
break;
case BOL:
if (lp != bol)
return 0;
break;
case EOL:
if (*lp)
return 0;
break;
case BOT:
bopat[*ap++] = lp;
break;
case EOT:
eopat[*ap++] = lp;
break;
case BOW:
if (lp!=bol && iswordc(lp[-1]) || !iswordc(*lp))
return 0;
break;
case EOW:
if (lp==bol || !iswordc(lp[-1]) || iswordc(*lp))
return 0;
break;
case REF:
n = *ap++;
bp = bopat[n];
ep = eopat[n];
while (bp < ep)
if (*bp++ != *lp++)
return 0;
break;
case CLO:
are = lp;
switch(*ap) {
case ANY:
while (*lp)
lp++;
n = ANYSKIP;
break;
case CHR:
c = *(ap+1);
while (*lp && c == *lp)
lp++;
n = CHRSKIP;
break;
case CCL:
while ((c = *lp) && isinset(ap+1,c))
lp++;
n = CCLSKIP;
break;
default:
re_fail("closure: bad nfa.", *ap);
return 0;
}
ap += n;
while (lp >= are) {
if (e = pmatch(lp, ap))
return e;
--lp;
}
return 0;
default:
re_fail("re_exec: bad nfa.", op);
return 0;
}
return lp;
}
/*
* re_modw:
* add new characters into the word table to change re_exec's
* understanding of what a word should look like. Note that we
* only accept additions into the word definition.
*
* If the string parameter is 0 or null string, the table is
* reset back to the default containing A-Z a-z 0-9 _. [We use
* the compact bitset representation for the default table]
*/
static CHAR deftab[16] = {
0, 0, 0, 0, 0, 0, 0377, 003, 0376, 0377, 0377, 0207,
0376, 0377, 0377, 007
};
void
re_modw( char *s )
{
register int i;
if (!s || !*s) {
for (i = 0; i < MAXCHR; i++)
if (!isinset(deftab,i))
iswordc(i) = 0;
}
else
while(*s)
iswordc(*s++) = 1;
}
/*
* re_subs:
* substitute the matched portions of the src in dst.
*
* & substitute the entire matched pattern.
*
* \digit substitute a subpattern, with the given tag number.
* Tags are numbered from 1 to 9. If the particular
* tagged subpattern does not exist, null is substituted.
*/
int
re_subs( char *src, char *dst)
{
register char c;
register int pin;
register char *bp;
register char *ep;
if (!*src || !bopat[0])
return 0;
while (c = *src++) {
switch(c) {
case '&':
pin = 0;
break;
case '\\':
c = *src++;
if (c >= '0' && c <= '9') {
pin = c - '0';
break;
}
default:
*dst++ = c;
continue;
}
if ((bp = bopat[pin]) && (ep = eopat[pin])) {
while (*bp && bp < ep)
*dst++ = *bp++;
if (bp < ep)
return 0;
}
}
*dst = (char) 0;
return 1;
}
#ifdef DEBUG
/*
* symbolic - produce a symbolic dump of the nfa
*/
symbolic( char *s )
{
printf("pattern: %s\n", s);
printf("nfacode:\n");
nfadump(nfa);
}
static
nfadump( CHAR *ap)
{
register int n;
while (*ap != END)
switch(*ap++) {
case CLO:
printf("CLOSURE");
nfadump(ap);
switch(*ap) {
case CHR:
n = CHRSKIP;
break;
case ANY:
n = ANYSKIP;
break;
case CCL:
n = CCLSKIP;
break;
}
ap += n;
break;
case CHR:
printf("\tCHR %c\n",*ap++);
break;
case ANY:
printf("\tANY .\n");
break;
case BOL:
printf("\tBOL -\n");
break;
case EOL:
printf("\tEOL -\n");
break;
case BOT:
printf("BOT: %d\n",*ap++);
break;
case EOT:
printf("EOT: %d\n",*ap++);
break;
case BOW:
printf("BOW\n");
break;
case EOW:
printf("EOW\n");
break;
case REF:
printf("REF: %d\n",*ap++);
break;
case CCL:
printf("\tCCL [");
for (n = 0; n < MAXCHR; n++)
if (isinset(ap,(CHAR)n)) {
if (n < ' ')
printf("^%c", n ^ 0x040);
else
printf("%c", n);
}
printf("]\n");
ap += BITBLK;
break;
default:
printf("bad nfa. opcode %o\n", ap[-1]);
exit(1);
break;
}
}
#endif
#endif /* MACOS or DOS or NEED_BSDREGEX */

View file

@ -121,7 +121,13 @@ send_ldap_result2(
pthread_mutex_lock( &active_threads_mutex );
active_threads--;
conn->c_writewaiter = 1;
#ifdef linux
pthread_kill( listener_tid, SIGSTKFLT );
#else /* !linux */
pthread_kill( listener_tid, SIGUSR1 );
#endif /* !linux */
pthread_cond_wait( &conn->c_wcv, &active_threads_mutex );
pthread_mutex_unlock( &active_threads_mutex );
@ -192,6 +198,7 @@ send_search_entry(
Attribute *a;
int i, rc, bytes, sd;
struct acl *acl;
char *edn;
Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 );
@ -202,15 +209,19 @@ send_search_entry(
return( 1 );
}
edn = dn_normalize_case( strdup( e->e_dn ) );
#ifdef COMPAT30
if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER ))
== NULLBER ) {
== NULLBER )
#else
if ( (ber = der_alloc()) == NULLBER ) {
if ( (ber = der_alloc()) == NULLBER )
#endif
{
Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL,
"ber_alloc" );
"ber_alloc" );
free(edn);
return( 1 );
}
@ -220,26 +231,44 @@ send_search_entry(
LDAP_RES_SEARCH_ENTRY, e->e_dn );
} else
#endif
{
rc = ber_printf( ber, "{it{s{", op->o_msgid,
LDAP_RES_SEARCH_ENTRY, e->e_dn );
LDAP_RES_SEARCH_ENTRY, e->e_dn );
}
if ( rc == -1 ) {
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL,
"ber_printf dn" );
free(edn);
return( 1 );
}
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
regmatch_t matches[MAXREMATCHES];
if ( attrs != NULL && ! charray_inlist( attrs, a->a_type ) ) {
continue;
}
acl = acl_get_applicable( be, op, e, a->a_type );
/* the lastmod attributes are ignored by ACL checking */
if ( strcasecmp( a->a_type, "modifiersname" ) == 0 ||
strcasecmp( a->a_type, "modifytimestamp" ) == 0 ||
strcasecmp( a->a_type, "creatorsname" ) == 0 ||
strcasecmp( a->a_type, "createtimestamp" ) == 0 )
{
Debug( LDAP_DEBUG_ACL, "LASTMOD attribute: %s access DEFAULT\n",
a->a_type, 0, 0 );
acl = NULL;
} else {
acl = acl_get_applicable( be, op, e, a->a_type, edn,
MAXREMATCHES, matches );
}
if ( ! acl_access_allowed( acl, be, conn, e, NULL, op,
ACL_READ ) ) {
if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, ACL_READ,
edn, matches ) )
{
continue;
}
@ -248,14 +277,15 @@ send_search_entry(
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "ber_printf type" );
free(edn);
return( 1 );
}
if ( ! attrsonly ) {
for ( i = 0; a->a_vals[i] != NULL; i++ ) {
if ( a->a_syntax & SYNTAX_DN &&
! acl_access_allowed( acl, be, conn, e,
a->a_vals[i], op, ACL_READ ) )
if ( a->a_syntax & SYNTAX_DN &&
! acl_access_allowed( acl, be, conn, e, a->a_vals[i], op,
ACL_READ, edn, matches) )
{
continue;
}
@ -270,6 +300,7 @@ send_search_entry(
send_ldap_result( conn, op,
LDAP_OPERATIONS_ERROR, NULL,
"ber_printf value" );
free(edn);
return( 1 );
}
}
@ -280,10 +311,13 @@ send_search_entry(
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "ber_printf type end" );
free(edn);
return( 1 );
}
}
free(edn);
#ifdef COMPAT30
if ( conn->c_version == 30 ) {
rc = ber_printf( ber, "}}}}" );

View file

@ -6,6 +6,9 @@
#define LDAP_SYSLOG
#include <syslog.h>
#include <sys/types.h>
#include <regex.h>
#include "avl.h"
#include "lber.h"
#include "ldap.h"
@ -17,6 +20,9 @@
#define ON 1
#define OFF (-1)
#define UNDEFINED 0
#define MAXREMATCHES 10
/*
* represents an attribute value assertion (i.e., attr=value)
@ -121,6 +127,11 @@ struct access {
char *a_domainpat;
char *a_dnattr;
long a_access;
#ifdef ACLGROUP
char *a_group;
#endif
#define ACL_NONE 0x01
#define ACL_COMPARE 0x02
#define ACL_SEARCH 0x04
@ -134,6 +145,7 @@ struct access {
struct acl {
/* "to" part: the entries this acl applies to */
Filter *acl_filter;
regex_t acl_dnre;
char *acl_dnpat;
char **acl_attrs;
@ -187,6 +199,10 @@ typedef struct backend {
IFP be_config; /* backend config routine */
IFP be_init; /* backend init routine */
IFP be_close; /* backend close routine */
#ifdef ACLGROUP
IFP be_group; /* backend group member test */
#endif
} Backend;
/*

View file

@ -24,15 +24,15 @@ OBJS2 = ../config.o ../ch_malloc.o ../backend.o ../charray.o \
../aclparse.o ../schema.o ../result.o ../filterentry.o \
../acl.o ../phonetic.o ../attr.o ../value.o ../entry.o \
../dn.o ../filter.o ../str2filter.o ../ava.o ../init.o \
../schemaparse.o ../regex.o ../strdup.o
../schemaparse.o ../strdup.o
INCLUDES= -I. -I$(HDIR) $(EXINCLUDES)
DEFINES = $(DEFS) $(SERVERDEFS) $(THREADS)
DEFINES = $(DEFS) $(LDAP_CRYPT) $(SERVERDEFS) $(THREADS)
CFLAGS = $(INCLUDES) $(DEFINES) $(ACFLAGS)
LDFLAGS = -L$(LDIR) $(EXLDFLAGS)
LIBS = -lldif -lldap -llber -lldbm -lavl $(LDBMLIB) $(EXLIBS) $(ALIBS)
LIBS2 = -lldif -lldbm -lavl $(LDBMLIB) -llber $(KRBLIBFLAG) $(KRBLIBS) \
-llthread $(THREADSLIB) $(ALIBS)
-llthread $(THREADSLIB) $(ALIBS) $(LDAP_CRYPT_LIB)
all: build-edb2ldif ldif2index ldif2ldbm ldbmcat ldif2id2entry \
ldif2id2children centipede ldbmtest ldif
@ -73,13 +73,10 @@ ldif2index: ldif2index.o ../libbackends.a $(OBJS2)
$(CC) $(ALDFLAGS) -o $@ ldif2index.o $(OBJS2) \
../libbackends.a $(LDFLAGS) $(LIBS2)
ldif2ldbm: ldif2ldbm.sed.o ../libbackends.a $(OBJS2)
$(CC) $(ALDFLAGS) -o $@ ldif2ldbm.sed.o $(OBJS2) \
ldif2ldbm: ldif2ldbm.o ../libbackends.a $(OBJS2)
$(CC) $(ALDFLAGS) -o $@ ldif2ldbm.o $(OBJS2) \
../libbackends.a $(LDFLAGS) $(LIBS2)
ldif2ldbm.sed.c: ldif2ldbm.c
$(SED) -e 's;%ETCDIR%;$(RUNTIMEETCDIR);' ldif2ldbm.c > ldif2ldbm.sed.c
ldif2id2entry: ldif2id2entry.o ../libbackends.a $(OBJS2)
$(CC) $(ALDFLAGS) -o $@ ldif2id2entry.o $(OBJS2) \
../libbackends.a $(LDFLAGS) $(LIBS2)
@ -106,49 +103,49 @@ ldbmtest: ldbmtest.o ../libbackends.a $(OBJS2)
$(CC) $(ALDFLAGS) -o ldbmtest ldbmtest.o $(OBJS2) \
../libbackends.a $(LDFLAGS) $(LIBS2)
install: $(ETCDIR) $(ETCDIR)/edb2ldif $(ETCDIR)/ldif2ldbm \
$(ETCDIR)/ldif2index $(ETCDIR)/ldif2id2entry \
$(ETCDIR)/ldif2id2children $(ETCDIR)/ldbmcat \
$(ETCDIR)/centipede $(ETCDIR)/ldbmtest \
$(ETCDIR)/ldif
install: $(LDAP_SBINDIR) $(LDAP_SBINDIR)/edb2ldif $(LDAP_SBINDIR)/ldif2ldbm \
$(LDAP_SBINDIR)/ldif2index $(LDAP_SBINDIR)/ldif2id2entry \
$(LDAP_SBINDIR)/ldif2id2children $(LDAP_SBINDIR)/ldbmcat \
$(LDAP_SBINDIR)/centipede $(LDAP_SBINDIR)/ldbmtest \
$(LDAP_SBINDIR)/ldif
$(ETCDIR)/edb2ldif: build-edb2ldif
$(LDAP_SBINDIR)/edb2ldif: build-edb2ldif
@if [ "$(HAVEISODE)" = "yes" ]; then \
$(INSTALL) $(INSTALLFLAGS) -m 755 edb2ldif $(ETCDIR); \
$(INSTALL) $(INSTALLFLAGS) -m 755 edb2ldif $(LDAP_SBINDIR); \
else \
exit 0; \
fi
$(ETCDIR)/chlog2replog: build-chlog2replog
$(LDAP_SBINDIR)/chlog2replog: build-chlog2replog
@if [ "$(HAVEISODE)" = "yes" ]; then \
$(INSTALL) $(INSTALLFLAGS) -m 755 chlog2replog $(ETCDIR); \
$(INSTALL) $(INSTALLFLAGS) -m 755 chlog2replog $(LDAP_SBINDIR); \
else \
exit 0; \
fi
$(ETCDIR)/ldif2ldbm: ldif2ldbm
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2ldbm $(ETCDIR)
$(LDAP_SBINDIR)/ldif2ldbm: ldif2ldbm
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2ldbm $(LDAP_SBINDIR)
$(ETCDIR)/ldif2index: ldif2index
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2index $(ETCDIR)
$(LDAP_SBINDIR)/ldif2index: ldif2index
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2index $(LDAP_SBINDIR)
$(ETCDIR)/ldif2id2entry: ldif2id2entry
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2id2entry $(ETCDIR)
$(LDAP_SBINDIR)/ldif2id2entry: ldif2id2entry
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2id2entry $(LDAP_SBINDIR)
$(ETCDIR)/ldif2id2children: ldif2id2children
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2id2children $(ETCDIR)
$(LDAP_SBINDIR)/ldif2id2children: ldif2id2children
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif2id2children $(LDAP_SBINDIR)
$(ETCDIR)/ldbmcat: ldbmcat
$(INSTALL) $(INSTALLFLAGS) -m 755 ldbmcat $(ETCDIR)
$(LDAP_SBINDIR)/ldbmcat: ldbmcat
$(INSTALL) $(INSTALLFLAGS) -m 755 ldbmcat $(LDAP_SBINDIR)
$(ETCDIR)/ldif: ldif
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif $(ETCDIR)
$(LDAP_SBINDIR)/ldif: ldif
$(INSTALL) $(INSTALLFLAGS) -m 755 ldif $(LDAP_SBINDIR)
$(ETCDIR)/centipede: centipede
$(INSTALL) $(INSTALLFLAGS) -m 755 centipede $(ETCDIR)
$(LDAP_SBINDIR)/centipede: centipede
$(INSTALL) $(INSTALLFLAGS) -m 755 centipede $(LDAP_SBINDIR)
$(ETCDIR)/ldbmtest: ldbmtest
$(INSTALL) $(INSTALLFLAGS) -m 755 ldbmtest $(ETCDIR)
$(LDAP_SBINDIR)/ldbmtest: ldbmtest
$(INSTALL) $(INSTALLFLAGS) -m 755 ldbmtest $(LDAP_SBINDIR)
lint: FORCE
$(LINT) $(INCLUDES) $(DEFINES) $(SRCS)
@ -160,60 +157,17 @@ clean: FORCE
@echo "making clean in `$(PWD)`"
$(RM) edb2ldif ldif2index *.o core a.out edb2-vers.c \
ldif2ldbm ldif2id2entry ldif2id2children ldbmcat ldif \
centipede chlog2replog sizecount ldif2ldbm.sed.c ldbmtest
centipede chlog2replog sizecount ldbmtest
depend: ldif2ldbm.sed.c FORCE
depend: FORCE
@if [ ! -z "$(HAVEISODE)" ]; then \
DEPENDEXTRAS="$(ISODEINCLUDEFLAG) chlog2replog.c $(EDB2LDIFSRCS)"; \
fi; \
$(MKDEP) $(INCLUDES) $(DEFINES) $$DEPENDEXTRAS ldif2index.c \
ldif2ldbm.c ldif2id2entry.c ldif2id2children.c ldbmcat.c \
centipede.c sizecount.c ldif2ldbm.sed.c ldbmtest.c ldif.c
centipede.c sizecount.c ldbmtest.c ldif.c
links:
@echo "making links in `$(PWD)`"
@$(LN) .src/*.[ch] .
# DO NOT DELETE THIS LINE -- mkdep uses it.
# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
chlog2replog.o: chlog2replog.c ../../../include/ldif.h
edb2ldif.o: edb2ldif.c
ldapsyntax.o: ldapsyntax.c ../../../include/lber.h ../../../include/ldap.h
ldapsyntax.o: ../../../include/ldif.h ldapsyntax.h
ldif2index.o: ldif2index.c ../slap.h ../../../include/avl.h
ldif2index.o: ../../../include/lber.h ../../../include/ldap.h
ldif2index.o: ../../../include/lthread.h ../../../include/ldif.h
ldif2ldbm.o: ldif2ldbm.c ../slap.h ../../../include/avl.h
ldif2ldbm.o: ../../../include/lber.h ../../../include/ldap.h
ldif2ldbm.o: ../../../include/lthread.h ../../../include/ldif.h
ldif2ldbm.o: ../back-ldbm/back-ldbm.h ../../../include/ldbm.h
ldif2id2entry.o: ldif2id2entry.c ../slap.h ../../../include/avl.h
ldif2id2entry.o: ../../../include/lber.h ../../../include/ldap.h
ldif2id2entry.o: ../../../include/lthread.h ../../../include/ldif.h
ldif2id2entry.o: ../back-ldbm/back-ldbm.h ../../../include/ldbm.h
ldif2id2children.o: ldif2id2children.c ../slap.h ../../../include/avl.h
ldif2id2children.o: ../../../include/lber.h ../../../include/ldap.h
ldif2id2children.o: ../../../include/lthread.h ../../../include/ldif.h
ldif2id2children.o: ../back-ldbm/back-ldbm.h ../../../include/ldbm.h
ldbmcat.o: ldbmcat.c ../../../include/ldbm.h ../slap.h ../../../include/avl.h
ldbmcat.o: ../../../include/lber.h ../../../include/ldap.h
ldbmcat.o: ../../../include/lthread.h ../../../include/ldif.h
centipede.o: centipede.c ../../../include/lber.h ../../../include/ldap.h
centipede.o: ../../../include/ldapconfig.h ../../../include/ldbm.h
sizecount.o: sizecount.c ../../../include/ldbm.h ../../../include/lber.h
sizecount.o: ../../../include/ldap.h ../../../include/portable.h
ldif2ldbm.sed.o: ldif2ldbm.sed.c ../slap.h ../../../include/avl.h
ldif2ldbm.sed.o: ../../../include/lber.h ../../../include/ldap.h
ldif2ldbm.sed.o: ../../../include/lthread.h ../../../include/ldif.h
ldif2ldbm.sed.o: ../back-ldbm/back-ldbm.h ../../../include/ldbm.h
ldbmtest.o: ldbmtest.c ../../../include/portable.h
ldbmtest.o: ../../../include/ldapconfig.h ../slap.h ../../../include/avl.h
ldbmtest.o: ../../../include/lber.h ../../../include/ldap.h
ldbmtest.o: ../../../include/lthread.h ../../../include/ldif.h
ldbmtest.o: ../back-ldbm/back-ldbm.h ../../../include/ldbm.h
ldif.o: ldif.c ../../../include/lber.h ../../../include/ldap.h
ldif.o: ../../../include/ldif.h
# IF YOU PUT ANYTHING HERE IT WILL GO AWAY

View file

@ -21,8 +21,6 @@ multilinedescription: Outstanding
title: Mad Cow Researcher, UM Alumni Association
pager: +1 313 555 3923
mail: jaj@mail.alumni.umich.edu
modifytimestamp: 960404171231Z
modifiersname: cn=Manager,o=University of Michigan,c=US
facsimiletelephonenumber: +1 313 555 4332
telephonenumber: +1 313 555 0895
dn: cn=All Staff,ou=Groups,o=University of Michigan,c=US
@ -180,7 +178,6 @@ member: cn=John Doe, ou=Information Technology Division, ou=People, o=Universi
member: cn=James A Jones 1, ou=Alumni Association, ou=People, o=University of
Michigan, c=US
labeledurl: http://www.itd.umich.edu ITD Home Page
University of Michigan,c=US
telephonenumber: +1 810 555 1212
dn: cn=James A Jones 2, ou=Information Technology Division, ou=People, o=Unive

2
tests/scripts/acfilter.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
egrep -iv '^modifiersname:|^modifytimestamp:|^creatorsname:|^createtimestamp'

View file

@ -5,10 +5,10 @@
echo "Cleaning up in $DBDIR..."
rm -f $DBDIR/*
rm -f $DBDIR/[^C]*
echo "Starting slapd on TCP/IP port $PORT..."
$SLAPD -f $CONF -p $PORT -d 1 > /dev/null 2>&1 &
$SLAPD -f $CONF -p $PORT -d 1 > $MASTERLOG 2>&1 &
PID=$!
echo "Using ldapsearch to check that slapd is running..."
@ -44,8 +44,13 @@ if [ $RC != 0 ]; then
exit $RC
fi
echo "Comparing retrieved entries to LDIF file used to create database"
cmp $SEARCHOUT $LDIF
echo "Filtering ldapsearch results..."
. scripts/acfilter.sh < $SEARCHOUT > $SEARCHFLT
echo "Filtering original ldif used to create database..."
. scripts/acfilter.sh < $LDIF > $LDIFFLT
echo "Comparing filter output..."
cmp $SEARCHFLT $LDIFFLT
if [ $? != 0 ]; then
echo "comparison failed - database was not created correctly"
exit 1

View file

@ -4,7 +4,7 @@
echo "Cleaning up in $DBDIR..."
rm -f $DBDIR/*
rm -f $DBDIR/[^C]*
echo "Running ldif2ldbm to build slapd database..."
$LDIF2LDBM -f $CONF -i $LDIF -e ../servers/slapd/tools
@ -15,7 +15,7 @@ if [ $RC != 0 ]; then
fi
echo "Starting slapd on TCP/IP port $PORT..."
$SLAPD -f $ACLCONF -p $PORT -d 1 > /dev/null 2>&1 &
$SLAPD -f $ACLCONF -p $PORT -d 1 > $MASTERLOG 2>&1 &
PID=$!
echo "Testing slapd access control..."
@ -96,8 +96,7 @@ EOMODS4
echo "Using ldapsearch to retrieve all the entries..."
$LDAPSEARCH -L -S "" -b "$BASEDN" -h localhost -p $PORT \
'objectClass=*' | egrep -iv '^modifytimestamp|^modifiersname' \
>> $SEARCHOUT 2>&1
'objectClass=*' | . scripts/acfilter.sh >> $SEARCHOUT 2>&1
RC=$?
kill -HUP $PID
if [ $RC != 0 ]; then