From 1d562a7a52fe9cb9db29416e2eab85c797ac6c36 Mon Sep 17 00:00:00 2001 From: Ryan Tandy Date: Mon, 31 Aug 2015 16:54:34 -0700 Subject: [PATCH] ITS#6035 olcAuthIDRewrite insert/delete support --- servers/slapd/back-meta/config.c | 41 ------- servers/slapd/bconfig.c | 104 +++++++++--------- servers/slapd/overlays/rwm.c | 45 +------- servers/slapd/proto-slap.h | 6 +- servers/slapd/saslauthz.c | 179 +++++++++++++++++++++++++++++-- 5 files changed, 230 insertions(+), 145 deletions(-) diff --git a/servers/slapd/back-meta/config.c b/servers/slapd/back-meta/config.c index 5cb4d1c1dd..67b815c5e4 100644 --- a/servers/slapd/back-meta/config.c +++ b/servers/slapd/back-meta/config.c @@ -696,47 +696,6 @@ meta_suffixm_config( return rc; } -static int -slap_bv_x_ordered_unparse( BerVarray in, BerVarray *out ) -{ - int i; - BerVarray bva = NULL; - char ibuf[32], *ptr; - struct berval idx; - - assert( in != NULL ); - - for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) - /* count'em */ ; - - if ( i == 0 ) { - return 1; - } - - idx.bv_val = ibuf; - - bva = ch_malloc( ( i + 1 ) * sizeof(struct berval) ); - BER_BVZERO( &bva[ 0 ] ); - - for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) { - idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i ); - if ( idx.bv_len >= sizeof( ibuf ) ) { - ber_bvarray_free( bva ); - return 1; - } - - bva[i].bv_len = idx.bv_len + in[i].bv_len; - bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 ); - ptr = lutil_strcopy( bva[i].bv_val, ibuf ); - ptr = lutil_strcopy( ptr, in[i].bv_val ); - *ptr = '\0'; - BER_BVZERO( &bva[ i + 1 ] ); - } - - *out = bva; - return 0; -} - int meta_subtree_free( metasubtree_t *ms ) { diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index ab6efbad5a..a6953089ea 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -81,9 +81,6 @@ static CfBackInfo cfBackInfo; static char *passwd_salt; static FILE *logfile; static char *logfileName; -#ifdef SLAP_AUTH_REWRITE -static BerVarray authz_rewrites; -#endif static AccessControl *defacl_parsed = NULL; static struct berval cfdir; @@ -335,7 +332,7 @@ static ConfigTable config_back_cf_table[] = { NULL, NULL }, { "authid-rewrite", "rewrite", 2, 0, STRLENOF( "authid-rewrite" ), #ifdef SLAP_AUTH_REWRITE - ARG_MAGIC|CFG_REWRITE|ARG_NO_INSERT, &config_generic, + ARG_MAGIC|CFG_REWRITE, &config_generic, #else ARG_IGNORED, NULL, #endif @@ -1401,29 +1398,7 @@ config_generic(ConfigArgs *c) { #endif #ifdef SLAP_AUTH_REWRITE case CFG_REWRITE: - if ( authz_rewrites ) { - struct berval bv, idx; - char ibuf[32]; - int i; - - idx.bv_val = ibuf; - for ( i=0; !BER_BVISNULL( &authz_rewrites[i] ); i++ ) { - idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i ); - if ( idx.bv_len >= sizeof( ibuf ) ) { - ber_bvarray_free_x( c->rvalue_vals, NULL ); - c->rvalue_vals = NULL; - break; - } - bv.bv_len = idx.bv_len + authz_rewrites[i].bv_len; - bv.bv_val = ch_malloc( bv.bv_len + 1 ); - AC_MEMCPY( bv.bv_val, idx.bv_val, idx.bv_len ); - AC_MEMCPY( &bv.bv_val[ idx.bv_len ], - authz_rewrites[i].bv_val, - authz_rewrites[i].bv_len + 1 ); - ber_bvarray_add( &c->rvalue_vals, &bv ); - } - } - if ( !c->rvalue_vals ) rc = 1; + rc = slap_sasl_rewrite_unparse( &c->rvalue_vals ); break; #endif default: @@ -1455,7 +1430,6 @@ config_generic(ConfigArgs *c) { /* no-ops, requires slapd restart */ case CFG_PLUGIN: case CFG_MODLOAD: - case CFG_REWRITE: snprintf(c->log, sizeof( c->log ), "change requires slapd restart"); break; @@ -1499,6 +1473,12 @@ config_generic(ConfigArgs *c) { rc = slap_sasl_regexp_delete( c->valx ); break; +#ifdef SLAP_AUTH_REWRITE + case CFG_REWRITE: + rc = slap_sasl_rewrite_delete( c->valx ); + break; +#endif /* SLAP_AUTH_REWRITE */ + case CFG_SALT: ch_free( passwd_salt ); passwd_salt = NULL; @@ -2448,36 +2428,13 @@ sortval_reject: #ifdef SLAP_AUTH_REWRITE case CFG_REWRITE: { - struct berval bv; - char *line; - int rc = 0; + int rc; if ( c->op == LDAP_MOD_ADD ) { c->argv++; c->argc--; } - if(slap_sasl_rewrite_config(c->fname, c->lineno, c->argc, c->argv)) - rc = 1; - if ( rc == 0 ) { - - if ( c->argc > 1 ) { - char *s; - - /* quote all args but the first */ - line = ldap_charray2str( c->argv, "\" \"" ); - ber_str2bv( line, 0, 0, &bv ); - s = ber_bvchr( &bv, '"' ); - assert( s != NULL ); - /* move the trailing quote of argv[0] to the end */ - AC_MEMCPY( s, s + 1, bv.bv_len - ( s - bv.bv_val ) ); - bv.bv_val[ bv.bv_len - 1 ] = '"'; - - } else { - ber_str2bv( c->argv[ 0 ], 0, 1, &bv ); - } - - ber_bvarray_add( &authz_rewrites, &bv ); - } + rc = slap_sasl_rewrite_config(c->fname, c->lineno, c->argc, c->argv, c->valx); if ( c->op == LDAP_MOD_ADD ) { c->argv--; c->argc++; @@ -3992,6 +3949,47 @@ anlist_unparse( AttributeName *an, char *ptr, ber_len_t buflen ) { return ptr; } +int +slap_bv_x_ordered_unparse( BerVarray in, BerVarray *out ) +{ + int i; + BerVarray bva = NULL; + char ibuf[32], *ptr; + struct berval idx; + + assert( in != NULL ); + + for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) + /* count'em */ ; + + if ( i == 0 ) { + return 1; + } + + idx.bv_val = ibuf; + + bva = ch_malloc( ( i + 1 ) * sizeof(struct berval) ); + BER_BVZERO( &bva[ 0 ] ); + + for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) { + idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), SLAP_X_ORDERED_FMT, i ); + if ( idx.bv_len >= sizeof( ibuf ) ) { + ber_bvarray_free( bva ); + return 1; + } + + bva[i].bv_len = idx.bv_len + in[i].bv_len; + bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 ); + ptr = lutil_strcopy( bva[i].bv_val, ibuf ); + ptr = lutil_strcopy( ptr, in[i].bv_val ); + *ptr = '\0'; + BER_BVZERO( &bva[ i + 1 ] ); + } + + *out = bva; + return 0; +} + static int config_updatedn(ConfigArgs *c) { if (c->op == SLAP_CONFIG_EMIT) { diff --git a/servers/slapd/overlays/rwm.c b/servers/slapd/overlays/rwm.c index 8f28348d1c..4c0534380a 100644 --- a/servers/slapd/overlays/rwm.c +++ b/servers/slapd/overlays/rwm.c @@ -1968,46 +1968,6 @@ static ConfigOCs rwmocs[] = { { NULL, 0, NULL } }; -static void -slap_bv_x_ordered_unparse( BerVarray in, BerVarray *out ) -{ - int i; - BerVarray bva = NULL; - char ibuf[32], *ptr; - struct berval idx; - - assert( in != NULL ); - - for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) - /* count'em */ ; - - if ( i == 0 ) { - return; - } - - idx.bv_val = ibuf; - - bva = ch_malloc( ( i + 1 ) * sizeof(struct berval) ); - BER_BVZERO( &bva[ 0 ] ); - - for ( i = 0; !BER_BVISNULL( &in[i] ); i++ ) { - idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), "{%d}", i ); - if ( idx.bv_len >= sizeof( ibuf ) ) { - ber_bvarray_free( bva ); - return; - } - - bva[i].bv_len = idx.bv_len + in[i].bv_len; - bva[i].bv_val = ch_malloc( bva[i].bv_len + 1 ); - ptr = lutil_strcopy( bva[i].bv_val, ibuf ); - ptr = lutil_strcopy( ptr, in[i].bv_val ); - *ptr = '\0'; - BER_BVZERO( &bva[ i + 1 ] ); - } - - *out = bva; -} - static int rwm_bva_add( BerVarray *bva, @@ -2108,10 +2068,7 @@ rwm_cf_gen( ConfigArgs *c ) rc = 1; } else { - slap_bv_x_ordered_unparse( rwmap->rwm_bva_rewrite, &c->rvalue_vals ); - if ( !c->rvalue_vals ) { - rc = 1; - } + rc = slap_bv_x_ordered_unparse( rwmap->rwm_bva_rewrite, &c->rvalue_vals ); } break; diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index c99dc29e54..2d68e857e2 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -760,6 +760,7 @@ LDAP_SLAPD_F (int) slap_client_connect LDAP_P(( LDAP **ldp, slap_bindconf *sb )) LDAP_SLAPD_F (int) config_generic_wrapper LDAP_P(( Backend *be, const char *fname, int lineno, int argc, char **argv )); LDAP_SLAPD_F (char *) anlist_unparse LDAP_P(( AttributeName *, char *, ber_len_t buflen )); +LDAP_SLAPD_F (int) slap_bv_x_ordered_unparse LDAP_P(( BerVarray in, BerVarray *out )); LDAP_SLAPD_F (int) slap_keepalive_parse( struct berval *val, void *bc, slap_cf_aux_table *tab0, const char *tabmsg, int unparse ); @@ -1723,7 +1724,10 @@ LDAP_SLAPD_F (int) slap_sasl_rewrite_config LDAP_P(( const char *fname, int lineno, int argc, - char **argv )); + char **argv, + int valx )); +LDAP_SLAPD_F (int) slap_sasl_rewrite_delete LDAP_P(( int valx )); +LDAP_SLAPD_F (int) slap_sasl_rewrite_unparse LDAP_P(( BerVarray *bva )); #endif /* SLAP_AUTH_REWRITE */ LDAP_SLAPD_F (void) slap_sasl_regexp_destroy LDAP_P(( void )); LDAP_SLAPD_F (int) slap_sasl_regexp_delete LDAP_P(( int valx )); diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index 01261f4094..38ce43ae2a 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -28,6 +28,7 @@ #include "slap.h" #include "lutil.h" +#include "config.h" #define SASLREGEX_REPLACE 10 @@ -82,6 +83,7 @@ static SaslRegexp_t *SaslRegexp = NULL; #include "rewrite.h" struct rewrite_info *sasl_rwinfo = NULL; #define AUTHID_CONTEXT "authid" +static BerVarray authz_rewrites = NULL; #endif /* SLAP_AUTH_REWRITE */ /* What SASL proxy authorization policies are allowed? */ @@ -1281,7 +1283,7 @@ static int slap_sasl_rx_off(char *rep, int *off) #endif /* ! SLAP_AUTH_REWRITE */ #ifdef SLAP_AUTH_REWRITE -int slap_sasl_rewrite_config( +static int slap_sasl_rewrite_config_argv( const char *fname, int lineno, int argc, @@ -1289,22 +1291,80 @@ int slap_sasl_rewrite_config( ) { int rc; - char *savearg0; + char *argv0 = NULL; + + if ( strncasecmp( argv[0], "authid-", STRLENOF( "authid-" ) ) == 0 ) { + /* strip "authid-" prefix for parsing */ + argv0 = argv[0]; + argv[0] = &argv0[ STRLENOF( "authid-" ) ]; + } /* init at first call */ if ( sasl_rwinfo == NULL ) { sasl_rwinfo = rewrite_info_init( REWRITE_MODE_USE_DEFAULT ); } - /* strip "authid-" prefix for parsing */ - savearg0 = argv[0]; - argv[0] += STRLENOF( "authid-" ); rc = rewrite_parse( sasl_rwinfo, fname, lineno, argc, argv ); - argv[0] = savearg0; + + if ( argv0 ) + argv[0] = argv0; return rc; } +static int slap_sasl_rewrite_config_bv( + const char *fname, + int lineno, + struct berval bv +) +{ + int rc; + ConfigArgs ca = { 0 }; + + ca.line = bv.bv_val; + ca.argc = 0; + config_fp_parse_line( &ca ); + + rc = slap_sasl_rewrite_config_argv( fname, lineno, ca.argc, ca.argv ); + + ch_free( ca.tline ); + ch_free( ca.argv ); + + return rc; +} + +static void +slap_sasl_rewrite_bva_add( + BerVarray *bva, + int idx, + int argc, + char **argv +) +{ + char *line, *s; + struct berval bv; + + if ( argc > 1 ) { + /* quote all args but the first */ + line = ldap_charray2str( argv, "\" \"" ); + ber_str2bv( line, 0, 0, &bv ); + s = ber_bvchr( &bv, '"' ); + assert( s != NULL ); + + /* move the trailing quote of argv[0] to the end */ + AC_MEMCPY( s, s + 1, bv.bv_len - ( s - bv.bv_val ) ); + bv.bv_val[ bv.bv_len - 1 ] = '"'; + } else { + ber_str2bv( argv[ 0 ], 0, 1, &bv ); + } + + if ( idx == -1 ) { + ber_bvarray_add( bva, &bv ); + } else { + (*bva)[ idx ] = bv; + } +} + static int slap_sasl_rewrite_destroy( void ) { @@ -1316,6 +1376,113 @@ slap_sasl_rewrite_destroy( void ) return 0; } +int slap_sasl_rewrite_config( + const char *fname, + int lineno, + int argc, + char **argv, + int valx +) +{ + int rc, i, last; + char *line; + struct berval bv; + struct rewrite_info *rw = sasl_rwinfo; + + for ( last = 0; authz_rewrites && !BER_BVISNULL( &authz_rewrites[ last ] ); last++ ) + /* count'em */ ; + + if ( valx == -1 || valx >= last ) { + valx = -1; + rc = slap_sasl_rewrite_config_argv( fname, lineno, argc, argv ); + if ( rc == 0 ) { + slap_sasl_rewrite_bva_add( &authz_rewrites, valx, argc, argv ); + } + return rc; + } + + sasl_rwinfo = NULL; + + for ( i = 0; i < valx; i++ ) + { + rc = slap_sasl_rewrite_config_bv( fname, lineno, authz_rewrites[ i ] ); + assert( rc == 0 ); + } + + rc = slap_sasl_rewrite_config_argv( fname, lineno, argc, argv ); + if ( rc != 0 ) { + slap_sasl_rewrite_destroy(); + sasl_rwinfo = rw; + return 1; + } + + for ( i = valx; authz_rewrites && !BER_BVISNULL( &authz_rewrites[ i ] ); i++ ) + { + rc = slap_sasl_rewrite_config_bv( fname, lineno, authz_rewrites[ i ] ); + assert( rc == 0 ); + } + + authz_rewrites = ch_realloc( authz_rewrites, + ( last + 2 )*sizeof( struct berval ) ); + BER_BVZERO( &authz_rewrites[ last + 1 ] ); + + for ( i = last - 1; i >= valx; i-- ) + { + authz_rewrites[ i + 1 ] = authz_rewrites[ i ]; + } + + slap_sasl_rewrite_bva_add( &authz_rewrites, valx, argc, argv ); + + if ( rw ) + rewrite_info_delete( &rw ); + + return rc; +} + +int slap_sasl_rewrite_delete( int valx ) { + int rc, i; + + if ( valx == -1 ) { + slap_sasl_rewrite_destroy(); + if ( authz_rewrites ) { + ber_bvarray_free( authz_rewrites ); + authz_rewrites = NULL; + } + return 0; + } + + for ( i = 0; !BER_BVISNULL( &authz_rewrites[ i ] ); i++ ) + /* count'em */ ; + + if ( valx >= i ) { + return 1; + } + + ber_memfree( authz_rewrites[ i ].bv_val ); + for ( i = valx; !BER_BVISNULL( &authz_rewrites[ i + 1 ] ); i++ ) + { + authz_rewrites[ i ] = authz_rewrites[ i + 1 ]; + } + BER_BVZERO( &authz_rewrites[ i ] ); + + slap_sasl_rewrite_destroy(); + + for ( i = 0; !BER_BVISNULL( &authz_rewrites[ i ] ); i++ ) + { + rc = slap_sasl_rewrite_config_bv( "slapd", 0, authz_rewrites[ i ] ); + assert( rc == 0 ); + } + + return rc; +} + +int slap_sasl_rewrite_unparse( BerVarray *bva ) { + if ( authz_rewrites ) { + return slap_bv_x_ordered_unparse( authz_rewrites, bva ); + } + return 0; +} + static int slap_sasl_regexp_rewrite_config( struct rewrite_info **rwinfo,