- slap_overinst *on = (slap_overinst *)(c->bi);
- constraint *cn = on->on_bi.bi_private, *cp;
- struct berval bv;
- int i, rc = 0;
- constraint ap = { NULL, NULL, NULL }, *a2 = NULL;
- regmatch_t rm[2];
- const char *text = NULL;
-
- switch ( c->op ) {
- case SLAP_CONFIG_EMIT:
- switch (c->type) {
- case CONSTRAINT_ATTRIBUTE:
- for (cp=cn; cp; cp=cp->ap_next) {
- int len;
- char *s;
-
- len = cp->ap->ad_cname.bv_len +
- strlen( REGEX_STR ) + strlen( cp->re_str) + 3;
- s = ch_malloc(len);
- if (!s) continue;
- snprintf(s, len, "%s %s %s", cp->ap->ad_cname.bv_val,
- REGEX_STR, cp->re_str);
- bv.bv_val = s;
- bv.bv_len = strlen(s);
- rc = value_add_one( &c->rvalue_vals, &bv );
- if (rc) return rc;
- rc = value_add_one( &c->rvalue_nvals, &bv );
- if (rc) return rc;
- ch_free(s);
- }
- break;
- default:
- abort();
- break;
- }
- break;
- case LDAP_MOD_DELETE:
- switch (c->type) {
- case CONSTRAINT_ATTRIBUTE:
- if (!cn) break; /* nothing to do */
-
- if (c->valx < 0) {
- /* zap all constraints */
- while (cn) {
- cp = cn->ap_next;
- if (cn->re) {
- regfree(cn->re);
- ch_free(cn->re);
- }
- if (cn->re_str) ch_free(cn->re_str);
- ch_free(cn);
- cn = cp;
- }
-
- on->on_bi.bi_private = NULL;
- } else {
- constraint **cpp;
-
- /* zap constraint numbered 'valx' */
- for(i=0, cp = cn, cpp = &cn;
- (cp) && (i<c->valx);
- i++, cpp = &cp->ap_next, cp = *cpp);
-
- if (cp) {
- /* zap cp, and join cpp to cp->ap_next */
- *cpp = cp->ap_next;
- if (cp->re) {
- regfree(cp->re);
- ch_free(cp->re);
- }
- if (cp->re_str) ch_free(cp->re_str);
- ch_free(cp);
- }
- on->on_bi.bi_private = cn;
- }
-
- break;
- default:
- abort();
- break;
- }
- break;
- case SLAP_CONFIG_ADD:
- case LDAP_MOD_ADD:
- switch (c->type) {
- case CONSTRAINT_ATTRIBUTE:
- if ( slap_str2ad( c->argv[1], &ap.ap, &text ) ) {
- Debug( LDAP_DEBUG_CONFIG,
- "constraint_add: <%s>: attribute description unknown %s.\n",
- c->argv[1], text, 0 );
- return( ARG_BAD_CONF );
- }
-
- if ( strcasecmp( c->argv[2], "regex" ) == 0) {
- int err;
-
- ap.re = ch_malloc( sizeof(regex_t) );
- if ((err = regcomp( ap.re,
- c->argv[3], REG_EXTENDED )) != 0) {
- char errmsg[1024];
-
- regerror( err, ap.re, errmsg, sizeof(errmsg) );
- ch_free(ap.re);
- Debug( LDAP_DEBUG_CONFIG,
- "%s: Illegal regular expression \"%s\": Error %s\n",
- c->argv[1], c->argv[3], errmsg);
- ap.re = NULL;
- return( ARG_BAD_CONF );
- }
- ap.re_str = ch_strdup( c->argv[3] );
- } else {
- Debug( LDAP_DEBUG_CONFIG,
- "%s: Unknown constraint type: %s\n",
- c->argv[1], c->argv[2], 0 );
- return ( ARG_BAD_CONF );
- }
-
-
- a2 = ch_malloc( sizeof(constraint) );
- a2->ap_next = on->on_bi.bi_private;
- a2->ap = ap.ap;
- a2->re = ap.re;
- a2->re_str = ap.re_str;
- on->on_bi.bi_private = a2;
- break;
- default:
- abort();
- break;
- }
- break;
- default:
- abort();
- }
-
- return rc;
+ slap_overinst *on = (slap_overinst *)(c->bi);
+ constraint *cn = on->on_bi.bi_private, *cp;
+ struct berval bv;
+ int i, rc = 0;
+ constraint ap = { NULL, NULL, NULL }, *a2 = NULL;
+ const char *text = NULL;
+
+ switch ( c->op ) {
+ case SLAP_CONFIG_EMIT:
+ switch (c->type) {
+ case CONSTRAINT_ATTRIBUTE:
+ for (cp=cn; cp; cp=cp->ap_next) {
+ int len;
+ char *s;
+ char *tstr = NULL;
+
+ len = cp->ap->ad_cname.bv_len + 3;
+ if (cp->re) {
+ len += STRLENOF(REGEX_STR);
+ tstr = REGEX_STR;
+ } else if (cp->lud) {
+ len += STRLENOF(URI_STR);
+ tstr = URI_STR;
+ }
+ len += cp->val.bv_len;
+
+ s = ch_malloc(len);
+
+ bv.bv_len = snprintf(s, len, "%s %s %s", cp->ap->ad_cname.bv_val,
+ tstr, cp->val.bv_val);
+ bv.bv_val = s;
+ rc = value_add_one( &c->rvalue_vals, &bv );
+ if (rc) return rc;
+ rc = value_add_one( &c->rvalue_nvals, &bv );
+ if (rc) return rc;
+ ch_free(s);
+ }
+ break;
+ default:
+ abort();
+ break;
+ }
+ break;
+ case LDAP_MOD_DELETE:
+ switch (c->type) {
+ case CONSTRAINT_ATTRIBUTE:
+ if (!cn) break; /* nothing to do */
+
+ if (c->valx < 0) {
+ /* zap all constraints */
+ while (cn) {
+ cp = cn->ap_next;
+ constraint_free( cn );
+ cn = cp;
+ }
+
+ on->on_bi.bi_private = NULL;
+ } else {
+ constraint **cpp;
+
+ /* zap constraint numbered 'valx' */
+ for(i=0, cp = cn, cpp = &cn;
+ (cp) && (i<c->valx);
+ i++, cpp = &cp->ap_next, cp = *cpp);
+
+ if (cp) {
+ /* zap cp, and join cpp to cp->ap_next */
+ *cpp = cp->ap_next;
+ constraint_free( cp );
+ }
+ on->on_bi.bi_private = cn;
+ }
+ break;
+
+ default:
+ abort();
+ break;
+ }
+ break;
+ case SLAP_CONFIG_ADD:
+ case LDAP_MOD_ADD:
+ switch (c->type) {
+ case CONSTRAINT_ATTRIBUTE:
+ if ( slap_str2ad( c->argv[1], &ap.ap, &text ) ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "%s <%s>: %s\n", c->argv[0], c->argv[1], text );
+ Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
+ "%s: %s\n", c->log, c->cr_msg, 0 );
+ return( ARG_BAD_CONF );
+ }
+
+ if ( strcasecmp( c->argv[2], REGEX_STR ) == 0) {
+ int err;
+
+ ap.re = ch_malloc( sizeof(regex_t) );
+ if ((err = regcomp( ap.re,
+ c->argv[3], REG_EXTENDED )) != 0) {
+ char errmsg[1024];
+
+ regerror( err, ap.re, errmsg, sizeof(errmsg) );
+ ch_free(ap.re);
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "%s %s: Illegal regular expression \"%s\": Error %s",
+ c->argv[0], c->argv[1], c->argv[3], errmsg);
+ Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
+ "%s: %s\n", c->log, c->cr_msg, 0 );
+ ap.re = NULL;
+ return( ARG_BAD_CONF );
+ }
+ ber_str2bv( c->argv[3], 0, 1, &ap.val );
+ } else if ( strcasecmp( c->argv[2], URI_STR ) == 0) {
+ int err;
+
+ err = ldap_url_parse(c->argv[3], &ap.lud);
+ if ( err != LDAP_URL_SUCCESS ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "%s %s: Invalid URI \"%s\"",
+ c->argv[0], c->argv[1], c->argv[3]);
+ Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
+ "%s: %s\n", c->log, c->cr_msg, 0 );
+ return( ARG_BAD_CONF );
+ }
+
+ if (ap.lud->lud_host != NULL) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "%s %s: unsupported hostname in URI \"%s\"",
+ c->argv[0], c->argv[1], c->argv[3]);
+ Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
+ "%s: %s\n", c->log, c->cr_msg, 0 );
+
+ ldap_free_urldesc(ap.lud);
+
+ return( ARG_BAD_CONF );
+ }
+
+ for ( i=0; ap.lud->lud_attrs[i]; i++);
+ /* FIXME: This is worthless without at least one attr */
+ if ( i ) {
+ ap.attrs = ch_malloc( (i+1)*sizeof(AttributeDescription *));
+ for ( i=0; ap.lud->lud_attrs[i]; i++) {
+ ap.attrs[i] = NULL;
+ if ( slap_str2ad( ap.lud->lud_attrs[i], &ap.attrs[i], &text ) ) {
+ ch_free( ap.attrs );
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "%s <%s>: %s\n", c->argv[0], ap.lud->lud_attrs[i], text );
+ Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
+ "%s: %s\n", c->log, c->cr_msg, 0 );
+ return( ARG_BAD_CONF );
+ }
+ }
+ ap.attrs[i] = NULL;
+ }
+
+ if (ap.lud->lud_dn == NULL)
+ ap.lud->lud_dn = ch_strdup("");
+
+ if (ap.lud->lud_filter == NULL)
+ ap.lud->lud_filter = ch_strdup("objectClass=*");
+
+ ber_str2bv( c->argv[3], 0, 1, &ap.val );
+ } else {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "%s %s: Unknown constraint type: %s",
+ c->argv[0], c->argv[1], c->argv[2] );
+ Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
+ "%s: %s\n", c->log, c->cr_msg, 0 );
+ return ( ARG_BAD_CONF );
+ }
+
+ a2 = ch_calloc( sizeof(constraint), 1 );
+ a2->ap_next = on->on_bi.bi_private;
+ a2->ap = ap.ap;
+ a2->re = ap.re;
+ a2->val = ap.val;
+ a2->lud = ap.lud;
+ if ( a2->lud ) {
+ ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn);
+ ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter);
+ }
+ a2->attrs = ap.attrs;
+ on->on_bi.bi_private = a2;
+ break;
+ default:
+ abort();
+ break;
+ }
+ break;
+ default:
+ abort();
+ }
+
+ return rc;
+}
+
+static int
+constraint_uri_cb( Operation *op, SlapReply *rs )
+{
+ if(rs->sr_type == REP_SEARCH) {
+ int *foundp = op->o_callback->sc_private;
+
+ *foundp = 1;
+
+ Debug(LDAP_DEBUG_TRACE, "==> constraint_uri_cb <%s>\n",
+ rs->sr_entry ? rs->sr_entry->e_name.bv_val : "UNKNOWN_DN", 0, 0);
+ }
+ return 0;