X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Faclparse.c;h=00c93c23b1ea036d99c88214c4cd57981883ffd9;hb=0f30fb0d8f0adbbb7b41fd455c57aa56d64c9853;hp=8d64d9aad8d9f7b4f0d16846a535acda6291122f;hpb=1bfcb4b03915b951392d3c36483b7ce84ba5a6e3;p=openldap diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index 8d64d9aad8..00c93c23b1 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -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; @@ -258,7 +260,7 @@ parse_acl( b = (Access *) ch_calloc( 1, sizeof(Access) ); - ACL_INVALIDATE( b->a_mask ); + ACL_INVALIDATE( b->a_access_mask ); if ( ++i == argc ) { fprintf( stderr, @@ -279,7 +281,7 @@ parse_acl( { sty = ACL_STYLE_REGEX; } else if ( strcasecmp( style, "exact" ) == 0 ) { - sty = ACL_STYLE_BASE; + sty = ACL_STYLE_EXACT; } else if ( strcasecmp( style, "base" ) == 0 ) { sty = ACL_STYLE_BASE; } else if ( strcasecmp( style, "one" ) == 0 ) { @@ -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", @@ -393,7 +402,9 @@ parse_acl( if( !is_at_syntax( b->a_dn_at->ad_type, - SLAPD_DN_SYNTAX ) ) + SLAPD_DN_SYNTAX ) && + !is_at_syntax( b->a_dn_at->ad_type, + SLAPD_NAMEUID_SYNTAX )) { fprintf( stderr, "%s: line %d: dnattr \"%s\": " @@ -417,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", @@ -436,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); @@ -466,7 +485,6 @@ parse_acl( } } -#if 0 if( is_object_subclass( b->a_group_oc, slap_schema.si_oc_referral ) ) { @@ -486,10 +504,9 @@ parse_acl( fname, lineno, value ); acl_usage(); } -#endif if (name && *name) { - rc = slap_str2ad( right, &b->a_group_at, &text ); + rc = slap_str2ad( name, &b->a_group_at, &text ); if( rc != LDAP_SUCCESS ) { fprintf( stderr, @@ -510,7 +527,9 @@ parse_acl( } if( !is_at_syntax( b->a_group_at->ad_type, - SLAPD_DN_SYNTAX ) ) + SLAPD_DN_SYNTAX ) && + !is_at_syntax( b->a_group_at->ad_type, + SLAPD_NAMEUID_SYNTAX ) ) { fprintf( stderr, "%s: line %d: group \"%s\": inappropriate syntax: %s\n", @@ -537,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(); } @@ -546,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", @@ -555,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", @@ -571,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", @@ -587,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", @@ -603,9 +659,33 @@ 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 ); + } + continue; + } + + if ( strcasecmp( left, "set" ) == 0 ) { + if( b->a_set_pat != NULL ) { + fprintf( stderr, + "%s: line %d: set attribute already specified.\n", + fname, lineno ); + acl_usage(); } - b->a_sockurl_pat = ch_strdup( right ); + + if ( right == NULL || *right == '\0' ) { + fprintf( stderr, + "%s: line %d: no set is defined\n", + fname, lineno ); + acl_usage(); + } + + b->a_set_style = sty; + b->a_set_pat = ch_strdup(right); + continue; } @@ -653,6 +733,110 @@ parse_acl( } #endif /* SLAPD_ACI_ENABLED */ + if ( strcasecmp( left, "ssf" ) == 0 ) { + if( b->a_authz.sai_ssf ) { + fprintf( stderr, + "%s: line %d: ssf attribute already specified.\n", + fname, lineno ); + acl_usage(); + } + + if ( right == NULL || *right == '\0' ) { + fprintf( stderr, + "%s: line %d: no ssf is defined\n", + fname, lineno ); + acl_usage(); + } + + b->a_authz.sai_ssf = atoi( right ); + + if( !b->a_authz.sai_ssf ) { + fprintf( stderr, + "%s: line %d: invalid ssf value (%s)\n", + fname, lineno, right ); + acl_usage(); + } + continue; + } + + if ( strcasecmp( left, "transport_ssf" ) == 0 ) { + if( b->a_authz.sai_transport_ssf ) { + fprintf( stderr, + "%s: line %d: transport_ssf attribute already specified.\n", + fname, lineno ); + acl_usage(); + } + + if ( right == NULL || *right == '\0' ) { + fprintf( stderr, + "%s: line %d: no transport_ssf is defined\n", + fname, lineno ); + acl_usage(); + } + + b->a_authz.sai_transport_ssf = atoi( right ); + + if( !b->a_authz.sai_transport_ssf ) { + fprintf( stderr, + "%s: line %d: invalid transport_ssf value (%s)\n", + fname, lineno, right ); + acl_usage(); + } + continue; + } + + if ( strcasecmp( left, "tls_ssf" ) == 0 ) { + if( b->a_authz.sai_tls_ssf ) { + fprintf( stderr, + "%s: line %d: tls_ssf attribute already specified.\n", + fname, lineno ); + acl_usage(); + } + + if ( right == NULL || *right == '\0' ) { + fprintf( stderr, + "%s: line %d: no tls_ssf is defined\n", + fname, lineno ); + acl_usage(); + } + + b->a_authz.sai_tls_ssf = atoi( right ); + + if( !b->a_authz.sai_tls_ssf ) { + fprintf( stderr, + "%s: line %d: invalid tls_ssf value (%s)\n", + fname, lineno, right ); + acl_usage(); + } + continue; + } + + if ( strcasecmp( left, "sasl_ssf" ) == 0 ) { + if( b->a_authz.sai_sasl_ssf ) { + fprintf( stderr, + "%s: line %d: sasl_ssf attribute already specified.\n", + fname, lineno ); + acl_usage(); + } + + if ( right == NULL || *right == '\0' ) { + fprintf( stderr, + "%s: line %d: no sasl_ssf is defined\n", + fname, lineno ); + acl_usage(); + } + + b->a_authz.sai_sasl_ssf = atoi( right ); + + if( !b->a_authz.sai_sasl_ssf ) { + fprintf( stderr, + "%s: line %d: invalid sasl_ssf value (%s)\n", + fname, lineno, right ); + acl_usage(); + } + continue; + } + if( right != NULL ) { /* unsplit */ right[-1] = '='; @@ -663,7 +847,7 @@ parse_acl( if( i == argc || ( strcasecmp( left, "stop" ) == 0 )) { /* out of arguments or plain stop */ - ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE); + ACL_PRIV_ASSIGN(b->a_access_mask, ACL_PRIV_ADDITIVE); b->a_type = ACL_STOP; access_append( &a->acl_access, b ); @@ -673,7 +857,7 @@ parse_acl( if( strcasecmp( left, "continue" ) == 0 ) { /* plain continue */ - ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE); + ACL_PRIV_ASSIGN(b->a_access_mask, ACL_PRIV_ADDITIVE); b->a_type = ACL_CONTINUE; access_append( &a->acl_access, b ); @@ -683,7 +867,7 @@ parse_acl( if( strcasecmp( left, "break" ) == 0 ) { /* plain continue */ - ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE); + ACL_PRIV_ASSIGN(b->a_access_mask, ACL_PRIV_ADDITIVE); b->a_type = ACL_BREAK; access_append( &a->acl_access, b ); @@ -693,7 +877,7 @@ parse_acl( if ( strcasecmp( left, "by" ) == 0 ) { /* we've gone too far */ --i; - ACL_PRIV_ASSIGN(b->a_mask, ACL_PRIV_ADDITIVE); + ACL_PRIV_ASSIGN(b->a_access_mask, ACL_PRIV_ADDITIVE); b->a_type = ACL_STOP; access_append( &a->acl_access, b ); @@ -703,13 +887,13 @@ parse_acl( /* get */ if( strncasecmp( left, "self", 4 ) == 0 ) { b->a_dn_self = 1; - ACL_PRIV_ASSIGN( b->a_mask, str2accessmask( &left[4] ) ); + ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[4] ) ); } else { - ACL_PRIV_ASSIGN( b->a_mask, str2accessmask( left ) ); + ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( left ) ); } - if( ACL_IS_INVALID( b->a_mask ) ) { + if( ACL_IS_INVALID( b->a_access_mask ) ) { fprintf( stderr, "%s: line %d: expecting got \"%s\"\n", fname, lineno, left ); @@ -774,7 +958,7 @@ parse_acl( } char * -accessmask2str( slap_access_mask_t mask, char *buf ) +accessmask2str( slap_mask_t mask, char *buf ) { int none=1; @@ -861,12 +1045,12 @@ accessmask2str( slap_access_mask_t mask, char *buf ) return buf; } -slap_access_mask_t +slap_mask_t str2accessmask( const char *str ) { - slap_access_mask_t mask; + slap_mask_t mask; - if( !isalpha(str[0]) ) { + if( !ASCII_ALPHA(str[0]) ) { int i; if ( str[0] == '=' ) { @@ -938,18 +1122,22 @@ acl_usage( void ) { fprintf( stderr, "\n" " ::= access to " - "[ by ]+ \n" - " ::= * | [dn=] [filter=] [attrs=]\n" + "[ by [ ] ]+ \n" + " ::= * | [dn[.]=] [filter=] [attrs=]\n" " ::= | , \n" " ::= | entry | children\n" - " ::= [ * | anonymous | users | self | dn= ]\n" + " ::= [ * | anonymous | users | self | dn[.]= ]\n" "\t[dnattr=]\n" - "\t[group[/[/]]=]\n" - "\t[peername=] [sockname=]\n" - "\t[domain=] [sockurl=]\n" + "\t[group[/[/]][.