From 07a34489c6710ea341a9cd0b50d84c054c909ad1 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 14 Jun 2002 08:10:14 +0000 Subject: [PATCH] Added saslAuthzTo and saslAuthzFrom to system schema. Added sasl-authz-policy config keyword to control proxy authorization. Moved sasl-related config processing to sasl.c:slap_sasl_config(). Moved other global defs used only in saslauthz.c into saslauthz.c. --- servers/slapd/config.c | 127 +-------------------------- servers/slapd/proto-slap.h | 13 ++- servers/slapd/sasl.c | 165 ++++++++++++++++++++++++++++++++++++ servers/slapd/saslauthz.c | 86 +++++++++++++------ servers/slapd/schema_prep.c | 16 ++++ servers/slapd/slap.h | 22 +---- servers/slapd/tools/mimic.c | 14 +-- 7 files changed, 264 insertions(+), 179 deletions(-) diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 513372912a..0fdb6229c2 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -61,9 +61,6 @@ char *slapd_args_file = NULL; char *strtok_quote_ptr; -int nSaslRegexp = 0; -SaslRegexp_t *SaslRegexp = NULL; - #ifdef SLAPD_RLOOKUPS int use_reverse_lookup = 1; #else /* !SLAPD_RLOOKUPS */ @@ -561,129 +558,11 @@ read_config( const char *fname ) lutil_salt_format( cargv[1] ); - /* set SASL host */ - } else if ( strcasecmp( cargv[0], "sasl-host" ) == 0 ) { - if ( cargc < 2 ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "config", LDAP_LEVEL_CRIT, - "%s: line %d: missing host in \"sasl-host \" line\n", - fname, lineno )); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing host in \"sasl-host \" line\n", - fname, lineno, 0 ); -#endif - - return( 1 ); - } - - if ( global_host != NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "config", LDAP_LEVEL_CRIT, - "%s: line %d: already set sasl-host!\n", - fname, lineno )); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: already set sasl-host!\n", - fname, lineno, 0 ); -#endif - + /* SASL config options */ + } else if ( strncasecmp( cargv[0], "sasl", 4 ) == 0 ) { + if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) ) return 1; - } else { - global_host = ch_strdup( cargv[1] ); - } - - /* set SASL realm */ - } else if ( strcasecmp( cargv[0], "sasl-realm" ) == 0 ) { - if ( cargc < 2 ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "config", LDAP_LEVEL_CRIT, - "%s: line %d: missing realm in \"sasl-realm \" line.\n", - fname, lineno )); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing realm in \"sasl-realm \" line\n", - fname, lineno, 0 ); -#endif - - return( 1 ); - } - - if ( global_realm != NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "config", LDAP_LEVEL_CRIT, - "%s: line %d: already set sasl-realm!\n", - fname, lineno )); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: already set sasl-realm!\n", - fname, lineno, 0 ); -#endif - - return 1; - - } else { - global_realm = ch_strdup( cargv[1] ); - } - - } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) - || !strcasecmp( cargv[0], "saslregexp" ) ) - { - int rc; - if ( cargc != 3 ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "config", LDAP_LEVEL_CRIT, - "%s: line %d: need 2 args in " - "\"saslregexp \"\n", - fname, lineno )); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: need 2 args in \"saslregexp \"\n", - fname, lineno, 0 ); -#endif - - return( 1 ); - } - rc = slap_sasl_regexp_config( cargv[1], cargv[2] ); - if ( rc ) { - return rc; - } - - /* SASL security properties */ - } else if ( strcasecmp( cargv[0], "sasl-secprops" ) == 0 ) { - char *txt; - - if ( cargc < 2 ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "config", LDAP_LEVEL_CRIT, - "%s: line %d: missing flags in " - "\"sasl-secprops \" line\n", - fname, lineno )); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing flags in \"sasl-secprops \" line\n", - fname, lineno, 0 ); -#endif - - return 1; - } - - txt = slap_sasl_secprops( cargv[1] ); - if ( txt != NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG(( "config", LDAP_LEVEL_CRIT, - "%s: line %d sas-secprops: %s\n", - fname, lineno, txt )); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: sasl-secprops: %s\n", - fname, lineno, txt ); -#endif - - return 1; - } - /* set UCDATA path */ } else if ( strcasecmp( cargv[0], "ucdata-path" ) == 0 ) { int err; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index ad0f101074..98aab651f7 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -840,6 +840,14 @@ LDAP_SLAPD_F (int) slap_sasl_setpass( LDAPControl *** rspctrls, const char **text ); +LDAP_SLAPD_F (int) slap_sasl_config( + int cargc, + char **cargv, + char *line, + const char *fname, + int lineno ); + + /* * saslauthz.c */ @@ -852,6 +860,8 @@ LDAP_SLAPD_F (int) slap_sasl_authorized LDAP_P(( struct berval *authzid )); LDAP_SLAPD_F (int) slap_sasl_regexp_config LDAP_P(( const char *match, const char *replace )); +LDAP_SLAPD_F (int) slap_sasl_setpolicy LDAP_P(( const char * )); + /* * schema.c @@ -1038,9 +1048,6 @@ LDAP_SLAPD_V (int) ldap_syslog; LDAP_SLAPD_V (struct berval) default_search_base; LDAP_SLAPD_V (struct berval) default_search_nbase; -LDAP_SLAPD_V (int) nSaslRegexp; -LDAP_SLAPD_V (SaslRegexp_t*) SaslRegexp; - LDAP_SLAPD_V (ldap_pvt_thread_mutex_t) num_sent_mutex; LDAP_SLAPD_V (unsigned long) num_bytes_sent; LDAP_SLAPD_V (unsigned long) num_pdu_sent; diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 0ce8be3881..13088088af 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -44,6 +44,171 @@ static sasl_security_properties_t sasl_secprops; +int slap_sasl_config( int cargc, char **cargv, char *line, + const char *fname, int lineno ) +{ + /* set SASL proxy authorization policy */ + if ( strcasecmp( cargv[0], "sasl-authz-policy" ) == 0 ) { + if ( cargc != 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: missing policy in \"sasl-authz-policy \" line\n", + fname, lineno )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing policy in \"sasl-authz-policy \" line\n", + fname, lineno, 0 ); +#endif + + return( 1 ); + } + if ( slap_sasl_setpolicy( cargv[1] ) ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: unable " + "to parse value \"%s\" " + "in \"sasl-authz-policy " + "\" line.\n", + fname, lineno, cargv[1] )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: unable " + "to parse value \"%s\" " + "in \"sasl-authz-policy " + "\" line\n", + fname, lineno, cargv[1] ); +#endif + return( 1 ); + } + + + /* set SASL host */ + } else if ( strcasecmp( cargv[0], "sasl-host" ) == 0 ) { + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: missing host in \"sasl-host \" line\n", + fname, lineno )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing host in \"sasl-host \" line\n", + fname, lineno, 0 ); +#endif + + return( 1 ); + } + + if ( global_host != NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: already set sasl-host!\n", + fname, lineno )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: already set sasl-host!\n", + fname, lineno, 0 ); +#endif + + return 1; + + } else { + global_host = ch_strdup( cargv[1] ); + } + + /* set SASL realm */ + } else if ( strcasecmp( cargv[0], "sasl-realm" ) == 0 ) { + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: missing realm in \"sasl-realm \" line.\n", + fname, lineno )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing realm in \"sasl-realm \" line\n", + fname, lineno, 0 ); +#endif + + return( 1 ); + } + + if ( global_realm != NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: already set sasl-realm!\n", + fname, lineno )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: already set sasl-realm!\n", + fname, lineno, 0 ); +#endif + + return 1; + + } else { + global_realm = ch_strdup( cargv[1] ); + } + + } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) + || !strcasecmp( cargv[0], "saslregexp" ) ) + { + int rc; + if ( cargc != 3 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: need 2 args in " + "\"saslregexp \"\n", + fname, lineno )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: need 2 args in \"saslregexp \"\n", + fname, lineno, 0 ); +#endif + + return( 1 ); + } + rc = slap_sasl_regexp_config( cargv[1], cargv[2] ); + if ( rc ) { + return rc; + } + + /* SASL security properties */ + } else if ( strcasecmp( cargv[0], "sasl-secprops" ) == 0 ) { + char *txt; + + if ( cargc < 2 ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d: missing flags in " + "\"sasl-secprops \" line\n", + fname, lineno )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing flags in \"sasl-secprops \" line\n", + fname, lineno, 0 ); +#endif + + return 1; + } + + txt = slap_sasl_secprops( cargv[1] ); + if ( txt != NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "config", LDAP_LEVEL_CRIT, + "%s: line %d sasl-secprops: %s\n", + fname, lineno, txt )); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: sasl-secprops: %s\n", + fname, lineno, txt ); +#endif + + return 1; + } + } + + return LDAP_SUCCESS; +} + static int slap_sasl_log( void *context, diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index 8efc6d6713..b3f5ff9ca3 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -30,6 +30,50 @@ #include +#define SASLREGEX_REPLACE 10 + +typedef struct sasl_uri { + struct berval dn; + struct berval filter; + int scope; +} SaslUri_t; + +typedef struct sasl_regexp { + char *sr_match; /* regexp match pattern */ + SaslUri_t sr_replace; /* regexp replace pattern */ + regex_t sr_workspace; /* workspace for regexp engine */ + regmatch_t sr_strings[SASLREGEX_REPLACE]; /* strings matching $1,$2 ... */ + int sr_dn_offset[SASLREGEX_REPLACE+2]; /* offsets of $1,$2... in *replace */ + int sr_fi_offset[SASLREGEX_REPLACE+2]; /* offsets of $1,$2... in *replace */ +} SaslRegexp_t; + +static int nSaslRegexp = 0; +static SaslRegexp_t *SaslRegexp = NULL; + +/* What SASL proxy authorization policies are allowed? */ +#define SASL_AUTHZ_NONE 0 +#define SASL_AUTHZ_FROM 1 +#define SASL_AUTHZ_TO 2 + +static int authz_policy = SASL_AUTHZ_NONE; + +int slap_sasl_setpolicy( const char *arg ) +{ + int rc = LDAP_SUCCESS; + + if ( strcasecmp( arg, "none" ) == 0 ) + authz_policy = SASL_AUTHZ_NONE; + else if ( strcasecmp( arg, "from" ) == 0 ) + authz_policy = SASL_AUTHZ_FROM; + else if ( strcasecmp( arg, "to" ) == 0 ) + authz_policy = SASL_AUTHZ_TO; + else if ( strcasecmp( arg, "both" ) == 0 ) + authz_policy = SASL_AUTHZ_FROM | SASL_AUTHZ_TO; + else + rc = LDAP_OTHER; + return rc; +} + /* URI format: ldap:///[?[][?[][?[]]]] */ static int slap_parseURI( struct berval *uri, @@ -598,27 +642,21 @@ CONCLUDED: * The DNs should not have the dn: prefix */ static int -slap_sasl_check_authz(struct berval *searchDN, struct berval *assertDN, struct berval *attr, struct berval *authc) +slap_sasl_check_authz(struct berval *searchDN, struct berval *assertDN, AttributeDescription *ad, struct berval *authc) { - const char *errmsg; int i, rc; BerVarray vals=NULL; - AttributeDescription *ad=NULL; #ifdef NEW_LOGGING LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY, "slap_sasl_check_authz: does %s match %s rule in %s?\n", - assertDN->bv_val, attr->bv_val, searchDN->bv_val )); + assertDN->bv_val, ad->ad_cname.bv_val, searchDN->bv_val )); #else Debug( LDAP_DEBUG_TRACE, "==>slap_sasl_check_authz: does %s match %s rule in %s?\n", - assertDN->bv_val, attr->bv_val, searchDN->bv_val); + assertDN->bv_val, ad->ad_cname.bv_val, searchDN->bv_val); #endif - rc = slap_bv2ad( attr, &ad, &errmsg ); - if( rc != LDAP_SUCCESS ) - goto COMPLETE; - rc = backend_attribute( NULL, NULL, NULL, NULL, searchDN, ad, &vals ); if( rc != LDAP_SUCCESS ) goto COMPLETE; @@ -636,10 +674,10 @@ COMPLETE: #ifdef NEW_LOGGING LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY, - "slap_sasl_check_authz: %s check returning %s\n", attr->bv_val, rc )); + "slap_sasl_check_authz: %s check returning %s\n", ad->ad_cname.bv_val, rc )); #else Debug( LDAP_DEBUG_TRACE, - "<==slap_sasl_check_authz: %s check returning %d\n", attr->bv_val, rc, 0); + "<==slap_sasl_check_authz: %s check returning %d\n", ad->ad_cname.bv_val, rc, 0); #endif return( rc ); @@ -651,12 +689,6 @@ COMPLETE: * The DNs should not have the dn: prefix */ -static struct berval sasl_authz_src = { - sizeof(SASL_AUTHZ_SOURCE_ATTR)-1, SASL_AUTHZ_SOURCE_ATTR }; - -static struct berval sasl_authz_dst = { - sizeof(SASL_AUTHZ_DEST_ATTR)-1, SASL_AUTHZ_DEST_ATTR }; - int slap_sasl_authorized( struct berval *authcDN, struct berval *authzDN ) { int rc = LDAP_INAPPROPRIATE_AUTH; @@ -683,17 +715,21 @@ int slap_sasl_authorized( struct berval *authcDN, struct berval *authzDN ) } /* Check source rules */ - rc = slap_sasl_check_authz( authcDN, authzDN, &sasl_authz_src, - authcDN ); - if( rc == LDAP_SUCCESS ) { - goto DONE; + if( authz_policy & SASL_AUTHZ_TO ) { + rc = slap_sasl_check_authz( authcDN, authzDN, + slap_schema.si_ad_saslAuthzTo, authcDN ); + if( rc == LDAP_SUCCESS ) { + goto DONE; + } } /* Check destination rules */ - rc = slap_sasl_check_authz( authzDN, authcDN, &sasl_authz_dst, - authcDN ); - if( rc == LDAP_SUCCESS ) { - goto DONE; + if( authz_policy & SASL_AUTHZ_FROM ) { + rc = slap_sasl_check_authz( authzDN, authcDN, + slap_schema.si_ad_saslAuthzFrom, authcDN ); + if( rc == LDAP_SUCCESS ) { + goto DONE; + } } rc = LDAP_INAPPROPRIATE_AUTH; diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c index 84c3daf257..78ebcd5f43 100644 --- a/servers/slapd/schema_prep.c +++ b/servers/slapd/schema_prep.c @@ -478,6 +478,22 @@ static struct slap_schema_ad_map { "SINGLE-VALUE NO-USER-MODIFICATION USAGE dSAOperation )", NULL, SLAP_AT_HIDE, NULL, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_children) }, + { "saslAuthzTo", "( 1.3.6.1.4.1.4203.1.3.3 " + "NAME 'saslAuthzTo' " + "DESC 'SASL proxy authorization targets' " + "EQUALITY caseExactMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " + "USAGE dSAOperation )", + NULL, 0, NULL, NULL, NULL, + offsetof(struct slap_internal_schema, si_ad_saslAuthzTo) }, + { "saslAuthzFrom", "( 1.3.6.1.4.1.4203.1.3.4 " + "NAME 'saslAuthzFrom' " + "DESC 'SASL proxy authorization sources' " + "EQUALITY caseExactMatch " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " + "USAGE dSAOperation )", + NULL, 0, NULL, NULL, NULL, + offsetof(struct slap_internal_schema, si_ad_saslAuthzFrom) }, #ifdef SLAPD_ACI_ENABLED { "OpenLDAPaci", "( 1.3.6.1.4.1.4203.666.1.5 " "NAME 'OpenLDAPaci' " diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index fb8ab890a5..b4c0d795dd 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -618,6 +618,8 @@ struct slap_internal_schema { /* Access Control Internals */ AttributeDescription *si_ad_entry; AttributeDescription *si_ad_children; + AttributeDescription *si_ad_saslAuthzTo; + AttributeDescription *si_ad_saslAuthzFrom; #ifdef SLAPD_ACI_ENABLED AttributeDescription *si_ad_aci; #endif @@ -1604,26 +1606,6 @@ typedef struct slap_conn { #define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) #endif - -#define SASLREGEX_REPLACE 10 -#define SASL_AUTHZ_SOURCE_ATTR "saslAuthzTo" -#define SASL_AUTHZ_DEST_ATTR "saslAuthzFrom" - -typedef struct sasl_uri { - struct berval dn; - struct berval filter; - int scope; -} SaslUri_t; - -typedef struct sasl_regexp { - char *sr_match; /* regexp match pattern */ - SaslUri_t sr_replace; /* regexp replace pattern */ - regex_t sr_workspace; /* workspace for regexp engine */ - regmatch_t sr_strings[SASLREGEX_REPLACE]; /* strings matching $1,$2 ... */ - int sr_dn_offset[SASLREGEX_REPLACE+2]; /* offsets of $1,$2... in *replace */ - int sr_fi_offset[SASLREGEX_REPLACE+2]; /* offsets of $1,$2... in *replace */ -} SaslRegexp_t; - /* * listener; need to access it from monitor backend */ diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c index afd1388389..a6c9ebb3ae 100644 --- a/servers/slapd/tools/mimic.c +++ b/servers/slapd/tools/mimic.c @@ -153,14 +153,14 @@ int slap_sasl_setpass( return LDAP_SUCCESS; } -char * slap_sasl_secprops( const char *in ) +int slap_sasl_config( + int cargc, + char **cargv, + char *line, + const char *fname, + int lineno ) { - return NULL; -} - -int slap_sasl_regexp_config( const char *match, const char *replace ) -{ - return(0); + return LDAP_SUCCESS; } -- 2.39.5