adds POSIX RegEx (and removes BSD re_comp/re_exec) support.
* POSIX RegEx is not currently included in the distribution, however
we will probably add Henry Spencer's REGEX library soon.
* ACL Group functionality is also included in this merge!
# uncomment this line to enable support for LDAP referrals in libldap
LDAP_REFERRALS=-DLDAP_REFERRALS
+# uncomment this line to enable ACL by groups
+# LDAP_ACLGROUP=-DACLGROUP
+
# uncomment these lines to enable support for CRYPT passwords in LDBM.
# LDAP_CRYPT=-DLDAP_CRYPT
# LDAP_CRYPT_LIB?=
--- /dev/null
+#-----------------------------------------------------------------------------
+# Copyright (c) 1994 Regents of the University of Michigan.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms are permitted
+# provided that this notice is preserved and that due credit is given
+# to the University of Michigan at Ann Arbor. The name of the University
+# may not be used to endorse or promote products derived from this
+# software without specific prior written permission. This software
+# is provided ``as is'' without express or implied warranty.
+#
+# LDAP common Make defines (included in all but top-level Makefile)
+#
+#-----------------------------------------------------------------------------
+
+#############################################################################
+## Edit the following variables to have appropriate values for your system ##
+#############################################################################
+
+#############################################################################
+## LDAP install paths ##
+#############################################################################
+#
+# by default, everything is installed below INSTROOT
+# servers, config files, etc. are put in ETCDIR
+# include files get put in INCLUDEDIR
+# libraries are put in LIBDIR
+# man pages are put under MANDIR
+# programs end-users will run are put in BINDIR
+#
+INSTROOT=/usr/local
+ETCDIR= $(INSTROOT)/etc
+INCLUDEDIR= $(INSTROOT)/include
+LIBDIR= $(INSTROOT)/lib
+MANDIR= $(INSTROOT)/man
+BINDIR= $(INSTROOT)/bin
+#
+# if you want things to run in a different directory from where they
+# are installed, set this accordingly (this path gets compiled into a
+# few binaries). otherwise, leave it alone.
+RUNTIMEETCDIR= $(ETCDIR)
+
+#############################################################################
+## General compiler options ##
+#############################################################################
+# Passed to every compile (cc or gcc). This is where you put -O or -g, etc.
+EXTRACFLAGS=-g
+# Passed to every link (ld). Include -g here if you did in EXTRACFLAGS.
+EXTRALDFLAGS=-g
+
+#############################################################################
+## If you are NOT using Kerberos authentication, you can skip this section.##
+#############################################################################
+#
+# Otherwise, to enable kerberos authentication, uncomment KERBEROS (and
+# AFSKERBEROS if you are running the AFS version of kerberos). Also
+# uncomment and change the various KRB* lines to point to where the
+# kerberos libraries and include files are installed at your site.
+#
+KERBEROS=-DKERBEROS
+AFSKERBEROS=-DAFSKERBEROS
+KRBINCLUDEFLAG = -I/usr/local/kerberos/include
+KRBLIBFLAG = -L/usr/local/kerberos/lib
+KRBLIBS = -lkrb -ldes
+
+#############################################################################
+## ISODE is required ONLY to build the ldap <-> X.500 server (ldapd) ##
+## If you don't want to build it, you can skip this section. ##
+#############################################################################
+#
+# To build the ldap server, uncomment the HAVEISODE line,
+# and the section describing build settings for your version of isode.
+#
+HAVEISODE = yes
+# If you compiled ISODE with TURBO_DISK defined, uncomment this
+#ISODETURBOLIBS = -lgdbm
+# uncomment these to have ldapd "pretty print" protocol elements w/debugging
+PEPSY_DUMP=-DPEPSY_DUMP
+PEPSY=/usr/local/ic/bin/pepsy
+# uncommment this line to have ldapd load PP syntax handlers
+# you'll also need to add -lpp to ISODEBASELIBS below
+#LDAP_USE_PP=-DLDAP_USE_PP
+# uncomment NO_SETPROCTITLE to have ldapd NOT change its title
+#NO_SETPROCTITLE=-DNOSETPROCTITLE
+#
+# ISODE Consortium release build settings
+# You should change the next line so that ICRELEASE matches the (integer)
+# version number of whatever IC release you have, e.g. 1, 2, or 3 and
+# also uncomment the next 5 lines.
+ICRELEASE=-DICRELEASE=2
+ISODEPACKAGE=-DISODEPACKAGE=IC
+ISODEINCLUDEFLAG= -I/usr/local/ic/include
+ISODELIBFLAG = -L/usr/local/ic/lib
+ISODEBASELIBS = -lisode
+#
+# Freely available ISODE 8.0 release build settings (uncomment the next 4 lines)
+#ISODEPACKAGE=-DISODEPACKAGE
+#ISODEINCLUDEFLAG= -I/usr/local/isode/include
+#ISODELIBFLAG = -L/usr/local/isode/lib
+#ISODEBASELIBS = -ldsap -lisode
+#
+# NEXOR ISODE release build settings (uncomment the next 4 lines)
+#ISODEPACKAGE=-DISODEPACKAGE=XT
+#ISODEINCLUDEFLAG= -I/usr/include/isode
+#ISODELIBFLAG = -L/usr/local/lib -L/usr/sunlink/osi/lib
+#ISODEBASELIBS = -lxtpp -lresolv -lxtdsap -lxtisode -losi
+
+#############################################################################
+## If you don't want to run slapd, skip this section. ##
+#############################################################################
+#
+# To build slapd (the stand-alone ldap daemon), uncomment the MAKESLAPD
+# line and select the SLAPD_BACKENDS you want to use. If you enable the
+# LDBM backend, also select one of the LDBM backends.
+MAKESLAPD= yes
+#
+# remove the defines for backends you don't want to enable
+SLAPD_BACKENDS= -DLDAP_LDBM -DLDAP_SHELL -DLDAP_PASSWD
+#
+# If you have included -DLDAP_LDBM in the SLAPD_BACKENDS line you need
+# to specify which low-level database package to use. There are
+# four choices: Berkeley db b-tree, Berkeley db hash, GNU dbm, or ndbm.
+#
+# berkeley db btree package
+LDBMBACKEND=-DLDBM_USE_DBBTREE
+LDBMINCLUDE=-I/usr/local/include
+LDBMLIB=-ldb
+# berkeley db hash package
+#LDBMBACKEND=-DLDBM_USE_DBHASH
+#LDBMINCLUDE=-I/usr/local/include
+#LDBMLIB=-ldb
+# gnu dbm (gdbm)
+#LDBMBACKEND=-DLDBM_USE_GDBM
+#LDBMINCLUDE=-I/usr/local/include
+#LDBMLIB=-lgdbm
+# standard unix ndbm
+#LDBMBACKEND=-DLDBM_USE_NDBM
+#
+# if you want to use a non-default threads package change these lines
+#THREADS=-DNO_THREADS
+#THREADSLIB=
+
+#############################################################################
+## The following options are used by the xax500 client. If you haven't ##
+## retrieved the xax500 source and dropped it into the "clients" ##
+## directory, you can skip this section. ##
+#############################################################################
+#
+# location of your X include files
+#XINCLUDES= -I/usr/local/X11/include
+#
+# location of your X libraries
+#XLIBDIRS=-L/usr/local/X11/lib
+#
+# include any extra X libraries you need here
+# the following works with sunos 4 and X11R5
+#XLIBS = $(XLIBDIRS) -lXm -lXt -lX11
+# the following has been known to work with Solaris 2.4 and X11R6
+#XLIBS = $(XLIBDIRS) -lXm -lXext -lSM -lICE -lXpm -lXt -lX11
+
+#############################################################################
+## If you don't want to do auto-translation of character sets, skip this ##
+#############################################################################
+#
+# Otherwise, uncomment this line and set the following options.
+#STR_TRANSLATION=-DSTR_TRANSLATION
+#
+# remove the defines for LDAP client library T.61 character translation
+# you do not need. If you use LDAP_CHARSET_8859, replace the '1' in "88591"
+# with the number of the particular character set you use. E.g., use "88594"
+# if you use the ISO 8859-4 chracter set.
+#LIBLDAP_CHARSETS=-DLDAP_CHARSET_8859="88591"
+#
+# uncomment one these lines to enable automatic T.61 translation by default
+#LIBLDAP_DEF_CHARSET=-DLDAP_DEFAULT_CHARSET=LDAP_CHARSET_8859
+
+#############################################################################
+## General options ##
+#############################################################################
+# uncomment this line to enable debugging code (a good idea)
+LDAP_DEBUG=-DLDAP_DEBUG
+
+# uncomment this line to turn on a few U of Michigan specific things
+UOFM=-DUOFM
+
+# uncomment this line to delete a few printfs in the lber and ldap libraries.
+#NO_USERINTERFACE=-DNO_USERINTERFACE
+
+# uncomment this line to include Connectionless LDAP support
+CLDAP=-DCLDAP
+
+# uncomment this line to eliminate local caching support in the libldap
+#NO_CACHE=-DNO_CACHE
+
+# uncomment this line to enable support for LDAP referrals in libldap
+LDAP_REFERRALS=-DLDAP_REFERRALS
+
+# uncomment this line to use soundex for approximate matches in slapd.
+# the default is to use the metaphone algorithm.
+#PHONETIC=-DSOUNDEX
# DEFS are included in CFLAGS
DEFS = $(PLATFORMCFLAGS) $(LDAP_DEBUG) $(KERBEROS) $(AFSKERBEROS) \
$(UOFM) $(UOFA) $(NO_USERINTERFACE) $(CLDAP) $(NO_CACHE) \
- $(LDAP_REVERSE_LOOKUP) \
$(LDAP_REFERRALS) $(LDAP_DNS) $(STR_TRANSLATION) \
- $(LIBLDAP_CHARSETS) $(LIBLDAP_DEF_CHARSET) \
- $(SLAPD_BACKENDS) $(LDBMBACKEND) $(LDBMINCLUDE) $(PHONETIC)
+ $(LIBLDAP_CHARSETS) $(LIBLDAP_DEF_CHARSET)
+
+# LDBMDEFS are included by servers (though only slapd only cares)
+# and libldbm
+LDBMDEFS = $(SLAPD_BACKENDS) $(LDBMBACKEND) $(LDBMINCLUDE)
# SERVERDEFS are added to server builds CFLAGS (in addition to DEFS)
SERVERDEFS = $(ISODEPACKAGE) $(ICRELEASE) $(LDAP_USE_PP) \
- $(NO_SETPROCTITLE) $(PEPSY_DUMP)
-
+ $(NO_SETPROCTITLE) $(PEPSY_DUMP) \
+ $(LDAP_REVERSE_LOOKUP) $(LDAP_CRYPT) $(LDAP_ACLGROUP) \
+ $(PHONETIC) $(LDBMDEFS)
#
# ISODELIBS are used in server/ldapd builds
#
# -------------------------------------------------------------------------
CC = gcc
PLATFORMCFLAGS= -Dfreebsd
-PLATFORMLIBS=-lcompat
--- /dev/null
+#if defined( MACOS ) || defined( DOS ) || defined( _WIN32 ) || defined( NEED_BSDREGEX )
+/*
+ * Copyright (c) 1993 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+/*
+ * regex.h -- includes for regular expression matching routines
+ * 13 August 1993 Mark C Smith
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined( NEEDPROTOS ) && defined( __STDC__ )
+#define NEEDPROTOS
+#endif
+
+#ifdef NEEDPROTOS
+char *re_comp( char *pat );
+int re_exec( char *lp );
+void re_modw( char *s );
+int re_subs( char *src, char *dst );
+#else /* NEEDPROTOS */
+char *re_comp();
+int re_exec();
+void re_modw();
+int re_subs();
+#endif /* NEEDPROTOS */
+
+#define re_fail( m, p )
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* MACOS or DOS or NEED_BSDREGEX */
--- /dev/null
+/*
+ * Copyright (c) 1994 Regents of the University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of Michigan at Ann Arbor. The name of the University
+ * may not be used to endorse or promote products derived from this
+ * software without specific prior written permission. This software
+ * is provided ``as is'' without express or implied warranty.
+ */
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+/*
+ * config.h for LDAP -- edit this file to customize LDAP client behavior.
+ * NO platform-specific definitions should be placed in this file.
+ * Note that this is NOT used by the LDAP or LBER libraries.
+ */
+
+/*
+ * SHARED DEFINITIONS - things you should change
+ */
+ /* default ldap host */
+#define LDAPHOST "ldap.itd.umich.edu"
+ /* default place to start searching */
+#define DEFAULT_BASE "o=University of Michigan, c=US"
+
+/*********************************************************************
+ * *
+ * You probably do not need to edit anything below this point *
+ * *
+ *********************************************************************/
+
+/*
+ * SHARED DEFINITIONS - other things you can change
+ */
+ /* default attribute to use when sorting entries, NULL => sort by DN */
+#define SORT_ATTR NULL
+ /* default count of DN components to show in entry displays */
+#define DEFAULT_RDNCOUNT 2
+ /* default config file locations */
+#define FILTERFILE "%ETCDIR%/ldapfilter.conf"
+#define TEMPLATEFILE "%ETCDIR%/ldaptemplates.conf"
+#define SEARCHFILE "%ETCDIR%/ldapsearchprefs.conf"
+#define FRIENDLYFILE "%ETCDIR%/ldapfriendly"
+
+/*
+ * FINGER DEFINITIONS
+ */
+ /* who to bind as */
+#define FINGER_BINDDN "cn=finger, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* where to search */
+#define FINGER_BASE DEFAULT_BASE
+ /* banner to print */
+#define FINGER_BANNER "X.500 Finger Service...\r\n"
+ /* who to report errors to */
+#define FINGER_ERRORS "x500@umich.edu"
+ /* what to say if no matches are found */
+#define FINGER_NOMATCH \
+"Search failed to find anything. Currently, this service contains\r\n\
+information only on University of Michigan faculty, staff, and students.\r\n\
+Other likely places to finger are:\r\n\
+ um.cc.umich.edu\r\n\
+ azure.engin.umich.edu\r\n"
+ /* what to say if the service may be unavailable */
+#define FINGER_UNAVAILABLE \
+"The X.500 service may be temporarily unavailable.\r\n\
+Please try again later.\r\n"
+ /* printed if a match has no email address - for disptmp default */
+#define FINGER_NOEMAIL1 "None registered in this service. Try fingering at:"
+#define FINGER_NOEMAIL2 "um.cc.umich.edu or azure.engin.umich.edu"
+#define FINGER_NOEMAIL { FINGER_NOEMAIL1, FINGER_NOEMAIL2, NULL }
+ /* maximum number of matches returned */
+#define FINGER_SIZELIMIT 50
+ /* max number of hits displayed in full before a list is presented */
+#define FINGER_LISTLIMIT 1
+ /* what to exec for "finger @host" */
+#define FINGER_CMD "/usr/ucb/finger"
+ /* how to treat aliases when searching */
+#define FINGER_DEREF LDAP_DEREF_FINDING
+ /* attribute to use when sorting results */
+#define FINGER_SORT_ATTR SORT_ATTR
+ /* enable ufn support */
+#define FINGER_UFN
+ /* timeout for searches */
+#define FINGER_TIMEOUT 60
+ /* number of DN components to show in entry displays */
+#define FINGER_RDNCOUNT DEFAULT_RDNCOUNT
+
+/*
+ * GO500 GOPHER GATEWAY DEFINITIONS
+ */
+ /* who to bind as */
+#define GO500_BINDDN "cn=go500, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* where to search */
+#define GO500_BASE DEFAULT_BASE
+ /* port on which to listen */
+#define GO500_PORT 5555
+ /* how to handle aliases */
+#define GO500_DEREF LDAP_DEREF_FINDING
+ /* attribute to use when sorting results */
+#define GO500_SORT_ATTR SORT_ATTR
+ /* timeout for searches */
+#define GO500_TIMEOUT 60
+ /* enable ufn support */
+#define GO500_UFN
+ /*
+ * only set and uncomment this if your hostname() does not return
+ * a fully qualified hostname
+ */
+/* #define GO500_HOSTNAME "fully.qualified.hostname.here" */
+ /* number of DN components to show in entry displays */
+#define GO500_RDNCOUNT DEFAULT_RDNCOUNT
+
+/*
+ * GO500GW GOPHER GATEWAY DEFINITIONS
+ */
+ /* who to bind as */
+#define GO500GW_BINDDN "cn=go500gw, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* where the helpfile lives */
+#define GO500GW_HELPFILE "%ETCDIR%/go500gw.help"
+ /* port on which to listen */
+#define GO500GW_PORT 7777
+ /* timeout on all searches */
+#define GO500GW_TIMEOUT 180
+ /* enable ufn support */
+#define GO500GW_UFN
+ /* attribute to use when sorting results */
+#define GO500GW_SORT_ATTR SORT_ATTR
+ /*
+ * only set and uncomment this if your hostname() does not return
+ * a fully qualified hostname
+ */
+/* #define GO500GW_HOSTNAME "fully.qualified.hostname.here" */
+ /* number of DN components to show in entry displays */
+#define GO500GW_RDNCOUNT DEFAULT_RDNCOUNT
+
+/*
+ * RCPT500 MAIL RESPONDER GATEWAY DEFINITIONS
+ */
+ /* who to bind as */
+#define RCPT500_BINDDN "cn=Rcpt500, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* where the helpfile lives */
+#define RCPT500_HELPFILE "%ETCDIR%/rcpt500.help"
+ /* maximum number of matches returned */
+#define RCPT500_SIZELIMIT 50
+ /* address replies will appear to come from */
+#define RCPT500_FROM "\"X.500 Query Program\" <X500-Query>"
+ /* command that will accept an RFC822 message text on standard
+ input, and send it. sendmail -t does this nicely. */
+#define RCPT500_PIPEMAILCMD "/usr/lib/sendmail -t"
+ /* where to search */
+#define RCPT500_BASE DEFAULT_BASE
+ /* attribute to use when sorting results */
+#define RCPT500_SORT_ATTR SORT_ATTR
+ /* max number of hits displayed in full before a list is presented */
+#define RCPT500_LISTLIMIT 3
+ /* enable ufn support */
+#define RCPT500_UFN
+ /* number of DN components to show in entry displays */
+#define RCPT500_RDNCOUNT DEFAULT_RDNCOUNT
+
+/*
+ * LDAPSEARCH TOOL
+ */
+ /* who to bind as */
+#define LDAPSEARCH_BINDDN "cn=LDAP Search Tool, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* search base */
+#define LDAPSEARCH_BASE DEFAULT_BASE
+
+/*
+ * LDAPMODIFY TOOL
+ */
+ /* who to bind as */
+#define LDAPMODIFY_BINDDN "cn=Manager, o=University of Michigan, c=US"
+ /* search base */
+#define LDAPMODIFY_BASE DEFAULT_BASE
+
+/*
+ * LDAPDELETE TOOL
+ */
+ /* who to bind as */
+#define LDAPDELETE_BINDDN "cn=Manager, o=University of Michigan, c=US"
+ /* search base */
+#define LDAPDELETE_BASE DEFAULT_BASE
+
+/*
+ * LDAPMODRDN TOOL
+ */
+ /* who to bind as */
+#define LDAPMODRDN_BINDDN "cn=Manager, o=University of Michigan, c=US"
+ /* search base */
+#define LDAPMODRDN_BASE DEFAULT_BASE
+
+/*
+ * MAIL500 MAILER DEFINITIONS
+ */
+ /* who to bind as */
+#define MAIL500_BINDDN "cn=mail500, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* max number of ambiguous matches reported */
+#define MAIL500_MAXAMBIGUOUS 10
+ /* max subscribers allowed (size limit when searching for them ) */
+#define MAIL500_MAXGROUPMEMBERS LDAP_NO_LIMIT
+ /* timeout for all searches */
+#define MAIL500_TIMEOUT 180
+ /* sendmail location - mail500 needs to exec this */
+#define MAIL500_SENDMAIL "/usr/lib/sendmail"
+
+/*
+ * UD DEFINITIONS
+ */
+ /* ud configuration file */
+#define UD_CONFIG_FILE "%ETCDIR%/ud.conf"
+ /* default editor */
+#define UD_DEFAULT_EDITOR "/usr/ucb/vi"
+ /* default bbasename of user config file */
+#define UD_USER_CONFIG_FILE ".udrc"
+ /* default user to bind as */
+#define UD_BINDDN "cn=ud, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* default password to bind with */
+#define UD_PASSWD NULL
+ /* default search base */
+#define UD_BASE DEFAULT_BASE
+ /* default base where groups are created */
+#define UD_WHERE_GROUPS_ARE_CREATED "ou=User Groups, ou=Groups, o=University of Michigan, c=US"
+ /* default base below which all groups live */
+#define UD_WHERE_ALL_GROUPS_LIVE "ou=Groups, o=University of Michigan, c=US"
+
+/*
+ * FAX500 DEFINITIONS
+ */
+ /* what to bind as */
+#define FAX_BINDDN "cn=mail500, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* how long to wait for searches */
+#define FAX_TIMEOUT 180
+ /* maximum number of ambiguous matches reported */
+#define FAX_MAXAMBIGUOUS 10
+ /* maximum number of members allowed */
+#define FAX_MAXMEMBERS LDAP_NO_LIMIT
+ /* program to send mail */
+#define FAX_SENDMAIL "/usr/lib/sendmail"
+
+/*
+ * RP500 DEFINITIONS
+ */
+ /* what to bind as */
+#define RP_BINDDN "cn=rp500, ou=Miscellaneous Servers, o=University of Michigan, c=US"
+ /* prefix to add to non-fully-qualified numbers */
+#define RP_PHONEPREFIX "1313"
+
+/*
+ * SLAPD DEFINITIONS
+ */
+ /* location of the default slapd config file */
+#define SLAPD_DEFAULT_CONFIGFILE "%ETCDIR%/slapd.conf"
+ /* default sizelimit on number of entries from a search */
+#define SLAPD_DEFAULT_SIZELIMIT 500
+ /* default timelimit to spend on a search */
+#define SLAPD_DEFAULT_TIMELIMIT 3600
+ /* location of the slapd pid file */
+#define SLAPD_PIDFILE "%ETCDIR%/slapd.pid"
+ /* location of the slapd args file */
+#define SLAPD_ARGSFILE "%ETCDIR%/slapd.args"
+ /* dn of the special "monitor" entry */
+#define SLAPD_MONITOR_DN "cn=monitor"
+ /* dn of the special "config" entry */
+#define SLAPD_CONFIG_DN "cn=config"
+ /* minimum max ids that a single index entry can map to in ldbm */
+#define SLAPD_LDBM_MIN_MAXIDS 4000
+
+#endif /* _CONFIG_H */
+++ /dev/null
-#if defined( MACOS ) || defined( DOS ) || defined( _WIN32 ) || defined( NEED_BSDREGEX )
-/*
- * Copyright (c) 1993 Regents of the University of Michigan.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is given
- * to the University of Michigan at Ann Arbor. The name of the University
- * may not be used to endorse or promote products derived from this
- * software without specific prior written permission. This software
- * is provided ``as is'' without express or implied warranty.
- */
-/*
- * regex.h -- includes for regular expression matching routines
- * 13 August 1993 Mark C Smith
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined( NEEDPROTOS ) && defined( __STDC__ )
-#define NEEDPROTOS
-#endif
-
-#ifdef NEEDPROTOS
-char *re_comp( char *pat );
-int re_exec( char *lp );
-void re_modw( char *s );
-int re_subs( char *src, char *dst );
-#else /* NEEDPROTOS */
-char *re_comp();
-int re_exec();
-void re_modw();
-int re_subs();
-#endif /* NEEDPROTOS */
-
-#define re_fail( m, p )
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* MACOS or DOS or NEED_BSDREGEX */
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
#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
#else /* DOS */
#include <sys/types.h>
#include <sys/file.h>
-#include <stdlib.h>
#include <sys/errno.h>
#ifndef VMS
#include <unistd.h>
#include "lber.h"
#include "ldap.h"
-#include "regex.h"
#ifdef NEEDPROTOS
static int break_into_words( char *str, char *delims, char ***wordsp );
#if !defined( MACOS ) && !defined( DOS )
extern int errno;
-extern char *re_comp();
#endif
#define FILT_MAX_LINE_LEN 1024
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 );
}
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
free_strarray( tok );
return( NULL );
}
+ regfree(&re);
nextflp->lfl_delims = tok[ 1 ];
nextflp->lfl_ilist = NULL;
ldap_getfirstfilter( LDAPFiltDesc *lfdp, char *tagpat, char *value )
{
LDAPFiltList *flp;
+ int rc;
+ regex_t re;
if ( lfdp->lfd_curvalcopy != NULL ) {
free( lfdp->lfd_curvalcopy );
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 ) {
+++ /dev/null
-#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.
- *
- * Vendor Modification history:
- *
- * 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 */
HDIR = ../../include
INCLUDES= -I$(HDIR)
-DEFINES = $(DEFS)
+DEFINES = $(DEFS) $(LDBMDEFS)
CFLAGS = $(INCLUDES) $(DEFINES) $(ACFLAGS)
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) $(LDAP_CRYPT) $(LDAP_TCP_WRAPPERS) $(SERVERDEFS)
+DEFINES = $(DEFS) $(SERVERDEFS)
CFLAGS = $(INCLUDES) $(THREADSINCLUDE) $(DEFINES) $(ACFLAGS) $(THREADS)
LDFLAGS = -L$(LDIR) $(KRBLIBFLAG)
-LIBS = $(KRBLIBS) -llber -lldbm -lavl -llthread -lldif $(THREADSLIB) \
+LIBS = $(KRBLIBS) -llber -lldbm -lavl -llthread -lldif \
+ $(REGEXLIB) $(THREADSLIB) \
$(LDBMLIB) $(LDAP_CRYPT_LIB) $(LDAP_TCP_WRAPPERS_LIB) $(ALIBS)
all: FORCE
#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();
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
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 );
}
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,
return( NULL );
}
+ Debug( LDAP_DEBUG_ARGS, "=> acl_get: edn %s\n", edn, 0, 0 );
+
/* check for a backend-specific acl that matches the entry */
for ( i = 1, a = be->be_acl; a != NULL; a = a->acl_next, i++ ) {
- if ( a->acl_dnpat != NULL ) {
- edn = dn_normalize_case( strdup( e->e_dn ) );
- if ( ! regex_matches( a->acl_dnpat, edn ) ) {
- free( edn );
+ if (a->acl_dnpat != NULL) {
+ Debug( LDAP_DEBUG_TRACE, "=> dnpat: [%d] %s nsub: %d\n",
+ i, a->acl_dnpat, a->acl_dnre.re_nsub);
+
+ if (regexec(&a->acl_dnre, edn, nmatch, matches, 0))
continue;
- }
- free( edn );
+ else
+ Debug( LDAP_DEBUG_TRACE, "=> acl_get:[%d] backend ACL match\n",
+ i, 0, 0);
}
+
if ( a->acl_filter != NULL ) {
- if ( test_filter( NULL, NULL, NULL, e, a->acl_filter )
- != 0 ) {
+ if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
continue;
}
}
+
+ Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr %s\n", i, attr, 0);
+
if ( attr == NULL || a->acl_attrs == NULL ||
- charray_inlist( a->acl_attrs, attr ) ) {
- Debug( LDAP_DEBUG_ACL, "<= acl_get: backend acl #%d\n",
- i, e->e_dn, attr );
+ charray_inlist( a->acl_attrs, attr ) )
+ {
+ Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] backend acl %s attr: %s\n",
+ i, e->e_dn, attr );
return( a );
}
+ matches[0].rm_so = matches[0].rm_eo = -1;
}
/* check for a global acl that matches the entry */
for ( i = 1, a = global_acl; a != NULL; a = a->acl_next, i++ ) {
- if ( a->acl_dnpat != NULL ) {
- edn = dn_normalize_case( strdup( e->e_dn ) );
- if ( ! regex_matches( a->acl_dnpat, edn ) ) {
- free( edn );
+ if (a->acl_dnpat != NULL) {
+ Debug( LDAP_DEBUG_TRACE, "=> dnpat: [%d] %s nsub: %d\n",
+ i, a->acl_dnpat, a->acl_dnre.re_nsub);
+
+ if (regexec(&a->acl_dnre, edn, nmatch, matches, 0)) {
continue;
+ } else {
+ Debug( LDAP_DEBUG_TRACE, "=> acl_get: [%d] global ACL match\n",
+ i, 0, 0);
}
- free( edn );
}
+
if ( a->acl_filter != NULL ) {
- if ( test_filter( NULL, NULL, NULL, e, a->acl_filter )
- != 0 ) {
+ if ( test_filter( NULL, NULL, NULL, e, a->acl_filter ) != 0 ) {
continue;
}
}
- if ( attr == NULL || a->acl_attrs == NULL || charray_inlist(
- a->acl_attrs, attr ) ) {
- Debug( LDAP_DEBUG_ACL, "<= acl_get: global acl #%d\n",
- i, e->e_dn, attr );
+
+ Debug( LDAP_DEBUG_ARGS, "=> acl_get: [%d] check attr\n", i, 0, 0);
+
+ if ( attr == NULL || a->acl_attrs == NULL ||
+ charray_inlist( a->acl_attrs, attr ) )
+ {
+ Debug( LDAP_DEBUG_ACL, "<= acl_get: [%d] global acl %s attr: %s\n",
+ i, e->e_dn, attr );
return( a );
}
+
+ matches[0].rm_so = matches[0].rm_eo = -1;
}
- Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
+ Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
return( NULL );
}
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 );
}
}
for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
if ( b->a_dnpat != NULL ) {
+ Debug( LDAP_DEBUG_TRACE, "<= check a_dnpat: %s\n",
+ b->a_dnpat, 0, 0);
/*
* if access applies to the entry itself, and the
* user is bound as somebody in the same namespace as
* the entry, OR the given dn matches the dn pattern
*/
- if ( strcasecmp( b->a_dnpat, "self" ) == 0 && op->o_dn
- != NULL && *(op->o_dn) && e->e_dn != NULL ) {
- edn = dn_normalize_case( strdup( e->e_dn ) );
+ if ( strcasecmp( b->a_dnpat, "self" ) == 0 &&
+ op->o_dn != NULL && *(op->o_dn) && e->e_dn != NULL )
+ {
if ( strcasecmp( edn, op->o_dn ) == 0 ) {
- free( edn );
- if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
- "<= acl: matched by clause #%d access %s\n",
+ "<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >=
access ? "granted" : "denied", 0 );
- return( (b->a_access & ~ACL_SELF)
- >= access );
+ if ( odn ) free( odn );
+ return( (b->a_access & ~ACL_SELF) >= access );
}
- free( edn );
} else {
- if ( regex_matches( b->a_dnpat, odn ) ) {
- if ( odn ) free( odn );
+ if ( regex_matches( b->a_dnpat, odn, edn, matches ) ) {
Debug( LDAP_DEBUG_ACL,
- "<= acl: matched by clause #%d access %s\n",
+ "<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
- return( (b->a_access & ~ACL_SELF)
- >= access );
+ if ( odn ) free( odn );
+ return( (b->a_access & ~ACL_SELF) >= access );
}
}
}
if ( b->a_addrpat != NULL ) {
- if ( regex_matches( b->a_addrpat, conn->c_addr ) ) {
- if ( odn ) free( odn );
+ if ( regex_matches( b->a_addrpat, conn->c_addr, edn, matches ) ) {
Debug( LDAP_DEBUG_ACL,
- "<= acl: matched by clause #%d access %s\n",
+ "<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
+ if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
}
if ( b->a_domainpat != NULL ) {
- if ( regex_matches( b->a_domainpat, conn->c_domain ) ) {
- if ( odn ) free( odn );
+ Debug( LDAP_DEBUG_ARGS, "<= check a_domainpath: %s\n",
+ b->a_domainpat, 0, 0 );
+ if ( regex_matches( b->a_domainpat, conn->c_domain, edn, matches ) )
+ {
Debug( LDAP_DEBUG_ACL,
- "<= acl: matched by clause #%d access %s\n",
+ "<= acl_access_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
+ if ( odn ) free( odn );
return( (b->a_access & ~ACL_SELF) >= access );
}
}
if ( b->a_dnattr != NULL && op->o_dn != NULL ) {
+ Debug( LDAP_DEBUG_ARGS, "<= check a_dnattr: %s\n",
+ b->a_dnattr, 0, 0);
/* see if asker is listed in dnattr */
- if ( (at = attr_find( e->e_attrs, b->a_dnattr ))
- != NULL && value_find( at->a_vals, &bv,
- at->a_syntax, 3 ) == 0 )
+ if ( (at = attr_find( e->e_attrs, b->a_dnattr )) != NULL &&
+ value_find( at->a_vals, &bv, at->a_syntax, 3 ) == 0 )
{
- if ( (b->a_access & ACL_SELF) && (val == NULL
- || value_cmp( &bv, val, at->a_syntax,
- 2 )) ) {
+ if ( (b->a_access & ACL_SELF) &&
+ (val == NULL || value_cmp( &bv, val, at->a_syntax, 2 )) )
+ {
continue;
}
if ( odn ) free( odn );
Debug( LDAP_DEBUG_ACL,
- "<= acl: matched by clause #%d access %s\n",
+ "<= acl_acces_allowed: matched by clause #%d access %s\n",
i, (b->a_access & ~ACL_SELF) >= access ?
"granted" : "denied", 0 );
/* 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 );
{
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:
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 );
}
}
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 );
}
}
}
}
+ 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;
-
- if ( (e = compile( pat, NULL, NULL )) == NULL ) {
- Debug( LDAP_DEBUG_ANY,
- "compile( \"%s\", \"%s\") failed\n", pat, str, 0 );
- return( 0 );
+ int size;
+ char *sp;
+ char *dp;
+ int flag;
+
+ 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( ®ex_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( ®ex_mutex );
+ "compile( \"%s\", \"%s\") failed %s\n",
+ pat, str, error );
return( 0 );
}
- rc = re_exec( str ? str : "" );
- pthread_mutex_unlock( ®ex_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 */
#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();
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,
}
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;
}
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;
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();
}
} 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();
}
} 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,
/* 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 );
}
}
}
-#endif
+#endif /* LDAP_DEBUG */
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) $(LDAP_CRYPT) $(THREADS)
+DEFINES = $(DEFS) $(SERVERDEFS) $(THREADS)
CFLAGS = $(INCLUDES) $(THREADSINCLUDE) $(DEFINES) $(ACFLAGS)
LDFLAGS = -L$(LDIR) $(KRBLIBFLAG) $(LDAP_CRYPT_LIB)
--- /dev/null
+/* 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
+
#include <stdio.h>
#include <sys/types.h>
-#include <sys/socket.h>
#include "slap.h"
#include "ldapconfig.h"
#include "back-ldbm.h"
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 ); */
extern int ldbm_back_config();
extern int ldbm_back_init();
extern int ldbm_back_close();
+extern int ldbm_back_group();
#endif
#ifdef LDAP_PASSWD
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;
}
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;
}
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;
}
for ( i = 0; i < nbackends; i++ ) {
for ( j = 0; backends[i].be_suffix != NULL &&
backends[i].be_suffix[j] != NULL; j++ ) {
- /* Add greg@greg.rim.or.jp
- * It's quick hack for cheep client
- * Some browser offer a NULL base at ldap_search
- */
- if(dnlen == 0) {
- Debug( LDAP_DEBUG_TRACE, "select_backend: use default backend\n", 0, 0, 0 );
- return (&backends[i]);
- }
len = strlen( backends[i].be_suffix[j] );
if ( len > dnlen ) {
}
}
}
+
+#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
#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();
char pat[BUFSIZ];
char buf[BUFSIZ];
struct berval *val;
+ regex_t re;
Debug( LDAP_DEBUG_FILTER, "begin test_substring_filter\n", 0, 0, 0 );
}
/* compile the regex */
-#ifdef sunos5
- if ( (p = compile( pat, NULL, NULL )) == NULL ) {
- Debug( LDAP_DEBUG_ANY, "compile failed (%s)\n", p, 0, 0 );
- return( -1 );
- }
-#else /* sunos5 */
- pthread_mutex_lock( ®ex_mutex );
- if ( (p = re_comp( pat )) != 0 ) {
- Debug( LDAP_DEBUG_ANY, "re_comp failed (%s)\n", p, 0, 0 );
- pthread_mutex_unlock( ®ex_mutex );
+ 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 );
}
-#endif /* sunos5 */
/* for each value in the attribute see if regex matches */
for ( i = 0; a->a_vals[i] != NULL; i++ ) {
}
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( ®ex_mutex );
-#endif /* sunos5 */
+ regfree(&re);
return( 0 );
}
}
-#ifdef sunos5
- free( p );
-#else /* sunos5 */
- pthread_mutex_unlock( ®ex_mutex );
-#endif /* sunos5 */
+
+ regfree(&re);
Debug( LDAP_DEBUG_FILTER, "end test_substring_filter 1\n", 0, 0, 0 );
return( 1 );
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()
{
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( ®ex_mutex, pthread_mutexattr_default );
-#endif
}
*/
pthread_mutex_t entry2str_mutex;
pthread_mutex_t replog_mutex;
-#ifndef sunos5
-pthread_mutex_t regex_mutex;
-#endif
static
usage( name )
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 );
+++ /dev/null
-#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.
- *
- * Vendor Modification history:
- *
- * 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 */
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 );
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 );
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 );
}
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;
}
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;
}
send_ldap_result( conn, op,
LDAP_OPERATIONS_ERROR, NULL,
"ber_printf value" );
+ free(edn);
return( 1 );
}
}
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, "}}}}" );
#define LDAP_SYSLOG
#include <syslog.h>
+#include <sys/types.h>
+#include <regex.h>
+
#include "avl.h"
#include "lber.h"
#include "ldap.h"
#define OFF (-1)
#define UNDEFINED 0
+#define MAXREMATCHES 10
+
/*
* represents an attribute value assertion (i.e., attr=value)
*/
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
struct acl {
/* "to" part: the entries this acl applies to */
Filter *acl_filter;
+ regex_t acl_dnre;
char *acl_dnpat;
char **acl_attrs;
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;
/*
../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) $(LDAP_CRYPT) $(SERVERDEFS) $(THREADS)
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
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
#!/bin/sh
-grep -v "modifiersname" | \
-grep -v "modifytimestamp" | \
-grep -v "creatorsname" | \
-grep -v "createtimestamp"
+egrep -iv '^modifiersname:|^modifytimestamp:|^creatorsname:|^createtimestamp'
. 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
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