From 58865ccb387c7c78458ba4f4a9959da00860ed64 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 1 Mar 2005 23:01:47 +0000 Subject: [PATCH] Added general limits retrieval --- servers/slapd/config.c | 32 +++++++-- servers/slapd/limits.c | 138 ++++++++++++++++++++++++++++++------- servers/slapd/proto-slap.h | 4 +- 3 files changed, 142 insertions(+), 32 deletions(-) diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 8417f3ab8b..76ce626036 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -984,8 +984,22 @@ config_generic(ConfigArgs *c) { else rc = 1; break; - case CFG_LIMITS: /* FIXME */ - rc = 1; + case CFG_LIMITS: + if ( c->be->be_limits ) { + char buf[4096*3]; + struct berval bv; + int i; + + for ( i=0; c->be->be_limits[i]; i++ ) { + bv.bv_len = sprintf( buf, "{%d}", i ); + bv.bv_val = buf+bv.bv_len; + limits_unparse( c->be->be_limits[i], &bv ); + bv.bv_len += bv.bv_val - buf; + bv.bv_val = buf; + value_add_one( &c->rvalue_vals, &bv ); + } + } + if ( !c->rvalue_vals ) rc = 1; break; case CFG_RO: c->value_int = (c->be->be_restrictops & SLAP_RESTRICT_OP_WRITES) != 0; @@ -1483,10 +1497,13 @@ config_sizelimit(ConfigArgs *c) { char *next; struct slap_limits_set *lim = &c->be->be_def_limit; if (c->emit) { - struct berval bv = BER_BVNULL; + char buf[8192]; + struct berval bv; + bv.bv_val = buf; + bv.bv_len = 0; limits_unparse_one( lim, SLAP_LIMIT_SIZE, &bv ); if ( !BER_BVISEMPTY( &bv )) - ber_bvarray_add( &c->rvalue_vals, &bv ); + value_add_one( &c->rvalue_vals, &bv ); else rc = 1; return rc; @@ -1528,10 +1545,13 @@ config_timelimit(ConfigArgs *c) { char *next; struct slap_limits_set *lim = &c->be->be_def_limit; if (c->emit) { - struct berval bv = BER_BVNULL; + char buf[8192]; + struct berval bv; + bv.bv_val = buf; + bv.bv_len = 0; limits_unparse_one( lim, SLAP_LIMIT_TIME, &bv ); if ( !BER_BVISEMPTY( &bv )) - ber_bvarray_add( &c->rvalue_vals, &bv ); + value_add_one( &c->rvalue_vals, &bv ); else rc = 1; return rc; diff --git a/servers/slapd/limits.c b/servers/slapd/limits.c index 337129e142..8cd968dff8 100644 --- a/servers/slapd/limits.c +++ b/servers/slapd/limits.c @@ -900,33 +900,91 @@ limits_parse_one( return 0; } +static const char *lmpats[] = { + "exact", + "exact", + "onelvel", + "subtree", + "children", + "regex", + "anonymous", + "users", + "*" +}; + +/* Caller must provide an adequately sized buffer in bv */ +void +limits_unparse( struct slap_limits *lim, struct berval *bv ) +{ + struct berval btmp; + char *ptr; + int lm; + + if ( !bv || !bv->bv_val ) return; + + ptr = bv->bv_val; + + if (( lim->lm_flags & SLAP_LIMITS_TYPE_MASK ) == SLAP_LIMITS_TYPE_GROUP ) { + ptr = lutil_strcopy( ptr, "group/" ); + ptr = lutil_strcopy( ptr, lim->lm_group_oc->soc_cname.bv_val ); + *ptr++ = '/'; + ptr = lutil_strcopy( ptr, lim->lm_group_ad->ad_cname.bv_val ); + } else { + lm = lim->lm_flags & SLAP_LIMITS_MASK; + switch( lm ) { + case SLAP_LIMITS_ANONYMOUS: + case SLAP_LIMITS_USERS: + case SLAP_LIMITS_ANY: + ptr = lutil_strcopy( ptr, lmpats[lm] ); + break; + case SLAP_LIMITS_UNDEFINED: + case SLAP_LIMITS_EXACT: + case SLAP_LIMITS_ONE: + case SLAP_LIMITS_SUBTREE: + case SLAP_LIMITS_CHILDREN: + case SLAP_LIMITS_REGEX: + ptr = lutil_strcopy( ptr, "dn." ); + ptr = lutil_strcopy( ptr, lmpats[lm] ); + *ptr++ = '='; + *ptr++ = '"'; + ptr = lutil_strcopy( ptr, lim->lm_pat.bv_val ); + *ptr++ = '"'; + break; + } + } + *ptr++ = ' '; + bv->bv_len = ptr - bv->bv_val; + btmp.bv_val = ptr; + btmp.bv_len = 0; + limits_unparse_one( &lim->lm_limits, SLAP_LIMIT_SIZE|SLAP_LIMIT_TIME, &btmp ); + bv->bv_len += btmp.bv_len; +} + +/* Caller must provide an adequately sized buffer in bv */ void limits_unparse_one( struct slap_limits_set *lim, int which, struct berval *bv ) { - char buf[8192], *ptr; + char *ptr; + + if ( !bv || !bv->bv_val ) return; + + ptr = bv->bv_val; - ptr = buf; - if ( which & SLAP_LIMIT_TIME ) { - if ( lim->lms_t_soft != SLAPD_DEFAULT_TIMELIMIT ) { - ptr = lutil_strcopy( ptr, " time.soft=" ); - if ( lim->lms_t_soft == -1 ) - ptr = lutil_strcopy( ptr, "unlimited" ); - else - ptr += sprintf( ptr, "%d", lim->lms_t_soft ); - *ptr++ = ' '; - } - if ( lim->lms_t_hard ) { - ptr = lutil_strcopy( ptr, " time.hard=" ); - if ( lim->lms_t_hard == -1 ) - ptr = lutil_strcopy( ptr, "unlimited" ); - else - ptr += sprintf( ptr, "%d", lim->lms_t_hard ); - *ptr++ = ' '; - } - } if ( which & SLAP_LIMIT_SIZE ) { if ( lim->lms_s_soft != SLAPD_DEFAULT_SIZELIMIT ) { - ptr = lutil_strcopy( ptr, " size.soft=" ); + + /* If there's also a hard limit, fully qualify this one */ + if ( lim->lms_s_hard ) + ptr = lutil_strcopy( ptr, " size.soft=" ); + + /* If doing both size & time, qualify this */ + else if ( which & SLAP_LIMIT_TIME ) + ptr = lutil_strcopy( ptr, " size=" ); + + /* Otherwise if same as global limit, drop it */ + else if ( lim != &frontendDB->be_def_limit && + lim->lms_s_soft == frontendDB->be_def_limit.lms_s_soft ) + return; if ( lim->lms_s_soft == -1 ) ptr = lutil_strcopy( ptr, "unlimited" ); else @@ -935,7 +993,7 @@ limits_unparse_one( struct slap_limits_set *lim, int which, struct berval *bv ) } if ( lim->lms_s_hard ) { ptr = lutil_strcopy( ptr, " size.hard=" ); - if ( lim->lms_s_soft == -1 ) + if ( lim->lms_s_hard == -1 ) ptr = lutil_strcopy( ptr, "unlimited" ); else ptr += sprintf( ptr, "%d", lim->lms_s_hard ); @@ -971,11 +1029,41 @@ limits_unparse_one( struct slap_limits_set *lim, int which, struct berval *bv ) *ptr++ = ' '; } } - if ( ptr != buf ) { + if ( which & SLAP_LIMIT_TIME ) { + if ( lim->lms_t_soft != SLAPD_DEFAULT_TIMELIMIT ) { + + /* If there's also a hard limit, fully qualify this one */ + if ( lim->lms_t_hard ) + ptr = lutil_strcopy( ptr, " time.soft=" ); + + /* If doing both size & time, qualify this */ + else if ( which & SLAP_LIMIT_SIZE ) + ptr = lutil_strcopy( ptr, " time=" ); + + /* Otherwise, if same as global limit, drop it */ + else if ( lim != &frontendDB->be_def_limit && + lim->lms_t_soft == frontendDB->be_def_limit.lms_t_soft ) + return; + + if ( lim->lms_t_soft == -1 ) + ptr = lutil_strcopy( ptr, "unlimited" ); + else + ptr += sprintf( ptr, "%d", lim->lms_t_soft ); + *ptr++ = ' '; + } + if ( lim->lms_t_hard ) { + ptr = lutil_strcopy( ptr, " time.hard=" ); + if ( lim->lms_t_hard == -1 ) + ptr = lutil_strcopy( ptr, "unlimited" ); + else + ptr += sprintf( ptr, "%d", lim->lms_t_hard ); + *ptr++ = ' '; + } + } + if ( ptr != bv->bv_val ) { ptr--; *ptr = '\0'; - bv->bv_len = ptr - buf - 1; - ber_str2bv( buf+1, bv->bv_len, 1, bv ); + bv->bv_len = ptr - bv->bv_val; } } diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 7a257120dd..314bb933fa 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -799,7 +799,9 @@ LDAP_SLAPD_F (int) limits_parse_one LDAP_P(( const char *arg, LDAP_SLAPD_F (int) limits_check LDAP_P(( Operation *op, SlapReply *rs )); LDAP_SLAPD_F (void) limits_unparse_one LDAP_P(( - struct slap_limits_set *limit, struct berval *bv )); + struct slap_limits_set *limit, int which, struct berval *bv )); +LDAP_SLAPD_F (void) limits_unparse LDAP_P(( + struct slap_limits *limit, struct berval *bv )); /* * lock.c