static int pblock_set( Slapi_PBlock *pb, int param, void *value ) { int rc = PBLOCK_SUCCESS; pblock_lock( pb ); switch ( param ) { case SLAPI_OPERATION: pb->pb_op = (Operation *)value; break; case SLAPI_OPINITIATED_TIME: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_time = *((long *)value); break; case SLAPI_OPERATION_ID: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_opid = *((long *)value); break; case SLAPI_OPERATION_TYPE: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_tag = *((ber_tag_t *)value); break; case SLAPI_OPERATION_MSGID: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_msgid = *((long *)value); break; case SLAPI_X_OPERATION_DELETE_GLUE_PARENT: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_delete_glue_parent = *((int *)value); break; case SLAPI_X_OPERATION_NO_SCHEMA_CHECK: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_no_schema_check = *((int *)value); break; case SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_no_subordinate_glue = *((int *)value); break; case SLAPI_REQCONTROLS: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_ctrls = (LDAPControl **)value; break; case SLAPI_RESCONTROLS: { LDAPControl **ctrls = NULL; pblock_get_default( pb, param, (void **)&ctrls ); if ( ctrls != NULL ) { /* free old ones first */ ldap_controls_free( ctrls ); } rc = pblock_set_default( pb, param, value ); break; } case SLAPI_ADD_RESCONTROL: PBLOCK_ASSERT_OP( pb, 0 ); rc = pblock_add_control( pb, (LDAPControl *)value ); break; case SLAPI_REQUESTOR_DN: PBLOCK_ASSERT_OP( pb, 0 ); rc = pblock_set_dn( value, &pb->pb_op->o_dn, &pb->pb_op->o_ndn, pb->pb_op->o_tmpmemctx ); break; case SLAPI_MANAGEDSAIT: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_managedsait = *((int *)value); break; case SLAPI_X_RELAX: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_relax = *((int *)value); break; case SLAPI_BACKEND: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_op->o_bd = (BackendDB *)value; break; case SLAPI_CONNECTION: pb->pb_conn = (Connection *)value; break; case SLAPI_X_CONN_SSF: PBLOCK_ASSERT_CONN( pb ); PBLOCK_LOCK_CONN( pb ); pb->pb_conn->c_ssf = (slap_ssf_t)(long)value; PBLOCK_UNLOCK_CONN( pb ); break; case SLAPI_X_CONN_SASL_CONTEXT: PBLOCK_ASSERT_CONN( pb ); PBLOCK_LOCK_CONN( pb ); pb->pb_conn->c_sasl_authctx = value; PBLOCK_UNLOCK_CONN( pb ); break; case SLAPI_TARGET_DN: PBLOCK_ASSERT_OP( pb, 0 ); rc = pblock_set_dn( value, &pb->pb_op->o_req_dn, &pb->pb_op->o_req_ndn, pb->pb_op->o_tmpmemctx ); break; case SLAPI_CONN_ID: PBLOCK_ASSERT_CONN( pb ); PBLOCK_LOCK_CONN( pb ); pb->pb_conn->c_connid = *((long *)value); PBLOCK_UNLOCK_CONN( pb ); break; case SLAPI_CONN_DN: PBLOCK_ASSERT_CONN( pb ); PBLOCK_LOCK_CONN( pb ); rc = pblock_set_dn( value, &pb->pb_conn->c_dn, &pb->pb_conn->c_ndn, NULL ); PBLOCK_UNLOCK_CONN( pb ); break; case SLAPI_RESULT_CODE: case SLAPI_PLUGIN_INTOP_RESULT: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_rs->sr_err = *((int *)value); break; case SLAPI_RESULT_TEXT: PBLOCK_ASSERT_OP( pb, 0 ); snprintf( pb->pb_textbuf, sizeof( pb->pb_textbuf ), "%s", (char *)value ); pb->pb_rs->sr_text = pb->pb_textbuf; break; case SLAPI_RESULT_MATCHED: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_rs->sr_matched = (char *)value; /* XXX should dup? */ break; case SLAPI_ADD_ENTRY: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) pb->pb_op->ora_e = (Slapi_Entry *)value; else rc = PBLOCK_ERROR; break; case SLAPI_MODIFY_MODS: { Modifications **mlp; Modifications *newmods; PBLOCK_ASSERT_OP( pb, 0 ); rc = pblock_set_default( pb, param, value ); if ( rc != PBLOCK_SUCCESS ) { break; } if ( pb->pb_op->o_tag == LDAP_REQ_MODIFY ) { mlp = &pb->pb_op->orm_modlist; } else if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) { mlp = &pb->pb_op->ora_modlist; } else if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) { mlp = &pb->pb_op->orr_modlist; } else { break; } newmods = slapi_int_ldapmods2modifications( pb->pb_op, (LDAPMod **)value ); if ( newmods != NULL ) { slap_mods_free( *mlp, 1 ); *mlp = newmods; } break; } case SLAPI_MODRDN_NEWRDN: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) { rc = pblock_set_dn( value, &pb->pb_op->orr_newrdn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx ); if ( rc == LDAP_SUCCESS ) rc = rdn_validate( &pb->pb_op->orr_nnewrdn ); } else { rc = PBLOCK_ERROR; } break; case SLAPI_MODRDN_NEWSUPERIOR: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) { if ( value == NULL ) { if ( pb->pb_op->orr_newSup != NULL ) { pb->pb_op->o_tmpfree( pb->pb_op->orr_newSup, pb->pb_op->o_tmpmemctx ); BER_BVZERO( pb->pb_op->orr_newSup ); pb->pb_op->orr_newSup = NULL; } if ( pb->pb_op->orr_newSup != NULL ) { pb->pb_op->o_tmpfree( pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx ); BER_BVZERO( pb->pb_op->orr_nnewSup ); pb->pb_op->orr_nnewSup = NULL; } } else { if ( pb->pb_op->orr_newSup == NULL ) { pb->pb_op->orr_newSup = (struct berval *)pb->pb_op->o_tmpalloc( sizeof(struct berval), pb->pb_op->o_tmpmemctx ); BER_BVZERO( pb->pb_op->orr_newSup ); } if ( pb->pb_op->orr_nnewSup == NULL ) { pb->pb_op->orr_nnewSup = (struct berval *)pb->pb_op->o_tmpalloc( sizeof(struct berval), pb->pb_op->o_tmpmemctx ); BER_BVZERO( pb->pb_op->orr_nnewSup ); } rc = pblock_set_dn( value, pb->pb_op->orr_newSup, pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx ); } } else { rc = PBLOCK_ERROR; } break; case SLAPI_MODRDN_DELOLDRDN: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) pb->pb_op->orr_deleteoldrdn = *((int *)value); else rc = PBLOCK_ERROR; break; case SLAPI_SEARCH_SCOPE: { int scope = *((int *)value); PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) { switch ( *((int *)value) ) { case LDAP_SCOPE_BASE: case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBORDINATE: pb->pb_op->ors_scope = scope; break; default: rc = PBLOCK_ERROR; break; } } else { rc = PBLOCK_ERROR; } break; } case SLAPI_SEARCH_DEREF: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) pb->pb_op->ors_deref = *((int *)value); else rc = PBLOCK_ERROR; break; case SLAPI_SEARCH_SIZELIMIT: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) pb->pb_op->ors_slimit = *((int *)value); else rc = PBLOCK_ERROR; break; case SLAPI_SEARCH_TIMELIMIT: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) pb->pb_op->ors_tlimit = *((int *)value); else rc = PBLOCK_ERROR; break; case SLAPI_SEARCH_FILTER: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) pb->pb_op->ors_filter = (Slapi_Filter *)value; else rc = PBLOCK_ERROR; break; case SLAPI_SEARCH_STRFILTER: PBLOCK_ASSERT_OP( pb, 0 ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) { pb->pb_op->ors_filterstr.bv_val = (char *)value; pb->pb_op->ors_filterstr.bv_len = strlen((char *)value); } else { rc = PBLOCK_ERROR; } break; case SLAPI_SEARCH_ATTRS: { AttributeName *an = NULL; size_t i = 0, j = 0; char **attrs = (char **)value; PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) { rc = PBLOCK_ERROR; break; } /* also set mapped attrs */ rc = pblock_set_default( pb, param, value ); if ( rc != PBLOCK_SUCCESS ) { break; } if ( pb->pb_op->ors_attrs != NULL ) { pb->pb_op->o_tmpfree( pb->pb_op->ors_attrs, pb->pb_op->o_tmpmemctx ); pb->pb_op->ors_attrs = NULL; } if ( attrs != NULL ) { for ( i = 0; attrs[i] != NULL; i++ ) ; } if ( i ) { an = (AttributeName *)pb->pb_op->o_tmpcalloc( i + 1, sizeof(AttributeName), pb->pb_op->o_tmpmemctx ); for ( i = 0; attrs[i] != NULL; i++ ) { an[j].an_desc = NULL; an[j].an_oc = NULL; an[j].an_flags = 0; an[j].an_name.bv_val = attrs[i]; an[j].an_name.bv_len = strlen( attrs[i] ); if ( slap_bv2ad( &an[j].an_name, &an[j].an_desc, &pb->pb_rs->sr_text ) == LDAP_SUCCESS ) { j++; } } an[j].an_name.bv_val = NULL; an[j].an_name.bv_len = 0; } pb->pb_op->ors_attrs = an; break; } case SLAPI_SEARCH_ATTRSONLY: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) pb->pb_op->ors_attrsonly = *((int *)value); else rc = PBLOCK_ERROR; break; case SLAPI_SEARCH_RESULT_ENTRY: PBLOCK_ASSERT_OP( pb, 0 ); rs_replace_entry( pb->pb_op, pb->pb_rs, NULL, (Slapi_Entry *)value ); /* TODO: Should REP_ENTRY_MODIFIABLE be set? */ pb->pb_rs->sr_flags |= REP_ENTRY_MUSTBEFREED; break; case SLAPI_BIND_RET_SASLCREDS: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_rs->sr_sasldata = (struct berval *)value; break; case SLAPI_EXT_OP_REQ_OID: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED ) { pb->pb_op->ore_reqoid.bv_val = (char *)value; pb->pb_op->ore_reqoid.bv_len = strlen((char *)value); } else { rc = PBLOCK_ERROR; } break; case SLAPI_EXT_OP_REQ_VALUE: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED ) pb->pb_op->ore_reqdata = (struct berval *)value; else rc = PBLOCK_ERROR; break; case SLAPI_EXT_OP_RET_OID: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_rs->sr_rspoid = (char *)value; break; case SLAPI_EXT_OP_RET_VALUE: PBLOCK_ASSERT_OP( pb, 0 ); pb->pb_rs->sr_rspdata = (struct berval *)value; break; case SLAPI_BIND_METHOD: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_BIND ) pb->pb_op->orb_method = *((int *)value); else rc = PBLOCK_ERROR; break; case SLAPI_BIND_CREDENTIALS: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_BIND ) pb->pb_op->orb_cred = *((struct berval *)value); else rc = PBLOCK_ERROR; break; case SLAPI_COMPARE_TYPE: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) { const char *text; pb->pb_op->orc_ava->aa_desc = NULL; rc = slap_str2ad( (char *)value, &pb->pb_op->orc_ava->aa_desc, &text ); } else { rc = PBLOCK_ERROR; } break; case SLAPI_COMPARE_VALUE: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) pb->pb_op->orc_ava->aa_value = *((struct berval *)value); else rc = PBLOCK_ERROR; break; case SLAPI_ABANDON_MSGID: PBLOCK_ASSERT_OP( pb, 0 ); PBLOCK_VALIDATE_IS_INTOP( pb ); if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON) pb->pb_op->orn_msgid = *((int *)value); else rc = PBLOCK_ERROR; break; case SLAPI_REQUESTOR_ISROOT: case SLAPI_IS_REPLICATED_OPERATION: case SLAPI_CONN_AUTHTYPE: case SLAPI_CONN_AUTHMETHOD: case SLAPI_IS_INTERNAL_OPERATION: case SLAPI_X_CONN_IS_UDP: case SLAPI_CONN_CLIENTIP: case SLAPI_X_CONN_CLIENTPATH: case SLAPI_CONN_SERVERIP: case SLAPI_X_CONN_SERVERPATH: case SLAPI_X_ADD_STRUCTURAL_CLASS: /* These parameters cannot be set */ rc = PBLOCK_ERROR; break; default: rc = pblock_set_default( pb, param, value ); break; } pblock_unlock( pb ); return rc; }
static int constraint_cf_gen( ConfigArgs *c ) { 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 }; 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) { char *s; char *tstr = NULL; int quotes = 0, numeric = 0; int j; size_t val = 0; char val_buf[SLAP_TEXT_BUFLEN] = { '\0' }; bv.bv_len = STRLENOF(" "); for (j = 0; cp->ap[j]; j++) { bv.bv_len += cp->ap[j]->ad_cname.bv_len; } /* room for commas */ bv.bv_len += j - 1; switch (cp->type) { case CONSTRAINT_COUNT: tstr = COUNT_STR; val = cp->count; numeric = 1; break; case CONSTRAINT_SIZE: tstr = SIZE_STR; val = cp->size; numeric = 1; break; case CONSTRAINT_REGEX: tstr = REGEX_STR; quotes = 1; break; case CONSTRAINT_SET: tstr = SET_STR; quotes = 1; break; case CONSTRAINT_URI: tstr = URI_STR; quotes = 1; break; default: abort(); } bv.bv_len += strlen(tstr); bv.bv_len += cp->val.bv_len + 2*quotes; if (cp->restrict_lud != NULL) { bv.bv_len += cp->restrict_val.bv_len + STRLENOF(" restrict=\"\""); } if (numeric) { int len = snprintf(val_buf, sizeof(val_buf), "%zu", val); if (len <= 0) { /* error */ return -1; } bv.bv_len += len; } s = bv.bv_val = ch_malloc(bv.bv_len + 1); s = lutil_strncopy( s, cp->ap[0]->ad_cname.bv_val, cp->ap[0]->ad_cname.bv_len ); for (j = 1; cp->ap[j]; j++) { *s++ = ','; s = lutil_strncopy( s, cp->ap[j]->ad_cname.bv_val, cp->ap[j]->ad_cname.bv_len ); } *s++ = ' '; s = lutil_strcopy( s, tstr ); *s++ = ' '; if (numeric) { s = lutil_strcopy( s, val_buf ); } else { if ( quotes ) *s++ = '"'; s = lutil_strncopy( s, cp->val.bv_val, cp->val.bv_len ); if ( quotes ) *s++ = '"'; } if (cp->restrict_lud != NULL) { s = lutil_strcopy( s, " restrict=\"" ); s = lutil_strncopy( s, cp->restrict_val.bv_val, cp->restrict_val.bv_len ); *s++ = '"'; } *s = '\0'; rc = value_add_one( &c->rvalue_vals, &bv ); if (rc == LDAP_SUCCESS) rc = value_add_one( &c->rvalue_nvals, &bv ); ch_free(bv.bv_val); if (rc) return rc; } 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, 1 ); 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, 1 ); } 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: { int j; char **attrs = ldap_str2charray( c->argv[1], "," ); for ( j = 0; attrs[j]; j++) /* just count */ ; ap.ap = ch_calloc( sizeof(AttributeDescription*), j + 1 ); for ( j = 0; attrs[j]; j++) { if ( slap_str2ad( attrs[j], &ap.ap[j], &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s <%s>: %s\n", c->argv[0], attrs[j], text ); rc = ARG_BAD_CONF; goto done; } } if ( strcasecmp( c->argv[2], REGEX_STR ) == 0) { int err; ap.type = CONSTRAINT_REGEX; 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); ap.re = NULL; rc = ARG_BAD_CONF; goto done; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SIZE_STR ) == 0 ) { char *endptr; ap.type = CONSTRAINT_SIZE; ap.size = strtoull(c->argv[3], &endptr, 10); if ( *endptr ) rc = ARG_BAD_CONF; } else if ( strcasecmp( c->argv[2], COUNT_STR ) == 0 ) { char *endptr; ap.type = CONSTRAINT_COUNT; ap.count = strtoull(c->argv[3], &endptr, 10); if ( *endptr ) rc = ARG_BAD_CONF; } else if ( strcasecmp( c->argv[2], URI_STR ) == 0 ) { int err; ap.type = CONSTRAINT_URI; 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]); rc = ARG_BAD_CONF; goto done; } 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]); ldap_free_urldesc(ap.lud); rc = ARG_BAD_CONF; goto done; } 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 ); rc = ARG_BAD_CONF; goto done; } } ap.attrs[i] = NULL; } if (ap.lud->lud_dn == NULL) { ap.lud->lud_dn = ch_strdup(""); } else { struct berval dn, ndn; ber_str2bv( ap.lud->lud_dn, 0, 0, &dn ); if (dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) ) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: URI %s DN normalization failed", c->argv[0], c->argv[1], c->argv[3] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg ); rc = ARG_BAD_CONF; goto done; } ldap_memfree( ap.lud->lud_dn ); ap.lud->lud_dn = ndn.bv_val; } if (ap.lud->lud_filter == NULL) { ap.lud->lud_filter = ch_strdup("objectClass=*"); } else if ( ap.lud->lud_filter[0] == '(' ) { ber_len_t len = strlen( ap.lud->lud_filter ); if ( ap.lud->lud_filter[len - 1] != ')' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: invalid URI filter: %s", c->argv[0], c->argv[1], ap.lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } memmove( &ap.lud->lud_filter[0], &ap.lud->lud_filter[1], len - 2 ); ap.lud->lud_filter[len - 2] = '\0'; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SET_STR ) == 0 ) { ap.set = 1; ber_str2bv( c->argv[3], 0, 1, &ap.val ); ap.type = CONSTRAINT_SET; } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Unknown constraint type: %s", c->argv[0], c->argv[1], c->argv[2] ); rc = ARG_BAD_CONF; goto done; } if ( c->argc > 4 ) { int argidx; for ( argidx = 4; argidx < c->argc; argidx++ ) { if ( strncasecmp( c->argv[argidx], "restrict=", STRLENOF("restrict=") ) == 0 ) { int err; char *arg = c->argv[argidx] + STRLENOF("restrict="); err = ldap_url_parse(arg, &ap.restrict_lud); if ( err != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Invalid restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if (ap.restrict_lud->lud_host != NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unsupported hostname in restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if ( ap.restrict_lud->lud_attrs != NULL ) { if ( ap.restrict_lud->lud_attrs[0] != '\0' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: attrs not allowed in restrict URI %s\n", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } ldap_memvfree((void *)ap.restrict_lud->lud_attrs); ap.restrict_lud->lud_attrs = NULL; } if (ap.restrict_lud->lud_dn != NULL) { if (ap.restrict_lud->lud_dn[0] == '\0') { ldap_memfree(ap.restrict_lud->lud_dn); ap.restrict_lud->lud_dn = NULL; } else { struct berval dn, ndn; int j; ber_str2bv(ap.restrict_lud->lud_dn, 0, 0, &dn); if (dnNormalize(0, NULL, NULL, &dn, &ndn, NULL)) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI %s DN normalization failed", c->argv[0], c->argv[1], arg ); rc = ARG_BAD_CONF; goto done; } assert(c->be != NULL); if (c->be->be_nsuffix == NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI requires suffix", c->argv[0], c->argv[1] ); rc = ARG_BAD_CONF; goto done; } for ( j = 0; !BER_BVISNULL(&c->be->be_nsuffix[j]); j++) { if (dnIsSuffix(&ndn, &c->be->be_nsuffix[j])) break; } if (BER_BVISNULL(&c->be->be_nsuffix[j])) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI DN %s not within database naming context(s)", c->argv[0], c->argv[1], dn.bv_val ); rc = ARG_BAD_CONF; goto done; } ap.restrict_ndn = ndn; } } if (ap.restrict_lud->lud_filter != NULL) { ap.restrict_filter = str2filter(ap.restrict_lud->lud_filter); if (ap.restrict_filter == NULL) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI filter %s invalid", c->argv[0], c->argv[1], ap.restrict_lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } } ber_str2bv(c->argv[argidx] + STRLENOF("restrict="), 0, 1, &ap.restrict_val); } else { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unrecognized arg #%d (%s)", c->argv[0], c->argv[1], argidx, c->argv[argidx] ); rc = ARG_BAD_CONF; goto done; } } } done:; if ( rc == LDAP_SUCCESS ) { constraint *a2 = ch_calloc( sizeof(constraint), 1 ); a2->ap_next = on->on_bi.bi_private; a2->ap = ap.ap; a2->type = ap.type; a2->re = ap.re; a2->val = ap.val; a2->lud = ap.lud; a2->set = ap.set; a2->size = ap.size; a2->count = ap.count; 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; a2->restrict_lud = ap.restrict_lud; a2->restrict_ndn = ap.restrict_ndn; a2->restrict_filter = ap.restrict_filter; a2->restrict_val = ap.restrict_val; on->on_bi.bi_private = a2; } else { Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg ); constraint_free( &ap, 0 ); } ldap_memvfree((void**)attrs); } break; default: abort(); break; } break; default: abort(); } return rc; }
static int distproc_ldadd( CfEntryInfo *p, Entry *e, ConfigArgs *ca ) { slap_overinst *on; ldap_distproc_t *lc; ldapinfo_t *li; AttributeDescription *ad = NULL; Attribute *at; const char *text; int rc; if ( p->ce_type != Cft_Overlay || !p->ce_bi || p->ce_bi->bi_cf_ocs != distproc_ocs ) { return LDAP_CONSTRAINT_VIOLATION; } on = (slap_overinst *)p->ce_bi; lc = (ldap_distproc_t *)on->on_bi.bi_private; assert( ca->be == NULL ); ca->be = (BackendDB *)ch_calloc( 1, sizeof( BackendDB ) ); ca->be->bd_info = (BackendInfo *)on; rc = slap_str2ad( "olcDbURI", &ad, &text ); assert( rc == LDAP_SUCCESS ); at = attr_find( e->e_attrs, ad ); if ( lc->lc_common_li == NULL && at != NULL ) { /* FIXME: we should generate an empty default entry * if none is supplied */ Debug( LDAP_DEBUG_ANY, "slapd-distproc: " "first underlying database \"%s\" " "cannot contain attribute \"%s\".\n", e->e_name.bv_val, ad->ad_cname.bv_val, 0 ); rc = LDAP_CONSTRAINT_VIOLATION; goto done; } else if ( lc->lc_common_li != NULL && at == NULL ) { /* FIXME: we should generate an empty default entry * if none is supplied */ Debug( LDAP_DEBUG_ANY, "slapd-distproc: " "subsequent underlying database \"%s\" " "must contain attribute \"%s\".\n", e->e_name.bv_val, ad->ad_cname.bv_val, 0 ); rc = LDAP_CONSTRAINT_VIOLATION; goto done; } if ( lc->lc_common_li == NULL ) { rc = ldap_distproc_db_init_common( ca->be ); } else { rc = ldap_distproc_db_init_one( ca->be ); } if ( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "slapd-distproc: " "unable to init %sunderlying database \"%s\".\n", lc->lc_common_li == NULL ? "common " : "", e->e_name.bv_val, 0 ); return LDAP_CONSTRAINT_VIOLATION; } li = ca->be->be_private; if ( lc->lc_common_li == NULL ) { lc->lc_common_li = li; } else if ( avl_insert( &lc->lc_lai.lai_tree, (caddr_t)li, ldap_distproc_uri_cmp, ldap_distproc_uri_dup ) ) { Debug( LDAP_DEBUG_ANY, "slapd-distproc: " "database \"%s\" insert failed.\n", e->e_name.bv_val, 0, 0 ); rc = LDAP_CONSTRAINT_VIOLATION; goto done; } done:; if ( rc != LDAP_SUCCESS ) { (void)ldap_distproc_db_destroy_one( ca->be, NULL ); ch_free( ca->be ); ca->be = NULL; } return rc; }
static int sasl_ap_lookup( Operation *op, SlapReply *rs ) { BerVarray bv; AttributeDescription *ad; Attribute *a; const char *text; int rc, i; lookup_info *sl = (lookup_info *)op->o_callback->sc_private; if (rs->sr_type != REP_SEARCH) return 0; for( i = 0; sl->list[i].name; i++ ) { const char *name = sl->list[i].name; if ( name[0] == '*' ) { if ( sl->flags & SASL_AUXPROP_AUTHZID ) continue; /* Skip our private properties */ if ( !strcmp( name, slap_propnames[0] )) { i += SLAP_SASL_PROP_COUNT - 1; continue; } name++; } else if ( !(sl->flags & SASL_AUXPROP_AUTHZID ) ) continue; if ( sl->list[i].values ) { if ( !(sl->flags & SASL_AUXPROP_OVERRIDE) ) continue; } ad = NULL; rc = slap_str2ad( name, &ad, &text ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "slap_ap_lookup: str2ad(%s): %s\n", name, text, 0 ); continue; } /* If it's the rootdn and a rootpw was present, we already set * it so don't override it here. */ if ( ad == slap_schema.si_ad_userPassword && sl->list[i].values && be_isroot_dn( op->o_bd, &op->o_req_ndn )) continue; a = attr_find( rs->sr_entry->e_attrs, ad ); if ( !a ) continue; if ( ! access_allowed( op, rs->sr_entry, ad, NULL, ACL_AUTH, NULL ) ) { continue; } if ( sl->list[i].values && ( sl->flags & SASL_AUXPROP_OVERRIDE ) ) { sl->sparams->utils->prop_erase( sl->sparams->propctx, sl->list[i].name ); } for ( bv = a->a_vals; bv->bv_val; bv++ ) { /* ITS#3846 don't give hashed passwords to SASL */ if ( ad == slap_schema.si_ad_userPassword && bv->bv_val[0] == '{' /*}*/ ) { if ( lutil_passwd_scheme( bv->bv_val ) ) { /* If it's not a recognized scheme, just assume it's * a cleartext password that happened to include brackets. * * If it's a recognized scheme, skip this value, unless the * scheme is {CLEARTEXT}. In that case, skip over the * scheme name and use the remainder. If there is nothing * past the scheme name, skip this value. */ #ifdef SLAPD_CLEARTEXT if ( !strncasecmp( bv->bv_val, sc_cleartext.bv_val, sc_cleartext.bv_len )) { struct berval cbv; cbv.bv_len = bv->bv_len - sc_cleartext.bv_len; if ( cbv.bv_len > 0 ) { cbv.bv_val = bv->bv_val + sc_cleartext.bv_len; sl->sparams->utils->prop_set( sl->sparams->propctx, sl->list[i].name, cbv.bv_val, cbv.bv_len ); } } #endif continue; } } sl->sparams->utils->prop_set( sl->sparams->propctx, sl->list[i].name, bv->bv_val, bv->bv_len ); } } return LDAP_SUCCESS; }
static void * slapd_rw_config( const char *fname, int lineno, int argc, char **argv ) { slapd_map_data *ret = NULL; LDAPURLDesc *lud = NULL; char *uri; AttributeDescription *ad = NULL; int rc, flen = 0; struct berval dn, ndn; if ( argc != 1 ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] slapd map needs URI\n", fname, lineno, 0 ); return NULL; } uri = argv[0]; if ( strncasecmp( uri, "uri=", STRLENOF( "uri=" ) ) == 0 ) { uri += STRLENOF( "uri=" ); } if ( ldap_url_parse( uri, &lud ) != LDAP_URL_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] illegal URI '%s'\n", fname, lineno, uri ); return NULL; } if ( strcasecmp( lud->lud_scheme, "ldap" )) { Debug( LDAP_DEBUG_ANY, "[%s:%d] illegal URI scheme '%s'\n", fname, lineno, lud->lud_scheme ); goto done; } if (( lud->lud_host && lud->lud_host[0] ) || lud->lud_exts || !lud->lud_dn ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] illegal URI '%s'\n", fname, lineno, uri ); goto done; } if ( lud->lud_attrs ) { if ( lud->lud_attrs[1] ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] only one attribute allowed in URI\n", fname, lineno, 0 ); goto done; } if ( strcasecmp( lud->lud_attrs[0], "dn" ) && strcasecmp( lud->lud_attrs[0], "entryDN" )) { const char *text; rc = slap_str2ad( lud->lud_attrs[0], &ad, &text ); if ( rc ) goto done; } } ber_str2bv( lud->lud_dn, 0, 0, &dn ); if ( dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL )) goto done; if ( lud->lud_filter ) { flen = strlen( lud->lud_filter ) + 1; } ret = ch_malloc( sizeof( slapd_map_data ) + flen ); ret->base = ndn; if ( flen ) { ret->filter.bv_val = (char *)(ret+1); ret->filter.bv_len = flen - 1; strcpy( ret->filter.bv_val, lud->lud_filter ); } else { BER_BVZERO( &ret->filter ); } ret->scope = lud->lud_scope; if ( ad ) { ret->attrs[0].an_name = ad->ad_cname; } else { BER_BVZERO( &ret->attrs[0].an_name ); } ret->attrs[0].an_desc = ad; BER_BVZERO( &ret->attrs[1].an_name ); done: ldap_free_urldesc( lud ); return ret; }
static int adremap_cf_dnv(ConfigArgs *c) { BackendDB *be = (BackendDB *)c->be; slap_overinst *on = (slap_overinst *)c->bi; adremap_info *ai = on->on_bi.bi_private; adremap_dnv *ad, **a2; int rc = ARG_BAD_CONF; switch(c->op) { case SLAP_CONFIG_EMIT: for (ad = ai->ai_dnv; ad; ad=ad->ad_next) { char *ptr; struct berval bv; bv.bv_len = ad->ad_dnattr->ad_cname.bv_len + ad->ad_deref->ad_cname.bv_len + ad->ad_newattr->ad_cname.bv_len + 2; bv.bv_len += ad->ad_group->soc_cname.bv_len + ad->ad_mapgrp->soc_cname.bv_len + ad->ad_refgrp->soc_cname.bv_len + 3; bv.bv_len += ad->ad_refbase.bv_len + 3; bv.bv_val = ch_malloc(bv.bv_len + 1); ptr = lutil_strcopy(bv.bv_val, ad->ad_dnattr->ad_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_deref->ad_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_newattr->ad_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_group->soc_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_mapgrp->soc_cname.bv_val); *ptr++ = ' '; ptr = lutil_strcopy(ptr, ad->ad_refgrp->soc_cname.bv_val); *ptr++ = ' '; *ptr++ = '"'; ptr = lutil_strcopy(ptr, ad->ad_refbase.bv_val); *ptr++ = '"'; *ptr = '\0'; ber_bvarray_add(&c->rvalue_vals, &bv); } if (ai->ai_dnv) rc = 0; break; case LDAP_MOD_DELETE: if (c->valx < 0) { for (ad = ai->ai_dnv; ad; ad=ai->ai_dnv) { ai->ai_dnv = ad->ad_next; ch_free(ad); } } else { int i; for (i=0, a2 = &ai->ai_dnv; i<c->valx; i++, a2 = &(*a2)->ad_next); ad = *a2; *a2 = ad->ad_next; ch_free(ad); } rc = 0; break; default: { const char *text; adremap_dnv av = {0}; struct berval dn; rc = slap_str2ad(c->argv[1], &av.ad_dnattr, &text); if (rc) break; if (av.ad_dnattr->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName) { rc = 1; snprintf(c->cr_msg, sizeof(c->cr_msg), "<%s> not a DN-valued attribute", c->argv[0]); Debug(LDAP_DEBUG_ANY, "%s: %s(%s)\n", c->log, c->cr_msg, c->argv[1]); break; } rc = slap_str2ad(c->argv[2], &av.ad_deref, &text); if (rc) break; rc = slap_str2ad(c->argv[3], &av.ad_newattr, &text); if (rc) break; av.ad_group = oc_find(c->argv[4]); if (!av.ad_group) { rc = 1; break; } av.ad_mapgrp = oc_find(c->argv[5]); if (!av.ad_mapgrp) { rc = 1; break; } av.ad_refgrp = oc_find(c->argv[6]); if (!av.ad_refgrp) { rc = 1; break; } ber_str2bv(c->argv[7], 0, 0, &dn); rc = dnNormalize(0, NULL, NULL, &dn, &av.ad_refbase, NULL); if (rc) break; for (a2 = &ai->ai_dnv; *a2; a2 = &(*a2)->ad_next); ad = ch_malloc(sizeof(adremap_dnv)); ad->ad_next = NULL; ad->ad_dnattr = av.ad_dnattr; ad->ad_deref = av.ad_deref; ad->ad_newattr = av.ad_newattr; ad->ad_group = av.ad_group; ad->ad_mapgrp = av.ad_mapgrp; ad->ad_refgrp = av.ad_refgrp; ad->ad_refbase = av.ad_refbase; *a2 = ad; break; } } return rc; }
static int cloak_cfgen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; cloak_info_t *ci = (cloak_info_t *)on->on_bi.bi_private; int rc = 0, i; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case CLOAK_ATTR: for ( i = 0; ci; i++, ci = ci->ci_next ) { struct berval bv; int len; assert( ci->ci_ad != NULL ); if ( ci->ci_oc != NULL ) len = snprintf( c->cr_msg, sizeof( c->cr_msg ), SLAP_X_ORDERED_FMT "%s %s", i, ci->ci_ad->ad_cname.bv_val, ci->ci_oc->soc_cname.bv_val ); else len = snprintf( c->cr_msg, sizeof( c->cr_msg ), SLAP_X_ORDERED_FMT "%s", i, ci->ci_ad->ad_cname.bv_val ); bv.bv_val = c->cr_msg; bv.bv_len = len; value_add_one( &c->rvalue_vals, &bv ); } break; default: rc = 1; break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { cloak_info_t *ci_next; switch( c->type ) { case CLOAK_ATTR: for ( ci_next = ci, i = 0; ci_next, c->valx < 0 || i < c->valx; ci = ci_next, i++ ){ ci_next = ci->ci_next; ch_free ( ci->ci_ad ); if ( ci->ci_oc != NULL ) ch_free ( ci->ci_oc ); ch_free( ci ); } ci = (cloak_info_t *)on->on_bi.bi_private; break; default: rc = 1; break; } return rc; } switch( c->type ) { case CLOAK_ATTR: { ObjectClass *oc = NULL; AttributeDescription *ad = NULL; const char *text; cloak_info_t **cip = NULL; cloak_info_t *ci_next = NULL; if ( c->argc == 3 ) { oc = oc_find( c->argv[ 2 ] ); if ( oc == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), CLOAK_USAGE "unable to find ObjectClass \"%s\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } } rc = slap_str2ad( c->argv[ 1 ], &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), CLOAK_USAGE "unable to find AttributeDescription \"%s\"", c->argv[ 1 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } for ( i = 0, cip = (cloak_info_t **)&on->on_bi.bi_private; c->valx < 0 || i < c->valx, *cip; i++, cip = &(*cip)->ci_next ) { if ( c->valx >= 0 && *cip == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), CLOAK_USAGE "invalid index {%d}\n", c->valx ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } ci_next = *cip; } *cip = (cloak_info_t *)ch_calloc( 1, sizeof( cloak_info_t ) ); (*cip)->ci_oc = oc; (*cip)->ci_ad = ad; (*cip)->ci_next = ci_next; rc = 0; break; } default: rc = 1; break; } return rc; }
static int nss_cf_gen(ConfigArgs *c) { slap_overinst *on = (slap_overinst *)c->bi; nssov_info *ni = on->on_bi.bi_private; nssov_mapinfo *mi; int i, j, rc = 0; slap_mask_t m; if ( c->op == SLAP_CONFIG_EMIT ) { switch(c->type) { case NSS_SSD: rc = 1; for (i=NM_alias;i<NM_NONE;i++) { struct berval scope; struct berval ssd; struct berval base; mi = &ni->ni_maps[i]; /* ignore all-default services */ if ( mi->mi_scope == LDAP_SCOPE_DEFAULT && bvmatch( &mi->mi_filter, &mi->mi_filter0 ) && BER_BVISNULL( &mi->mi_base )) continue; if ( BER_BVISNULL( &mi->mi_base )) base = ni->ni_db->be_nsuffix[0]; else base = mi->mi_base; ldap_pvt_scope2bv(mi->mi_scope == LDAP_SCOPE_DEFAULT ? LDAP_SCOPE_SUBTREE : mi->mi_scope, &scope); ssd.bv_len = STRLENOF(" ldap:///???") + nss_svcs[i].word.bv_len + base.bv_len + scope.bv_len + mi->mi_filter.bv_len; ssd.bv_val = ch_malloc( ssd.bv_len + 1 ); sprintf(ssd.bv_val, "%s ldap:///%s??%s?%s", nss_svcs[i].word.bv_val, base.bv_val, scope.bv_val, mi->mi_filter.bv_val ); ber_bvarray_add( &c->rvalue_vals, &ssd ); rc = 0; } break; case NSS_MAP: rc = 1; for (i=NM_alias;i<NM_NONE;i++) { mi = &ni->ni_maps[i]; for (j=0;!BER_BVISNULL(&mi->mi_attrkeys[j]);j++) { if ( ber_bvstrcasecmp(&mi->mi_attrkeys[j], &mi->mi_attrs[j].an_name)) { struct berval map; map.bv_len = nss_svcs[i].word.bv_len + mi->mi_attrkeys[j].bv_len + mi->mi_attrs[j].an_desc->ad_cname.bv_len + 2; map.bv_val = ch_malloc(map.bv_len + 1); sprintf(map.bv_val, "%s %s %s", nss_svcs[i].word.bv_val, mi->mi_attrkeys[j].bv_val, mi->mi_attrs[j].an_desc->ad_cname.bv_val ); ber_bvarray_add( &c->rvalue_vals, &map ); rc = 0; } } } break; case NSS_PAM: rc = mask_to_verbs( pam_opts, ni->ni_pam_opts, &c->rvalue_vals ); break; case NSS_PAMGROUP: if (!BER_BVISEMPTY( &ni->ni_pam_group_dn )) { value_add_one( &c->rvalue_vals, &ni->ni_pam_group_dn ); value_add_one( &c->rvalue_nvals, &ni->ni_pam_group_dn ); } else { rc = 1; } break; case NSS_PAMSESS: if (ni->ni_pam_sessions) { ber_bvarray_dup_x( &c->rvalue_vals, ni->ni_pam_sessions, NULL ); } else { rc = 1; } break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */ return 1; } switch( c->type ) { case NSS_SSD: { LDAPURLDesc *lud; i = verb_to_mask(c->argv[1], nss_svcs); if ( i == NM_NONE ) return 1; mi = &ni->ni_maps[i]; rc = ldap_url_parse(c->argv[2], &lud); if ( rc ) return 1; do { struct berval base; /* Must be LDAP scheme */ if (strcasecmp(lud->lud_scheme,"ldap")) { rc = 1; break; } /* Host part, attrs, and extensions must be empty */ if (( lud->lud_host && *lud->lud_host ) || lud->lud_attrs || lud->lud_exts ) { rc = 1; break; } ber_str2bv( lud->lud_dn,0,0,&base); rc = dnNormalize( 0,NULL,NULL,&base,&mi->mi_base,NULL); if ( rc ) break; if ( lud->lud_filter ) { /* steal this */ ber_str2bv( lud->lud_filter,0,0,&mi->mi_filter); lud->lud_filter = NULL; } mi->mi_scope = lud->lud_scope; } while(0); ldap_free_urldesc( lud ); } break; case NSS_MAP: i = verb_to_mask(c->argv[1], nss_svcs); if ( i == NM_NONE ) return 1; rc = 1; mi = &ni->ni_maps[i]; for (j=0; !BER_BVISNULL(&mi->mi_attrkeys[j]); j++) { if (!strcasecmp(c->argv[2],mi->mi_attrkeys[j].bv_val)) { AttributeDescription *ad = NULL; const char *text; rc = slap_str2ad( c->argv[3], &ad, &text); if ( rc == 0 ) { mi->mi_attrs[j].an_desc = ad; mi->mi_attrs[j].an_name = ad->ad_cname; } break; } } break; case NSS_PAM: m = ni->ni_pam_opts; i = verbs_to_mask(c->argc, c->argv, pam_opts, &m); if (i == 0) { ni->ni_pam_opts = m; if ((m & NI_PAM_USERHOST) && !nssov_pam_host_ad) { const char *text; i = slap_str2ad("host", &nssov_pam_host_ad, &text); if (i != LDAP_SUCCESS) { snprintf(c->cr_msg, sizeof(c->cr_msg), "nssov: host attr unknown: %s", text); Debug(LDAP_DEBUG_ANY,"%s\n",c->cr_msg,0,0); rc = 1; break; } } if ((m & (NI_PAM_USERSVC|NI_PAM_HOSTSVC)) && !nssov_pam_svc_ad) { const char *text; i = slap_str2ad("authorizedService", &nssov_pam_svc_ad, &text); if (i != LDAP_SUCCESS) { snprintf(c->cr_msg, sizeof(c->cr_msg), "nssov: authorizedService attr unknown: %s", text); Debug(LDAP_DEBUG_ANY,"%s\n",c->cr_msg,0,0); rc = 1; break; } } } else { rc = 1; } break; case NSS_PAMGROUP: ni->ni_pam_group_dn = c->value_ndn; ch_free( c->value_dn.bv_val ); break; case NSS_PAMSESS: ber_str2bv( c->argv[1], 0, 1, &c->value_bv ); ber_bvarray_add( &ni->ni_pam_sessions, &c->value_bv ); break; } return rc; }
static int nssov_db_open( BackendDB *be, ConfigReply *cr ) { slap_overinst *on = (slap_overinst *)be->bd_info; nssov_info *ni = on->on_bi.bi_private; nssov_mapinfo *mi; int i, sock; struct sockaddr_un addr; /* Set default bases */ for (i=0; i<NM_NONE; i++) { if ( BER_BVISNULL( &ni->ni_maps[i].mi_base )) { ber_dupbv( &ni->ni_maps[i].mi_base, &be->be_nsuffix[0] ); } if ( ni->ni_maps[i].mi_scope == LDAP_SCOPE_DEFAULT ) ni->ni_maps[i].mi_scope = LDAP_SCOPE_SUBTREE; } /* validate attribute maps */ mi = ni->ni_maps; for ( i=0; i<NM_NONE; i++,mi++) { const char *text; int j; for (j=0; !BER_BVISNULL(&mi->mi_attrkeys[j]); j++) { /* skip attrs we already validated */ if ( mi->mi_attrs[j].an_desc ) continue; if ( slap_bv2ad( &mi->mi_attrs[j].an_name, &mi->mi_attrs[j].an_desc, &text )) { Debug(LDAP_DEBUG_ANY,"nssov: invalid attr \"%s\": %s\n", mi->mi_attrs[j].an_name.bv_val, text, 0 ); return -1; } } BER_BVZERO(&mi->mi_attrs[j].an_name); mi->mi_attrs[j].an_desc = NULL; } /* Find host and authorizedService definitions */ if ((ni->ni_pam_opts & NI_PAM_USERHOST) && !nssov_pam_host_ad) { const char *text; i = slap_str2ad("host", &nssov_pam_host_ad, &text); if (i != LDAP_SUCCESS) { Debug(LDAP_DEBUG_ANY,"nssov: host attr unknown: %s\n", text, 0, 0 ); return -1; } } if ((ni->ni_pam_opts & (NI_PAM_USERSVC|NI_PAM_HOSTSVC)) && !nssov_pam_svc_ad) { const char *text; i = slap_str2ad("authorizedService", &nssov_pam_svc_ad, &text); if (i != LDAP_SUCCESS) { Debug(LDAP_DEBUG_ANY,"nssov: authorizedService attr unknown: %s\n", text, 0, 0 ); return -1; } } if ( slapMode & SLAP_SERVER_MODE ) { /* make sure /var/run/nslcd exists */ if (mkdir(NSLCD_PATH, (mode_t) 0555)) { Debug(LDAP_DEBUG_TRACE,"nssov: mkdir(%s) failed (ignored): %s\n", NSLCD_PATH,strerror(errno),0); } else { Debug(LDAP_DEBUG_TRACE,"nssov: created %s\n",NSLCD_PATH,0,0); } /* create a socket */ if ( (sock=socket(PF_UNIX,SOCK_STREAM,0))<0 ) { Debug(LDAP_DEBUG_ANY,"nssov: cannot create socket: %s\n",strerror(errno),0,0); return -1; } /* remove existing named socket */ if (unlink(NSLCD_SOCKET)<0) { Debug( LDAP_DEBUG_TRACE,"nssov: unlink() of "NSLCD_SOCKET" failed (ignored): %s\n", strerror(errno),0,0); } /* create socket address structure */ memset(&addr,0,sizeof(struct sockaddr_un)); addr.sun_family=AF_UNIX; strncpy(addr.sun_path,NSLCD_SOCKET,sizeof(addr.sun_path)); addr.sun_path[sizeof(addr.sun_path)-1]='\0'; /* bind to the named socket */ if (bind(sock,(struct sockaddr *)&addr,sizeof(struct sockaddr_un))) { Debug( LDAP_DEBUG_ANY,"nssov: bind() to "NSLCD_SOCKET" failed: %s", strerror(errno),0,0); if (close(sock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return -1; } /* close the file descriptor on exit */ if (fcntl(sock,F_SETFD,FD_CLOEXEC)<0) { Debug( LDAP_DEBUG_ANY,"nssov: fcntl(F_SETFL,O_NONBLOCK) failed: %s",strerror(errno),0,0); if (close(sock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return -1; } /* set permissions of socket so anybody can do requests */ /* Note: we use chmod() here instead of fchmod() because fchmod does not work on sockets http://www.opengroup.org/onlinepubs/009695399/functions/fchmod.html http://lkml.org/lkml/2005/5/16/11 */ if (chmod(NSLCD_SOCKET,(mode_t)0666)) { Debug( LDAP_DEBUG_ANY,"nssov: chmod(0666) failed: %s",strerror(errno),0,0); if (close(sock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return -1; } /* start listening for connections */ if (listen(sock,SOMAXCONN)<0) { Debug( LDAP_DEBUG_ANY,"nssov: listen() failed: %s",strerror(errno),0,0); if (close(sock)) Debug( LDAP_DEBUG_ANY,"nssov: problem closing socket: %s",strerror(errno),0,0); return -1; } ni->ni_socket = sock; ni->ni_conn = connection_client_setup( sock, acceptconn, ni ); } return 0; }
int bdb_attr_index_config( struct bdb_info *bdb, const char *fname, int lineno, int argc, char **argv, struct config_reply_s *c_reply) { int rc = 0; int i; slap_mask_t mask; char **attrs; char **indexes = NULL; attrs = ldap_str2charray( argv[0], "," ); if( attrs == NULL ) { fprintf( stderr, "%s: line %d: " "no attributes specified: %s\n", fname, lineno, argv[0] ); return LDAP_PARAM_ERROR; } if ( argc > 1 ) { indexes = ldap_str2charray( argv[1], "," ); if( indexes == NULL ) { fprintf( stderr, "%s: line %d: " "no indexes specified: %s\n", fname, lineno, argv[1] ); rc = LDAP_PARAM_ERROR; goto done; } } if( indexes == NULL ) { mask = bdb->bi_defaultmask; } else { mask = 0; for ( i = 0; indexes[i] != NULL; i++ ) { slap_mask_t index; rc = slap_str2index( indexes[i], &index ); if( rc != LDAP_SUCCESS ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index type \"%s\" undefined", indexes[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_PARAM_ERROR; goto done; } mask |= index; } } if( !mask ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "no indexes selected" ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_PARAM_ERROR; goto done; } for ( i = 0; attrs[i] != NULL; i++ ) { AttrInfo *a; AttributeDescription *ad; const char *text; #ifdef LDAP_COMP_MATCH ComponentReference* cr = NULL; AttrInfo *a_cr = NULL; #endif if( strcasecmp( attrs[i], "default" ) == 0 ) { bdb->bi_defaultmask |= mask; continue; } #ifdef LDAP_COMP_MATCH if ( is_component_reference( attrs[i] ) ) { rc = extract_component_reference( attrs[i], &cr ); if ( rc != LDAP_SUCCESS ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index component reference\"%s\" undefined", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } goto done; } cr->cr_indexmask = mask; /* * After extracting a component reference * only the name of a attribute will be remaining */ } else { cr = NULL; } #endif ad = NULL; rc = slap_str2ad( attrs[i], &ad, &text ); if( rc != LDAP_SUCCESS ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index attribute \"%s\" undefined", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } fail: #ifdef LDAP_COMP_MATCH ch_free( cr ); #endif goto done; } if( ad == slap_schema.si_ad_entryDN || slap_ad_is_binary( ad ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_UNWILLING_TO_PERFORM; goto fail; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( ad->ad_type->sat_approx && ad->ad_type->sat_approx->smr_indexer && ad->ad_type->sat_approx->smr_filter ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "approx index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_INAPPROPRIATE_MATCHING; goto fail; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( ad->ad_type->sat_equality && ad->ad_type->sat_equality->smr_indexer && ad->ad_type->sat_equality->smr_filter ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "equality index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_INAPPROPRIATE_MATCHING; goto fail; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( ad->ad_type->sat_substr && ad->ad_type->sat_substr->smr_indexer && ad->ad_type->sat_substr->smr_filter ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "substr index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_INAPPROPRIATE_MATCHING; goto fail; } Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", ad->ad_cname.bv_val, mask ); a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); #ifdef LDAP_COMP_MATCH a->ai_cr = NULL; #endif a->ai_desc = ad; if ( bdb->bi_flags & BDB_IS_OPEN ) { a->ai_indexmask = 0; a->ai_newmask = mask; } else { a->ai_indexmask = mask; a->ai_newmask = 0; } #ifdef LDAP_COMP_MATCH if ( cr ) { a_cr = bdb_attr_mask( bdb, ad ); if ( a_cr ) { /* * AttrInfo is already in AVL * just add the extracted component reference * in the AttrInfo */ ch_free( a ); rc = insert_component_reference( cr, &a_cr->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); rc = LDAP_PARAM_ERROR; goto fail; } continue; } else { rc = insert_component_reference( cr, &a->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); rc = LDAP_PARAM_ERROR; ch_free( a ); goto fail; } } } #endif rc = ainfo_insert( bdb, a ); if( rc ) { if ( bdb->bi_flags & BDB_IS_OPEN ) { AttrInfo *b = bdb_attr_mask( bdb, ad ); /* If there is already an index defined for this attribute * it must be replaced. Otherwise we end up with multiple * olcIndex values for the same attribute */ if ( b->ai_indexmask & BDB_INDEX_DELETING ) { /* If we were editing this attr, reset it */ b->ai_indexmask &= ~BDB_INDEX_DELETING; /* If this is leftover from a previous add, commit it */ if ( b->ai_newmask ) b->ai_indexmask = b->ai_newmask; b->ai_newmask = a->ai_newmask; ch_free( a ); rc = 0; continue; } } if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "duplicate index definition for attr \"%s\"", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_PARAM_ERROR; goto done; } } done: ldap_charray_free( attrs ); if ( indexes != NULL ) ldap_charray_free( indexes ); return rc; }
static int dl_cfgen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private; int rc = 0, i; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case DL_ATTRSET: for ( i = 0; dli; i++, dli = dli->dli_next ) { struct berval bv; char *ptr = c->cr_msg; dynlist_map_t *dlm; assert( dli->dli_oc != NULL ); assert( dli->dli_ad != NULL ); /* FIXME: check buffer overflow! */ ptr += snprintf( c->cr_msg, sizeof( c->cr_msg ), SLAP_X_ORDERED_FMT "%s", i, dli->dli_oc->soc_cname.bv_val ); if ( !BER_BVISNULL( &dli->dli_uri ) ) { *ptr++ = ' '; *ptr++ = '"'; ptr = lutil_strncopy( ptr, dli->dli_uri.bv_val, dli->dli_uri.bv_len ); *ptr++ = '"'; } *ptr++ = ' '; ptr = lutil_strncopy( ptr, dli->dli_ad->ad_cname.bv_val, dli->dli_ad->ad_cname.bv_len ); for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) { ptr[ 0 ] = ' '; ptr++; if ( dlm->dlm_mapped_ad ) { ptr = lutil_strcopy( ptr, dlm->dlm_mapped_ad->ad_cname.bv_val ); ptr[ 0 ] = ':'; ptr++; } ptr = lutil_strcopy( ptr, dlm->dlm_member_ad->ad_cname.bv_val ); } bv.bv_val = c->cr_msg; bv.bv_len = ptr - bv.bv_val; value_add_one( &c->rvalue_vals, &bv ); } break; case DL_ATTRPAIR_COMPAT: case DL_ATTRPAIR: rc = 1; break; default: rc = 1; break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { case DL_ATTRSET: if ( c->valx < 0 ) { dynlist_info_t *dli_next; for ( dli_next = dli; dli_next; dli = dli_next ) { dynlist_map_t *dlm = dli->dli_dlm; dynlist_map_t *dlm_next; dli_next = dli->dli_next; if ( !BER_BVISNULL( &dli->dli_uri ) ) { ch_free( dli->dli_uri.bv_val ); } if ( dli->dli_lud != NULL ) { ldap_free_urldesc( dli->dli_lud ); } if ( !BER_BVISNULL( &dli->dli_uri_nbase ) ) { ber_memfree( dli->dli_uri_nbase.bv_val ); } if ( dli->dli_uri_filter != NULL ) { filter_free( dli->dli_uri_filter ); } ch_free( dli->dli_default_filter.bv_val ); while ( dlm != NULL ) { dlm_next = dlm->dlm_next; ch_free( dlm ); dlm = dlm_next; } ch_free( dli ); } on->on_bi.bi_private = NULL; } else { dynlist_info_t **dlip; dynlist_map_t *dlm; dynlist_map_t *dlm_next; for ( i = 0, dlip = (dynlist_info_t **)&on->on_bi.bi_private; i < c->valx; i++ ) { if ( *dlip == NULL ) { return 1; } dlip = &(*dlip)->dli_next; } dli = *dlip; *dlip = dli->dli_next; if ( !BER_BVISNULL( &dli->dli_uri ) ) { ch_free( dli->dli_uri.bv_val ); } if ( dli->dli_lud != NULL ) { ldap_free_urldesc( dli->dli_lud ); } if ( !BER_BVISNULL( &dli->dli_uri_nbase ) ) { ber_memfree( dli->dli_uri_nbase.bv_val ); } if ( dli->dli_uri_filter != NULL ) { filter_free( dli->dli_uri_filter ); } ch_free( dli->dli_default_filter.bv_val ); dlm = dli->dli_dlm; while ( dlm != NULL ) { dlm_next = dlm->dlm_next; ch_free( dlm ); dlm = dlm_next; } ch_free( dli ); dli = (dynlist_info_t *)on->on_bi.bi_private; } break; case DL_ATTRPAIR_COMPAT: case DL_ATTRPAIR: rc = 1; break; default: rc = 1; break; } return rc; } switch( c->type ) { case DL_ATTRSET: { dynlist_info_t **dlip, *dli_next = NULL; ObjectClass *oc = NULL; AttributeDescription *ad = NULL; int attridx = 2; LDAPURLDesc *lud = NULL; struct berval nbase = BER_BVNULL; Filter *filter = NULL; struct berval uri = BER_BVNULL; dynlist_map_t *dlm = NULL, *dlml = NULL; const char *text; oc = oc_find( c->argv[ 1 ] ); if ( oc == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find ObjectClass \"%s\"", c->argv[ 1 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } if ( strncasecmp( c->argv[ attridx ], "ldap://", STRLENOF("ldap://") ) == 0 ) { if ( ldap_url_parse( c->argv[ attridx ], &lud ) != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to parse URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } if ( lud->lud_host != NULL ) { if ( lud->lud_host[0] == '\0' ) { ch_free( lud->lud_host ); lud->lud_host = NULL; } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "host not allowed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } } if ( lud->lud_attrs != NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "attrs not allowed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } if ( lud->lud_exts != NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "extensions not allowed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } if ( lud->lud_dn != NULL && lud->lud_dn[ 0 ] != '\0' ) { struct berval dn; ber_str2bv( lud->lud_dn, 0, 0, &dn ); rc = dnNormalize( 0, NULL, NULL, &dn, &nbase, NULL ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "DN normalization failed in URI \"%s\"", c->argv[ attridx ] ); goto done_uri; } } if ( lud->lud_filter != NULL && lud->lud_filter[ 0 ] != '\0' ) { filter = str2filter( lud->lud_filter ); if ( filter == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "filter parsing failed in URI \"%s\"", c->argv[ attridx ] ); rc = 1; goto done_uri; } } ber_str2bv( c->argv[ attridx ], 0, 1, &uri ); done_uri:; if ( rc ) { if ( lud ) { ldap_free_urldesc( lud ); } if ( !BER_BVISNULL( &nbase ) ) { ber_memfree( nbase.bv_val ); } if ( filter != NULL ) { filter_free( filter ); } while ( dlm != NULL ) { dlml = dlm; dlm = dlm->dlm_next; ch_free( dlml ); } Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return rc; } attridx++; } rc = slap_str2ad( c->argv[ attridx ], &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find AttributeDescription \"%s\"", c->argv[ attridx ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); rc = 1; goto done_uri; } if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "AttributeDescription \"%s\" " "must be a subtype of \"labeledURI\"", c->argv[ attridx ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); rc = 1; goto done_uri; } attridx++; for ( i = attridx; i < c->argc; i++ ) { char *arg; char *cp; AttributeDescription *member_ad = NULL; AttributeDescription *mapped_ad = NULL; dynlist_map_t *dlmp; /* * If no mapped attribute is given, dn is used * for backward compatibility. */ arg = c->argv[i]; if ( ( cp = strchr( arg, ':' ) ) != NULL ) { struct berval bv; ber_str2bv( arg, cp - arg, 0, &bv ); rc = slap_bv2ad( &bv, &mapped_ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find mapped AttributeDescription #%d \"%s\"\n", i - 3, c->argv[ i ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); rc = 1; goto done_uri; } arg = cp + 1; } rc = slap_str2ad( arg, &member_ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "unable to find AttributeDescription #%d \"%s\"\n", i - 3, c->argv[ i ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); rc = 1; goto done_uri; } dlmp = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) ); if ( dlm == NULL ) { dlm = dlmp; } dlmp->dlm_member_ad = member_ad; dlmp->dlm_mapped_ad = mapped_ad; dlmp->dlm_next = NULL; if ( dlml != NULL ) dlml->dlm_next = dlmp; dlml = dlmp; } if ( c->valx > 0 ) { int i; for ( i = 0, dlip = (dynlist_info_t **)&on->on_bi.bi_private; i < c->valx; i++ ) { if ( *dlip == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "invalid index {%d}\n", c->valx ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); rc = 1; goto done_uri; } dlip = &(*dlip)->dli_next; } dli_next = *dlip; } else { for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private; *dlip; dlip = &(*dlip)->dli_next ) /* goto last */; } *dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) ); (*dlip)->dli_oc = oc; (*dlip)->dli_ad = ad; (*dlip)->dli_dlm = dlm; (*dlip)->dli_next = dli_next; (*dlip)->dli_lud = lud; (*dlip)->dli_uri_nbase = nbase; (*dlip)->dli_uri_filter = filter; (*dlip)->dli_uri = uri; rc = dynlist_build_def_filter( *dlip ); } break; case DL_ATTRPAIR_COMPAT: snprintf( c->cr_msg, sizeof( c->cr_msg ), "warning: \"attrpair\" only supported for limited " "backward compatibility with overlay \"dyngroup\"" ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); /* fallthru */ case DL_ATTRPAIR: { dynlist_info_t **dlip; ObjectClass *oc = NULL; AttributeDescription *ad = NULL, *member_ad = NULL; const char *text; oc = oc_find( "groupOfURLs" ); if ( oc == NULL ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find default ObjectClass \"groupOfURLs\"" ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } rc = slap_str2ad( c->argv[ 1 ], &member_ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find AttributeDescription \"%s\"", c->argv[ 1 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } rc = slap_str2ad( c->argv[ 2 ], &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "unable to find AttributeDescription \"%s\"\n", c->argv[ 2 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), DYNLIST_USAGE "AttributeDescription \"%s\" " "must be a subtype of \"labeledURI\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); return 1; } for ( dlip = (dynlist_info_t **)&on->on_bi.bi_private; *dlip; dlip = &(*dlip)->dli_next ) { /* * The same URL attribute / member attribute pair * cannot be repeated, but we enforce this only * when the member attribute is unique. Performing * the check for multiple values would require * sorting and comparing the lists, which is left * as a future improvement */ if ( (*dlip)->dli_ad == ad && (*dlip)->dli_dlm->dlm_next == NULL && member_ad == (*dlip)->dli_dlm->dlm_member_ad ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "\"dynlist-attrpair <member-ad> <URL-ad>\": " "URL attributeDescription \"%s\" already mapped.\n", ad->ad_cname.bv_val ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 ); #if 0 /* make it a warning... */ return 1; #endif } } *dlip = (dynlist_info_t *)ch_calloc( 1, sizeof( dynlist_info_t ) ); (*dlip)->dli_oc = oc; (*dlip)->dli_ad = ad; (*dlip)->dli_dlm = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) ); (*dlip)->dli_dlm->dlm_member_ad = member_ad; (*dlip)->dli_dlm->dlm_mapped_ad = NULL; rc = dynlist_build_def_filter( *dlip ); } break; default: rc = 1; break; } return rc; }
static int dynlist_db_open( BackendDB *be, ConfigReply *cr ) { slap_overinst *on = (slap_overinst *) be->bd_info; dynlist_info_t *dli = (dynlist_info_t *)on->on_bi.bi_private; ObjectClass *oc = NULL; AttributeDescription *ad = NULL; const char *text; int rc; if ( dli == NULL ) { dli = ch_calloc( 1, sizeof( dynlist_info_t ) ); on->on_bi.bi_private = (void *)dli; } for ( ; dli; dli = dli->dli_next ) { if ( dli->dli_oc == NULL ) { if ( oc == NULL ) { oc = oc_find( "groupOfURLs" ); if ( oc == NULL ) { snprintf( cr->msg, sizeof( cr->msg), "unable to fetch objectClass \"groupOfURLs\"" ); Debug( LDAP_DEBUG_ANY, "dynlist_db_open: %s.\n", cr->msg, 0, 0 ); return 1; } } dli->dli_oc = oc; } if ( dli->dli_ad == NULL ) { if ( ad == NULL ) { rc = slap_str2ad( "memberURL", &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( cr->msg, sizeof( cr->msg), "unable to fetch attributeDescription \"memberURL\": %d (%s)", rc, text ); Debug( LDAP_DEBUG_ANY, "dynlist_db_open: %s.\n", cr->msg, 0, 0 ); return 1; } } dli->dli_ad = ad; } if ( BER_BVISNULL( &dli->dli_default_filter ) ) { rc = dynlist_build_def_filter( dli ); if ( rc != 0 ) { return rc; } } } if ( ad_dgIdentity == NULL ) { rc = slap_str2ad( "dgIdentity", &ad_dgIdentity, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( cr->msg, sizeof( cr->msg), "unable to fetch attributeDescription \"dgIdentity\": %d (%s)", rc, text ); Debug( LDAP_DEBUG_ANY, "dynlist_db_open: %s\n", cr->msg, 0, 0 ); /* Just a warning */ } } if ( ad_dgAuthz == NULL ) { rc = slap_str2ad( "dgAuthz", &ad_dgAuthz, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( cr->msg, sizeof( cr->msg), "unable to fetch attributeDescription \"dgAuthz\": %d (%s)", rc, text ); Debug( LDAP_DEBUG_ANY, "dynlist_db_open: %s\n", cr->msg, 0, 0 ); /* Just a warning */ } } return 0; }
static int mdb_cf_gen( ConfigArgs *c ) { struct mdb_info *mdb = c->be->be_private; int rc; if ( c->op == SLAP_CONFIG_EMIT ) { rc = 0; switch( c->type ) { case MDB_MODE: { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "0%o", mdb->mi_dbenv_mode ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } break; case MDB_CHKPT: if ( mdb->mi_txn_cp ) { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "%ld %ld", (long) mdb->mi_txn_cp_kbyte, (long) mdb->mi_txn_cp_min ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } else { rc = 1; } break; case MDB_DIRECTORY: if ( mdb->mi_dbenv_home ) { c->value_string = ch_strdup( mdb->mi_dbenv_home ); } else { rc = 1; } break; case MDB_DBNOSYNC: if ( mdb->mi_dbenv_flags & MDB_NOSYNC ) c->value_int = 1; break; case MDB_ENVFLAGS: if ( mdb->mi_dbenv_flags ) { mask_to_verbs( mdb_envflags, mdb->mi_dbenv_flags, &c->rvalue_vals ); } if ( !c->rvalue_vals ) rc = 1; break; case MDB_INDEX: mdb_attr_index_unparse( mdb, &c->rvalue_vals ); if ( !c->rvalue_vals ) rc = 1; break; case MDB_SSTACK: c->value_int = mdb->mi_search_stack_depth; break; case MDB_MAXREADERS: c->value_int = mdb->mi_readers; break; case MDB_MAXSIZE: c->value_ulong = mdb->mi_mapsize; break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { rc = 0; switch( c->type ) { case MDB_MODE: #if 0 /* FIXME: does it make any sense to change the mode, * if we don't exec a chmod()? */ mdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; break; #endif /* single-valued no-ops */ case MDB_SSTACK: case MDB_MAXREADERS: case MDB_MAXSIZE: break; case MDB_CHKPT: if ( mdb->mi_txn_cp_task ) { struct re_s *re = mdb->mi_txn_cp_task; mdb->mi_txn_cp_task = NULL; ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) ldap_pvt_runqueue_stoptask( &slapd_rq, re ); ldap_pvt_runqueue_remove( &slapd_rq, re ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } mdb->mi_txn_cp = 0; break; case MDB_DIRECTORY: mdb->mi_flags |= MDB_RE_OPEN; ch_free( mdb->mi_dbenv_home ); mdb->mi_dbenv_home = NULL; c->cleanup = mdb_cf_cleanup; ldap_pvt_thread_pool_purgekey( mdb->mi_dbenv ); break; case MDB_DBNOSYNC: mdb_env_set_flags( mdb->mi_dbenv, MDB_NOSYNC, 0 ); mdb->mi_dbenv_flags &= ~MDB_NOSYNC; break; case MDB_ENVFLAGS: if ( c->valx == -1 ) { int i; for ( i=0; mdb_envflags[i].mask; i++) { if ( mdb->mi_dbenv_flags & mdb_envflags[i].mask ) { /* not all flags are runtime resettable */ rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; rc = 0; } mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; } } } else { int i = verb_to_mask( c->line, mdb_envflags ); if ( mdb_envflags[i].mask & mdb->mi_dbenv_flags ) { rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; rc = 0; } mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; } else { /* unknown keyword */ rc = 1; } } break; case MDB_INDEX: if ( c->valx == -1 ) { int i; /* delete all (FIXME) */ for ( i = 0; i < mdb->mi_nattrs; i++ ) { mdb->mi_attrs[i]->ai_indexmask |= MDB_INDEX_DELETING; } mdb->mi_flags |= MDB_DEL_INDEX; c->cleanup = mdb_cf_cleanup; } else { struct berval bv, def = BER_BVC("default"); char *ptr; for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++); bv.bv_val = c->line; bv.bv_len = ptr - bv.bv_val; if ( bvmatch( &bv, &def )) { mdb->mi_defaultmask = 0; } else { int i; char **attrs; char sep; sep = bv.bv_val[ bv.bv_len ]; bv.bv_val[ bv.bv_len ] = '\0'; attrs = ldap_str2charray( bv.bv_val, "," ); for ( i = 0; attrs[ i ]; i++ ) { AttributeDescription *ad = NULL; const char *text; AttrInfo *ai; slap_str2ad( attrs[ i ], &ad, &text ); /* if we got here... */ assert( ad != NULL ); ai = mdb_attr_mask( mdb, ad ); /* if we got here... */ assert( ai != NULL ); ai->ai_indexmask |= MDB_INDEX_DELETING; mdb->mi_flags |= MDB_DEL_INDEX; c->cleanup = mdb_cf_cleanup; } bv.bv_val[ bv.bv_len ] = sep; ldap_charray_free( attrs ); } } break; } return rc; } switch( c->type ) { case MDB_MODE: if ( ASCII_DIGIT( c->argv[1][0] ) ) { long mode; char *next; errno = 0; mode = strtol( c->argv[1], &next, 0 ); if ( errno != 0 || next == c->argv[1] || next[0] != '\0' ) { fprintf( stderr, "%s: " "unable to parse mode=\"%s\".\n", c->log, c->argv[1] ); return 1; } mdb->mi_dbenv_mode = mode; } else { char *m = c->argv[1]; int who, what, mode = 0; if ( strlen( m ) != STRLENOF("-rwxrwxrwx") ) { return 1; } if ( m[0] != '-' ) { return 1; } m++; for ( who = 0; who < 3; who++ ) { for ( what = 0; what < 3; what++, m++ ) { if ( m[0] == '-' ) { continue; } else if ( m[0] != "rwx"[what] ) { return 1; } mode += ((1 << (2 - what)) << 3*(2 - who)); } } mdb->mi_dbenv_mode = mode; } break; case MDB_CHKPT: { long l; mdb->mi_txn_cp = 1; if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid kbyte \"%s\" in \"checkpoint\".\n", c->log, c->argv[1] ); return 1; } mdb->mi_txn_cp_kbyte = l; if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid minutes \"%s\" in \"checkpoint\".\n", c->log, c->argv[2] ); return 1; } mdb->mi_txn_cp_min = l; /* If we're in server mode and time-based checkpointing is enabled, * submit a task to perform periodic checkpoints. */ if ((slapMode & SLAP_SERVER_MODE) && mdb->mi_txn_cp_min ) { struct re_s *re = mdb->mi_txn_cp_task; if ( re ) { re->interval.tv_sec = mdb->mi_txn_cp_min * 60; } else { if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"checkpoint\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); mdb->mi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq, mdb->mi_txn_cp_min * 60, mdb_checkpoint, mdb, LDAP_XSTRING(mdb_checkpoint), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } } } break; case MDB_DIRECTORY: { FILE *f; char *ptr, *testpath; int len; len = strlen( c->value_string ); testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 ); ptr = lutil_strcopy( testpath, c->value_string ); *ptr++ = LDAP_DIRSEP[0]; strcpy( ptr, "DUMMY" ); f = fopen( testpath, "w" ); if ( f ) { fclose( f ); unlink( testpath ); } ch_free( testpath ); if ( !f ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s", c->log, strerror( errno )); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } if ( mdb->mi_dbenv_home ) ch_free( mdb->mi_dbenv_home ); mdb->mi_dbenv_home = c->value_string; } break; case MDB_DBNOSYNC: if ( c->value_int ) mdb->mi_dbenv_flags |= MDB_NOSYNC; else mdb->mi_dbenv_flags ^= MDB_NOSYNC; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb_env_set_flags( mdb->mi_dbenv, MDB_NOSYNC, c->value_int ); } break; case MDB_ENVFLAGS: { int i, j; for ( i=1; i<c->argc; i++ ) { j = verb_to_mask( c->argv[i], mdb_envflags ); if ( mdb_envflags[j].mask ) { if ( mdb->mi_flags & MDB_IS_OPEN ) rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[j].mask, 1 ); else rc = 0; if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; rc = 0; } mdb->mi_dbenv_flags |= mdb_envflags[i].mask; } else { /* unknown keyword */ rc = 1; } } } break; case MDB_INDEX: rc = mdb_attr_index_config( mdb, c->fname, c->lineno, c->argc - 1, &c->argv[1], &c->reply); if( rc != LDAP_SUCCESS ) return 1; c->cleanup = mdb_cf_cleanup; mdb->mi_flags |= MDB_OPEN_INDEX; if (( mdb->mi_flags & MDB_IS_OPEN ) && !mdb->mi_index_task ) { /* Start the task as soon as we finish here. Set a long * interval (10 hours) so that it only gets scheduled once. */ if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"index\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); mdb->mi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000, mdb_online_index, c->be, LDAP_XSTRING(mdb_online_index), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } break; case MDB_SSTACK: if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) { fprintf( stderr, "%s: depth %d too small, using %d\n", c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH ); c->value_int = MINIMUM_SEARCH_STACK_DEPTH; } mdb->mi_search_stack_depth = c->value_int; break; case MDB_MAXREADERS: mdb->mi_readers = c->value_int; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; } break; case MDB_MAXSIZE: mdb->mi_mapsize = c->value_ulong; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; } break; } return 0; }
static int dgroup_cf( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; int rc = 1; switch( c->op ) { case SLAP_CONFIG_EMIT: { adpair *ap; for ( ap = on->on_bi.bi_private; ap; ap = ap->ap_next ) { struct berval bv; char *ptr; bv.bv_len = ap->ap_mem->ad_cname.bv_len + 1 + ap->ap_uri->ad_cname.bv_len; bv.bv_val = ch_malloc( bv.bv_len + 1 ); ptr = lutil_strcopy( bv.bv_val, ap->ap_mem->ad_cname.bv_val ); *ptr++ = ' '; strcpy( ptr, ap->ap_uri->ad_cname.bv_val ); ber_bvarray_add( &c->rvalue_vals, &bv ); rc = 0; } } break; case LDAP_MOD_DELETE: if ( c->valx == -1 ) { adpair *ap; while (( ap = on->on_bi.bi_private )) { on->on_bi.bi_private = ap->ap_next; ch_free( ap ); } } else { adpair **app, *ap; int i; app = (adpair **)&on->on_bi.bi_private; for (i=0; i<=c->valx; i++, app = &ap->ap_next) { ap = *app; } *app = ap->ap_next; ch_free( ap ); } rc = 0; break; case SLAP_CONFIG_ADD: case LDAP_MOD_ADD: { adpair ap = { NULL, NULL, NULL }, *a2; const char *text; if ( slap_str2ad( c->argv[1], &ap.ap_mem, &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"", c->argv[0], c->argv[1] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); return ARG_BAD_CONF; } if ( slap_str2ad( c->argv[2], &ap.ap_uri, &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"", c->argv[0], c->argv[2] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); return ARG_BAD_CONF; } /* The on->on_bi.bi_private pointer can be used for * anything this instance of the overlay needs. */ a2 = ch_malloc( sizeof(adpair) ); a2->ap_next = on->on_bi.bi_private; a2->ap_mem = ap.ap_mem; a2->ap_uri = ap.ap_uri; on->on_bi.bi_private = a2; rc = 0; } } return rc; }