X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fconfig.c;h=8951f40664229f103fa8e1c54acede67ce3d63bc;hb=9b4bf8a973c8cfea809be9a4b658f785a6b16f2f;hp=f04c52f4d3e09113306c3a30c1c726b2805565c7;hpb=07ebdca237e239aeca47ff53b8f68d5f24ae4a7a;p=openldap diff --git a/servers/slapd/config.c b/servers/slapd/config.c index f04c52f4d3..8951f40664 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -1,7 +1,7 @@ /* config.c - configuration file handling routines */ /* $OpenLDAP$ */ /* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -15,9 +15,12 @@ #include #include -#include "lutil.h" #include "ldap_pvt.h" #include "slap.h" +#ifdef LDAP_SLAPI +#include "slapi.h" +#endif +#include "lutil.h" #define ARGS_STEP 512 @@ -30,7 +33,9 @@ struct slap_limits_set deflimit = { SLAPD_DEFAULT_SIZELIMIT, /* backward compatible limits */ 0, - -1 /* no limit on unchecked size */ + -1, /* no limit on unchecked size */ + 0, /* page limit */ + 0 /* hide number of entries left */ }; AccessControl *global_acl = NULL; @@ -52,24 +57,21 @@ char **cargv; struct berval default_search_base = { 0, NULL }; struct berval default_search_nbase = { 0, NULL }; unsigned num_subordinates = 0; -#ifdef SLAPD_SCHEMA_DN -struct berval global_schemadn; -struct berval global_schemandn; -#endif +struct berval global_schemadn = { 0, NULL }; +struct berval global_schemandn = { 0, NULL }; ber_len_t sockbuf_max_incoming = SLAP_SB_MAX_INCOMING_DEFAULT; ber_len_t sockbuf_max_incoming_auth= SLAP_SB_MAX_INCOMING_AUTH; +int slap_conn_max_pending = SLAP_CONN_MAX_PENDING_DEFAULT; +int slap_conn_max_pending_auth = SLAP_CONN_MAX_PENDING_AUTH; + char *slapd_pid_file = NULL; char *slapd_args_file = NULL; char *strtok_quote_ptr; -#ifdef SLAPD_RLOOKUPS -int use_reverse_lookup = 1; -#else /* !SLAPD_RLOOKUPS */ int use_reverse_lookup = 0; -#endif /* !SLAPD_RLOOKUPS */ static char *fp_getline(FILE *fp, int *lineno); static void fp_getline_init(int *lineno); @@ -333,6 +335,80 @@ read_config( const char *fname, int depth ) sockbuf_max_incoming_auth = max; + /* set conn pending max */ + } else if ( strcasecmp( cargv[0], "conn_max_pending" ) == 0 ) { + long max; + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: missing max in \"conn_max_pending " + "\" line\n", fname, lineno, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing max in \"conn_max_pending \" line\n", + fname, lineno, 0 ); +#endif + + return( 1 ); + } + + max = atol( cargv[1] ); + + if( max < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: invalid max value (%ld) in " + "\"conn_max_pending \" line.\n", + fname, lineno, max ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: invalid max value (%ld) in " + "\"conn_max_pending \" line.\n", + fname, lineno, max ); +#endif + + return( 1 ); + } + + slap_conn_max_pending = max; + + /* set conn pending max authenticated */ + } else if ( strcasecmp( cargv[0], "conn_max_pending_auth" ) == 0 ) { + long max; + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: missing max in \"conn_max_pending_auth " + "\" line\n", fname, lineno, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing max in \"conn_max_pending_auth \" line\n", + fname, lineno, 0 ); +#endif + + return( 1 ); + } + + max = atol( cargv[1] ); + + if( max < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: invalid max value (%ld) in " + "\"conn_max_pending_auth \" line.\n", + fname, lineno, max ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: invalid max value (%ld) in " + "\"conn_max_pending_auth \" line.\n", + fname, lineno, max ); +#endif + + return( 1 ); + } + + slap_conn_max_pending_auth = max; + /* default search base */ } else if ( strcasecmp( cargv[0], "defaultSearchBase" ) == 0 ) { if ( cargc < 2 ) { @@ -561,14 +637,11 @@ read_config( const char *fname, int depth ) lutil_salt_format( cargv[1] ); -#ifdef HAVE_CYRUS_SASL /* SASL config options */ } else if ( strncasecmp( cargv[0], "sasl", 4 ) == 0 ) { if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) ) return 1; -#endif /* HAVE_CYRUS_SASL */ -#ifdef SLAPD_SCHEMA_DN } else if ( strcasecmp( cargv[0], "schemadn" ) == 0 ) { struct berval dn; if ( cargc < 2 ) { @@ -603,7 +676,7 @@ read_config( const char *fname, int depth ) #endif return 1; } -#endif /* SLAPD_SCHEMA_DN */ + /* set UCDATA path */ } else if ( strcasecmp( cargv[0], "ucdata-path" ) == 0 ) { int err; @@ -667,25 +740,55 @@ read_config( const char *fname, int depth ) for ( i = 1; i < cargc; i++ ) { if ( strncasecmp( cargv[i], "size", 4 ) == 0 ) { rc = parse_limit( cargv[i], lim ); + if ( rc ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: unable " + "to parse value \"%s\" in \"sizelimit " + "\" line.\n", fname, lineno, cargv[i] ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: unable " + "to parse value \"%s\" " + "in \"sizelimit " + "\" line\n", + fname, lineno, cargv[i] ); +#endif + return( 1 ); + } + } else { - lim->lms_s_soft = atoi( cargv[i] ); - lim->lms_s_hard = 0; - } + if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) { + lim->lms_s_soft = -1; + } else { + char *next; - if ( rc ) { + lim->lms_s_soft = strtol( cargv[i] , &next, 0 ); + if ( next == cargv[i] ) { #ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: unable " - "to parse value \"%s\" in \"sizelimit " - "\" line.\n", fname, lineno, cargv[i] ); + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: unable to parse limit \"%s\" in \"sizelimit \" " + "line.\n", fname, lineno, cargv[i] ); #else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: unable " - "to parse value \"%s\" " - "in \"sizelimit " - "\" line\n", - fname, lineno, cargv[i] ); + Debug( LDAP_DEBUG_ANY, + "%s: line %d: unable to parse limit \"%s\" in \"sizelimit \" line\n", + fname, lineno, cargv[i] ); +#endif + return( 1 ); + + } else if ( next[0] != '\0' ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: trailing chars \"%s\" in \"sizelimit \" " + "line ignored.\n", fname, lineno, next ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: trailing chars \"%s\" in \"sizelimit \" line ignored\n", + fname, lineno, next ); #endif + } + } + lim->lms_s_hard = 0; } } @@ -717,25 +820,55 @@ read_config( const char *fname, int depth ) for ( i = 1; i < cargc; i++ ) { if ( strncasecmp( cargv[i], "time", 4 ) == 0 ) { rc = parse_limit( cargv[i], lim ); + if ( rc ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: unable to parse value \"%s\" " + "in \"timelimit \" line.\n", + fname, lineno, cargv[i] ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: unable " + "to parse value \"%s\" " + "in \"timelimit " + "\" line\n", + fname, lineno, cargv[i] ); +#endif + return( 1 ); + } + } else { - lim->lms_t_soft = atoi( cargv[i] ); - lim->lms_t_hard = 0; - } + if ( strcasecmp( cargv[i], "unlimited" ) == 0 ) { + lim->lms_t_soft = -1; + } else { + char *next; - if ( rc ) { + lim->lms_t_soft = strtol( cargv[i] , &next, 0 ); + if ( next == cargv[i] ) { #ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: unable to parse value \"%s\" " - "in \"timelimit \" line.\n", - fname, lineno, cargv[i] ); + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: unable to parse limit \"%s\" in \"timelimit \" " + "line.\n", fname, lineno, cargv[i] ); #else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: unable " - "to parse value \"%s\" " - "in \"timelimit " - "\" line\n", - fname, lineno, cargv[i] ); + Debug( LDAP_DEBUG_ANY, + "%s: line %d: unable to parse limit \"%s\" in \"timelimit \" line\n", + fname, lineno, cargv[i] ); +#endif + return( 1 ); + + } else if ( next[0] != '\0' ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: trailing chars \"%s\" in \"timelimit \" " + "line ignored.\n", fname, lineno, next ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: trailing chars \"%s\" in \"timelimit \" line ignored\n", + fname, lineno, next ); #endif + } + } + lim->lms_t_hard = 0; } } @@ -900,141 +1033,6 @@ read_config( const char *fname, int depth ) ber_bvarray_add( &be->be_suffix, &pdn ); ber_bvarray_add( &be->be_nsuffix, &ndn ); - /* set database suffixAlias */ - } else if ( strcasecmp( cargv[0], "suffixAlias" ) == 0 ) { - Backend *tmp_be; - struct berval alias, palias, nalias; - struct berval aliased, paliased, naliased; - - if ( cargc < 2 ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: missing alias and aliased_dn in " - "\"suffixAlias \" line.\n", - fname, lineno, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing alias and aliased_dn in " - "\"suffixAlias \" line.\n", - fname, lineno, 0 ); -#endif - - return( 1 ); - } else if ( cargc < 3 ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: missing aliased_dn in " - "\"suffixAlias \" line\n", - fname, lineno, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing aliased_dn in " - "\"suffixAlias \" line\n", - fname, lineno, 0 ); -#endif - return( 1 ); - - } else if ( cargc > 3 ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: extra cruft in suffixAlias line (ignored)\n", - fname, lineno, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: extra cruft in suffixAlias line (ignored)\n", - fname, lineno, 0 ); -#endif - } - - if ( be == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, INFO, - "%s: line %d: suffix line must appear inside a database " - "definition.\n", fname, lineno, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: suffixAlias line" - " must appear inside a database definition.\n", - fname, lineno, 0 ); -#endif - return 1; - } - - if ( load_ucdata( NULL ) < 0 ) return 1; - - alias.bv_val = cargv[1]; - alias.bv_len = strlen( cargv[1] ); - - rc = dnPrettyNormal( NULL, &alias, &palias, &nalias ); - if( rc != LDAP_SUCCESS ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: alias DN is invalid.\n", fname, lineno, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: alias DN is invalid\n", - fname, lineno, 0 ); -#endif - return( 1 ); - } - - tmp_be = select_backend( &nalias, 0, 0 ); - free( nalias.bv_val ); - if ( tmp_be && tmp_be != be ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, INFO, - "%s: line %d: suffixAlias served by a preceeding " - "backend \"%s\"\n", fname, lineno, - tmp_be->be_suffix[0].bv_val ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: suffixAlias served by" - " a preceeding backend \"%s\"\n", - fname, lineno, tmp_be->be_suffix[0].bv_val ); -#endif - free( palias.bv_val ); - return -1; - } - - aliased.bv_val = cargv[2]; - aliased.bv_len = strlen( cargv[2] ); - - rc = dnPrettyNormal( NULL, &aliased, &paliased, &naliased ); - if( rc != LDAP_SUCCESS ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: aliased DN is invalid.\n", fname, lineno,0 ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: aliased DN is invalid\n", - fname, lineno, 0 ); -#endif - free( palias.bv_val ); - return( 1 ); - } - - tmp_be = select_backend( &naliased, 0, 0 ); - free( naliased.bv_val ); - if ( tmp_be && tmp_be != be ) { -#ifdef NEW_LOGGING - LDAP_LOG( CONFIG, INFO, - "%s: line %d: suffixAlias derefs to a different backend " - "a preceeding backend \"%s\"\n", - fname, lineno, tmp_be->be_suffix[0].bv_val ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: suffixAlias derefs to differnet backend" - " a preceeding backend \"%s\"\n", - fname, lineno, tmp_be->be_suffix[0].bv_val ); -#endif - free( palias.bv_val ); - free( paliased.bv_val ); - return -1; - } - - ber_bvarray_add( &be->be_suffixAlias, &palias ); - ber_bvarray_add( &be->be_suffixAlias, &paliased ); - /* set max deref depth */ } else if ( strcasecmp( cargv[0], "maxDerefDepth" ) == 0 ) { int i; @@ -1260,16 +1258,18 @@ read_config( const char *fname, int depth ) } else if( strcasecmp( cargv[i], "bind_anon_dn" ) == 0 ) { allows |= SLAP_ALLOW_BIND_ANON_DN; + } else if( strcasecmp( cargv[i], "update_anon" ) == 0 ) { + allows |= SLAP_ALLOW_UPDATE_ANON; + } else if( strcasecmp( cargv[i], "none" ) != 0 ) { #ifdef NEW_LOGGING - LDAP_LOG( CONFIG, CRIT, - "%s: line %d: unknown feature %s in " - "\"allow \" line.\n", - fname, lineno, cargv[1] ); + LDAP_LOG( CONFIG, CRIT, "%s: line %d: " + "unknown feature %s in \"allow \" line.\n", + fname, lineno, cargv[1] ); #else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: unknown feature %s in \"allow \" line\n", - fname, lineno, cargv[i] ); + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "unknown feature %s in \"allow \" line\n", + fname, lineno, cargv[i] ); #endif return( 1 ); @@ -1320,9 +1320,6 @@ read_config( const char *fname, int depth ) } else if( strcasecmp( cargv[i], "bind_simple" ) == 0 ) { disallows |= SLAP_DISALLOW_BIND_SIMPLE; - } else if( strcasecmp( cargv[i], "bind_simple_unprotected" ) == 0 ) { - disallows |= SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED; - } else if( strcasecmp( cargv[i], "bind_krbv4" ) == 0 ) { disallows |= SLAP_DISALLOW_BIND_KRBV4; @@ -1483,6 +1480,12 @@ read_config( const char *fname, int depth ) set->sss_update_sasl = atoi( &cargv[i][sizeof("update_sasl")] ); + } else if( strncasecmp( cargv[i], "simple_bind=", + sizeof("simple_bind") ) == 0 ) + { + set->sss_simple_bind = + atoi( &cargv[i][sizeof("simple_bind")] ); + } else { #ifdef NEW_LOGGING LDAP_LOG( CONFIG, CRIT, @@ -1529,7 +1532,8 @@ read_config( const char *fname, int depth ) vals[0].bv_val = cargv[1]; vals[0].bv_len = strlen( vals[0].bv_val ); - value_add( &default_referral, vals ); + if( value_add( &default_referral, vals ) ) + return LDAP_OTHER; #ifdef NEW_LOGGING } else if ( strcasecmp( cargv[0], "logfile" ) == 0 ) { @@ -1577,9 +1581,21 @@ read_config( const char *fname, int depth ) /* specify an objectclass */ } else if ( strcasecmp( cargv[0], "objectclass" ) == 0 ) { - if ( *cargv[1] == '(' ) { + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, + "%s: line %d: illegal objectclass format.\n", + fname, lineno , 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: illegal objectclass format.\n", + fname, lineno, 0 ); +#endif + return( 1 ); + + } else if ( *cargv[1] == '(' /*')'*/) { char * p; - p = strchr(saveline,'('); + p = strchr(saveline,'(' /*')'*/); rc = parse_oc( fname, lineno, p, cargv ); if( rc ) return rc; @@ -1595,13 +1611,33 @@ read_config( const char *fname, int depth ) #endif } +#ifdef SLAP_EXTENDED_SCHEMA + } else if ( strcasecmp( cargv[0], "ditcontentrule" ) == 0 ) { + char * p; + p = strchr(saveline,'(' /*')'*/); + rc = parse_cr( fname, lineno, p, cargv ); + if( rc ) return rc; +#endif + /* specify an attribute type */ } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 ) || ( strcasecmp( cargv[0], "attribute" ) == 0 )) { - if ( *cargv[1] == '(' ) { + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, "%s: line %d: " + "illegal attribute type format.\n", + fname, lineno , 0 ); +#else + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "illegal attribute type format.\n", + fname, lineno, 0 ); +#endif + return( 1 ); + + } else if ( *cargv[1] == '(' /*')'*/) { char * p; - p = strchr(saveline,'('); + p = strchr(saveline,'(' /*')'*/); rc = parse_at( fname, lineno, p, cargv ); if( rc ) return rc; @@ -1618,6 +1654,13 @@ read_config( const char *fname, int depth ) } + /* define attribute option(s) */ + } else if ( strcasecmp( cargv[0], "attributeoptions" ) == 0 ) { + ad_define_option( NULL, NULL, 0 ); + for ( i = 1; i < cargc; i++ ) + if ( ad_define_option( cargv[i], fname, lineno ) != 0 ) + return 1; + /* turn on/off schema checking */ } else if ( strcasecmp( cargv[0], "schemacheck" ) == 0 ) { if ( cargc < 2 ) { @@ -1905,7 +1948,8 @@ read_config( const char *fname, int depth ) vals[0].bv_val = cargv[1]; vals[0].bv_len = strlen( vals[0].bv_val ); - value_add( &be->be_update_refs, vals ); + if( value_add( &be->be_update_refs, vals ) ) + return LDAP_OTHER; /* replication log file to which changes are appended */ } else if ( strcasecmp( cargv[0], "replogfile" ) == 0 ) { @@ -2239,6 +2283,74 @@ read_config( const char *fname, int depth ) #endif #endif /* !SLAPD_RLOOKUPS */ + /* Netscape plugins */ + } else if ( strcasecmp( cargv[0], "plugin" ) == 0 ) { +#if defined( LDAP_SLAPI ) + +#ifdef notdef /* allow global plugins, too */ + /* + * a "plugin" line must be inside a database + * definition, since we implement pre-,post- + * and extended operation plugins + */ + if ( be == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, + "%s: line %d: plugin line must appear " + "inside a database definition.\n", + fname, lineno, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "%s: line %d: plugin " + "line must appear inside a database " + "definition\n", fname, lineno, 0 ); +#endif + return( 1 ); + } +#endif /* notdef */ + + if ( netscape_plugin( be, fname, lineno, cargc, cargv ) + != LDAP_SUCCESS ) { + return( 1 ); + } + +#else /* !defined( LDAP_SLAPI ) */ +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, + "%s: line %d: SLAPI not supported.\n", + fname, lineno, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "%s: line %d: SLAPI " + "not supported.\n", fname, lineno, 0 ); +#endif + return( 1 ); + +#endif /* !defined( LDAP_SLAPI ) */ + + /* Netscape plugins */ + } else if ( strcasecmp( cargv[0], "pluginlog" ) == 0 ) { +#if defined( LDAP_SLAPI ) + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, INFO, + "%s: line %d: missing file name " + "in pluginlog line.\n", + fname, lineno, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing file name " + "in pluginlog line.\n", + fname, lineno, 0 ); +#endif + return( 1 ); + } + + if ( slapi_log_file != NULL ) { + ch_free( slapi_log_file ); + } + + slapi_log_file = ch_strdup( cargv[1] ); +#endif /* !defined( LDAP_SLAPI ) */ + /* pass anything else to the current backend info/db config routine */ } else { if ( bi != NULL ) { @@ -2301,13 +2413,11 @@ read_config( const char *fname, int depth ) if ( depth == 0 ) ch_free( cargv ); -#ifdef SLAPD_SCHEMA_DN if ( !global_schemadn.bv_val ) { ber_str2bv( SLAPD_SCHEMA_DN, sizeof(SLAPD_SCHEMA_DN)-1, 1, &global_schemadn ); dnNormalize2( NULL, &global_schemadn, &global_schemandn ); } -#endif if ( load_ucdata( NULL ) < 0 ) return 1; return( 0 ); @@ -2528,14 +2638,14 @@ void config_destroy( ) { ucdata_unload( UCDATA_ALL ); -#ifdef SLAPD_SCHEMA_DN free( global_schemandn.bv_val ); free( global_schemadn.bv_val ); -#endif free( line ); if ( slapd_args_file ) free ( slapd_args_file ); if ( slapd_pid_file ) free ( slapd_pid_file ); + if ( default_passwd_hash ) + free( default_passwd_hash ); acl_destroy( global_acl, NULL ); }