]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
Merged in ACL changes.
authorKurt Zeilenga <kurt@openldap.org>
Wed, 19 Aug 1998 20:02:01 +0000 (20:02 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 19 Aug 1998 20:02:01 +0000 (20:02 +0000)
libraries/libldap/regex.c
servers/slapd/acl.c
servers/slapd/aclparse.c
servers/slapd/back-ldbm/Make-template
servers/slapd/backend.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/slap.h

index 4f309c5fb0ab14807a429fb4aee9e7507e4d210b..f34fc85eb21337210cda9ccc5f14ec424e6b1bbb 100644 (file)
@@ -1,7 +1,7 @@
 #include "portable.h"
 
 #if defined( MACOS ) || defined( DOS ) || defined( _WIN32 ) || defined( NEED_BSDREGEX )
-#include "regex.h"
+#include "compat_regex.h"
 
 /*
  * regex - Regular expression pattern matching  and replacement
@@ -20,9 +20,8 @@
  * see Henry Spencer's regexp routines, or GNU Emacs pattern
  * matching module.
  *
- * Modification history:
+ * Vendor Modification history:
  *
- * $Log: regex.c,v $
  * Revision 1.12  1996/04/25  16:20:59  mcs
  * make re_exec() match "" with ".*" and similar patterns
  * hopefully this change doesn't break anything else!
index 6c3b22ee857b04b4f34b74b385891a2a84a66fc9..7e4379ecb7c69bd02c0fcfdbd45dfa82b912d7d4 100644 (file)
@@ -11,6 +11,7 @@
 #else
 #include "regex.h"
 #endif
+
 #include "slap.h"
 
 extern Attribute       *attr_find();
@@ -25,8 +26,12 @@ int          access_allowed();
 struct acl     *acl_get_applicable();
 
 static int     regex_matches();
+#ifdef USEREGEX
+static string_expand(char *newbuf, int bufsiz, char *pattern, char *match, regmatch_t *matches);
+#endif
 
 extern pthread_mutex_t regex_mutex;
+extern Entry * be_dn2entry(Backend *be, char *bdn, char **matched);
 
 /*
  * access_allowed - check whether dn is allowed the requested access
@@ -39,6 +44,7 @@ extern pthread_mutex_t        regex_mutex;
  *             1       access allowed
  */
 
+
 int
 access_allowed(
     Backend            *be,
@@ -53,13 +59,47 @@ access_allowed(
 {
        int             rc;
        struct acl      *a;
+        char            *edn;
+
+#ifdef USEREGEX
+        regmatch_t       matches[MAXREMATCHES];
+        int              i;
+        int              n;
+#endif
 
        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 );
+            return(1);
+        }
+#ifdef USEREGEX
+       a = acl_get_applicable( be, op, e, attr, edn, MAXREMATCHES, matches );
+
+        if (a) {
+            for (i = 0; i < MAXREMATCHES && matches[i].rm_so>-1; i++) {
+                Debug( LDAP_DEBUG_ARGS, "=> match[%d]: %d %d ", i, matches[i].rm_so, matches[i].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 );
+#else
+       a = acl_get_applicable( be, op, e, attr, edn );
+       rc = acl_access_allowed( a, be, conn, e, val, op, access, edn );
+#endif
+        free(edn);
 
        return( rc );
 }
@@ -70,20 +110,32 @@ access_allowed(
  * acl_access_allowed().
  */
 
+#ifdef USEREGEX
 struct acl *
 acl_get_applicable(
     Backend            *be,
     Operation          *op,
     Entry              *e,
-    char               *attr
+    char               *attr,
+    char               *edn,
+    int                  nmatch,
+    regmatch_t          matches[]
 )
+#else
+struct acl *
+acl_get_applicable(
+    Backend            *be,
+    Operation          *op,
+    Entry              *e,
+    char               *attr,
+    char               *edn
+)
+#endif
 {
        int             i;
        struct acl      *a;
-       char            *edn;
 
-       Debug( LDAP_DEBUG_ACL, "=> acl_get: entry (%s) attr (%s)\n", e->e_dn,
-           attr, 0 );
+       Debug( LDAP_DEBUG_ACL, "\n=> acl_get: entry (%s) attr (%s)\n", e->e_dn, attr, 0 );
 
        if ( be_isroot( be, op->o_dn ) ) {
                Debug( LDAP_DEBUG_ACL,
@@ -92,58 +144,78 @@ acl_get_applicable(
                return( NULL );
        }
 
+       Debug( LDAP_DEBUG_ARGS, "=> acl_get: edn %s\n", edn, 0, 0 );
+
        /* check for a backend-specific acl that matches the entry */
        for ( i = 1, a = be->be_acl; a != NULL; a = a->acl_next, i++ ) {
+#ifdef USEREGEX
+                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]  backend ACL match\n", i, 0, 0);
+                }
+#else
                if ( a->acl_dnpat != NULL ) {
-                       edn = dn_normalize_case( strdup( e->e_dn ) );
-                       if ( ! regex_matches( a->acl_dnpat, edn ) ) {
-                               free( edn );
+                       if ( ! regex_matches( a->acl_dnpat, edn ) ) 
                                continue;
-                       }
-                       free( edn );
                }
+#endif
                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: backend acl #%d\n",
-                           i, e->e_dn, attr );
+                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: [%d] backend acl %s attr: %s\n", i, e->e_dn, attr );
                        return( a );
                }
+#ifdef USEREGEX
+                matches[0].rm_so = matches[0].rm_eo = -1;
+#endif
        }
 
        /* check for a global acl that matches the entry */
        for ( i = 1, a = global_acl; a != NULL; a = a->acl_next, i++ ) {
+#ifdef USEREGEX
+                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);
+                }
+#else
                if ( a->acl_dnpat != NULL ) {
-                       edn = dn_normalize_case( strdup( e->e_dn ) );
-                       if ( ! regex_matches( a->acl_dnpat, edn ) ) {
-                               free( edn );
+                       if ( ! regex_matches( a->acl_dnpat, edn ) ) 
                                continue;
-                       }
-                       free( edn );
                }
+#endif
                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 );
+                        free( edn );
                        return( a );
                }
+#ifdef USEREGEX
+                matches[0].rm_so = matches[0].rm_eo = -1;
+#endif
        }
        Debug( LDAP_DEBUG_ACL, "<= acl_get: no match\n", 0, 0, 0 );
 
        return( NULL );
 }
 
+
 /*
  * acl_access_allowed - check whether the given acl allows dn the
  * requested access to entry e, attribute attr, value val.  if val
@@ -153,6 +225,7 @@ acl_get_applicable(
  *             1       access allowed
  */
 
+#ifdef USEREGEX
 int
 acl_access_allowed(
     struct acl         *a,
@@ -161,19 +234,36 @@ acl_access_allowed(
     Entry              *e,
     struct berval      *val,
     Operation          *op,
-    int                        access
+    int                        access,
+    char                *edn,
+    regmatch_t          matches[]
+)
+#else
+int
+acl_access_allowed(
+    struct acl         *a,
+    Backend            *be,
+    Connection         *conn,
+    Entry              *e,
+    struct berval      *val,
+    Operation          *op,
+    int                        access,
+    char                *edn
 )
+#endif
 {
        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: %s access to entry \"%s\" attr: \"%s\"\n",
+           access2str( access ), e->e_dn, e->e_attrs);
+
+       Debug( LDAP_DEBUG_ACL, "\n=> acl: %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",
@@ -181,8 +271,8 @@ acl_access_allowed(
                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",
@@ -198,69 +288,84 @@ acl_access_allowed(
        }
        for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
                if ( b->a_dnpat != NULL ) {
+                        Debug( LDAP_DEBUG_TRACE, "<= check a_dnpat: %s\n", b->a_dnpat, 0, 0);
                        /*
                         * if access applies to the entry itself, and the
                         * user is bound as somebody in the same namespace as
                         * the entry, OR the given dn matches the dn pattern
                         */
-                       if ( strcasecmp( b->a_dnpat, "self" ) == 0 && op->o_dn
-                           != NULL && *(op->o_dn) && e->e_dn != NULL ) {
-                               edn = dn_normalize_case( strdup( e->e_dn ) );
+                       if ( strcasecmp( b->a_dnpat, "self" ) == 0 && 
+                                op->o_dn != NULL && *(op->o_dn) && e->e_dn != NULL ) 
+                        {
                                if ( strcasecmp( edn, op->o_dn ) == 0 ) {
-                                       free( edn );
-                                       if ( odn ) free( odn );
                                        Debug( LDAP_DEBUG_ACL,
                                    "<= acl: matched by clause #%d access %s\n",
                                            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 );
+#ifdef USEREGEX
+                               if ( regex_matches( b->a_dnpat, odn, edn, matches ) ) 
+#else
+                               if ( regex_matches( b->a_dnpat, odn ) ) 
+#endif
+                                {
                                        Debug( LDAP_DEBUG_ACL,
                                    "<= acl: 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 );
+                        Debug( LDAP_DEBUG_ARGS, "<= check a_addrpat: %s\n", b->a_addrpat, 0, 0);
+#ifdef USEREGEX
+                       if ( regex_matches( b->a_addrpat, conn->c_addr, edn, matches ) ) 
+#else
+                       if ( regex_matches( b->a_addrpat, conn->c_addr ) ) 
+#endif
+                        {
                                Debug( LDAP_DEBUG_ACL,
                                    "<= acl: 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_domainpat: %s\n", b->a_domainpat, 0, 0);
+#ifdef USEREGEX
+                       if ( regex_matches( b->a_domainpat, conn->c_domain, edn, matches ) ) 
+#else
+                       if ( regex_matches( b->a_domainpat, conn->c_domain ) ) 
+#endif
+                        {
                                Debug( LDAP_DEBUG_ACL,
                                    "<= acl: 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,
+                               if ( (b->a_access & ACL_SELF) && 
+                                        (val == NULL || value_cmp( &bv, val, at->a_syntax,
                                    2 )) ) {
                                        continue;
                                }
@@ -275,8 +380,7 @@ acl_access_allowed(
                        }
 
                        /* asker not listed in dnattr - check for self access */
-                       if ( ! (b->a_access & ACL_SELF) || val == NULL ||
-                           value_cmp( &bv, val, at->a_syntax, 2 ) != 0 ) {
+                       if ( ! (b->a_access & ACL_SELF) || val == NULL || value_cmp( &bv, val, at->a_syntax, 2 ) != 0 ) {
                                continue;
                        }
 
@@ -288,6 +392,30 @@ acl_access_allowed(
 
                        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, 512, b->a_group, edn, matches);
+
+                        if (be_group(be, buf, odn) == 0) {
+
+                                Debug( LDAP_DEBUG_ACL,
+                                    "<= acl: matched by clause #%d (group) access granted\n",i, 0, 0 );
+                                if ( odn ) free( odn );
+                                return( (b->a_access & ~ACL_SELF) >= access );
+                        }
+               }
+#endif
        }
 
        if ( odn ) free( odn );
@@ -316,14 +444,32 @@ acl_check_mods(
 {
        int             i;
        struct acl      *a;
+        char            *edn;
+
+        edn = dn_normalize_case( strdup( e->e_dn ) );
 
        for ( ; mods != NULL; mods = mods->mod_next ) {
+
+#ifdef USEREGEX
+                regmatch_t       matches[MAXREMATCHES];
+#endif
+
+                /* the lastmod attributes are ignored by ACL checking */
                if ( strcasecmp( mods->mod_type, "modifiersname" ) == 0 ||
-                   strcasecmp( mods->mod_type, "modifytimestamp" ) == 0 ) {
-                       continue;
+                   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 );
+#ifdef USEREGEX
+               a = acl_get_applicable( be, op, e, mods->mod_type, edn, MAXREMATCHES, matches );
+#else
+               a = acl_get_applicable( be, op, e, mods->mod_type, edn );
+#endif
 
                switch ( mods->mod_op & ~LDAP_MOD_BVALUES ) {
                case LDAP_MOD_REPLACE:
@@ -332,8 +478,15 @@ acl_check_mods(
                                break;
                        }
                        for ( i = 0; mods->mod_bvalues[i] != NULL; i++ ) {
-                               if ( ! acl_access_allowed( a, be, conn, e,
-                                   mods->mod_bvalues[i], op, ACL_WRITE ) ) {
+#ifdef USEREGEX
+                               if ( ! acl_access_allowed( a, be, conn, e, mods->mod_bvalues[i], 
+                                            op, ACL_WRITE, edn, matches) ) 
+#else
+                               if ( ! acl_access_allowed( a, be, conn, e, mods->mod_bvalues[i], 
+                                            op, ACL_WRITE, edn ) ) 
+#endif
+                                {
+                                        free(edn);
                                        return( LDAP_INSUFFICIENT_ACCESS );
                                }
                        }
@@ -341,15 +494,29 @@ acl_check_mods(
 
                case LDAP_MOD_DELETE:
                        if ( mods->mod_bvalues == NULL ) {
+#ifdef USEREGEX
                                if ( ! acl_access_allowed( a, be, conn, e,
-                                   NULL, op, ACL_WRITE ) ) {
+                                   NULL, op, ACL_WRITE, edn, matches) ) 
+#else
+                               if ( ! acl_access_allowed( a, be, conn, e,
+                                   NULL, op, ACL_WRITE, edn ) ) 
+#endif
+                                {
+                                        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 ) ) {
+#ifdef USEREGEX
+                               if ( ! acl_access_allowed( a, be, conn, e, mods->mod_bvalues[i], 
+                                            op, ACL_WRITE, edn, matches) ) 
+#else
+                               if ( ! acl_access_allowed( a, be, conn, e, mods->mod_bvalues[i], 
+                                            op, ACL_WRITE, edn ) ) 
+#endif
+                                {
+                                        free(edn);
                                        return( LDAP_INSUFFICIENT_ACCESS );
                                }
                        }
@@ -357,9 +524,95 @@ acl_check_mods(
                }
        }
 
+        free(edn);
        return( LDAP_SUCCESS );
 }
+#ifdef USEREGEX
+static string_expand(char *newbuf, int bufsiz, char *pat, char *match, regmatch_t *matches)
+{
+        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++;
+                }
+            }
+        }
+        *dp = '\0';
+       Debug( LDAP_DEBUG_TRACE, "=> string_expand: pattern:  %s\n", pat, 0, 0 );
+       Debug( LDAP_DEBUG_TRACE, "=> string_expand: expanded: %s\n", newbuf, 0, 0 );
+}
+
+static int
+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 */
+        )
+{
+        regex_t re;
+        char    newbuf[512];
+       int     rc;
+
+        string_expand(newbuf, 512, 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,
+                   "compile( \"%s\", \"%s\") failed %s\n", pat, str, error );
+               return( 0 );
+       }
+
+        rc = regexec(&re, str, 0, NULL, 0);
+       regfree( &re );
+
+       Debug( LDAP_DEBUG_ARGS, "=> regex_matches: string:   %s\n", str, 0, 0 );
+       Debug( LDAP_DEBUG_ARGS, "=> regex_matches: rc: %d %s\n", rc, !rc?"matched":"no match", 0 );
+
+       return( !rc );
+}
 
+
+#else
 #ifdef sunos5
 
 static int
@@ -402,3 +655,4 @@ regex_matches( char *pat, char *str )
 }
 
 #endif /* sunos5 */
+#endif
index 10fa6a07210cd7681b2599953df1ceabeee7d107..ac48963a544073a41d24c7a6e8fea8fb7b409660 100644 (file)
@@ -7,12 +7,19 @@
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netdb.h>
+
+#include <unistd.h>
+
+#ifdef sunos5
+#include "regexpr.h"
+#else
 #include "regex.h"
+#endif
+
 #include "slap.h"
 #include "portable.h"
 
 extern Filter          *str2filter();
-extern char            *re_comp();
 extern struct acl      *global_acl;
 extern char            **str2charray();
 extern char            *dn_upcase();
@@ -26,6 +33,64 @@ static void          print_acl();
 static void            print_access();
 #endif
 
+#ifdef USEREGEX
+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 < 512) && *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 >= 511) {
+               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 buf[512];
+               regerror(e, &re, buf, 512);
+               fprintf( stderr,
+                       "%s: line %d: regular expression \"%s\" bad because of %s\n",
+                       fname, lineno, pat, buf );
+               acl_usage();
+               return(0);
+       }
+       regfree(&re);
+       return(1);
+}
+#endif
+
 void
 parse_acl(
     Backend    *be,
@@ -58,6 +123,19 @@ parse_acl(
                                }
 
                                if ( strcasecmp( argv[i], "*" ) == 0 ) {
+#ifdef USEREGEX
+                                       int e;
+                                       if ((e = regcomp( &a->acl_dnre, ".*",
+                                               REG_EXTENDED|REG_ICASE)))
+                                       {
+                                               char buf[512];
+                                               regerror(e, &a->acl_dnre, buf, 512);
+                                               fprintf( stderr,
+                                                       "%s: line %d: regular expression \"%s\" bad because of %s\n",
+                                                       fname, lineno, right, buf );
+                                               acl_usage();
+                                       }
+#endif
                                        a->acl_dnpat = strdup( ".*" );
                                        continue;
                                }
@@ -79,14 +157,31 @@ parse_acl(
                                                acl_usage();
                                        }
                                } else if ( strcasecmp( left, "dn" ) == 0 ) {
+#ifdef USEREGEX
+                                       int e;
+                                       if ((e = regcomp(&a->acl_dnre, right,
+                                               REG_EXTENDED|REG_ICASE))) {
+                                               char buf[512];
+                                               regerror(e, &a->acl_dnre, buf, 512);
+                                               fprintf( stderr,
+                                                       "%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 ));
+                                       }
+#else 
                                        if ( (e = re_comp( right )) != NULL ) {
                                                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, e );
                                                acl_usage();
+
+                                       } else {
+                                               a->acl_dnpat = dn_upcase( strdup( right ) );
                                        }
-                                       a->acl_dnpat = dn_upcase( strdup(
-                                           right ) );
+#endif
                                } else if ( strncasecmp( left, "attr", 4 )
                                    == 0 ) {
                                        char    **alist;
@@ -131,38 +226,65 @@ parse_acl(
                        } else if ( strcasecmp( argv[i], "self" ) == 0 ) {
                                b->a_dnpat = strdup( "self" );
                        } else if ( strcasecmp( left, "dn" ) == 0 ) {
+#ifdef USEREGEX
+                               regtest(fname, lineno, right);
+#else
                                if ( (e = re_comp( right )) != NULL ) {
-                                       fprintf( stderr,
-                       "%s: line %d: regular expression \"%s\" bad: %s\n",
+                                       fprintf( stderr, "%s: line %d: regular expression \"%s\" bad: %s\n",
                                            fname, lineno, right, e );
                                        acl_usage();
                                }
+#endif
                                b->a_dnpat = dn_upcase( strdup( right ) );
                        } else if ( strcasecmp( left, "dnattr" )
                            == 0 ) {
                                b->a_dnattr = strdup( right );
+
+#ifdef ACLGROUP
+                       } else if ( strcasecmp( left, "group" )
+                           == 0 ) {
+                               char    *s;
+#ifdef USEREGEX
+                               regtest(fname, lineno, right);
+#else
+                               if ( (e = re_comp( right )) != NULL ) {
+                                       fprintf( stderr, "%s: line %d: regular expression \"%s\" bad: %s\n",
+                                           fname, lineno, right, e );
+                                       acl_usage();
+                               }
+#endif
+                               b->a_group = dn_upcase(strdup( right ));
+#endif
                        } else if ( strcasecmp( left, "domain" )
                            == 0 ) {
                                char    *s;
-
+#ifdef USEREGEX
+                               regtest(fname, lineno, right);
+#else
                                if ( (e = re_comp( right )) != NULL ) {
                                        fprintf( stderr,
-                       "%s: line %d: regular expression \"%s\" bad: %s\n",
+                                               "%s: line %d: regular expression \"%s\" bad: %s\n",
                                            fname, lineno, right, e );
                                        acl_usage();
                                }
+#endif
                                b->a_domainpat = strdup( right );
+
                                /* normalize the domain */
                                for ( s = b->a_domainpat; *s; s++ ) {
                                        *s = TOLOWER( *s );
                                }
                        } else if ( strcasecmp( left, "addr" ) == 0 ) {
+#ifdef USEREGEX
+                               regtest(fname, lineno, right);
+#else
                                if ( (e = re_comp( right )) != NULL ) {
                                        fprintf( stderr,
-                       "%s: line %d: regular expression \"%s\" bad: %s\n",
+                                               "%s: line %d: regular expression \"%s\" bad: %s\n",
                                            fname, lineno, right, e );
                                        acl_usage();
                                }
+#endif
                                b->a_addrpat = strdup( right );
                        } else {
                                fprintf( stderr,
@@ -198,16 +320,15 @@ parse_acl(
 
        /* if we have no real access clause, complain and do nothing */
        if ( a == NULL ) {
-       
                        fprintf( stderr,
-                   "%s: line %d: warning: no access clause(s) specified in access line\n",
+                               "%s: line %d: warning: no access clause(s) specified in access line\n",
                            fname, lineno );
 
        } else {
        
                if ( a->acl_access == NULL ) {
                        fprintf( stderr,
-                   "%s: line %d: warning: no by clause(s) specified in access line\n",
+                       "%s: line %d: warning: no by clause(s) specified in access line\n",
                            fname, lineno );
                }
 
index 51ef7a8171294c91122cb78f26ffe34787504850..748c5214640096f312ce1284f206edfbc60e215b 100644 (file)
@@ -20,21 +20,21 @@ VERSIONFILE = $(LDAPSRC)/build/version
 SRCS   = idl.c add.c search.c cache.c dbcache.c dn2id.c id2entry.c \
                index.c id2children.c nextid.c abandon.c compare.c \
                modify.c modrdn.c delete.c init.c config.c bind.c attr.c \
-               filterindex.c unbind.c kerberos.c close.c
+               filterindex.c unbind.c kerberos.c close.c group.c
 OBJS   = idl.o add.o search.o cache.o dbcache.o dn2id.o id2entry.o \
                index.o id2children.o nextid.o abandon.o compare.o \
                modify.o modrdn.o delete.o init.o config.o bind.o attr.o \
-               filterindex.o unbind.o kerberos.o close.o
+               filterindex.o unbind.o kerberos.o close.o group.o
 
 INCLUDES= -I. -I.. -I$(HDIR) $(KRBINCLUDEFLAG)
-DEFINES = $(DEFS) $(THREADS)
+DEFINES = $(DEFS) $(LDAP_CRYPT) $(THREADS)
 CFLAGS = $(INCLUDES) $(THREADSINCLUDE) $(DEFINES) $(ACFLAGS)
-LDFLAGS        = -L$(LDIR) $(KRBLIBFLAG)
+LDFLAGS        = -L$(LDIR) $(KRBLIBFLAG) $(LDAP_CRYPT_LIB)
 
 all:   FORCE
        -@echo "$(SLAPD_BACKENDS)" | grep LDAP_LDBM 2>&1 > /dev/null; \
        if [ $$? = 0 ]; then \
-            $(MAKE) $(MFLAGS) CC=$(CC) libback-ldbm.a; \
+            $(MAKE) $(MFLAGS) CC="$(CC)" libback-ldbm.a; \
        else \
            echo "Include -DLDAP_LDBM in SLAPD_BACKENDS in the"; \
            echo "Make-common file to build the ldbm backend"; \
@@ -72,77 +72,60 @@ links:
 # DO NOT DELETE THIS LINE -- mkdep uses it.
 # DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
 
-idl.o: idl.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-idl.o: ../../../include/ldap.h ../../../include/lthread.h
-idl.o: ../../../include/ldif.h ../../../include/ldapconfig.h back-ldbm.h
-idl.o: ../../../include/ldbm.h
-add.o: add.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-add.o: ../../../include/ldap.h ../../../include/lthread.h
-add.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-search.o: search.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-search.o: ../../../include/ldap.h ../../../include/lthread.h
-search.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-cache.o: cache.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-cache.o: ../../../include/ldap.h ../../../include/lthread.h
-cache.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-dbcache.o: dbcache.c ../../../include/portable.h ../slap.h
-dbcache.o: ../../../include/avl.h ../../../include/lber.h
-dbcache.o: ../../../include/ldap.h ../../../include/lthread.h
-dbcache.o: ../../../include/ldif.h ../../../include/ldapconfig.h back-ldbm.h
-dbcache.o: ../../../include/ldbm.h
-dn2id.o: dn2id.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-dn2id.o: ../../../include/ldap.h ../../../include/lthread.h
-dn2id.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-id2entry.o: id2entry.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-id2entry.o: ../../../include/ldap.h ../../../include/lthread.h
-id2entry.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-index.o: index.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-index.o: ../../../include/ldap.h ../../../include/lthread.h
-index.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-id2children.o: id2children.c ../slap.h ../../../include/avl.h
-id2children.o: ../../../include/lber.h ../../../include/ldap.h
-id2children.o: ../../../include/lthread.h ../../../include/ldif.h back-ldbm.h
+idl.o: idl.c ../../../include/avl.h ../../../include/proto-lber.h
+idl.o: ../../../include/proto-ldap.h ../../../include/ldif.h back-ldbm.h
+add.o: add.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+add.o: ../../../include/ldif.h ../../../include/ldbm.h
+search.o: search.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+search.o: ../../../include/ldif.h ../../../include/ldbm.h
+cache.o: cache.c ../../../include/avl.h ../../../include/proto-lber.h
+cache.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+cache.o: ../../../include/ldbm.h
+dbcache.o: dbcache.c ../../../include/portable.h ../../../include/avl.h
+dbcache.o: ../../../include/proto-lber.h ../../../include/proto-ldap.h
+dbcache.o: ../../../include/ldif.h back-ldbm.h
+dn2id.o: dn2id.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+dn2id.o: ../../../include/ldif.h ../../../include/ldbm.h
+id2entry.o: id2entry.c ../../../include/avl.h ../../../include/proto-lber.h
+id2entry.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+id2entry.o: ../../../include/ldbm.h
+index.o: index.c ../../../include/avl.h ../../../include/proto-lber.h
+index.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+index.o: ../../../include/ldbm.h
+id2children.o: id2children.c ../../../include/proto-lber.h
+id2children.o: ../../../include/proto-ldap.h ../../../include/ldif.h
 id2children.o: ../../../include/ldbm.h
-nextid.o: nextid.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-nextid.o: ../../../include/ldap.h ../../../include/lthread.h
-nextid.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
+nextid.o: nextid.c ../../../include/avl.h ../../../include/proto-lber.h
+nextid.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+nextid.o: ../../../include/ldbm.h
 abandon.o: abandon.c
-compare.o: compare.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-compare.o: ../../../include/ldap.h ../../../include/lthread.h
-compare.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-modify.o: modify.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-modify.o: ../../../include/ldap.h ../../../include/lthread.h
-modify.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-modrdn.o: modrdn.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-modrdn.o: ../../../include/ldap.h ../../../include/lthread.h
-modrdn.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-delete.o: delete.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-delete.o: ../../../include/ldap.h ../../../include/lthread.h
-delete.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-init.o: init.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-init.o: ../../../include/ldap.h ../../../include/lthread.h
-init.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-config.o: config.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-config.o: ../../../include/ldap.h ../../../include/lthread.h
-config.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-bind.o: bind.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-bind.o: ../../../include/ldap.h ../../../include/lthread.h
-bind.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-attr.o: attr.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-attr.o: ../../../include/ldap.h ../../../include/lthread.h
-attr.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-filterindex.o: filterindex.c ../slap.h ../../../include/avl.h
-filterindex.o: ../../../include/lber.h ../../../include/ldap.h
-filterindex.o: ../../../include/lthread.h ../../../include/ldif.h back-ldbm.h
-filterindex.o: ../../../include/ldbm.h
-unbind.o: unbind.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-unbind.o: ../../../include/ldap.h ../../../include/lthread.h
-unbind.o: ../../../include/ldif.h
-kerberos.o: kerberos.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-kerberos.o: ../../../include/ldap.h ../../../include/lthread.h
-kerberos.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
-close.o: close.c ../slap.h ../../../include/avl.h ../../../include/lber.h
-close.o: ../../../include/ldap.h ../../../include/lthread.h
-close.o: ../../../include/ldif.h back-ldbm.h ../../../include/ldbm.h
+compare.o: compare.c ../../../include/proto-lber.h
+compare.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+compare.o: ../../../include/ldbm.h
+modify.o: modify.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+modify.o: ../../../include/ldif.h ../../../include/ldbm.h
+modrdn.o: modrdn.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+modrdn.o: ../../../include/ldif.h ../../../include/ldbm.h
+delete.o: delete.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+delete.o: ../../../include/ldif.h ../../../include/ldbm.h
+init.o: init.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+init.o: ../../../include/ldif.h ../../../include/ldbm.h
+config.o: config.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+config.o: ../../../include/ldif.h ../../../include/ldbm.h
+bind.o: bind.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+bind.o: ../../../include/ldif.h ../../../include/ldbm.h
+attr.o: attr.c ../../../include/proto-lber.h ../../../include/proto-ldap.h
+attr.o: ../../../include/ldif.h ../../../include/ldbm.h
+filterindex.o: filterindex.c ../../../include/avl.h
+filterindex.o: ../../../include/proto-lber.h ../../../include/proto-ldap.h
+filterindex.o: ../../../include/ldif.h ../../../include/ldbm.h
+unbind.o: unbind.c ../../../include/avl.h ../../../include/proto-lber.h
+unbind.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+kerberos.o: kerberos.c ../../../include/proto-lber.h
+kerberos.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+kerberos.o: ../../../include/ldbm.h
+close.o: close.c ../../../include/avl.h ../../../include/proto-lber.h
+close.o: ../../../include/proto-ldap.h ../../../include/ldif.h
+close.o: ../../../include/ldbm.h
 
 # IF YOU PUT ANYTHING HERE IT WILL GO AWAY
index 998bfa8c6acc215d0e6a1240cb494210580d55a1..c0e32b12d139b1785969a00f37556a09e7a565ee 100644 (file)
@@ -21,6 +21,7 @@ extern int    ldbm_back_abandon();
 extern int     ldbm_back_config();
 extern int     ldbm_back_init();
 extern int     ldbm_back_close();
+extern int      ldbm_back_group();
 #endif
 
 #ifdef LDAP_PASSWD
@@ -86,6 +87,9 @@ new_backend(
                be->be_config = ldbm_back_config;
                be->be_init = ldbm_back_init;
                be->be_close = ldbm_back_close;
+#ifdef ACLGROUP
+               be->be_group = ldbm_back_group;
+#endif
                be->be_type = "ldbm";
                foundit = 1;
        }
@@ -105,6 +109,9 @@ new_backend(
                be->be_config = passwd_back_config;
                be->be_init = NULL;
                be->be_close = NULL;
+#ifdef ACLGROUP
+               be->be_group = NULL;
+#endif
                be->be_type = "passwd";
                foundit = 1;
        }
@@ -124,6 +131,9 @@ new_backend(
                be->be_config = shell_back_config;
                be->be_init = shell_back_init;
                be->be_close = NULL;
+#ifdef ACLGROUP
+               be->be_group = NULL;
+#endif
                be->be_type = "shell";
                foundit = 1;
        }
@@ -231,3 +241,14 @@ be_unbind(
                }
        }
 }
+
+#ifdef ACLGROUP
+int 
+be_group(Backend *be, char *bdn, char *edn)
+{
+        if (be->be_group)
+                return(be->be_group(be, bdn, edn));
+        else
+                return(1);
+}
+#endif
index a1ff6e5e755cb202ec1fb25028591eb53c45af47..98faf2faaa0ad2c1dcf6645db05dd59114ebd35d 100644 (file)
@@ -7,10 +7,19 @@
 
 int access_allowed( Backend *be, Connection *conn, Operation *op, Entry *e,
        char *attr, struct berval *val, char *dn, int  access );
+
+#ifdef USEREGEX
+struct acl * acl_get_applicable( Backend *be, Operation *op, Entry *e,
+       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, char *edn, regmatch_t matches[] );
+#else
 struct acl * acl_get_applicable( Backend *be, Operation *op, Entry *e,
-       char *attr );
+       char *attr, char *edn );
 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 );
+#endif
+
 int acl_check_mods( Backend *be, Connection *conn, Operation *op, Entry *e,
        LDAPMod *mods );
 
index 0ef82a7b3e36e03f85a4a71a91040153fe182064..1e761f26494e82696b062a9c3a4c813a5c37edaa 100644 (file)
@@ -121,7 +121,13 @@ send_ldap_result2(
                pthread_mutex_lock( &active_threads_mutex );
                active_threads--;
                conn->c_writewaiter = 1;
+
+#ifdef SIGSTKFLT
+               pthread_kill( listener_tid, SIGSTKFLT );
+#else
                pthread_kill( listener_tid, SIGUSR1 );
+#endif
+
                pthread_cond_wait( &conn->c_wcv, &active_threads_mutex );
                pthread_mutex_unlock( &active_threads_mutex );
 
@@ -192,6 +198,9 @@ send_search_entry(
        Attribute       *a;
        int             i, rc, bytes, sd;
        struct acl      *acl;
+        char            *edn;
+
+
 
        Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 );
 
@@ -202,15 +211,18 @@ send_search_entry(
                return( 1 );
        }
 
+       edn = dn_normalize_case( strdup( e->e_dn ) );
+
 #ifdef COMPAT30
        if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER ))
-           == NULLBER ) {
+               == NULLBER ) {
 #else
        if ( (ber = der_alloc()) == NULLBER ) {
 #endif
                Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
                send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL,
-                   "ber_alloc" );
+                       "ber_alloc" );
+               free(edn);
                return( 1 );
        }
 
@@ -220,26 +232,53 @@ send_search_entry(
                    LDAP_RES_SEARCH_ENTRY, e->e_dn );
        } else
 #endif
-               rc = ber_printf( ber, "{it{s{", op->o_msgid,
-                   LDAP_RES_SEARCH_ENTRY, e->e_dn );
+       rc = ber_printf( ber, "{it{s{", op->o_msgid,
+               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 ) {
+#ifdef USEREGEX
+               regmatch_t       matches[MAXREMATCHES];
+#endif
+
                if ( attrs != NULL && ! charray_inlist( attrs, a->a_type ) ) {
                        continue;
                }
 
-               acl = acl_get_applicable( be, op, e, a->a_type );
+#ifdef USEREGEX
+               /* 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 );
+               }
+#else
+               acl= acl_get_applicable( be, op, e, a->a_type, edn );
+#endif
 
-               if ( ! acl_access_allowed( acl, be, conn, e, NULL, op,
-                   ACL_READ ) ) {
+#ifdef USEREGEX
+               if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, ACL_READ,
+                       edn, matches ) ) 
+#else
+               if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, ACL_READ,
+                       edn ) ) 
+#endif
+               {
                        continue;
                }
 
@@ -248,14 +287,21 @@ send_search_entry(
                        ber_free( ber, 1 );
                        send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
                            NULL, "ber_printf type" );
+                       free(edn);
                        return( 1 );
                }
 
                if ( ! attrsonly ) {
                        for ( i = 0; a->a_vals[i] != NULL; i++ ) {
-                               if ( a->a_syntax & SYNTAX_DN &&
-                                   ! acl_access_allowed( acl, be, conn, e,
-                                   a->a_vals[i], op, ACL_READ ) )
+#ifdef USEREGEX
+                               if ( a->a_syntax & SYNTAX_DN && 
+                                       ! acl_access_allowed( acl, be, conn, e, a->a_vals[i], op,
+                                               ACL_READ, edn, matches) )
+#else
+                               if ( a->a_syntax & SYNTAX_DN && 
+                                       ! acl_access_allowed( acl, be, conn, e, a->a_vals[i], op,
+                                               ACL_READ, edn ) )
+#endif
                                {
                                        continue;
                                }
@@ -270,6 +316,7 @@ send_search_entry(
                                        send_ldap_result( conn, op,
                                            LDAP_OPERATIONS_ERROR, NULL,
                                            "ber_printf value" );
+                                        free(edn);
                                        return( 1 );
                                }
                        }
@@ -280,10 +327,13 @@ send_search_entry(
                        ber_free( ber, 1 );
                        send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
                            NULL, "ber_printf type end" );
+                        free(edn);
                        return( 1 );
                }
        }
 
+       free(edn);
+
 #ifdef COMPAT30
        if ( conn->c_version == 30 ) {
                rc = ber_printf( ber, "}}}}" );
index a67e567cbe4071382181a8cbb4b832d1fc5a0318..ebdb2d6c43a2b032122ea90e7f5db629b462ea40 100644 (file)
@@ -6,6 +6,11 @@
 #define LDAP_SYSLOG
 
 #include <syslog.h>
+
+#ifdef USEREGEX
+#include <regex.h>
+#endif
+
 #include "avl.h"
 #include "lber.h"
 #include "ldap.h"
@@ -122,6 +127,9 @@ struct access {
        char            *a_domainpat;
        char            *a_dnattr;
        long            a_access;
+#ifdef USEREGEX
+        char            *a_group;
+#endif
 #define ACL_NONE       0x01
 #define ACL_COMPARE    0x02
 #define ACL_SEARCH     0x04
@@ -135,6 +143,9 @@ struct access {
 struct acl {
        /* "to" part: the entries this acl applies to */
        Filter          *acl_filter;
+#ifdef USEREGEX
+        regex_t          acl_dnre;
+#endif
        char            *acl_dnpat;
        char            **acl_attrs;
 
@@ -188,6 +199,10 @@ typedef struct backend {
        IFP     be_config;      /* backend config routine                  */
        IFP     be_init;        /* backend init routine                    */
        IFP     be_close;       /* backend close routine                   */
+
+#ifdef ACLGROUP
+       IFP     be_group;       /* backend group member test               */
+#endif
 } Backend;
 
 /*