]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/aclparse.c
minor cleanup
[openldap] / servers / slapd / aclparse.c
index e54db75c96fcafa01b09bd354974ba74876a7653..00c93c23b1ea036d99c88214c4cd57981883ffd9 100644 (file)
@@ -21,6 +21,8 @@ static void           split(char *line, int splitchar, char **left, char **right);
 static void            access_append(Access **l, Access *a);
 static void            acl_usage(void) LDAP_GCCATTR((noreturn));
 
+static char            *acl_regex_normalized_dn(const char *pattern);
+
 #ifdef LDAP_DEBUG
 static void            print_acl(Backend *be, AccessControl *a);
 static void            print_access(Access *b);
@@ -136,9 +138,9 @@ parse_acl(
                                split( argv[i], '=', &left, &right );
                                split( left, '.', &left, &style );
 
-                               if ( right == NULL || *right == '\0' ) {
+                               if ( right == NULL ) {
                                        fprintf( stderr,
-       "%s: line %d: missing \"=\" in (or value after) \"%s\" in to clause\n",
+       "%s: line %d: missing \"=\" in \"%s\" in to clause\n",
                                            fname, lineno, left );
                                        acl_usage();
                                }
@@ -167,7 +169,7 @@ parse_acl(
                                                        a->acl_dn_pat = ch_strdup( "*" );
 
                                                } else {
-                                                       a->acl_dn_pat = ch_strdup( right );
+                                                       a->acl_dn_pat = acl_regex_normalized_dn( right );
                                                }
                                        } else if ( strcasecmp( style, "base" ) == 0 ) {
                                                a->acl_dn_style = ACL_STYLE_BASE;
@@ -342,8 +344,8 @@ parse_acl(
                                                        pat = ch_strdup( "*" );
 
                                                } else {
-                                                       regtest(fname, lineno, right);
-                                                       pat = ch_strdup( right );
+                                                       pat = acl_regex_normalized_dn( right );
+                                                       regtest(fname, lineno, pat);
                                                }
                                        } else if ( right == NULL || *right == '\0' ) {
                                                fprintf( stderr,
@@ -375,6 +377,13 @@ parse_acl(
                                }
 
                                if ( strcasecmp( left, "dnattr" ) == 0 ) {
+                                       if ( right == NULL || right[ 0 ] == '\0' ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+                                                       fname, lineno, left );
+                                               acl_usage();
+                                       }
+
                                        if( b->a_dn_at != NULL ) {
                                                fprintf( stderr,
                                                        "%s: line %d: dnattr already specified.\n",
@@ -419,6 +428,13 @@ parse_acl(
                                        char *name = NULL;
                                        char *value = NULL;
 
+                                       if ( right == NULL || right[ 0 ] == '\0' ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+                                                       fname, lineno, left );
+                                               acl_usage();
+                                       }
+
                                        if( b->a_group_pat != NULL ) {
                                                fprintf( stderr,
                                                        "%s: line %d: group pattern already specified.\n",
@@ -438,8 +454,9 @@ parse_acl(
 
                                        b->a_group_style = sty;
                                        if (sty == ACL_STYLE_REGEX) {
-                                               regtest(fname, lineno, right);
-                                               b->a_group_pat = ch_strdup( right );
+                                               char *tmp = acl_regex_normalized_dn( right );
+                                               regtest(fname, lineno, tmp);
+                                               b->a_group_pat = tmp;
                                        } else {
                                                b->a_group_pat = ch_strdup( right );
                                                dn_normalize(b->a_group_pat);
@@ -539,7 +556,7 @@ parse_acl(
                                                        fprintf( stderr,
                                                                "%s: line %d: group: \"%s\" not allowed by \"%s\"\n",
                                                                fname, lineno,
-                                                               b->a_group_at->ad_cname->bv_val,
+                                                               b->a_group_at->ad_cname.bv_val,
                                                                b->a_group_oc->soc_oid );
                                                        acl_usage();
                                                }
@@ -548,6 +565,13 @@ parse_acl(
                                }
 
                                if ( strcasecmp( left, "peername" ) == 0 ) {
+                                       if ( right == NULL || right[ 0 ] == '\0' ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+                                                       fname, lineno, left );
+                                               acl_usage();
+                                       }
+
                                        if( b->a_peername_pat != NULL ) {
                                                fprintf( stderr,
                                                        "%s: line %d: peername pattern already specified.\n",
@@ -557,13 +581,23 @@ parse_acl(
 
                                        b->a_peername_style = sty;
                                        if (sty == ACL_STYLE_REGEX) {
-                                               regtest(fname, lineno, right);
+                                               char *tmp = acl_regex_normalized_dn( right );
+                                               regtest(fname, lineno, tmp);
+                                               b->a_peername_pat = tmp;
+                                       } else {
+                                               b->a_peername_pat = ch_strdup( right );
                                        }
-                                       b->a_peername_pat = ch_strdup( right );
                                        continue;
                                }
 
                                if ( strcasecmp( left, "sockname" ) == 0 ) {
+                                       if ( right == NULL || right[ 0 ] == '\0' ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+                                                       fname, lineno, left );
+                                               acl_usage();
+                                       }
+
                                        if( b->a_sockname_pat != NULL ) {
                                                fprintf( stderr,
                                                        "%s: line %d: sockname pattern already specified.\n",
@@ -573,13 +607,23 @@ parse_acl(
 
                                        b->a_sockname_style = sty;
                                        if (sty == ACL_STYLE_REGEX) {
-                                               regtest(fname, lineno, right);
+                                               char *tmp = acl_regex_normalized_dn( right );
+                                               regtest(fname, lineno, tmp);
+                                               b->a_sockname_pat = tmp;
+                                       } else {
+                                               b->a_sockname_pat = ch_strdup( right );
                                        }
-                                       b->a_sockname_pat = ch_strdup( right );
                                        continue;
                                }
 
                                if ( strcasecmp( left, "domain" ) == 0 ) {
+                                       if ( right == NULL || right[ 0 ] == '\0' ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+                                                       fname, lineno, left );
+                                               acl_usage();
+                                       }
+
                                        if( b->a_domain_pat != NULL ) {
                                                fprintf( stderr,
                                                        "%s: line %d: domain pattern already specified.\n",
@@ -589,13 +633,23 @@ parse_acl(
 
                                        b->a_domain_style = sty;
                                        if (sty == ACL_STYLE_REGEX) {
-                                               regtest(fname, lineno, right);
+                                               char *tmp = acl_regex_normalized_dn( right );
+                                               regtest(fname, lineno, tmp);
+                                               b->a_domain_pat = tmp;
+                                       } else {
+                                               b->a_domain_pat = ch_strdup( right );
                                        }
-                                       b->a_domain_pat = ch_strdup( right );
                                        continue;
                                }
 
                                if ( strcasecmp( left, "sockurl" ) == 0 ) {
+                                       if ( right == NULL || right[ 0 ] == '\0' ) {
+                                               fprintf( stderr,
+                                                       "%s: line %d: missing \"=\" in (or value after) \"%s\" in by clause\n",
+                                                       fname, lineno, left );
+                                               acl_usage();
+                                       }
+
                                        if( b->a_sockurl_pat != NULL ) {
                                                fprintf( stderr,
                                                        "%s: line %d: sockurl pattern already specified.\n",
@@ -605,9 +659,12 @@ parse_acl(
 
                                        b->a_sockurl_style = sty;
                                        if (sty == ACL_STYLE_REGEX) {
-                                               regtest(fname, lineno, right);
+                                               char *tmp = acl_regex_normalized_dn( right );
+                                               regtest(fname, lineno, tmp);
+                                               b->a_sockurl_pat = tmp;
+                                       } else {
+                                               b->a_sockurl_pat = ch_strdup( right );
                                        }
-                                       b->a_sockurl_pat = ch_strdup( right );
                                        continue;
                                }
 
@@ -1065,19 +1122,22 @@ acl_usage( void )
 {
        fprintf( stderr, "\n"
                "<access clause> ::= access to <what> "
-                               "[ by <who> <access> <control> ]+ \n"
-               "<what> ::= * | [dn=<regex>] [filter=<ldapfilter>] [attrs=<attrlist>]\n"
+                               "[ by <who> <access> [ <control> ] ]+ \n"
+               "<what> ::= * | [dn[.<dnstyle>]=<regex>] [filter=<ldapfilter>] [attrs=<attrlist>]\n"
                "<attrlist> ::= <attr> | <attr> , <attrlist>\n"
                "<attr> ::= <attrname> | entry | children\n"
-               "<who> ::= [ * | anonymous | users | self | dn=<regex> ]\n"
+               "<who> ::= [ * | anonymous | users | self | dn[.<dnstyle>]=<regex> ]\n"
                        "\t[dnattr=<attrname>]\n"
-                       "\t[group[/<objectclass>[/<attrname>]]=<regex>]\n"
-                       "\t[peername=<regex>] [sockname=<regex>]\n"
-                       "\t[domain=<regex>] [sockurl=<regex>]\n"
+                       "\t[group[/<objectclass>[/<attrname>]][.<style>]=<regex>]\n"
+                       "\t[peername[.<style>]=<regex>] [sockname[.<style>]=<regex>]\n"
+                       "\t[domain[.<style>]=<regex>] [sockurl[.<style>]=<regex>]\n"
 #ifdef SLAPD_ACI_ENABLED
                        "\t[aci=<attrname>]\n"
 #endif
                        "\t[ssf=<n>] [transport_ssf=<n>] [tls_ssf=<n>] [sasl_ssf=<n>]\n"
+               "<dnstyle> ::= regex | base | exact (alias of base) | one | sub | children\n"
+               "<style> ::= regex | base | exact (alias of base)\n"
+               "<groupflags> ::= R\n"
                "<access> ::= [self]{<level>|<priv>}\n"
                "<level> ::= none | auth | compare | search | read | write\n"
                "<priv> ::= {=|+|-}{w|r|s|c|x}+\n"
@@ -1086,6 +1146,45 @@ acl_usage( void )
        exit( EXIT_FAILURE );
 }
 
+/*
+ * At present it simply eats the (optional) space after 
+ * a RDN separator (,)
+ * Eventually will evolve in a more complete normalization
+ */
+static char *
+acl_regex_normalized_dn(
+       const char *pattern
+)
+{
+       char *str, *p;
+
+       str = ch_strdup( pattern );
+
+       if ( str == NULL ) {
+               return( NULL );
+       }
+
+       for ( p = str; p[ 0 ]; p++ ) {
+               /* escape */
+               if ( p[ 0 ] == '\\' ) {
+                       p++;
+               }
+
+               if ( p[ 0 ] == ',' ) {
+                       if ( p[ 1 ] == ' ' ) {
+                               char *q;
+                       
+                               for ( q = &p[ 2 ]; q[ 0 ] == ' '; q++ ) {
+                                       /* DO NOTHING */ ;
+                               }
+                               AC_MEMCPY( &p[ 1 ], &q[ 0 ], strlen( q ) + 1 );
+                       }
+               }
+       }
+
+       return( str );
+}
+
 static void
 split(
     char       *line,
@@ -1200,7 +1299,7 @@ print_access( Access *b )
        }
 
        if ( b->a_dn_at != NULL ) {
-               fprintf( stderr, " dnattr=%s", b->a_dn_at->ad_cname->bv_val );
+               fprintf( stderr, " dnattr=%s", b->a_dn_at->ad_cname.bv_val );
        }
 
        if ( b->a_group_pat != NULL ) {
@@ -1211,7 +1310,7 @@ print_access( Access *b )
                                b->a_group_oc->soc_oclass.oc_oid );
 
                        if ( b->a_group_at ) {
-                               fprintf( stderr, " attributeType: %s", b->a_group_at->ad_cname->bv_val );
+                               fprintf( stderr, " attributeType: %s", b->a_group_at->ad_cname.bv_val );
                        }
                }
     }
@@ -1234,7 +1333,7 @@ print_access( Access *b )
 
 #ifdef SLAPD_ACI_ENABLED
        if ( b->a_aci_at != NULL ) {
-               fprintf( stderr, " aci=%s", b->a_aci_at->ad_cname->bv_val );
+               fprintf( stderr, " aci=%s", b->a_aci_at->ad_cname.bv_val );
        }
 #endif