X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Faclparse.c;h=37db9afd7f80fbdbaf8fed5496b23ed83f823ab0;hb=6a9c44849c1c20b9d961de7a0b6585dcd059154a;hp=37fbd565f3cfe842f4eff5a9a09f1f6d91a1a533;hpb=b90c3d6fd3f9cc104d20cc80a5464c266b67a800;p=openldap diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index 37fbd565f3..37db9afd7f 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1998-2006 The OpenLDAP Foundation. + * Copyright 1998-2007 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -52,6 +52,7 @@ char *style_strings[] = { "users", "self", "ip", + "ipv6", "path", NULL }; @@ -340,7 +341,7 @@ parse_acl( Debug( LDAP_DEBUG_ANY, "%s: line %d: " "only one to clause allowed in access line\n", fname, lineno, 0 ); - return acl_usage(); + goto fail; } a = (AccessControl *) ch_calloc( 1, sizeof(AccessControl) ); for ( ++i; i < argc; i++ ) { @@ -756,7 +757,7 @@ parse_acl( "%s: line %d: empty level " "in \"level{n}\"\n", fname, lineno, 0 ); - return acl_usage(); + goto fail; } p[0] = '\0'; } @@ -804,6 +805,14 @@ parse_acl( } else if ( strcasecmp( style, "ip" ) == 0 ) { sty = ACL_STYLE_IP; + } else if ( strcasecmp( style, "ipv6" ) == 0 ) { +#ifndef LDAP_PF_INET6 + Debug( LDAP_DEBUG_ANY, + "%s: line %d: IPv6 not supported\n", + fname, lineno, 0 ); +#endif /* ! LDAP_PF_INET6 */ + sty = ACL_STYLE_IPV6; + } else if ( strcasecmp( style, "path" ) == 0 ) { sty = ACL_STYLE_PATH; #ifndef LDAP_PF_LOCAL @@ -1101,6 +1110,7 @@ parse_acl( if ( strncasecmp( left, "group", STRLENOF( "group" ) ) == 0 ) { char *name = NULL; char *value = NULL; + char *attr_name = SLAPD_GROUP_ATTR; switch ( sty ) { case ACL_STYLE_REGEX: @@ -1218,49 +1228,41 @@ parse_acl( } if ( name && *name ) { - rc = slap_str2ad( name, &b->a_group_at, &text ); - - if( rc != LDAP_SUCCESS ) { - char buf[ SLAP_TEXT_BUFLEN ]; - - snprintf( buf, sizeof( buf ), - "group \"%s\": %s.", - right, text ); - Debug( LDAP_DEBUG_ANY, - "%s: line %d: %s\n", - fname, lineno, buf ); - goto fail; - } + attr_name = name; *--name = '/'; - } else { - rc = slap_str2ad( SLAPD_GROUP_ATTR, &b->a_group_at, &text ); + } - if ( rc != LDAP_SUCCESS ) { - char buf[ SLAP_TEXT_BUFLEN ]; + rc = slap_str2ad( attr_name, &b->a_group_at, &text ); + if ( rc != LDAP_SUCCESS ) { + char buf[ SLAP_TEXT_BUFLEN ]; - snprintf( buf, sizeof( buf ), - "group \"%s\": %s.", - SLAPD_GROUP_ATTR, text ); - Debug( LDAP_DEBUG_ANY, - "%s: line %d: %s\n", - fname, lineno, buf ); - goto fail; - } + snprintf( buf, sizeof( buf ), + "group \"%s\": %s.", + right, text ); + Debug( LDAP_DEBUG_ANY, + "%s: line %d: %s\n", + fname, lineno, buf ); + goto fail; } if ( !is_at_syntax( b->a_group_at->ad_type, - SLAPD_DN_SYNTAX ) && - !is_at_syntax( b->a_group_at->ad_type, - SLAPD_NAMEUID_SYNTAX ) && - !is_at_subtype( b->a_group_at->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) + SLAPD_DN_SYNTAX ) /* e.g. "member" */ + && !is_at_syntax( b->a_group_at->ad_type, + SLAPD_NAMEUID_SYNTAX ) /* e.g. memberUID */ + && !is_at_subtype( b->a_group_at->ad_type, + slap_schema.si_ad_labeledURI->ad_type ) /* e.g. memberURL */ ) { char buf[ SLAP_TEXT_BUFLEN ]; snprintf( buf, sizeof( buf ), - "group \"%s\": inappropriate syntax: %s.", + "group \"%s\" attr \"%s\": inappropriate syntax: %s; " + "must be " SLAPD_DN_SYNTAX " (DN), " + SLAPD_NAMEUID_SYNTAX " (NameUID) " + "or a subtype of labeledURI.", right, - b->a_group_at->ad_type->sat_syntax_oid ); + attr_name, + at_syntax( b->a_group_at->ad_type ) ); Debug( LDAP_DEBUG_ANY, "%s: line %d: %s\n", fname, lineno, buf ); @@ -1270,13 +1272,13 @@ parse_acl( { int rc; - struct berval vals[2]; + ObjectClass *ocs[2]; - ber_str2bv( b->a_group_oc->soc_oid, 0, 0, &vals[0] ); - BER_BVZERO( &vals[1] ); + ocs[0] = b->a_group_oc; + ocs[1] = NULL; rc = oc_check_allowed( b->a_group_at->ad_type, - vals, NULL ); + ocs, NULL ); if( rc != 0 ) { char buf[ SLAP_TEXT_BUFLEN ]; @@ -1301,6 +1303,7 @@ parse_acl( case ACL_STYLE_EXPAND: /* cheap replacement to regex for simple expansion */ case ACL_STYLE_IP: + case ACL_STYLE_IPV6: case ACL_STYLE_PATH: /* legal, peername specific */ break; @@ -1384,6 +1387,52 @@ parse_acl( goto fail; } } + +#ifdef LDAP_PF_INET6 + } else if ( sty == ACL_STYLE_IPV6 ) { + char *addr = NULL, + *mask = NULL, + *port = NULL; + + split( right, '{', &addr, &port ); + split( addr, '%', &addr, &mask ); + + if ( inet_pton( AF_INET6, addr, &b->a_peername_addr6 ) != 1 ) { + /* illegal address */ + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "illegal peername address \"%s\".\n", + fname, lineno, addr ); + goto fail; + } + + if ( mask == NULL ) { + mask = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF"; + } + + if ( inet_pton( AF_INET6, mask, &b->a_peername_mask6 ) != 1 ) { + /* illegal mask */ + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "illegal peername address mask " + "\"%s\".\n", + fname, lineno, mask ); + goto fail; + } + + b->a_peername_port = -1; + if ( port ) { + char *end = NULL; + + b->a_peername_port = strtol( port, &end, 10 ); + if ( end == port || end[0] != '}' ) { + /* illegal port */ + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "illegal peername port specification " + "\"{%s}\".\n", + fname, lineno, port ); + goto fail; + } + } +#endif /* LDAP_PF_INET6 */ } } continue; @@ -1784,6 +1833,7 @@ parse_acl( /* out of arguments or plain stop */ ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE ); + ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE); b->a_type = ACL_STOP; access_append( &a->acl_access, b ); @@ -1794,6 +1844,7 @@ parse_acl( /* plain continue */ ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE ); + ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE); b->a_type = ACL_CONTINUE; access_append( &a->acl_access, b ); @@ -1804,6 +1855,7 @@ parse_acl( /* plain continue */ ACL_PRIV_ASSIGN(b->a_access_mask, ACL_PRIV_ADDITIVE); + ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE); b->a_type = ACL_BREAK; access_append( &a->acl_access, b ); @@ -1814,6 +1866,7 @@ parse_acl( /* we've gone too far */ --i; ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE ); + ACL_PRIV_SET( b->a_access_mask, ACL_PRIV_NONE); b->a_type = ACL_STOP; access_append( &a->acl_access, b ); @@ -1821,16 +1874,19 @@ parse_acl( } /* get */ - if ( strncasecmp( left, "self", STRLENOF( "self" ) ) == 0 ) { - b->a_dn_self = 1; - ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "self" ) ] ) ); + { + char *lleft = left; - } else if ( strncasecmp( left, "realself", STRLENOF( "realself" ) ) == 0 ) { - b->a_realdn_self = 1; - ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( &left[ STRLENOF( "realself" ) ] ) ); + if ( strncasecmp( left, "self", STRLENOF( "self" ) ) == 0 ) { + b->a_dn_self = 1; + lleft = &left[ STRLENOF( "self" ) ]; - } else { - ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( left ) ); + } else if ( strncasecmp( left, "realself", STRLENOF( "realself" ) ) == 0 ) { + b->a_realdn_self = 1; + lleft = &left[ STRLENOF( "realself" ) ]; + } + + ACL_PRIV_ASSIGN( b->a_access_mask, str2accessmask( lleft ) ); } if ( ACL_IS_INVALID( b->a_access_mask ) ) { @@ -2131,7 +2187,10 @@ str2accessmask( const char *str ) } else if( TOLOWER((unsigned char) str[i]) == 'd' ) { ACL_PRIV_SET(mask, ACL_PRIV_DISCLOSE); - } else if( str[i] != '0' ) { + } else if( str[i] == '0' ) { + ACL_PRIV_SET(mask, ACL_PRIV_NONE); + + } else { ACL_INVALIDATE(mask); return mask; } @@ -2182,9 +2241,9 @@ acl_usage( void ) { char *access = " ::= access to " - "[ by [ ] ]+ \n"; + "[ by [ ] [ ] ]+ \n"; char *what = - " ::= * | [dn[.]=] [filter=] [attrs=]\n" + " ::= * | dn[.=] [filter=] [attrs=]\n" " ::= [val[/][.]=] | \n" " ::= [ , ]\n" " ::= | @ | ! | entry | children\n"; @@ -2206,7 +2265,7 @@ acl_usage( void ) "exact | regex\n" " ::= exact | regex | base(Object) | one(level) | " "sub(tree) | children\n" - " ::= exact | regex | ip | path\n" + " ::= exact | regex | ip | ipv6 | path\n" " ::= exact | regex | base(Object) | sub(tree)\n" " ::= [[real]self]{|}\n" " ::= none|disclose|auth|compare|search|read|{write|add|delete}|manage\n" @@ -2453,11 +2512,6 @@ str2access( const char *str ) return ACL_NONE; } else if ( strcasecmp( str, "disclose" ) == 0 ) { -#ifndef SLAP_ACL_HONOR_DISCLOSE - Debug( LDAP_DEBUG_ACL, "str2access: warning, " - "\"disclose\" privilege disabled.\n", - 0, 0, 0 ); -#endif /* SLAP_ACL_HONOR_DISCLOSE */ return ACL_DISCLOSE; } else if ( strcasecmp( str, "auth" ) == 0 ) {