コード例 #1
0
ファイル: dn2id.c プロジェクト: bhanug/likewise-open
int
hdb_dn2id(
	Operation	*op,
	struct berval	*in,
	EntryInfo	*ei,
	DB_TXN *txn,
	DB_LOCK *lock )
{
	struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
	DB *db = bdb->bi_dn2id->bdi_db;
	DBT		key, data;
	DBC	*cursor;
	int		rc = 0, nrlen;
	diskNode *d;
	char	*ptr;
	unsigned char dlen[2];
	ID idp, parentID;

	Debug( LDAP_DEBUG_TRACE, "=> hdb_dn2id(\"%s\")\n", in->bv_val, 0, 0 );

	nrlen = dn_rdnlen( op->o_bd, in );
	if (!nrlen) nrlen = in->bv_len;

	DBTzero(&key);
	key.size = sizeof(ID);
	key.data = &idp;
	key.ulen = sizeof(ID);
	key.flags = DB_DBT_USERMEM;
	parentID = ( ei->bei_parent != NULL ) ? ei->bei_parent->bei_id : 0;
	BDB_ID2DISK( parentID, &idp );

	DBTzero(&data);
	data.size = sizeof(diskNode) + nrlen - sizeof(ID) - 1;
	data.ulen = data.size * 3;
	data.dlen = data.ulen;
	data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;

	rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
	if ( rc ) return rc;

	d = op->o_tmpalloc( data.size * 3, op->o_tmpmemctx );
	d->nrdnlen[1] = nrlen & 0xff;
	d->nrdnlen[0] = (nrlen >> 8) | 0x80;
	dlen[0] = d->nrdnlen[0];
	dlen[1] = d->nrdnlen[1];
	ptr = lutil_strncopy( d->nrdn, in->bv_val, nrlen );
	*ptr = '\0';
	data.data = d;

	rc = bdb_dn2id_lock( bdb, in, 0, txn, lock );
	if ( rc ) goto func_leave;

	rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE );
	if ( rc == 0 && (dlen[1] != d->nrdnlen[1] || dlen[0] != d->nrdnlen[0] ||
		strncmp( d->nrdn, in->bv_val, nrlen ))) {
		rc = DB_NOTFOUND;
	}
	if ( rc == 0 ) {
		ptr = (char *) data.data + data.size - sizeof(ID);
		BDB_DISK2ID( ptr, &ei->bei_id );
		ei->bei_rdn.bv_len = data.size - sizeof(diskNode) - nrlen;
		ptr = d->nrdn + nrlen + 1;
		ber_str2bv( ptr, ei->bei_rdn.bv_len, 1, &ei->bei_rdn );
		if ( ei->bei_parent != NULL && !ei->bei_parent->bei_dkids ) {
			db_recno_t dkids;
			/* How many children does the parent have? */
			/* FIXME: do we need to lock the parent
			 * entryinfo? Seems safe...
			 */
			cursor->c_count( cursor, &dkids, 0 );
			ei->bei_parent->bei_dkids = dkids;
		}
	}

func_leave:
	cursor->c_close( cursor );
	op->o_tmpfree( d, op->o_tmpmemctx );
	if( rc != 0 ) {
		Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: get failed: %s (%d)\n",
			db_strerror( rc ), rc, 0 );
	} else {
		Debug( LDAP_DEBUG_TRACE, "<= hdb_dn2id: got id=0x%lx\n",
			ei->bei_id, 0, 0 );
	}

	return rc;
}
コード例 #2
0
ファイル: dynlist.c プロジェクト: bhanug/likewise-open
static int
dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli )
{
	Attribute	*a, *id = NULL;
	slap_callback	cb;
	Operation	o = *op;
	SlapReply	r = { REP_SEARCH };
	struct berval	*url;
	Entry		*e;
	slap_mask_t	e_flags;
	int		opattrs,
			userattrs;
	dynlist_sc_t	dlc = { 0 };
	dynlist_map_t	*dlm;

	a = attrs_find( rs->sr_entry->e_attrs, dli->dli_ad );
	if ( a == NULL ) {
		/* FIXME: error? */
		return SLAP_CB_CONTINUE;
	}

#ifndef SLAP_OPATTRS
	opattrs = ( rs->sr_attrs == NULL ) ? 0 : an_find( rs->sr_attrs, slap_bv_operational_attrs );
	userattrs = ( rs->sr_attrs == NULL ) ? 1 : an_find( rs->sr_attrs, slap_bv_user_attrs );
#else /* SLAP_OPATTRS */
	opattrs = SLAP_OPATTRS( rs->sr_attr_flags );
	userattrs = SLAP_USERATTRS( rs->sr_attr_flags );
#endif /* SLAP_OPATTRS */

	/* Don't generate member list if it wasn't requested */
	for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
		AttributeDescription *ad = dlm->dlm_mapped_ad ? dlm->dlm_mapped_ad : dlm->dlm_member_ad;
		if ( userattrs || ad_inlist( ad, rs->sr_attrs ) )
			break;
	}
	if ( dli->dli_dlm && !dlm )
		return SLAP_CB_CONTINUE;

	if ( ad_dgIdentity && ( id = attrs_find( rs->sr_entry->e_attrs, ad_dgIdentity ))) {
		Attribute *authz = NULL;

		/* if not rootdn and dgAuthz is present,
		 * check if user can be authorized as dgIdentity */
		if ( ad_dgAuthz && !BER_BVISEMPTY( &id->a_nvals[0] ) && !be_isroot( op )
			&& ( authz = attrs_find( rs->sr_entry->e_attrs, ad_dgAuthz ) ) )
		{
			if ( slap_sasl_matches( op, authz->a_nvals,
				&o.o_ndn, &o.o_ndn ) != LDAP_SUCCESS )
			{
				return SLAP_CB_CONTINUE;
			}
		}

		o.o_dn = id->a_vals[0];
		o.o_ndn = id->a_nvals[0];
		o.o_groups = NULL;
	}

	e_flags = rs->sr_flags;
	if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
		e = entry_dup( rs->sr_entry );
		e_flags |= ( REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED );
	} else {
		e = rs->sr_entry;
	}

	dlc.dlc_e = e;
	dlc.dlc_dli = dli;
	cb.sc_private = &dlc;
	cb.sc_response = dynlist_sc_update;
	cb.sc_cleanup = NULL;
	cb.sc_next = NULL;

	o.o_callback = &cb;
	o.ors_deref = LDAP_DEREF_NEVER;
	o.ors_limit = NULL;
	o.ors_tlimit = SLAP_NO_LIMIT;
	o.ors_slimit = SLAP_NO_LIMIT;

	for ( url = a->a_nvals; !BER_BVISNULL( url ); url++ ) {
		LDAPURLDesc	*lud = NULL;
		int		i, j;
		struct berval	dn;
		int		rc;

		BER_BVZERO( &o.o_req_dn );
		BER_BVZERO( &o.o_req_ndn );
		o.ors_filter = NULL;
		o.ors_attrs = NULL;
		BER_BVZERO( &o.ors_filterstr );

		if ( ldap_url_parse( url->bv_val, &lud ) != LDAP_URL_SUCCESS ) {
			/* FIXME: error? */
			continue;
		}

		if ( lud->lud_host != NULL ) {
			/* FIXME: host not allowed; reject as illegal? */
			Debug( LDAP_DEBUG_ANY, "dynlist_prepare_entry(\"%s\"): "
				"illegal URI \"%s\"\n",
				e->e_name.bv_val, url->bv_val, 0 );
			goto cleanup;
		}

		if ( lud->lud_dn == NULL ) {
			/* note that an empty base is not honored in terms
			 * of defaultSearchBase, because select_backend()
			 * is not aware of the defaultSearchBase option;
			 * this can be useful in case of a database serving
			 * the empty suffix */
			BER_BVSTR( &dn, "" );

		} else {
			ber_str2bv( lud->lud_dn, 0, 0, &dn );
		}
		rc = dnPrettyNormal( NULL, &dn, &o.o_req_dn, &o.o_req_ndn, op->o_tmpmemctx );
		if ( rc != LDAP_SUCCESS ) {
			/* FIXME: error? */
			goto cleanup;
		}
		o.ors_scope = lud->lud_scope;

		for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
			if ( dlm->dlm_mapped_ad != NULL ) {
				break;
			}
		}

		if ( dli->dli_dlm && !dlm ) {
			/* if ( lud->lud_attrs != NULL ),
			 * the URL should be ignored */
			o.ors_attrs = slap_anlist_no_attrs;

		} else if ( lud->lud_attrs == NULL ) {
			o.ors_attrs = rs->sr_attrs;

		} else {
			for ( i = 0; lud->lud_attrs[i]; i++)
				/* just count */ ;

			o.ors_attrs = op->o_tmpcalloc( i + 1, sizeof( AttributeName ), op->o_tmpmemctx );
			for ( i = 0, j = 0; lud->lud_attrs[i]; i++) {
				const char	*text = NULL;
	
				ber_str2bv( lud->lud_attrs[i], 0, 0, &o.ors_attrs[j].an_name );
				o.ors_attrs[j].an_desc = NULL;
				(void)slap_bv2ad( &o.ors_attrs[j].an_name, &o.ors_attrs[j].an_desc, &text );
				/* FIXME: ignore errors... */

				if ( rs->sr_attrs == NULL ) {
					if ( o.ors_attrs[j].an_desc != NULL &&
							is_at_operational( o.ors_attrs[j].an_desc->ad_type ) )
					{
						continue;
					}

				} else {
					if ( o.ors_attrs[j].an_desc != NULL &&
							is_at_operational( o.ors_attrs[j].an_desc->ad_type ) )
					{
						if ( !opattrs ) {
							continue;
						}

						if ( !ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) ) {
							/* lookup if mapped -- linear search,
							 * not very efficient unless list
							 * is very short */
							for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
								if ( dlm->dlm_member_ad == o.ors_attrs[j].an_desc ) {
									break;
								}
							}

							if ( dlm == NULL ) {
								continue;
							}
						}

					} else {
						if ( !userattrs && 
								o.ors_attrs[j].an_desc != NULL &&
								!ad_inlist( o.ors_attrs[j].an_desc, rs->sr_attrs ) )
						{
							/* lookup if mapped -- linear search,
							 * not very efficient unless list
							 * is very short */
							for ( dlm = dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
								if ( dlm->dlm_member_ad == o.ors_attrs[j].an_desc ) {
									break;
								}
							}

							if ( dlm == NULL ) {
								continue;
							}
						}
					}
				}

				j++;
			}

			if ( j == 0 ) {
				goto cleanup;
			}
		
			BER_BVZERO( &o.ors_attrs[j].an_name );
		}

		if ( lud->lud_filter == NULL ) {
			ber_dupbv_x( &o.ors_filterstr,
					&dli->dli_default_filter, op->o_tmpmemctx );

		} else {
			struct berval	flt;
			ber_str2bv( lud->lud_filter, 0, 0, &flt );
			if ( dynlist_make_filter( op, &flt, &o.ors_filterstr ) ) {
				/* error */
				goto cleanup;
			}
		}
		o.ors_filter = str2filter_x( op, o.ors_filterstr.bv_val );
		if ( o.ors_filter == NULL ) {
			goto cleanup;
		}
		
		o.o_bd = select_backend( &o.o_req_ndn, 1 );
		if ( o.o_bd && o.o_bd->be_search ) {
#ifdef SLAP_OPATTRS
			r.sr_attr_flags = slap_attr_flags( o.ors_attrs );
#endif /* SLAP_OPATTRS */
			(void)o.o_bd->be_search( &o, &r );
		}

cleanup:;
		if ( id ) {
			slap_op_groups_free( &o );
		}
		if ( o.ors_filter ) {
			filter_free_x( &o, o.ors_filter, 1 );
		}
		if ( o.ors_attrs && o.ors_attrs != rs->sr_attrs
				&& o.ors_attrs != slap_anlist_no_attrs )
		{
			op->o_tmpfree( o.ors_attrs, op->o_tmpmemctx );
		}
		if ( !BER_BVISNULL( &o.o_req_dn ) ) {
			op->o_tmpfree( o.o_req_dn.bv_val, op->o_tmpmemctx );
		}
		if ( !BER_BVISNULL( &o.o_req_ndn ) ) {
			op->o_tmpfree( o.o_req_ndn.bv_val, op->o_tmpmemctx );
		}
		assert( BER_BVISNULL( &o.ors_filterstr )
			|| o.ors_filterstr.bv_val != lud->lud_filter );
		op->o_tmpfree( o.ors_filterstr.bv_val, op->o_tmpmemctx );
		ldap_free_urldesc( lud );
	}

	rs->sr_entry = e;
	rs->sr_flags = e_flags;

	return SLAP_CB_CONTINUE;
}
コード例 #3
0
ファイル: collect.c プロジェクト: osstech-jp/openldap
static int
collect_cf( ConfigArgs *c )
{
	slap_overinst *on = (slap_overinst *)c->bi;
	int rc = 1, idx;

	switch( c->op ) {
	case SLAP_CONFIG_EMIT:
		{
		collect_info *ci;
		for ( ci = on->on_bi.bi_private; ci; ci = ci->ci_next ) {
			struct berval bv;
			char *ptr;
			int len;

			/* calculate the length & malloc memory */
			bv.bv_len = ci->ci_dn.bv_len + STRLENOF("\"\" ");
			for (idx=0; idx<ci->ci_ad_num; idx++) {
				bv.bv_len += ci->ci_ad[idx]->ad_cname.bv_len;
				if (idx<(ci->ci_ad_num-1)) { 
					bv.bv_len++;
				}
			}
			bv.bv_val = ch_malloc( bv.bv_len + 1 );

			/* copy the value and update len */
			len = snprintf( bv.bv_val, bv.bv_len + 1, "\"%s\" ", 
				ci->ci_dn.bv_val);
			ptr = bv.bv_val + len;
			for (idx=0; idx<ci->ci_ad_num; idx++) {
				ptr = lutil_strncopy( ptr,
					ci->ci_ad[idx]->ad_cname.bv_val,
					ci->ci_ad[idx]->ad_cname.bv_len);
				if (idx<(ci->ci_ad_num-1)) {
					*ptr++ = ',';
				}
			}
			*ptr = '\0';
			bv.bv_len = ptr - bv.bv_val;

			ber_bvarray_add( &c->rvalue_vals, &bv );
			rc = 0;
		}
		}
		break;
	case LDAP_MOD_DELETE:
		if ( c->valx == -1 ) {
		/* Delete entire attribute */
			collect_info *ci;
			while (( ci = on->on_bi.bi_private )) {
				on->on_bi.bi_private = ci->ci_next;
				ch_free( ci->ci_dn.bv_val );
				ch_free( ci );
			}
		} else {
		/* Delete just one value */
			collect_info **cip, *ci;
			int i;
			cip = (collect_info **)&on->on_bi.bi_private;
			ci = *cip;
			for ( i=0; i < c->valx; i++ ) {
				cip = &ci->ci_next;
				ci = *cip;
			}
			*cip = ci->ci_next;
			ch_free( ci->ci_dn.bv_val );
			ch_free( ci );
		}
		rc = 0;
		break;
	case SLAP_CONFIG_ADD:
	case LDAP_MOD_ADD:
		{
		collect_info *ci;
		struct berval bv, dn;
		const char *text;
		int idx, count=0;
		char *arg;

		/* count delimiters in attribute argument */
		arg = strtok(c->argv[2], ",");
		while (arg!=NULL) {
			count++;
			arg = strtok(NULL, ",");
		}

		/* validate and normalize dn */
		ber_str2bv( c->argv[1], 0, 0, &bv );
		if ( dnNormalize( 0, NULL, NULL, &bv, &dn, NULL ) ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s invalid DN: \"%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;
		}

		/* check for duplicate DNs */
		for ( ci = (collect_info *)on->on_bi.bi_private; ci;
			ci = ci->ci_next ) {
			/* If new DN is longest, there are no possible matches */
			if ( dn.bv_len > ci->ci_dn.bv_len ) {
				ci = NULL;
				break;
			}
			if ( bvmatch( &dn, &ci->ci_dn )) {
				break;
			}
		}
		if ( ci ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s DN already configured: \"%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;
		}

		/* allocate config info with room for attribute array */
		ci = ch_malloc( sizeof( collect_info ) +
			sizeof( AttributeDescription * ) * count );

		/* load attribute description for attribute list */
		arg = c->argv[2];
		for( idx=0; idx<count; idx++) {
			ci->ci_ad[idx] = NULL;

			if ( slap_str2ad( arg, &ci->ci_ad[idx], &text ) ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), 
					"%s attribute description unknown: \"%s\"",
					c->argv[0], arg);
				Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
					"%s: %s\n", c->log, c->cr_msg, 0 );
				ch_free( ci );
				return ARG_BAD_CONF;
			}
			while(*arg!='\0') {
				arg++; /* skip to end of argument */
			}
			if (idx<count-1) {
				arg++; /* skip inner delimiters */
			}
		}

		/* The on->on_bi.bi_private pointer can be used for
		 * anything this instance of the overlay needs.
		 */
		ci->ci_ad[count] = NULL;
		ci->ci_ad_num = count;
		ci->ci_dn = dn;

		/* creates list of ci's ordered by dn length */ 
		insert_ordered ( on, ci );

		/* New ci wasn't simply appended to end, adjust its
		 * position in the config entry's a_vals
		 */
		if ( c->ca_entry && ci->ci_next ) {
			Attribute *a = attr_find( c->ca_entry->e_attrs,
				collectcfg[0].ad );
			if ( a ) {
				struct berval bv, nbv;
				collect_info *c2 = (collect_info *)on->on_bi.bi_private;
				int i, j;
				for ( i=0; c2 != ci; i++, c2 = c2->ci_next );
				bv = a->a_vals[a->a_numvals-1];
				nbv = a->a_nvals[a->a_numvals-1];
				for ( j=a->a_numvals-1; j>i; j-- ) {
					a->a_vals[j] = a->a_vals[j-1];
					a->a_nvals[j] = a->a_nvals[j-1];
				}
				a->a_vals[j] = bv;
				a->a_nvals[j] = nbv;
			}
		}

		rc = 0;
		}
	}
	return rc;
}
コード例 #4
0
ファイル: ad.c プロジェクト: dago/openldap
/*
 * Convert a delimited string into a list of AttributeNames; add
 * on to an existing list if it was given.  If the string is not
 * a valid attribute name, if a '-' is prepended it is skipped
 * and the remaining name is tried again; if a '@' (or '+') is
 * prepended, an objectclass name is searched instead; if a '!'
 * is prepended, the objectclass name is negated.
 * 
 * NOTE: currently, if a valid attribute name is not found, the
 * same string is also checked as valid objectclass name; however,
 * this behavior is deprecated.
 */
AttributeName *
str2anlist( AttributeName *an, char *in, const char *brkstr )
{
	char	*str;
	char	*s;
	char	*lasts;
	int	i, j;
	const char *text;
	AttributeName *anew;

	/* find last element in list */
	i = 0;
	if ( an != NULL ) {
		for ( i = 0; !BER_BVISNULL( &an[ i ].an_name ) ; i++)
			;
	}
	
	/* protect the input string from strtok */
	str = ch_strdup( in );

	/* Count words in string */
	j = 1;
	for ( s = str; *s; s++ ) {
		if ( strchr( brkstr, *s ) != NULL ) {
			j++;
		}
	}

	an = ch_realloc( an, ( i + j + 1 ) * sizeof( AttributeName ) );
	anew = an + i;
	for ( s = ldap_pvt_strtok( str, brkstr, &lasts );
		s != NULL;
		s = ldap_pvt_strtok( NULL, brkstr, &lasts ) )
	{
		/* put a stop mark */
		BER_BVZERO( &anew[1].an_name );

		anew->an_desc = NULL;
		anew->an_oc = NULL;
		anew->an_flags = 0;
		ber_str2bv(s, 0, 1, &anew->an_name);
		slap_bv2ad(&anew->an_name, &anew->an_desc, &text);
		if ( !anew->an_desc ) {
			switch( anew->an_name.bv_val[0] ) {
			case '-': {
					struct berval adname;
					adname.bv_len = anew->an_name.bv_len - 1;
					adname.bv_val = &anew->an_name.bv_val[1];
					slap_bv2ad(&adname, &anew->an_desc, &text);
					if ( !anew->an_desc ) {
						goto reterr;
					}
				} break;

			case '@':
			case '+': /* (deprecated) */
			case '!': {
					struct berval ocname;
					ocname.bv_len = anew->an_name.bv_len - 1;
					ocname.bv_val = &anew->an_name.bv_val[1];
					anew->an_oc = oc_bvfind( &ocname );
					if ( !anew->an_oc ) {
						goto reterr;
					}

					if ( anew->an_name.bv_val[0] == '!' ) {
						anew->an_flags |= SLAP_AN_OCEXCLUDE;
					}
				} break;

			default:
				/* old (deprecated) way */
				anew->an_oc = oc_bvfind( &anew->an_name );
				if ( !anew->an_oc ) {
					goto reterr;
				}
			}
		}
		anew->an_flags |= SLAP_AN_OCINITED;
		anew++;
	}

	BER_BVZERO( &anew->an_name );
	free( str );
	return( an );

reterr:
	anlist_free( an, 1, NULL );

	/*
	 * overwrites input string
	 * on error!
	 */
	strcpy( in, s );
	free( str );
	return NULL;
}
コード例 #5
0
ファイル: config.cpp プロジェクト: RevanthPar/openldap
static int
ndb_cf_gen( ConfigArgs *c )
{
	struct ndb_info *ni = (struct ndb_info *)c->be->be_private;
	int i, rc;
	NdbAttrInfo *ai;
	NdbOcInfo *oci;
	ListNode *ln, **l2;
	struct berval bv, *bva;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		char buf[BUFSIZ];
		rc = 0;
		bv.bv_val = buf;
		switch( c->type ) {
		case NDB_ATLEN:
			if ( ni->ni_attrlens ) {
				for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) {
					ai = (NdbAttrInfo *)ln->ln_data;
					bv.bv_len = snprintf( buf, sizeof(buf),
						"%s %d", ai->na_name.bv_val,
							ai->na_len );
					value_add_one( &c->rvalue_vals, &bv );
				}
			} else {
				rc = 1;
			}
			break;

		case NDB_ATSET:
			if ( ni->ni_attrsets ) {
				char *ptr, *end = buf+sizeof(buf);
				for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) {
					oci = (NdbOcInfo *)ln->ln_data;
					ptr = lutil_strcopy( buf, oci->no_name.bv_val );
					*ptr++ = ' ';
					for ( i=0; i<oci->no_nattrs; i++ ) {
						if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 )
							break;
						if ( i )
							*ptr++ = ',';
						ptr = lutil_strcopy(ptr,
							oci->no_attrs[i]->na_name.bv_val );
					}
					bv.bv_len = ptr - buf;
					value_add_one( &c->rvalue_vals, &bv );
				}
			} else {
				rc = 1;
			}
			break;

		case NDB_INDEX:
			if ( ni->ni_attridxs ) {
				for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
					ai = (NdbAttrInfo *)ln->ln_data;
					value_add_one( &c->rvalue_vals, &ai->na_name );
				}
			} else {
				rc = 1;
			}
			break;

		case NDB_ATBLOB:
			if ( ni->ni_attrblobs ) {
				for ( ln = ni->ni_attrblobs; ln; ln=ln->ln_next ) {
					ai = (NdbAttrInfo *)ln->ln_data;
					value_add_one( &c->rvalue_vals, &ai->na_name );
				}
			} else {
				rc = 1;
			}
			break;

		}
		return rc;
	} else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */
		rc = 0;
		switch( c->type ) {
		case NDB_INDEX:
			if ( c->valx == -1 ) {

				/* delete all */

			} else {

			}
			break;
		}
		return rc;
	}

	switch( c->type ) {
	case NDB_ATLEN:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		ai = ndb_ai_get( ni, &bv );
		if ( !ai ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
				c->log, c->argv[1] );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) {
			if ( ln->ln_data == (void *)ai ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s",
					c->log, c->argv[1] );
				Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
				return -1;
			}
		}
		ai->na_len = atoi( c->argv[2] );
		ai->na_flag |= NDB_INFO_ATLEN;
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = ai;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;
		
	case NDB_INDEX:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		ai = ndb_ai_get( ni, &bv );
		if ( !ai ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
				c->log, c->argv[1] );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) {
			if ( ln->ln_data == (void *)ai ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s",
					c->log, c->argv[1] );
				Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
				return -1;
			}
		}
		ai->na_flag |= NDB_INFO_INDEX;
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = ai;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;

	case NDB_ATSET:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',', NULL );
		rc = ndb_aset_get( ni, &bv, bva, &oci );
		ber_bvarray_free( bva );
		if ( rc ) {
			if ( rc == LDAP_ALREADY_EXISTS ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ),
					"%s: attrset %s already defined",
					c->log, c->argv[1] );
			} else {
				snprintf( c->cr_msg, sizeof( c->cr_msg ),
					"%s: invalid attrset %s (%d)",
					c->log, c->argv[1], rc );
			}
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = oci;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;

	case NDB_ATBLOB:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		ai = ndb_ai_get( ni, &bv );
		if ( !ai ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
				c->log, c->argv[1] );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		for ( ln = ni->ni_attrblobs; ln; ln = ln->ln_next ) {
			if ( ln->ln_data == (void *)ai ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr blob already set for %s",
					c->log, c->argv[1] );
				Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
				return -1;
			}
		}
		ai->na_flag |= NDB_INFO_ATBLOB;
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = ai;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attrblobs; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;

	}
	return 0;
}
コード例 #6
0
ファイル: bind.c プロジェクト: osstech-jp/ReOpenLDAP
/*
 * FIXME: error return must be handled in a cleaner way ...
 */
int
meta_back_op_result(
	metaconn_t		*mc,
	Operation		*op,
	SlapReply		*rs,
	int			candidate,
	ber_int_t		msgid,
	time_t			timeout,
	ldap_back_send_t	sendok )
{
	metainfo_t	*mi = ( metainfo_t * )op->o_bd->be_private;

	const char	*save_text = rs->sr_text,
			*save_matched = rs->sr_matched;
	BerVarray	save_ref = rs->sr_ref;
	LDAPControl	**save_ctrls = rs->sr_ctrls;
	void		*matched_ctx = NULL;

	char		*matched = NULL;
	char		*text = NULL;
	char		**refs = NULL;
	LDAPControl	**ctrls = NULL;

	assert( mc != NULL );

	rs->sr_text = NULL;
	rs->sr_matched = NULL;
	rs->sr_ref = NULL;
	rs->sr_ctrls = NULL;

	if ( candidate != META_TARGET_NONE ) {
		metatarget_t		*mt = mi->mi_targets[ candidate ];
		metasingleconn_t	*msc = &mc->mc_conns[ candidate ];

		if ( LDAP_ERR_OK( rs->sr_err ) ) {
			int		rc;
			struct timeval	tv;
			LDAPMessage	*res = NULL;
			time_t		stoptime = (time_t)(-1);
			int		timeout_err = op->o_protocol >= LDAP_VERSION3 ?
						LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
			const char	*timeout_text = "Operation timed out";

			/* if timeout is not specified, compute and use
			 * the one specific to the ongoing operation */
			if ( timeout == (time_t)(-1) ) {
				slap_op_t	opidx = slap_req2op( op->o_tag );

				if ( opidx == SLAP_OP_SEARCH ) {
					if ( op->ors_tlimit <= 0 ) {
						timeout = 0;

					} else {
						timeout = op->ors_tlimit;
						timeout_err = LDAP_TIMELIMIT_EXCEEDED;
						timeout_text = NULL;
					}

				} else {
					timeout = mt->mt_timeout[ opidx ];
				}
			}

			/* better than nothing :) */
			if ( timeout == 0 ) {
				if ( mi->mi_idle_timeout ) {
					timeout = mi->mi_idle_timeout;

				} else if ( mi->mi_conn_ttl ) {
					timeout = mi->mi_conn_ttl;
				}
			}

			if ( timeout ) {
				stoptime = op->o_time + timeout;
			}

			LDAP_BACK_TV_SET( &tv );

retry:;
			rc = ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res );
			switch ( rc ) {
			case 0:
				if ( timeout && ldap_time_steady() > stoptime ) {
					(void)meta_back_cancel( mc, op, rs, msgid, candidate, sendok );
					rs->sr_err = timeout_err;
					rs->sr_text = timeout_text;
					break;
				}

				LDAP_BACK_TV_SET( &tv );
				ldap_pvt_thread_yield();
				goto retry;

			case -1:
				ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE,
						&rs->sr_err );
				break;


			/* otherwise get the result; if it is not
			 * LDAP_SUCCESS, record it in the reply
			 * structure (this includes
			 * LDAP_COMPARE_{TRUE|FALSE}) */
			default:
				/* only touch when activity actually took place... */
				if ( mi->mi_idle_timeout != 0 && msc->msc_time < op->o_time ) {
					msc->msc_time = op->o_time;
				}

				rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err,
						&matched, &text, &refs, &ctrls, 1 );
				res = NULL;
				if ( rc == LDAP_SUCCESS ) {
					rs->sr_text = text;
				} else {
					rs->sr_err = rc;
				}
				rs->sr_err = slap_map_api2result( rs );

				/* RFC 4511: referrals can only appear
				 * if result code is LDAP_REFERRAL */
				if ( refs != NULL
					&& refs[ 0 ] != NULL
					&& refs[ 0 ][ 0 ] != '\0' )
				{
					if ( rs->sr_err != LDAP_REFERRAL ) {
						Debug( LDAP_DEBUG_ANY,
							"%s meta_back_op_result[%d]: "
							"got referrals with err=%d\n",
							op->o_log_prefix,
							candidate, rs->sr_err );

					} else {
						int	i;

						for ( i = 0; refs[ i ] != NULL; i++ )
							/* count */ ;
						rs->sr_ref = op->o_tmpalloc( sizeof( struct berval ) * ( i + 1 ),
							op->o_tmpmemctx );
						for ( i = 0; refs[ i ] != NULL; i++ ) {
							ber_str2bv( refs[ i ], 0, 0, &rs->sr_ref[ i ] );
						}
						BER_BVZERO( &rs->sr_ref[ i ] );
					}

				} else if ( rs->sr_err == LDAP_REFERRAL ) {
					Debug( LDAP_DEBUG_ANY,
						"%s meta_back_op_result[%d]: "
						"got err=%d with null "
						"or empty referrals\n",
						op->o_log_prefix,
						candidate, rs->sr_err );

					rs->sr_err = LDAP_NO_SUCH_OBJECT;
				}

				if ( ctrls != NULL ) {
					rs->sr_ctrls = ctrls;
				}
			}

			assert( res == NULL );
		}

		/* if the error in the reply structure is not
		 * LDAP_SUCCESS, try to map it from client
		 * to server error */
		if ( !LDAP_ERR_OK( rs->sr_err ) ) {
			rs->sr_err = slap_map_api2result( rs );

			/* internal ops ( op->o_conn == NULL )
			 * must not reply to client */
			if ( op->o_conn && !op->o_do_not_cache && matched ) {

				/* record the (massaged) matched
				 * DN into the reply structure */
				rs->sr_matched = matched;
			}
		}

		if ( META_BACK_TGT_QUARANTINE( mt ) ) {
			meta_back_quarantine( op, rs, candidate );
		}

	} else {
		int	i,
			err = rs->sr_err;

		for ( i = 0; i < mi->mi_ntargets; i++ ) {
			metasingleconn_t	*msc = &mc->mc_conns[ i ];
			char			*xtext = NULL;
			char			*xmatched = NULL;

			if ( msc->msc_ld == NULL ) {
				continue;
			}

			rs->sr_err = LDAP_SUCCESS;

			ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err );
			if ( rs->sr_err != LDAP_SUCCESS ) {
				/*
				 * better check the type of error. In some cases
				 * (search ?) it might be better to return a
				 * success if at least one of the targets gave
				 * positive result ...
				 */
				ldap_get_option( msc->msc_ld,
						LDAP_OPT_DIAGNOSTIC_MESSAGE, &xtext );
				if ( xtext != NULL && xtext [ 0 ] == '\0' ) {
					ldap_memfree( xtext );
					xtext = NULL;
				}

				ldap_get_option( msc->msc_ld,
						LDAP_OPT_MATCHED_DN, &xmatched );
				if ( xmatched != NULL && xmatched[ 0 ] == '\0' ) {
					ldap_memfree( xmatched );
					xmatched = NULL;
				}

				rs->sr_err = slap_map_api2result( rs );

				if ( DebugTest( LDAP_DEBUG_ANY ) ) {
					char	buf[ SLAP_TEXT_BUFLEN ];

					snprintf( buf, sizeof( buf ),
						"meta_back_op_result[%d] "
						"err=%d text=\"%s\" matched=\"%s\"",
						i, rs->sr_err,
						( xtext ? xtext : "" ),
						( xmatched ? xmatched : "" ) );
					Debug( LDAP_DEBUG_ANY, "%s %s.\n",
						op->o_log_prefix, buf );
				}

				/*
				 * FIXME: need to rewrite "match" (need rwinfo)
				 */
				switch ( rs->sr_err ) {
				default:
					err = rs->sr_err;
					if ( xtext != NULL ) {
						if ( text ) {
							ldap_memfree( text );
						}
						text = xtext;
						xtext = NULL;
					}
					if ( xmatched != NULL ) {
						if ( matched ) {
							ldap_memfree( matched );
						}
						matched = xmatched;
						xmatched = NULL;
					}
					break;
				}

				if ( xtext ) {
					ldap_memfree( xtext );
				}

				if ( xmatched ) {
					ldap_memfree( xmatched );
				}
			}

			if ( META_BACK_TGT_QUARANTINE( mi->mi_targets[ i ] ) ) {
				meta_back_quarantine( op, rs, i );
			}
		}

		if ( err != LDAP_SUCCESS ) {
			rs->sr_err = err;
		}
	}

	if ( matched != NULL ) {
		struct berval	dn, pdn;

		ber_str2bv( matched, 0, 0, &dn );
		if ( dnPretty( NULL, &dn, &pdn, op->o_tmpmemctx ) == LDAP_SUCCESS ) {
			ldap_memfree( matched );
			matched_ctx = op->o_tmpmemctx;
			matched = pdn.bv_val;
		}
		rs->sr_matched = matched;
	}

	if ( rs->sr_err == LDAP_UNAVAILABLE ) {
		if ( !( sendok & LDAP_BACK_RETRYING ) ) {
			if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) {
				if ( rs->sr_text == NULL ) rs->sr_text = "Proxy operation retry failed";
				send_ldap_result( op, rs );
			}
		}

	} else if ( op->o_conn &&
		( ( ( sendok & LDAP_BACK_SENDOK ) && LDAP_ERR_OK( rs->sr_err ) )
			|| ( ( sendok & LDAP_BACK_SENDERR ) && !LDAP_ERR_OK( rs->sr_err ) ) ) )
	{
		send_ldap_result( op, rs );
	}
	if ( matched ) {
		op->o_tmpfree( (char *)rs->sr_matched, matched_ctx );
	}
	if ( text ) {
		ldap_memfree( text );
	}
	if ( rs->sr_ref ) {
		op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx );
		rs->sr_ref = NULL;
	}
	if ( refs ) {
		ber_memvfree( (void **)refs );
	}
	if ( ctrls ) {
		assert( rs->sr_ctrls != NULL );
		ldap_controls_free( ctrls );
	}

	rs->sr_text = save_text;
	rs->sr_matched = save_matched;
	rs->sr_ref = save_ref;
	rs->sr_ctrls = save_ctrls;

	return( LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err );
}
コード例 #7
0
ファイル: slapauth.c プロジェクト: Distrotech/openldap
int
slapauth( int argc, char **argv )
{
	int			rc = EXIT_SUCCESS;
	const char		*progname = "slapauth";
	Connection		conn = {0};
	OperationBuffer	opbuf;
	Operation		*op;
	void			*thrctx;

	slap_tool_init( progname, SLAPAUTH, argc, argv );

	argv = &argv[ optind ];
	argc -= optind;

	thrctx = ldap_pvt_thread_pool_context();
	connection_fake_init( &conn, &opbuf, thrctx );
	op = &opbuf.ob_op;

	conn.c_sasl_bind_mech = mech;

	if ( !BER_BVISNULL( &authzID ) ) {
		struct berval	authzdn;
		
		rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
				SLAP_GETDN_AUTHZID );
		if ( rc != LDAP_SUCCESS ) {
			fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
					authzID.bv_val, rc,
					ldap_err2string( rc ) );
			rc = 1;
			BER_BVZERO( &authzID );
			goto destroy;
		} 

		authzID = authzdn;
	}


	if ( !BER_BVISNULL( &authcID ) ) {
		if ( !BER_BVISNULL( &authzID ) || argc == 0 ) {
			rc = do_check( &conn, op, &authcID );
			goto destroy;
		}

		for ( ; argc--; argv++ ) {
			struct berval	authzdn;
		
			ber_str2bv( argv[ 0 ], 0, 0, &authzID );

			rc = slap_sasl_getdn( &conn, op, &authzID, NULL, &authzdn,
					SLAP_GETDN_AUTHZID );
			if ( rc != LDAP_SUCCESS ) {
				fprintf( stderr, "authzID: <%s> check failed %d (%s)\n",
						authzID.bv_val, rc,
						ldap_err2string( rc ) );
				rc = -1;
				BER_BVZERO( &authzID );
				if ( !continuemode ) {
					goto destroy;
				}
			}

			authzID = authzdn;

			rc = do_check( &conn, op, &authcID );

			op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
			BER_BVZERO( &authzID );

			if ( rc && !continuemode ) {
				goto destroy;
			}
		}

		goto destroy;
	}

	for ( ; argc--; argv++ ) {
		struct berval	id;

		ber_str2bv( argv[ 0 ], 0, 0, &id );

		rc = do_check( &conn, op, &id );

		if ( rc && !continuemode ) {
			goto destroy;
		}
	}

destroy:;
	if ( !BER_BVISNULL( &authzID ) ) {
		op->o_tmpfree( authzID.bv_val, op->o_tmpmemctx );
	}
	if ( slap_tool_destroy())
		rc = EXIT_FAILURE;

	return rc;
}
コード例 #8
0
ファイル: nssov.c プロジェクト: DanahBlanahaseth/cniiag_ldap
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;
}
コード例 #9
0
ファイル: entry-id.c プロジェクト: ajinkya93/netbsd-src
/*
 * NOTE: the dn must be normalized
 */
int
backsql_dn2id(
	Operation		*op,
	SlapReply		*rs,
	SQLHDBC			dbh,
	struct berval		*ndn,
	backsql_entryID		*id,
	int			matched,
	int			muck )
{
	backsql_info		*bi = op->o_bd->be_private;
	SQLHSTMT		sth = SQL_NULL_HSTMT; 
	BACKSQL_ROW_NTS		row = { 0 };
	RETCODE 		rc;
	int			res;
	struct berval		realndn = BER_BVNULL;

	/* TimesTen */
	char			upperdn[ BACKSQL_MAX_DN_LEN + 1 ];
	struct berval		tbbDN;
	int			i, j;

	/*
	 * NOTE: id can be NULL; in this case, the function
	 * simply checks whether the DN can be successfully 
	 * turned into an ID, returning LDAP_SUCCESS for
	 * positive cases, or the most appropriate error
	 */

	Debug( LDAP_DEBUG_TRACE, "==>backsql_dn2id(\"%s\")%s%s\n", 
			ndn->bv_val, id == NULL ? " (no ID expected)" : "",
			matched ? " matched expected" : "" );

	if ( id ) {
		/* NOTE: trap inconsistencies */
		assert( BER_BVISNULL( &id->eid_ndn ) );
	}

	if ( ndn->bv_len > BACKSQL_MAX_DN_LEN ) {
		Debug( LDAP_DEBUG_TRACE, 
			"   backsql_dn2id(\"%s\"): DN length=%ld "
			"exceeds max DN length %d:\n",
			ndn->bv_val, ndn->bv_len, BACKSQL_MAX_DN_LEN );
		return LDAP_OTHER;
	}

	/* return baseObject if available and matches */
	/* FIXME: if ndn is already mucked, we cannot check this */
	if ( bi->sql_baseObject != NULL &&
			dn_match( ndn, &bi->sql_baseObject->e_nname ) )
	{
		if ( id != NULL ) {
#ifdef BACKSQL_ARBITRARY_KEY
			ber_dupbv_x( &id->eid_id, &backsql_baseObject_bv,
					op->o_tmpmemctx );
			ber_dupbv_x( &id->eid_keyval, &backsql_baseObject_bv,
					op->o_tmpmemctx );
#else /* ! BACKSQL_ARBITRARY_KEY */
			id->eid_id = BACKSQL_BASEOBJECT_ID;
			id->eid_keyval = BACKSQL_BASEOBJECT_KEYVAL;
#endif /* ! BACKSQL_ARBITRARY_KEY */
			id->eid_oc_id = BACKSQL_BASEOBJECT_OC;

			ber_dupbv_x( &id->eid_ndn, &bi->sql_baseObject->e_nname,
					op->o_tmpmemctx );
			ber_dupbv_x( &id->eid_dn, &bi->sql_baseObject->e_name,
					op->o_tmpmemctx );

			id->eid_next = NULL;
		}

		return LDAP_SUCCESS;
	}
	
	/* begin TimesTen */
	assert( bi->sql_id_query != NULL );
	Debug( LDAP_DEBUG_TRACE, "   backsql_dn2id(\"%s\"): id_query \"%s\"\n",
			ndn->bv_val, bi->sql_id_query, 0 );
 	rc = backsql_Prepare( dbh, &sth, bi->sql_id_query, 0 );
	if ( rc != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, 
			"   backsql_dn2id(\"%s\"): "
			"error preparing SQL:\n   %s", 
			ndn->bv_val, bi->sql_id_query, 0 );
		backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
		res = LDAP_OTHER;
		goto done;
	}

	realndn = *ndn;
	if ( muck ) {
		if ( backsql_api_dn2odbc( op, rs, &realndn ) ) {
			Debug( LDAP_DEBUG_TRACE, "   backsql_dn2id(\"%s\"): "
				"backsql_api_dn2odbc(\"%s\") failed\n", 
				ndn->bv_val, realndn.bv_val, 0 );
			res = LDAP_OTHER;
			goto done;
		}
	}

	if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
		/*
		 * Prepare an upper cased, byte reversed version 
		 * that can be searched using indexes
		 */

		for ( i = 0, j = realndn.bv_len - 1; realndn.bv_val[ i ]; i++, j--)
		{
			upperdn[ i ] = realndn.bv_val[ j ];
		}
		upperdn[ i ] = '\0';
		ldap_pvt_str2upper( upperdn );

		Debug( LDAP_DEBUG_TRACE, "   backsql_dn2id(\"%s\"): "
				"upperdn=\"%s\"\n",
				ndn->bv_val, upperdn, 0 );
		ber_str2bv( upperdn, 0, 0, &tbbDN );

	} else {
		if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
			AC_MEMCPY( upperdn, realndn.bv_val, realndn.bv_len + 1 );
			ldap_pvt_str2upper( upperdn );
			Debug( LDAP_DEBUG_TRACE,
				"   backsql_dn2id(\"%s\"): "
				"upperdn=\"%s\"\n",
				ndn->bv_val, upperdn, 0 );
			ber_str2bv( upperdn, 0, 0, &tbbDN );

		} else {
			tbbDN = realndn;
		}
	}

	rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &tbbDN );
	if ( rc != SQL_SUCCESS) {
		/* end TimesTen */ 
		Debug( LDAP_DEBUG_TRACE, "   backsql_dn2id(\"%s\"): "
			"error binding dn=\"%s\" parameter:\n", 
			ndn->bv_val, tbbDN.bv_val, 0 );
		backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
		res = LDAP_OTHER;
		goto done;
	}

	rc = SQLExecute( sth );
	if ( rc != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "   backsql_dn2id(\"%s\"): "
			"error executing query (\"%s\", \"%s\"):\n", 
			ndn->bv_val, bi->sql_id_query, tbbDN.bv_val );
		backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc );
		res = LDAP_OTHER;
		goto done;
	}

	backsql_BindRowAsStrings_x( sth, &row, op->o_tmpmemctx );
	rc = SQLFetch( sth );
	if ( BACKSQL_SUCCESS( rc ) ) {
		char	buf[ SLAP_TEXT_BUFLEN ];

#ifdef LDAP_DEBUG
		snprintf( buf, sizeof(buf),
			"id=%s keyval=%s oc_id=%s dn=%s",
			row.cols[ 0 ], row.cols[ 1 ],
			row.cols[ 2 ], row.cols[ 3 ] );
		Debug( LDAP_DEBUG_TRACE,
			"   backsql_dn2id(\"%s\"): %s\n",
			ndn->bv_val, buf, 0 );
#endif /* LDAP_DEBUG */

		res = LDAP_SUCCESS;
		if ( id != NULL ) {
			struct berval	dn;

			id->eid_next = NULL;

#ifdef BACKSQL_ARBITRARY_KEY
			ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
					op->o_tmpmemctx );
			ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
					op->o_tmpmemctx );
#else /* ! BACKSQL_ARBITRARY_KEY */
			if ( BACKSQL_STR2ID( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
				res = LDAP_OTHER;
				goto done;
			}
			if ( BACKSQL_STR2ID( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
				res = LDAP_OTHER;
				goto done;
			}
#endif /* ! BACKSQL_ARBITRARY_KEY */
			if ( BACKSQL_STR2ID( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) {
				res = LDAP_OTHER;
				goto done;
			}

			ber_str2bv( row.cols[ 3 ], 0, 0, &dn );

			if ( backsql_api_odbc2dn( op, rs, &dn ) ) {
				res = LDAP_OTHER;
				goto done;
			}
			
			res = dnPrettyNormal( NULL, &dn,
					&id->eid_dn, &id->eid_ndn,
					op->o_tmpmemctx );
			if ( res != LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_TRACE,
					"   backsql_dn2id(\"%s\"): "
					"dnPrettyNormal failed (%d: %s)\n",
					realndn.bv_val, res,
					ldap_err2string( res ) );

				/* cleanup... */
				(void)backsql_free_entryID( id, 0, op->o_tmpmemctx );
			}

			if ( dn.bv_val != row.cols[ 3 ] ) {
				free( dn.bv_val );
			}
		}

	} else {
		res = LDAP_NO_SUCH_OBJECT;
		if ( matched ) {
			struct berval	pdn = *ndn;

			/*
			 * Look for matched
			 */
			rs->sr_matched = NULL;
			while ( !be_issuffix( op->o_bd, &pdn ) ) {
				char		*matchedDN = NULL;
	
				dnParent( &pdn, &pdn );
	
				/*
				 * Empty DN ("") defaults to LDAP_SUCCESS
				 */
				rs->sr_err = backsql_dn2id( op, rs, dbh, &pdn, id, 0, 1 );
				switch ( rs->sr_err ) {
				case LDAP_NO_SUCH_OBJECT:
					/* try another one */
					break;
					
				case LDAP_SUCCESS:
					matchedDN = pdn.bv_val;
					/* fail over to next case */
	
				default:
					rs->sr_err = LDAP_NO_SUCH_OBJECT;
					rs->sr_matched = matchedDN;
					goto done;
				} 
			}
		}
	}

done:;
	backsql_FreeRow_x( &row, op->o_tmpmemctx );

	Debug( LDAP_DEBUG_TRACE,
		"<==backsql_dn2id(\"%s\"): err=%d\n",
		ndn->bv_val, res, 0 );
	if ( sth != SQL_NULL_HSTMT ) {
		SQLFreeStmt( sth, SQL_DROP );
	}

	if ( !BER_BVISNULL( &realndn ) && realndn.bv_val != ndn->bv_val ) {
		ch_free( realndn.bv_val );
	}

	return res;
}
コード例 #10
0
ファイル: util.c プロジェクト: Smilefant/ReOpenLDAP
int
backsql_split_pattern(
	const char	*_pattern,
	BerVarray	*split_pattern,
	int		expected )
{
	char		*pattern, *start, *end;
	struct berval	bv;
	int		rc = 0;

#define SPLIT_CHAR	'?'

	assert( _pattern != NULL );
	assert( split_pattern != NULL );

	pattern = ch_strdup( _pattern );

	start = pattern;
	end = strchr( start, SPLIT_CHAR );
	for ( ; start; expected-- ) {
		char		*real_end = end;
		ber_len_t	real_len;

		if ( real_end == NULL ) {
			real_end = start + strlen( start );

		} else if ( real_end[ 1 ] == SPLIT_CHAR ) {
			expected++;
			memmove( real_end, real_end + 1, strlen( real_end ) );
			end = strchr( real_end + 1, SPLIT_CHAR );
			continue;
		}

		real_len = real_end - start;
		if ( real_len == 0 ) {
			ber_str2bv( "", 0, 1, &bv );
		} else {
			ber_str2bv( start, real_len, 1, &bv );
		}

		ber_bvarray_add( split_pattern, &bv );

		if ( expected == 0 ) {
			if ( end != NULL ) {
				rc = -1;
				goto done;
			}
			break;
		}

		if ( end != NULL ) {
			start = end + 1;
			end = strchr( start, SPLIT_CHAR );
		}
	}

done:;

     	ch_free( pattern );

	return rc;
}
コード例 #11
0
ファイル: init.c プロジェクト: rashoodkhan/ldap-server-mirror
int
meta_back_db_open(
	Backend		*be,
	ConfigReply	*cr )
{
	metainfo_t	*mi = (metainfo_t *)be->be_private;
	BackendInfo *bi;

	int		i,
			not_always = 0,
			not_always_anon_proxyauthz = 0,
			not_always_anon_non_prescriptive = 0,
			rc;

	if ( mi->mi_ntargets == 0 ) {
		Debug( LDAP_DEBUG_ANY,
			"meta_back_db_open: no targets defined\n",
			0, 0, 0 );
		return 1;
	}

	bi = backend_info( "ldap" );
	if ( !bi || !bi->bi_extra ) {
		Debug( LDAP_DEBUG_ANY,
			"meta_back_db_open: needs back-ldap\n",
			0, 0, 0 );
		return 1;
	}
	mi->mi_ldap_extra = (ldap_extra_t *)bi->bi_extra;

	for ( i = 0; i < mi->mi_ntargets; i++ ) {
		slap_bindconf	sb = { BER_BVNULL };
		metatarget_t	*mt = mi->mi_targets[ i ];

		ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri );
		sb.sb_version = mt->mt_version;
		sb.sb_method = LDAP_AUTH_SIMPLE;
		BER_BVSTR( &sb.sb_binddn, "" );

		if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
					LDAP_FEATURE_ABSOLUTE_FILTERS );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_T_F;
			}
		}

		if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
					LDAP_EXOP_CANCEL );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP;
			}
		}

		if ( not_always == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
				|| mt->mt_idassert_authz != NULL )
			{
				not_always = 1;
			}
		}

		if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
			&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
		{
			Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): "
				"target #%d inconsistent idassert configuration "
				"(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
				be->be_suffix[ 0 ].bv_val, i, 0 );
			return 1;
		}

		if ( not_always_anon_proxyauthz == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
			{
				not_always_anon_proxyauthz = 1;
			}
		}

		if ( not_always_anon_non_prescriptive == 0 ) {
			if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
			{
				not_always_anon_non_prescriptive = 1;
			}
		}
	}

	if ( not_always == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
	}

	if ( not_always_anon_proxyauthz == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON;

	} else if ( not_always_anon_non_prescriptive == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON;
	}

	return 0;
}
コード例 #12
0
ファイル: monitor.c プロジェクト: ystk/debian-openldap
/*
 * call from within ldap_back_db_open()
 */
int
ldap_back_monitor_db_open( BackendDB *be )
{
	ldapinfo_t		*li = (ldapinfo_t *) be->be_private;
	char			buf[ BACKMONITOR_BUFSIZE ];
	Entry			*e = NULL;
	monitor_callback_t	*cb = NULL;
	struct berval		suffix, *filter, *base;
	char			*ptr;
	time_t			now;
	char			timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
	struct berval 		timestamp;
	int			rc = 0;
	BackendInfo		*mi;
	monitor_extra_t		*mbe;

	if ( !SLAP_DBMONITORING( be ) ) {
		return 0;
	}

	/* check if monitor is configured and usable */
	mi = backend_info( "monitor" );
	if ( !mi || !mi->bi_extra ) {
		SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
		return 0;
 	}
 	mbe = mi->bi_extra;

	/* don't bother if monitor is not configured */
	if ( !mbe->is_configured() ) {
		static int warning = 0;

		if ( warning++ == 0 ) {
			Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: "
				"monitoring disabled; "
				"configure monitor database to enable\n",
				0, 0, 0 );
		}

		return 0;
	}

	/* set up the fake subsystem that is used to create
	 * the volatile connection entries */
	li->li_monitor_info.lmi_mss.mss_name = "back-ldap";
	li->li_monitor_info.lmi_mss.mss_flags = MONITOR_F_VOLATILE_CH;
	li->li_monitor_info.lmi_mss.mss_create = ldap_back_monitor_conn_create;

	li->li_monitor_info.lmi_li = li;
	li->li_monitor_info.lmi_scope = LDAP_SCOPE_SUBORDINATE;
	base = &li->li_monitor_info.lmi_base;
	BER_BVSTR( base, "cn=databases,cn=monitor" );
	filter = &li->li_monitor_info.lmi_filter;
	BER_BVZERO( filter );

	suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] );
	if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) {
		suffix = be->be_nsuffix[ 0 ];

	} else {
		ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix );
	}
	
	filter->bv_len = STRLENOF( "(&" )
		+ li->li_monitor_info.lmi_more_filter.bv_len
		+ STRLENOF( "(monitoredInfo=" )
		+ strlen( be->bd_info->bi_type )
		+ STRLENOF( ")(!(monitorOverlay=" )
		+ strlen( be->bd_info->bi_type )
		+ STRLENOF( "))(namingContexts:distinguishedNameMatch:=" )
		+ suffix.bv_len + STRLENOF( "))" );
	ptr = filter->bv_val = ch_malloc( filter->bv_len + 1 );
	ptr = lutil_strcopy( ptr, "(&" );
	ptr = lutil_strncopy( ptr, li->li_monitor_info.lmi_more_filter.bv_val,
		li->li_monitor_info.lmi_more_filter.bv_len );
	ptr = lutil_strcopy( ptr, "(monitoredInfo=" );
	ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
	ptr = lutil_strcopy( ptr, ")(!(monitorOverlay=" );
	ptr = lutil_strcopy( ptr, be->bd_info->bi_type );
	ptr = lutil_strcopy( ptr, "))(namingContexts:distinguishedNameMatch:=" );
	ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len );
	ptr = lutil_strcopy( ptr, "))" );
	ptr[ 0 ] = '\0';
	assert( ptr == &filter->bv_val[ filter->bv_len ] );

	if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) {
		ch_free( suffix.bv_val );
	}

	now = slap_get_time();
	timestamp.bv_val = timebuf;
	timestamp.bv_len = sizeof( timebuf );
	slap_timestamp( &now, &timestamp );

	/* caller (e.g. an overlay based on back-ldap) may want to use
	 * a different RDN... */
	if ( BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) {
		ber_str2bv( "cn=Connections", 0, 1, &li->li_monitor_info.lmi_rdn );
	}

	ptr = ber_bvchr( &li->li_monitor_info.lmi_rdn, '=' );
	assert( ptr != NULL );
	ptr[ 0 ] = '\0';
	ptr++;

	snprintf( buf, sizeof( buf ),
		"dn: %s=%s\n"
		"objectClass: monitorContainer\n"
		"%s: %s\n"
		"creatorsName: %s\n"
		"createTimestamp: %s\n"
		"modifiersName: %s\n"
		"modifyTimestamp: %s\n",
		li->li_monitor_info.lmi_rdn.bv_val,
			ptr,
		li->li_monitor_info.lmi_rdn.bv_val,
			ptr,
		BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
		timestamp.bv_val,
		BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val,
		timestamp.bv_val );
	e = str2entry( buf );
	if ( e == NULL ) {
		rc = -1;
		goto cleanup;
	}

	ptr[ -1 ] = '=';

	/* add labeledURI and special, modifiable URI value */
	if ( li->li_uri != NULL ) {
		struct berval	bv;
		LDAPURLDesc	*ludlist = NULL;
		int		rc;

		rc = ldap_url_parselist_ext( &ludlist,
			li->li_uri, NULL,
			LDAP_PVT_URL_PARSE_NOEMPTY_HOST
				| LDAP_PVT_URL_PARSE_DEF_PORT );
		if ( rc != LDAP_URL_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY,
				"ldap_back_monitor_db_open: "
				"unable to parse URI list (ignored)\n",
				0, 0, 0 );
		} else {
			for ( ; ludlist != NULL; ) {
				LDAPURLDesc	*next = ludlist->lud_next;

				bv.bv_val = ldap_url_desc2str( ludlist );
				assert( bv.bv_val != NULL );
				ldap_free_urldesc( ludlist );
				bv.bv_len = strlen( bv.bv_val );
				attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI,
					&bv, NULL );
				ch_free( bv.bv_val );

				ludlist = next;
			}
		}
		
		ber_str2bv( li->li_uri, 0, 0, &bv );
		attr_merge_normalize_one( e, ad_olmDbURIList,
			&bv, NULL );
	}

	ber_dupbv( &li->li_monitor_info.lmi_nrdn, &e->e_nname );

	cb = ch_calloc( sizeof( monitor_callback_t ), 1 );
	cb->mc_update = ldap_back_monitor_update;
	cb->mc_modify = ldap_back_monitor_modify;
	cb->mc_free = ldap_back_monitor_free;
	cb->mc_private = (void *)li;

	rc = mbe->register_entry_parent( e, cb,
		(monitor_subsys_t *)&li->li_monitor_info,
		MONITOR_F_VOLATILE_CH,
		base, LDAP_SCOPE_SUBORDINATE, filter );

cleanup:;
	if ( rc != 0 ) {
		if ( cb != NULL ) {
			ch_free( cb );
			cb = NULL;
		}

		if ( e != NULL ) {
			entry_free( e );
			e = NULL;
		}

		if ( !BER_BVISNULL( filter ) ) {
			ch_free( filter->bv_val );
			BER_BVZERO( filter );
		}
	}

	/* store for cleanup */
	li->li_monitor_info.lmi_cb = (void *)cb;

	if ( e != NULL ) {
		entry_free( e );
	}

	return rc;
}
コード例 #13
0
ファイル: ldapmap.c プロジェクト: tiniesst/ReOpenLDAP
static void *
map_ldap_parse(
		const char *fname,
		int lineno,
		int argc,
		char **argv
)
{
	struct ldap_map_data *data;
	char *p, *uri;

	assert( fname != NULL );
	assert( argv != NULL );

	data = calloc( sizeof( struct ldap_map_data ), 1 );
	if ( data == NULL ) {
		return NULL;
	}

	if ( argc < 1 ) {
		Debug( LDAP_DEBUG_ANY,
				"[%s:%d] ldap map needs URI\n%s",
				fname, lineno, "" );
		free( data );
		return NULL;
	}

	uri = argv[ 0 ];
	if ( strncasecmp( uri, "uri=", STRLENOF( "uri=" ) ) == 0 ) {
		uri += STRLENOF( "uri=" );
	}

	data->lm_url = strdup( uri );
	if ( data->lm_url == NULL ) {
		map_ldap_free( data );
		return NULL;
	}

	if ( ldap_url_parse( uri, &data->lm_lud ) != REWRITE_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY,
				"[%s:%d] illegal URI '%s'\n",
				fname, lineno, argv[ 0 ] );
		map_ldap_free( data );
		return NULL;
	}

	/* trim everything after [host][:port] */
	p = strchr( data->lm_url, '/' );
	assert( p[ 1 ] == '/' );
	if ( ( p = strchr( p + 2, '/' ) ) != NULL ) {
		p[ 0 ] = '\0';
	}

	if ( data->lm_lud->lud_attrs == NULL ) {
		data->lm_attrs[ 0 ] = LDAP_NO_ATTRS;
		data->lm_wantdn = 1;

	} else {
		if ( data->lm_lud->lud_attrs[ 1 ] != NULL ) {
			Debug( LDAP_DEBUG_ANY,
				"[%s:%d] only one attribute allowed in URI\n",
				fname, lineno );
			map_ldap_free( data );
			return NULL;
		}

		if ( strcasecmp( data->lm_lud->lud_attrs[ 0 ], "dn" ) == 0
			|| strcasecmp( data->lm_lud->lud_attrs[ 0 ], "entryDN" ) == 0 )
		{
			ldap_memfree( data->lm_lud->lud_attrs[ 0 ] );
			ldap_memfree( data->lm_lud->lud_attrs );
			data->lm_lud->lud_attrs = NULL;
			data->lm_attrs[ 0 ] = LDAP_NO_ATTRS;
			data->lm_wantdn = 1;

		} else {
			data->lm_attrs[ 0 ] = data->lm_lud->lud_attrs[ 0 ];
		}
	}

	data->lm_attrs[ 1 ] = NULL;

	/* safe defaults */
	data->lm_version = LDAP_VERSION3;

	for ( argc--, argv++; argc > 0; argc--, argv++ ) {
		if ( strncasecmp( argv[ 0 ], "binddn=", STRLENOF( "binddn=" ) ) == 0 ) {
			char *p = argv[ 0 ] + STRLENOF( "binddn=" );
			int l;

			if ( p[ 0 ] == '\"' || p [ 0 ] == '\'' ) {
				l = strlen( p ) - 2;
				p++;
				if ( p[ l ] != p[ 0 ] ) {
					map_ldap_free( data );
					return NULL;
				}
			} else {
				l = strlen( p );
			}

			data->lm_binddn = strdup( p );
			if ( data->lm_binddn == NULL ) {
				map_ldap_free( data );
				return NULL;
			}

			if ( data->lm_binddn[ l ] == '\"'
					|| data->lm_binddn[ l ] == '\'' ) {
				data->lm_binddn[ l ] = '\0';
			}

			/* deprecated */
		} else if ( strncasecmp( argv[ 0 ], "bindpw=", STRLENOF( "bindpw=" ) ) == 0 ) {
			ber_str2bv( argv[ 0 ] + STRLENOF( "bindpw=" ), 0, 1, &data->lm_cred );
			if ( data->lm_cred.bv_val == NULL ) {
				map_ldap_free( data );
				return NULL;
			}

		} else if ( strncasecmp( argv[ 0 ], "credentials=", STRLENOF( "credentials=" ) ) == 0 ) {
			ber_str2bv( argv[ 0 ] + STRLENOF( "credentials=" ), 0, 1, &data->lm_cred );
			if ( data->lm_cred.bv_val == NULL ) {
				map_ldap_free( data );
				return NULL;
			}

		} else if ( strncasecmp( argv[ 0 ], "bindwhen=", STRLENOF( "bindwhen=" ) ) == 0 ) {
			char *p = argv[ 0 ] + STRLENOF( "bindwhen=" );

			if ( strcasecmp( p, "now" ) == 0 ) {
				int rc;

				data->lm_when = MAP_LDAP_NOW;

				/*
				 * Init LDAP handler ...
				 */
				rc = ldap_initialize( &data->lm_ld, data->lm_url );
				if ( rc != LDAP_SUCCESS ) {
					map_ldap_free( data );
					return NULL;
				}

				ldap_set_option( data->lm_ld,
					LDAP_OPT_PROTOCOL_VERSION,
					(void *)&data->lm_version );

#ifdef USE_REWRITE_LDAP_PVT_THREADS
				ldap_pvt_thread_mutex_init( &data->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

			} else if ( strcasecmp( p, "later" ) == 0 ) {
				data->lm_when = MAP_LDAP_LATER;

#ifdef USE_REWRITE_LDAP_PVT_THREADS
				ldap_pvt_thread_mutex_init( &data->lm_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */

			} else if ( strcasecmp( p, "everytime" ) == 0 ) {
				data->lm_when = MAP_LDAP_EVERYTIME;
			} else {
				/* ignore ... */
			}

		} else if ( strncasecmp( argv[ 0 ], "version=", STRLENOF( "version=" ) ) == 0 ) {
			if ( lutil_atoi( &data->lm_version, argv[ 0 ] + STRLENOF( "version=" ) ) ) {
				map_ldap_free( data );
				return NULL;
			}

			switch ( data->lm_version ) {
			case LDAP_VERSION2:
			case LDAP_VERSION3:
				break;

			default:
				Debug( LDAP_DEBUG_ANY,
					"[%s:%d] unknown version %s\n",
					fname, lineno, p );
				map_ldap_free( data );
				return NULL;
			}

		} else {
			Debug( LDAP_DEBUG_ANY,
				"[%s:%d] unknown option %s (ignored)\n",
				fname, lineno, argv[0] );
		}
	}

	if ( data->lm_when == MAP_LDAP_UNKNOWN ) {
		data->lm_when = MAP_LDAP_EVERYTIME;
	}

	return ( void * )data;
}
コード例 #14
0
ファイル: init.c プロジェクト: MPlatform/mdb
int
meta_back_db_open(
	Backend		*be,
	ConfigReply	*cr )
{
	metainfo_t	*mi = (metainfo_t *)be->be_private;

	int		i,
			not_always = 0,
			not_always_anon_proxyauthz = 0,
			not_always_anon_non_prescriptive = 0,
			rc;

	if ( mi->mi_ntargets == 0 ) {
		Debug( LDAP_DEBUG_ANY,
			"meta_back_db_open: no targets defined\n",
			0, 0, 0 );
		return 1;
	}

	for ( i = 0; i < mi->mi_ntargets; i++ ) {
		slap_bindconf	sb = { BER_BVNULL };
		metatarget_t	*mt = mi->mi_targets[ i ];

		struct berval mapped;

		ber_str2bv( mt->mt_uri, 0, 0, &sb.sb_uri );
		sb.sb_version = mt->mt_version;
		sb.sb_method = LDAP_AUTH_SIMPLE;
		BER_BVSTR( &sb.sb_binddn, "" );

		if ( META_BACK_TGT_T_F_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
					LDAP_FEATURE_ABSOLUTE_FILTERS );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_T_F;
			}
		}

		if ( META_BACK_TGT_CANCEL_DISCOVER( mt ) ) {
			rc = slap_discover_feature( &sb,
					slap_schema.si_ad_supportedExtension->ad_cname.bv_val,
					LDAP_EXOP_CANCEL );
			if ( rc == LDAP_COMPARE_TRUE ) {
				mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP;
			}
		}

		if ( not_always == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
				|| mt->mt_idassert_authz != NULL )
			{
				not_always = 1;
			}
		}

		if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL )
			&& !( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
		{
			Debug( LDAP_DEBUG_ANY, "meta_back_db_open(%s): "
				"target #%d inconsistent idassert configuration "
				"(likely authz=\"*\" used with \"non-prescriptive\" flag)\n",
				be->be_suffix[ 0 ].bv_val, i, 0 );
			return 1;
		}

		if ( not_always_anon_proxyauthz == 0 ) {
			if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
			{
				not_always_anon_proxyauthz = 1;
			}
		}

		if ( not_always_anon_non_prescriptive == 0 ) {
			if ( ( mt->mt_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) )
			{
				not_always_anon_non_prescriptive = 1;
			}
		}

		BER_BVZERO( &mapped );
		ldap_back_map( &mt->mt_rwmap.rwm_at, 
			&slap_schema.si_ad_entryDN->ad_cname, &mapped,
			BACKLDAP_REMAP );
		if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
			mt->mt_rep_flags |= REP_NO_ENTRYDN;
		}

		BER_BVZERO( &mapped );
		ldap_back_map( &mt->mt_rwmap.rwm_at, 
			&slap_schema.si_ad_subschemaSubentry->ad_cname, &mapped,
			BACKLDAP_REMAP );
		if ( BER_BVISNULL( &mapped ) || mapped.bv_val[0] == '\0' ) {
			mt->mt_rep_flags |= REP_NO_SUBSCHEMA;
		}
	}

	if ( not_always == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
	}

	if ( not_always_anon_proxyauthz == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ANON;

	} else if ( not_always_anon_non_prescriptive == 0 ) {
		mi->mi_flags |= META_BACK_F_PROXYAUTHZ_NOANON;
	}

	return 0;
}
コード例 #15
0
ファイル: constraint.c プロジェクト: verter2015/ReOpenLDAP
static int
constraint_violation( constraint *c, struct berval *bv, Operation *op )
{
	if ((!c) || (!bv)) return LDAP_SUCCESS;

	switch (c->type) {
		case CONSTRAINT_SIZE:
			if (bv->bv_len > c->size)
				return LDAP_CONSTRAINT_VIOLATION; /* size violation */
			break;
		case CONSTRAINT_REGEX:
			if (regexec(c->re, bv->bv_val, 0, NULL, 0) == REG_NOMATCH)
				return LDAP_CONSTRAINT_VIOLATION; /* regular expression violation */
			break;
		case CONSTRAINT_URI: {
			Operation nop = *op;
			slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
			slap_callback cb;
			int i;
			int found = 0;
			int rc;
			size_t len;
			struct berval filterstr;
			char *ptr;

			cb.sc_next = NULL;
			cb.sc_response = constraint_uri_cb;
			cb.sc_cleanup = NULL;
			cb.sc_private = &found;

			nop.o_protocol = LDAP_VERSION3;
			nop.o_tag = LDAP_REQ_SEARCH;
			nop.o_time = slap_get_time();
			if (c->lud->lud_dn) {
				struct berval dn;

				ber_str2bv(c->lud->lud_dn, 0, 0, &dn);
				nop.o_req_dn = dn;
				nop.o_req_ndn = dn;
				nop.o_bd = select_backend(&nop.o_req_ndn, 1 );
				if (!nop.o_bd) {
					return LDAP_NO_SUCH_OBJECT; /* unexpected error */
				}
				if (!nop.o_bd->be_search) {
					return LDAP_OTHER; /* unexpected error */
				}
			} else {
				nop.o_req_dn = nop.o_bd->be_nsuffix[0];
				nop.o_req_ndn = nop.o_bd->be_nsuffix[0];
				nop.o_bd = on->on_info->oi_origdb;
			}
			nop.o_do_not_cache = 1;
			nop.o_callback = &cb;

			nop.ors_scope = c->lud->lud_scope;
			nop.ors_deref = LDAP_DEREF_NEVER;
			nop.ors_slimit = SLAP_NO_LIMIT;
			nop.ors_tlimit = SLAP_NO_LIMIT;
			nop.ors_limit = NULL;

			nop.ors_attrsonly = 0;
			nop.ors_attrs = slap_anlist_no_attrs;

			len = STRLENOF("(&(") +
				  c->filter.bv_len +
				  STRLENOF(")(|");

			for (i = 0; c->attrs[i]; i++) {
				len += STRLENOF("(") +
					   c->attrs[i]->ad_cname.bv_len +
					   STRLENOF("=") +
					   bv->bv_len +
					   STRLENOF(")");
			}

			len += STRLENOF("))");
			filterstr.bv_len = len;
			filterstr.bv_val = op->o_tmpalloc(len + 1, op->o_tmpmemctx);

			ptr = filterstr.bv_val +
				snprintf(filterstr.bv_val, len, "(&(%s)(|", c->lud->lud_filter);
			for (i = 0; c->attrs[i]; i++) {
				*ptr++ = '(';
				ptr = lutil_strcopy( ptr, c->attrs[i]->ad_cname.bv_val );
				*ptr++ = '=';
				ptr = lutil_strcopy( ptr, bv->bv_val );
				*ptr++ = ')';
			}
			*ptr++ = ')';
			*ptr++ = ')';
			*ptr++ = '\0';

			nop.ors_filterstr = filterstr;
			nop.ors_filter = str2filter_x(&nop, filterstr.bv_val);
			if ( nop.ors_filter == NULL ) {
				Debug( LDAP_DEBUG_ANY,
					"%s constraint_violation uri filter=\"%s\" invalid\n",
					op->o_log_prefix, filterstr.bv_val );
				rc = LDAP_OTHER;

			} else {
				SlapReply nrs = { REP_RESULT };

				Debug(LDAP_DEBUG_TRACE,
					"==> constraint_violation uri filter = %s\n",
					filterstr.bv_val);

				rc = nop.o_bd->be_search( &nop, &nrs );

				Debug(LDAP_DEBUG_TRACE,
					"==> constraint_violation uri rc = %d, found = %d\n",
					rc, found);
			}
			op->o_tmpfree(filterstr.bv_val, op->o_tmpmemctx);

			if ((rc != LDAP_SUCCESS) && (rc != LDAP_NO_SUCH_OBJECT)) {
				return rc; /* unexpected error */
			}

			if (!found)
				return LDAP_CONSTRAINT_VIOLATION; /* constraint violation */
			break;
		}
	}

	return LDAP_SUCCESS;
}
コード例 #16
0
ファイル: entry-id.c プロジェクト: ajinkya93/netbsd-src
static int
backsql_get_attr_vals( void *v_at, void *v_bsi )
{
	backsql_at_map_rec	*at = v_at;
	backsql_srch_info	*bsi = v_bsi;
	backsql_info		*bi;
	RETCODE			rc;
	SQLHSTMT		sth = SQL_NULL_HSTMT;
	BACKSQL_ROW_NTS		row;
	unsigned long		i,
				k = 0,
				oldcount = 0,
				res = 0;
#ifdef BACKSQL_COUNTQUERY
	unsigned 		count,
				j,
				append = 0;
	SQLLEN			countsize = sizeof( count );
	Attribute		*attr = NULL;

	slap_mr_normalize_func		*normfunc = NULL;
#endif /* BACKSQL_COUNTQUERY */
#ifdef BACKSQL_PRETTY_VALIDATE
	slap_syntax_validate_func	*validate = NULL;
	slap_syntax_transform_func	*pretty = NULL;
#endif /* BACKSQL_PRETTY_VALIDATE */

	assert( at != NULL );
	assert( bsi != NULL );
	Debug( LDAP_DEBUG_TRACE, "==>backsql_get_attr_vals(): "
		"oc=\"%s\" attr=\"%s\" keyval=" BACKSQL_IDFMT "\n",
		BACKSQL_OC_NAME( bsi->bsi_oc ), at->bam_ad->ad_cname.bv_val, 
		BACKSQL_IDARG(bsi->bsi_c_eid->eid_keyval) );

	bi = (backsql_info *)bsi->bsi_op->o_bd->be_private;

#ifdef BACKSQL_PRETTY_VALIDATE
	validate = at->bam_true_ad->ad_type->sat_syntax->ssyn_validate;
	pretty =  at->bam_true_ad->ad_type->sat_syntax->ssyn_pretty;

	if ( validate == NULL && pretty == NULL ) {
		return 1;
	}
#endif /* BACKSQL_PRETTY_VALIDATE */

#ifdef BACKSQL_COUNTQUERY
	if ( at->bam_true_ad->ad_type->sat_equality ) {
		normfunc = at->bam_true_ad->ad_type->sat_equality->smr_normalize;
	}

	/* Count how many rows will be returned. This avoids memory 
	 * fragmentation that can result from loading the values in 
	 * one by one and using realloc() 
	 */
	rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_countquery, 0 );
	if ( rc != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
			"error preparing count query: %s\n",
			at->bam_countquery, 0, 0 );
		backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
		return 1;
	}

	rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
			&bsi->bsi_c_eid->eid_keyval );
	if ( rc != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
			"error binding key value parameter\n", 0, 0, 0 );
		SQLFreeStmt( sth, SQL_DROP );
		return 1;
	}

	rc = SQLExecute( sth );
	if ( ! BACKSQL_SUCCESS( rc ) ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
			"error executing attribute count query '%s'\n",
			at->bam_countquery, 0, 0 );
		backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
		SQLFreeStmt( sth, SQL_DROP );
		return 1;
	}

	SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_LONG,
			(SQLPOINTER)&count,
			(SQLINTEGER)sizeof( count ),
			&countsize );

	rc = SQLFetch( sth );
	if ( rc != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
			"error fetch results of count query: %s\n",
			at->bam_countquery, 0, 0 );
		backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
		SQLFreeStmt( sth, SQL_DROP );
		return 1;
	}

	Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
		"number of values in query: %u\n", count, 0, 0 );
	SQLFreeStmt( sth, SQL_DROP );
	if ( count == 0 ) {
		return 1;
	}

	attr = attr_find( bsi->bsi_e->e_attrs, at->bam_true_ad );
	if ( attr != NULL ) {
		BerVarray	tmp;

		if ( attr->a_vals != NULL ) {
			oldcount = attr->a_numvals;
		}

		tmp = ch_realloc( attr->a_vals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
		if ( tmp == NULL ) {
			return 1;
		}
		attr->a_vals = tmp;
		memset( &attr->a_vals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );

		if ( normfunc ) {
			tmp = ch_realloc( attr->a_nvals, ( oldcount + count + 1 ) * sizeof( struct berval ) );
			if ( tmp == NULL ) {
				return 1;
			}
			attr->a_nvals = tmp;
			memset( &attr->a_nvals[ oldcount ], 0, ( count + 1 ) * sizeof( struct berval ) );

		} else {
			attr->a_nvals = attr->a_vals;
		}
		attr->a_numvals += count;

	} else {
		append = 1;

		/* Make space for the array of values */
		attr = attr_alloc( at->bam_true_ad );
		attr->a_numvals = count;
		attr->a_vals = ch_calloc( count + 1, sizeof( struct berval ) );
		if ( attr->a_vals == NULL ) {
			Debug( LDAP_DEBUG_TRACE, "Out of memory!\n", 0,0,0 );
			ch_free( attr );
			return 1;
		}
		if ( normfunc ) {
			attr->a_nvals = ch_calloc( count + 1, sizeof( struct berval ) );
			if ( attr->a_nvals == NULL ) {
				ch_free( attr->a_vals );
				ch_free( attr );
				return 1;

			}

		} else {
			attr->a_nvals = attr->a_vals;
		}
	}
#endif /* BACKSQL_COUNTQUERY */

	rc = backsql_Prepare( bsi->bsi_dbh, &sth, at->bam_query, 0 );
	if ( rc != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
			"error preparing query: %s\n", at->bam_query, 0, 0 );
		backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
#ifdef BACKSQL_COUNTQUERY
		if ( append ) {
			attr_free( attr );
		}
#endif /* BACKSQL_COUNTQUERY */
		return 1;
	}

	rc = backsql_BindParamID( sth, 1, SQL_PARAM_INPUT,
			&bsi->bsi_c_eid->eid_keyval );
	if ( rc != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
			"error binding key value parameter\n", 0, 0, 0 );
#ifdef BACKSQL_COUNTQUERY
		if ( append ) {
			attr_free( attr );
		}
#endif /* BACKSQL_COUNTQUERY */
		return 1;
	}

#ifdef BACKSQL_TRACE
	Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
		"query=\"%s\" keyval=" BACKSQL_IDFMT "\n", at->bam_query,
		BACKSQL_IDARG(bsi->bsi_c_eid->eid_keyval), 0 );
#endif /* BACKSQL_TRACE */

	rc = SQLExecute( sth );
	if ( ! BACKSQL_SUCCESS( rc ) ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_get_attr_vals(): "
			"error executing attribute query \"%s\"\n",
			at->bam_query, 0, 0 );
		backsql_PrintErrors( bi->sql_db_env, bsi->bsi_dbh, sth, rc );
		SQLFreeStmt( sth, SQL_DROP );
#ifdef BACKSQL_COUNTQUERY
		if ( append ) {
			attr_free( attr );
		}
#endif /* BACKSQL_COUNTQUERY */
		return 1;
	}

	backsql_BindRowAsStrings_x( sth, &row, bsi->bsi_op->o_tmpmemctx );
#ifdef BACKSQL_COUNTQUERY
	j = oldcount;
#endif /* BACKSQL_COUNTQUERY */
	for ( rc = SQLFetch( sth ), k = 0;
			BACKSQL_SUCCESS( rc );
			rc = SQLFetch( sth ), k++ )
	{
		for ( i = 0; i < (unsigned long)row.ncols; i++ ) {

			if ( row.value_len[ i ] > 0 ) {
				struct berval		bv;
				int			retval;
#ifdef BACKSQL_TRACE
				AttributeDescription	*ad = NULL;
				const char		*text;

				retval = slap_bv2ad( &row.col_names[ i ], &ad, &text );
				if ( retval != LDAP_SUCCESS ) {
					Debug( LDAP_DEBUG_ANY,
						"==>backsql_get_attr_vals(\"%s\"): "
						"unable to find AttributeDescription %s "
						"in schema (%d)\n",
						bsi->bsi_e->e_name.bv_val,
						row.col_names[ i ].bv_val, retval );
					res = 1;
					goto done;
				}

				if ( ad != at->bam_ad ) {
					Debug( LDAP_DEBUG_ANY,
						"==>backsql_get_attr_vals(\"%s\"): "
						"column name %s differs from "
						"AttributeDescription %s\n",
						bsi->bsi_e->e_name.bv_val,
						ad->ad_cname.bv_val,
						at->bam_ad->ad_cname.bv_val );
					res = 1;
					goto done;
				}
#endif /* BACKSQL_TRACE */

				/* ITS#3386, ITS#3113 - 20070308
				 * If a binary is fetched?
				 * must use the actual size read
				 * from the database.
				 */
				if ( BACKSQL_IS_BINARY( row.col_type[ i ] ) ) {
#ifdef BACKSQL_TRACE
					Debug( LDAP_DEBUG_ANY,
						"==>backsql_get_attr_vals(\"%s\"): "
						"column name %s: data is binary; "
						"using database size %ld\n",
						bsi->bsi_e->e_name.bv_val,
						ad->ad_cname.bv_val,
						row.value_len[ i ] );
#endif /* BACKSQL_TRACE */
					bv.bv_val = row.cols[ i ];
					bv.bv_len = row.value_len[ i ];

				} else {
					ber_str2bv( row.cols[ i ], 0, 0, &bv );
				}

#ifdef BACKSQL_PRETTY_VALIDATE
				if ( pretty ) {
					struct berval	pbv;

					retval = pretty( at->bam_true_ad->ad_type->sat_syntax,
						&bv, &pbv, bsi->bsi_op->o_tmpmemctx );
					bv = pbv;

				} else {
					retval = validate( at->bam_true_ad->ad_type->sat_syntax,
						&bv );
				}

				if ( retval != LDAP_SUCCESS ) {
					char	buf[ SLAP_TEXT_BUFLEN ];

					/* FIXME: we're ignoring invalid values,
					 * but we're accepting the attributes;
					 * should we fail at all? */
					snprintf( buf, sizeof( buf ),
							"unable to %s value #%lu "
							"of AttributeDescription %s",
							pretty ? "prettify" : "validate",
							k - oldcount,
							at->bam_ad->ad_cname.bv_val );
					Debug( LDAP_DEBUG_TRACE,
						"==>backsql_get_attr_vals(\"%s\"): "
						"%s (%d)\n",
						bsi->bsi_e->e_name.bv_val, buf, retval );
					continue;
				}
#endif /* BACKSQL_PRETTY_VALIDATE */

#ifndef BACKSQL_COUNTQUERY
				(void)backsql_entry_addattr( bsi->bsi_e, 
						at->bam_true_ad, &bv,
						bsi->bsi_op->o_tmpmemctx );

#else /* BACKSQL_COUNTQUERY */
				if ( normfunc ) {
					struct berval	nbv;

					retval = (*normfunc)( SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
						at->bam_true_ad->ad_type->sat_syntax,
						at->bam_true_ad->ad_type->sat_equality,
						&bv, &nbv,
						bsi->bsi_op->o_tmpmemctx );

					if ( retval != LDAP_SUCCESS ) {
						char	buf[ SLAP_TEXT_BUFLEN ];

						/* FIXME: we're ignoring invalid values,
						 * but we're accepting the attributes;
						 * should we fail at all? */
						snprintf( buf, sizeof( buf ),
							"unable to normalize value #%lu "
							"of AttributeDescription %s",
							k - oldcount,
							at->bam_ad->ad_cname.bv_val );
						Debug( LDAP_DEBUG_TRACE,
							"==>backsql_get_attr_vals(\"%s\"): "
							"%s (%d)\n",
							bsi->bsi_e->e_name.bv_val, buf, retval );

#ifdef BACKSQL_PRETTY_VALIDATE
						if ( pretty ) {
							bsi->bsi_op->o_tmpfree( bv.bv_val,
									bsi->bsi_op->o_tmpmemctx );
						}
#endif /* BACKSQL_PRETTY_VALIDATE */

						continue;
					}
					ber_dupbv( &attr->a_nvals[ j ], &nbv );
					bsi->bsi_op->o_tmpfree( nbv.bv_val,
							bsi->bsi_op->o_tmpmemctx );
				}

				ber_dupbv( &attr->a_vals[ j ], &bv );

				assert( j < oldcount + count );
				j++;
#endif /* BACKSQL_COUNTQUERY */

#ifdef BACKSQL_PRETTY_VALIDATE
				if ( pretty ) {
					bsi->bsi_op->o_tmpfree( bv.bv_val,
							bsi->bsi_op->o_tmpmemctx );
				}
#endif /* BACKSQL_PRETTY_VALIDATE */

#ifdef BACKSQL_TRACE
				Debug( LDAP_DEBUG_TRACE, "prec=%d\n",
					(int)row.col_prec[ i ], 0, 0 );

			} else {
      				Debug( LDAP_DEBUG_TRACE, "NULL value "
					"in this row for attribute \"%s\"\n",
					row.col_names[ i ].bv_val, 0, 0 );
#endif /* BACKSQL_TRACE */
			}
		}
	}

#ifdef BACKSQL_COUNTQUERY
	if ( BER_BVISNULL( &attr->a_vals[ 0 ] ) ) {
		/* don't leave around attributes with no values */
		attr_free( attr );

	} else if ( append ) {
		Attribute	**ap;

		for ( ap = &bsi->bsi_e->e_attrs; (*ap) != NULL; ap = &(*ap)->a_next )
			/* goto last */ ;
		*ap =  attr;
	}
#endif /* BACKSQL_COUNTQUERY */

	SQLFreeStmt( sth, SQL_DROP );
	Debug( LDAP_DEBUG_TRACE, "<==backsql_get_attr_vals()\n", 0, 0, 0 );

	if ( at->bam_next ) {
		res = backsql_get_attr_vals( at->bam_next, v_bsi );
	} else {
		res = 1;
	}

#ifdef BACKSQL_TRACE
done:;
#endif /* BACKSQL_TRACE */
	backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );

	return res;
}
コード例 #17
0
ファイル: search.c プロジェクト: bagel/openldap-ga
int
ldap_back_search(
		Operation	*op,
		SlapReply	*rs )
{
	ldapinfo_t	*li = (ldapinfo_t *) op->o_bd->be_private;

	ldapconn_t	*lc = NULL;
	struct timeval	tv;
	time_t		stoptime = (time_t)(-1);
	LDAPMessage	*res,
			*e;
	int		rc = 0,
			msgid; 
	struct berval	match = BER_BVNULL,
			filter = BER_BVNULL;
	int		i, x;
	char		**attrs = NULL;
	int		freetext = 0, filter_undef = 0;
	int		do_retry = 1, dont_retry = 0;
	LDAPControl	**ctrls = NULL;
	char		**references = NULL;

	rs_assert_ready( rs );
	rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */

	if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
		return rs->sr_err;
	}

	/*
	 * FIXME: in case of values return filter, we might want
	 * to map attrs and maybe rewrite value
	 */

	if ( op->ors_tlimit != SLAP_NO_LIMIT ) {
		tv.tv_sec = op->ors_tlimit;
		tv.tv_usec = 0;
		stoptime = op->o_time + op->ors_tlimit;

	} else {
		LDAP_BACK_TV_SET( &tv );
	}

	i = 0;
	if ( op->ors_attrs ) {
		for ( ; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ )
			/* just count attrs */ ;
	}

	x = 0;
	if ( op->o_bd->be_extra_anlist ) {
		for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
			/* just count attrs */ ;
	}

	if ( i > 0 || x > 0 ) {
		int j = 0;

		attrs = op->o_tmpalloc( ( i + x + 1 )*sizeof( char * ),
			op->o_tmpmemctx );
		if ( attrs == NULL ) {
			rs->sr_err = LDAP_NO_MEMORY;
			rc = -1;
			goto finish;
		}

		if ( i > 0 ) {	
			for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++, j++ ) {
				attrs[ j ] = op->ors_attrs[i].an_name.bv_val;
			}
		}

		if ( x > 0 ) {
			for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++, j++ ) {
				if ( op->o_bd->be_extra_anlist[x].an_desc &&
					ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, op->ors_attrs ) )
				{
					continue;
				}

				attrs[ j ] = op->o_bd->be_extra_anlist[x].an_name.bv_val;
			}
		}

		attrs[ j ] = NULL;
	}

	ctrls = op->o_ctrls;
	rc = ldap_back_controls_add( op, rs, lc, &ctrls );
	if ( rc != LDAP_SUCCESS ) {
		goto finish;
	}

	/* deal with <draft-zeilenga-ldap-t-f> filters */
	filter = op->ors_filterstr;
retry:
	/* this goes after retry because ldap_back_munge_filter()
	 * optionally replaces RFC 4526 T-F filters (&) (|)
	 * if already computed, they will be re-installed
	 * by filter2bv_undef_x() later */
	if ( !LDAP_BACK_T_F( li ) ) {
		ldap_back_munge_filter( op, &filter );
	}

	rs->sr_err = ldap_pvt_search( lc->lc_ld, op->o_req_dn.bv_val,
			op->ors_scope, filter.bv_val,
			attrs, op->ors_attrsonly, ctrls, NULL,
			tv.tv_sec ? &tv : NULL,
			op->ors_slimit, op->ors_deref, &msgid );

	ldap_pvt_thread_mutex_lock( &li->li_counter_mutex );
	ldap_pvt_mp_add( li->li_ops_completed[ SLAP_OP_SEARCH ], 1 );
	ldap_pvt_thread_mutex_unlock( &li->li_counter_mutex );

	if ( rs->sr_err != LDAP_SUCCESS ) {
		switch ( rs->sr_err ) {
		case LDAP_SERVER_DOWN:
			if ( do_retry ) {
				do_retry = 0;
				if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) {
					goto retry;
				}
			}

			if ( lc == NULL ) {
				/* reset by ldap_back_retry ... */
				rs->sr_err = slap_map_api2result( rs );

			} else {
				rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND );
			}
				
			goto finish;

		case LDAP_FILTER_ERROR:
			/* first try? */
			if ( !filter_undef &&
				strstr( filter.bv_val, "(?" ) &&
				!LDAP_BACK_NOUNDEFFILTER( li ) )
			{
				BER_BVZERO( &filter );
				filter2bv_undef_x( op, op->ors_filter, 1, &filter );
				filter_undef = 1;
				goto retry;
			}

			/* invalid filters return success with no data */
			rs->sr_err = LDAP_SUCCESS;
			rs->sr_text = NULL;
			goto finish;
		
		default:
			rs->sr_err = slap_map_api2result( rs );
			rs->sr_text = NULL;
			goto finish;
		}
	}

	/* if needed, initialize timeout */
	if ( li->li_timeout[ SLAP_OP_SEARCH ] ) {
		if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) {
			tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ];
			tv.tv_usec = 0;
		}
	}

	/* We pull apart the ber result, stuff it into a slapd entry, and
	 * let send_search_entry stuff it back into ber format. Slow & ugly,
	 * but this is necessary for version matching, and for ACL processing.
	 */

	for ( rc = -2; rc != -1; rc = ldap_result( lc->lc_ld, msgid, LDAP_MSG_ONE, &tv, &res ) )
	{
		/* check for abandon */
		if ( op->o_abandon || LDAP_BACK_CONN_ABANDON( lc ) ) {
			if ( rc > 0 ) {
				ldap_msgfree( res );
			}
			(void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
			rc = SLAPD_ABANDON;
			goto finish;
		}

		if ( rc == 0 || rc == -2 ) {
			ldap_pvt_thread_yield();

			/* check timeout */
			if ( li->li_timeout[ SLAP_OP_SEARCH ] ) {
				if ( rc == 0 ) {
					(void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
					rs->sr_text = "Operation timed out";
					rc = rs->sr_err = op->o_protocol >= LDAP_VERSION3 ?
						LDAP_ADMINLIMIT_EXCEEDED : LDAP_OTHER;
					goto finish;
				}

			} else {
				LDAP_BACK_TV_SET( &tv );
			}

			/* check time limit */
			if ( op->ors_tlimit != SLAP_NO_LIMIT
					&& slap_get_time() > stoptime )
			{
				(void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
				rc = rs->sr_err = LDAP_TIMELIMIT_EXCEEDED;
				goto finish;
			}
			continue;

		} else {
			/* only touch when activity actually took place... */
			if ( li->li_idle_timeout ) {
				lc->lc_time = op->o_time;
			}

			/* don't retry any more */
			dont_retry = 1;
		}


		if ( rc == LDAP_RES_SEARCH_ENTRY ) {
			Entry		ent = { 0 };
			struct berval	bdn = BER_BVNULL;

			do_retry = 0;

			e = ldap_first_entry( lc->lc_ld, res );
			rc = ldap_build_entry( op, e, &ent, &bdn );
			if ( rc == LDAP_SUCCESS ) {
				ldap_get_entry_controls( lc->lc_ld, res, &rs->sr_ctrls );
				rs->sr_entry = &ent;
				rs->sr_attrs = op->ors_attrs;
				rs->sr_operational_attrs = NULL;
				rs->sr_flags = 0;
				rs->sr_err = LDAP_SUCCESS;
				rc = rs->sr_err = send_search_entry( op, rs );
				if ( rs->sr_ctrls ) {
					ldap_controls_free( rs->sr_ctrls );
					rs->sr_ctrls = NULL;
				}
				rs->sr_entry = NULL;
				rs->sr_flags = 0;
				if ( !BER_BVISNULL( &ent.e_name ) ) {
					assert( ent.e_name.bv_val != bdn.bv_val );
					op->o_tmpfree( ent.e_name.bv_val, op->o_tmpmemctx );
					BER_BVZERO( &ent.e_name );
				}
				if ( !BER_BVISNULL( &ent.e_nname ) ) {
					op->o_tmpfree( ent.e_nname.bv_val, op->o_tmpmemctx );
					BER_BVZERO( &ent.e_nname );
				}
				entry_clean( &ent );
			}
			ldap_msgfree( res );
			switch ( rc ) {
			case LDAP_SUCCESS:
			case LDAP_INSUFFICIENT_ACCESS:
				break;

			default:
				if ( rc == LDAP_UNAVAILABLE ) {
					rc = rs->sr_err = LDAP_OTHER;
				} else {
					(void)ldap_back_cancel( lc, op, rs, msgid, LDAP_BACK_DONTSEND );
				}
				goto finish;
			}

		} else if ( rc == LDAP_RES_SEARCH_REFERENCE ) {
			if ( LDAP_BACK_NOREFS( li ) ) {
				ldap_msgfree( res );
				continue;
			}

			do_retry = 0;
			rc = ldap_parse_reference( lc->lc_ld, res,
					&references, &rs->sr_ctrls, 1 );

			if ( rc != LDAP_SUCCESS ) {
				continue;
			}

			/* FIXME: there MUST be at least one */
			if ( references && references[ 0 ] && references[ 0 ][ 0 ] ) {
				int		cnt;

				for ( cnt = 0; references[ cnt ]; cnt++ )
					/* NO OP */ ;

				/* FIXME: there MUST be at least one */
				rs->sr_ref = op->o_tmpalloc( ( cnt + 1 ) * sizeof( struct berval ),
					op->o_tmpmemctx );

				for ( cnt = 0; references[ cnt ]; cnt++ ) {
					ber_str2bv( references[ cnt ], 0, 0, &rs->sr_ref[ cnt ] );
				}
				BER_BVZERO( &rs->sr_ref[ cnt ] );

				/* ignore return value by now */
				RS_ASSERT( !(rs->sr_flags & REP_ENTRY_MASK) );
				rs->sr_entry = NULL;
				( void )send_search_reference( op, rs );

			} else {
				Debug( LDAP_DEBUG_ANY,
					"%s ldap_back_search: "
					"got SEARCH_REFERENCE "
					"with no referrals\n",
					op->o_log_prefix, 0, 0 );
			}

			/* cleanup */
			if ( references ) {
				ber_memvfree( (void **)references );
				op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx );
				rs->sr_ref = NULL;
				references = NULL;
			}

			if ( rs->sr_ctrls ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}

		} else if ( rc == LDAP_RES_INTERMEDIATE ) {
			/* FIXME: response controls
			 * are passed without checks */
			rc = ldap_parse_intermediate( lc->lc_ld,
				res,
				(char **)&rs->sr_rspoid,
				&rs->sr_rspdata,
				&rs->sr_ctrls,
				0 );
			if ( rc != LDAP_SUCCESS ) {
				continue;
			}

			slap_send_ldap_intermediate( op, rs );

			if ( rs->sr_rspoid != NULL ) {
				ber_memfree( (char *)rs->sr_rspoid );
				rs->sr_rspoid = NULL;
			}

			if ( rs->sr_rspdata != NULL ) {
				ber_bvfree( rs->sr_rspdata );
				rs->sr_rspdata = NULL;
			}

			if ( rs->sr_ctrls != NULL ) {
				ldap_controls_free( rs->sr_ctrls );
				rs->sr_ctrls = NULL;
			}

		} else {
			char		*err = NULL;

			rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
					&match.bv_val, &err,
					&references, &rs->sr_ctrls, 1 );
			if ( rc == LDAP_SUCCESS ) {
				if ( err ) {
					rs->sr_text = err;
					freetext = 1;
				}
			} else {
				rs->sr_err = rc;
			}
			rs->sr_err = slap_map_api2result( rs );

			/* RFC 4511: referrals can only appear
			 * if result code is LDAP_REFERRAL */
			if ( references 
				&& references[ 0 ]
				&& references[ 0 ][ 0 ] )
			{
				if ( rs->sr_err != LDAP_REFERRAL ) {
					Debug( LDAP_DEBUG_ANY,
						"%s ldap_back_search: "
						"got referrals with err=%d\n",
						op->o_log_prefix,
						rs->sr_err, 0 );

				} else {
					int	cnt;

					for ( cnt = 0; references[ cnt ]; cnt++ )
						/* NO OP */ ;
				
					rs->sr_ref = op->o_tmpalloc( ( cnt + 1 ) * sizeof( struct berval ),
						op->o_tmpmemctx );

					for ( cnt = 0; references[ cnt ]; cnt++ ) {
						/* duplicating ...*/
						ber_str2bv( references[ cnt ], 0, 0, &rs->sr_ref[ cnt ] );
					}
					BER_BVZERO( &rs->sr_ref[ cnt ] );
				}

			} else if ( rs->sr_err == LDAP_REFERRAL ) {
				Debug( LDAP_DEBUG_ANY,
					"%s ldap_back_search: "
					"got err=%d with null "
					"or empty referrals\n",
					op->o_log_prefix,
					rs->sr_err, 0 );

				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			}

			if ( match.bv_val != NULL ) {
				match.bv_len = strlen( match.bv_val );
			}

			rc = 0;
			break;
		}

		/* if needed, restore timeout */
		if ( li->li_timeout[ SLAP_OP_SEARCH ] ) {
			if ( tv.tv_sec == 0 || tv.tv_sec > li->li_timeout[ SLAP_OP_SEARCH ] ) {
				tv.tv_sec = li->li_timeout[ SLAP_OP_SEARCH ];
				tv.tv_usec = 0;
			}
		}
	}

 	if ( rc == -1 ) {
		if ( dont_retry == 0 ) {
			if ( do_retry ) {
				do_retry = 0;
				if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) {
					goto retry;
				}
			}

			rs->sr_err = LDAP_SERVER_DOWN;
			rs->sr_err = slap_map_api2result( rs );
			goto finish;

		} else if ( LDAP_BACK_ONERR_STOP( li ) ) {
			/* if onerr == STOP */
			rs->sr_err = LDAP_SERVER_DOWN;
			rs->sr_err = slap_map_api2result( rs );
			goto finish;
		}
	}

	/*
	 * Rewrite the matched portion of the search base, if required
	 */
	if ( !BER_BVISNULL( &match ) && !BER_BVISEMPTY( &match ) ) {
		struct berval	pmatch;

		if ( dnPretty( NULL, &match, &pmatch, op->o_tmpmemctx ) != LDAP_SUCCESS ) {
			pmatch.bv_val = match.bv_val;
			match.bv_val = NULL;
		}
		rs->sr_matched = pmatch.bv_val;
		rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
	}

finish:;
	if ( !BER_BVISNULL( &match ) ) {
		ber_memfree( match.bv_val );
	}

	if ( rs->sr_v2ref ) {
		rs->sr_err = LDAP_REFERRAL;
	}

	if ( LDAP_BACK_QUARANTINE( li ) ) {
		ldap_back_quarantine( op, rs );
	}

	if ( filter.bv_val != op->ors_filterstr.bv_val ) {
		op->o_tmpfree( filter.bv_val, op->o_tmpmemctx );
	}

#if 0
	/* let send_ldap_result play cleanup handlers (ITS#4645) */
	if ( rc != SLAPD_ABANDON )
#endif
	{
		send_ldap_result( op, rs );
	}

	(void)ldap_back_controls_free( op, rs, &ctrls );

	if ( rs->sr_ctrls ) {
		ldap_controls_free( rs->sr_ctrls );
		rs->sr_ctrls = NULL;
	}

	if ( rs->sr_text ) {
		if ( freetext ) {
			ber_memfree( (char *)rs->sr_text );
		}
		rs->sr_text = NULL;
	}

	if ( rs->sr_ref ) {
		op->o_tmpfree( rs->sr_ref, op->o_tmpmemctx );
		rs->sr_ref = NULL;
	}

	if ( references ) {
		ber_memvfree( (void **)references );
	}

	if ( attrs ) {
		op->o_tmpfree( attrs, op->o_tmpmemctx );
	}

	if ( lc != NULL ) {
		ldap_back_release_conn( li, lc );
	}

	if ( rs->sr_err == LDAP_UNAVAILABLE &&
		/* if we originally bound and wanted rebind-as-user, must drop
		 * the connection now because we just discarded the credentials.
		 * ITS#7464, #8142
		 */
		LDAP_BACK_SAVECRED( li ) && SLAP_IS_AUTHZ_BACKEND( op ) )
		rs->sr_err = SLAPD_DISCONNECT;
	return rs->sr_err;
}
コード例 #18
0
ファイル: adremap.c プロジェクト: Distrotech/openldap
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;
}
コード例 #19
0
ファイル: allop.c プロジェクト: openldap/openldap
static int
allop_db_config(
	BackendDB	*be,
	const char	*fname,
	int		lineno,
	int		argc,
	char		**argv )
{
	slap_overinst	*on = (slap_overinst *)be->bd_info;
	allop_t		*ao = (allop_t *)on->on_bi.bi_private;

	if ( strcasecmp( argv[ 0 ], "allop-uri" ) == 0 ) {
		LDAPURLDesc	*lud;
		struct berval	dn,
				ndn;
		int		scope,
				rc = LDAP_SUCCESS;

		if ( argc != 2 ) {
			fprintf( stderr, "%s line %d: "
				"need exactly 1 arg "
				"in \"allop-uri <ldapURI>\" "
				"directive.\n",
				fname, lineno );
			return 1;
		}

		if ( ldap_url_parse( argv[ 1 ], &lud ) != LDAP_URL_SUCCESS ) {
			return -1;
		}

		scope = lud->lud_scope;
		if ( scope == LDAP_SCOPE_DEFAULT ) {
			scope = LDAP_SCOPE_BASE;
		}

		if ( lud->lud_dn == NULL || lud->lud_dn[ 0 ] == '\0' ) {
			if ( scope == LDAP_SCOPE_BASE ) {
				BER_BVZERO( &ndn );

			} else {
				ber_str2bv( "", 0, 1, &ndn );
			}

		} else {

			ber_str2bv( lud->lud_dn, 0, 0, &dn );
			rc = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
		}

		ldap_free_urldesc( lud );
		if ( rc != LDAP_SUCCESS ) {
			return -1;
		}

		if ( BER_BVISNULL( &ndn ) ) {
			/* rootDSE */
			if ( ao != NULL ) {
				ch_free( ao->ao_ndn.bv_val );
				ch_free( ao );
				on->on_bi.bi_private = NULL;
			}

		} else {
			if ( ao == NULL ) {
				ao = ch_calloc( 1, sizeof( allop_t ) );
				on->on_bi.bi_private = (void *)ao;

			} else {
				ch_free( ao->ao_ndn.bv_val );
			}

			ao->ao_ndn = ndn;
			ao->ao_scope = scope;
		}

	} else {
		return SLAP_CONF_UNKNOWN;
	}

	return 0;
}
コード例 #20
0
ファイル: slapd-bind.c プロジェクト: jaredmcneill/netbsd-src
int
main( int argc, char **argv )
{
	int		i;
	char		*uri = NULL;
	char		*host = "localhost";
	char		*dn = NULL;
	char		*base = NULL;
	char		*filter = "(objectClass=person)";
	struct berval	pass = { 0, NULL };
	char		*pwattr = NULL;
	int		port = -1;
	int		loops = LOOPS;
	int		outerloops = 1;
	int		force = 0;
	int		chaserefs = 0;
	int		noinit = 1;
	int		delay = 0;

	/* extra action to do after bind... */
	struct berval	type[] = {
		BER_BVC( "tester=" ),
		BER_BVC( "add=" ),
		BER_BVC( "bind=" ),
		BER_BVC( "modify=" ),
		BER_BVC( "modrdn=" ),
		BER_BVC( "read=" ),
		BER_BVC( "search=" ),
		BER_BVNULL
	};

	LDAPURLDesc	*extra_ludp = NULL;

	tester_init( "slapd-bind", TESTER_BIND );

	/* by default, tolerate invalid credentials */
	tester_ignore_str2errlist( "INVALID_CREDENTIALS" );

	while ( ( i = getopt( argc, argv, "a:B:b:D:Ff:H:h:Ii:L:l:p:t:w:" ) ) != EOF )
	{
		switch ( i ) {
		case 'a':
			pwattr = optarg;
			break;

		case 'b':		/* base DN of a tree of user DNs */
			base = optarg;
			break;

		case 'B':
			{
			int	c;

			for ( c = 0; type[c].bv_val; c++ ) {
				if ( strncasecmp( optarg, type[c].bv_val, type[c].bv_len ) == 0 )
				{
					break;
				}
			}

			if ( type[c].bv_val == NULL ) {
				usage( argv[0], 'B' );
			}

			switch ( c ) {
			case TESTER_TESTER:
			case TESTER_BIND:
				/* invalid */
				usage( argv[0], 'B' );

			case TESTER_SEARCH:
				{
				if ( ldap_url_parse( &optarg[type[c].bv_len], &extra_ludp ) != LDAP_URL_SUCCESS )
				{
					usage( argv[0], 'B' );
				}
				} break;

			case TESTER_ADDEL:
			case TESTER_MODIFY:
			case TESTER_MODRDN:
			case TESTER_READ:
				/* nothing to do */
				break;

			default:
				assert( 0 );
			}

			} break;

		case 'C':
			chaserefs++;
			break;

		case 'H':		/* the server uri */
			uri = optarg;
			break;

		case 'h':		/* the servers host */
			host = optarg;
			break;

		case 'i':
			tester_ignore_str2errlist( optarg );
			break;

		case 'p':		/* the servers port */
			if ( lutil_atoi( &port, optarg ) != 0 ) {
				usage( argv[0], 'p' );
			}
			break;

		case 'D':
			dn = optarg;
			break;

		case 'w':
			ber_str2bv( optarg, 0, 1, &pass );
			memset( optarg, '*', pass.bv_len );
			break;

		case 'l':		/* the number of loops */
			if ( lutil_atoi( &loops, optarg ) != 0 ) {
				usage( argv[0], 'l' );
			}
			break;

		case 'L':		/* the number of outerloops */
			if ( lutil_atoi( &outerloops, optarg ) != 0 ) {
				usage( argv[0], 'L' );
			}
			break;

		case 'f':
			filter = optarg;
			break;

		case 'F':
			force++;
			break;

		case 'I':
			/* reuse connection */
			noinit = 0;
			break;

		case 't':
			/* sleep between binds */
			if ( lutil_atoi( &delay, optarg ) != 0 ) {
				usage( argv[0], 't' );
			}
			break;

		default:
			usage( argv[0], i );
			break;
		}
	}

	if ( port == -1 && uri == NULL ) {
		usage( argv[0], '\0' );
	}

	uri = tester_uri( uri, host, port );

	for ( i = 0; i < outerloops; i++ ) {
		int rc;

		if ( base != NULL ) {
			rc = do_base( uri, dn, &pass, base, filter, pwattr, loops,
				force, chaserefs, noinit, delay, -1, NULL );
		} else {
			rc = do_bind( uri, dn, &pass, loops,
				force, chaserefs, noinit, NULL, -1, NULL );
		}
		if ( rc == LDAP_SERVER_DOWN )
			break;
	}

	exit( EXIT_SUCCESS );
}
コード例 #21
0
ファイル: dds.c プロジェクト: Smilefant/ReOpenLDAP
static int
dds_cfgen( ConfigArgs *c )
{
	slap_overinst	*on = (slap_overinst *)c->bi;
	dds_info_t	*di = on->on_bi.bi_private;
	int		rc = 0;
	unsigned long	t;


	if ( c->op == SLAP_CONFIG_EMIT ) {
		char		buf[ SLAP_TEXT_BUFLEN ];
		struct berval	bv;

		switch( c->type ) {
		case DDS_STATE:
			c->value_int = !DDS_OFF( di );
			break;

		case DDS_MAXTTL:
			lutil_unparse_time( buf, sizeof( buf ), di->di_max_ttl );
			ber_str2bv( buf, 0, 0, &bv );
			value_add_one( &c->rvalue_vals, &bv );
			break;

		case DDS_MINTTL:
			if ( di->di_min_ttl ) {
				lutil_unparse_time( buf, sizeof( buf ), di->di_min_ttl );
				ber_str2bv( buf, 0, 0, &bv );
				value_add_one( &c->rvalue_vals, &bv );

			} else {
				rc = 1;
			}
			break;

		case DDS_DEFAULTTTL:
			if ( di->di_default_ttl ) {
				lutil_unparse_time( buf, sizeof( buf ), di->di_default_ttl );
				ber_str2bv( buf, 0, 0, &bv );
				value_add_one( &c->rvalue_vals, &bv );

			} else {
				rc = 1;
			}
			break;

		case DDS_INTERVAL:
			if ( di->di_interval ) {
				lutil_unparse_time( buf, sizeof( buf ), di->di_interval );
				ber_str2bv( buf, 0, 0, &bv );
				value_add_one( &c->rvalue_vals, &bv );

			} else {
				rc = 1;
			}
			break;

		case DDS_TOLERANCE:
			if ( di->di_tolerance ) {
				lutil_unparse_time( buf, sizeof( buf ), di->di_tolerance );
				ber_str2bv( buf, 0, 0, &bv );
				value_add_one( &c->rvalue_vals, &bv );

			} else {
				rc = 1;
			}
			break;

		case DDS_MAXDYNAMICOBJS:
			if ( di->di_max_dynamicObjects > 0 ) {
				c->value_int = di->di_max_dynamicObjects;

			} else {
				rc = 1;
			}
			break;

		default:
			rc = 1;
			break;
		}

		return rc;

	} else if ( c->op == LDAP_MOD_DELETE ) {
		switch( c->type ) {
		case DDS_STATE:
			di->di_flags &= ~DDS_FOFF;
			break;

		case DDS_MAXTTL:
			di->di_min_ttl = DDS_RF2589_DEFAULT_TTL;
			break;

		case DDS_MINTTL:
			di->di_min_ttl = 0;
			break;

		case DDS_DEFAULTTTL:
			di->di_default_ttl = 0;
			break;

		case DDS_INTERVAL:
			di->di_interval = 0;
			break;

		case DDS_TOLERANCE:
			di->di_tolerance = 0;
			break;

		case DDS_MAXDYNAMICOBJS:
			di->di_max_dynamicObjects = 0;
			break;

		default:
			rc = 1;
			break;
		}

		return rc;
	}

	switch ( c->type ) {
	case DDS_STATE:
		if ( c->value_int ) {
			di->di_flags &= ~DDS_FOFF;

		} else {
			di->di_flags |= DDS_FOFF;
		}
		break;

	case DDS_MAXTTL:
		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"DDS unable to parse dds-max-ttl \"%s\"",
				c->argv[ 1 ] );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t < DDS_RF2589_DEFAULT_TTL || t > DDS_RF2589_MAX_TTL ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"DDS invalid dds-max-ttl=%lu; must be between %d and %d",
				t, DDS_RF2589_DEFAULT_TTL, DDS_RF2589_MAX_TTL );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		di->di_max_ttl = (time_t)t;
		break;

	case DDS_MINTTL:
		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"DDS unable to parse dds-min-ttl \"%s\"",
				c->argv[ 1 ] );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t > DDS_RF2589_MAX_TTL ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"DDS invalid dds-min-ttl=%lu",
				t );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t == 0 ) {
			di->di_min_ttl = DDS_RF2589_DEFAULT_TTL;

		} else {
			di->di_min_ttl = (time_t)t;
		}
		break;

	case DDS_DEFAULTTTL:
		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"DDS unable to parse dds-default-ttl \"%s\"",
				c->argv[ 1 ] );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t > DDS_RF2589_MAX_TTL ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"DDS invalid dds-default-ttl=%lu",
				t );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t == 0 ) {
			di->di_default_ttl = DDS_RF2589_DEFAULT_TTL;

		} else {
			di->di_default_ttl = (time_t)t;
		}
		break;

	case DDS_INTERVAL:
		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"DDS unable to parse dds-interval \"%s\"",
				c->argv[ 1 ] );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t <= 0 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"DDS invalid dds-interval=%lu",
				t );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t < 60 ) {
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE,
				"%s: dds-interval=%lu may be too small.\n",
				c->log, t );
		}

		di->di_interval = (time_t)t;
		if ( di->di_expire_task ) {
			ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
			if ( ldap_pvt_runqueue_isrunning( &slapd_rq, di->di_expire_task ) ) {
				ldap_pvt_runqueue_stoptask( &slapd_rq, di->di_expire_task );
			}
			di->di_expire_task->interval.tv_sec = DDS_INTERVAL( di );
			ldap_pvt_runqueue_resched( &slapd_rq, di->di_expire_task, 0 );
			ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
		}
		break;

	case DDS_TOLERANCE:
		if ( lutil_parse_time( c->argv[ 1 ], &t ) != 0 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg),
				"DDS unable to parse dds-tolerance \"%s\"",
				c->argv[ 1 ] );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		if ( t > DDS_RF2589_MAX_TTL ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"DDS invalid dds-tolerance=%lu",
				t );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}

		di->di_tolerance = (time_t)t;
		break;

	case DDS_MAXDYNAMICOBJS:
		if ( c->value_int < 0 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"DDS invalid dds-max-dynamicObjects=%d", c->value_int );
			Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
				"%s: %s.\n", c->log, c->cr_msg );
			return 1;
		}
		di->di_max_dynamicObjects = c->value_int;
		break;

	default:
		rc = 1;
		break;
	}

	return rc;
}
コード例 #22
0
ファイル: sasl.c プロジェクト: swinkelhofer/ad2openldap
static int
slap_auxprop_store(
	void *glob_context,
	sasl_server_params_t *sparams,
	struct propctx *prctx,
	const char *user,
	unsigned ulen)
{
	Operation op = {0};
	Opheader oph;
	SlapReply rs = {REP_RESULT};
	int rc, i;
	unsigned j;
	Connection *conn = NULL;
	const struct propval *pr;
	Modifications *modlist = NULL, **modtail = &modlist, *mod;
	slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
	char textbuf[SLAP_TEXT_BUFLEN];
	const char *text;
	size_t textlen = sizeof(textbuf);

	/* just checking if we are enabled */
	if (!prctx) return SASL_OK;

	if (!sparams || !user) return SASL_BADPARAM;

	pr = sparams->utils->prop_get( sparams->propctx );

	/* Find our DN and conn first */
	for( i = 0; pr[i].name; i++ ) {
		if ( pr[i].name[0] == '*' ) {
			if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) {
				if ( pr[i].values && pr[i].values[0] )
					AC_MEMCPY( &conn, pr[i].values[0], sizeof( conn ) );
				continue;
			}
			if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_AUTHCLEN] )) {
				if ( pr[i].values && pr[i].values[0] )
					AC_MEMCPY( &op.o_req_ndn.bv_len, pr[i].values[0],
						sizeof( op.o_req_ndn.bv_len ) );
			} else if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
				if ( pr[i].values )
					op.o_req_ndn.bv_val = (char *)pr[i].values[0];
			}
		}
	}
	if (!conn || !op.o_req_ndn.bv_val) return SASL_BADPARAM;

	op.o_bd = select_backend( &op.o_req_ndn, 1 );

	if ( !op.o_bd || !op.o_bd->be_modify ) return SASL_FAIL;
		
	pr = sparams->utils->prop_get( prctx );
	if (!pr) return SASL_BADPARAM;

	for (i=0; pr[i].name; i++);
	if (!i) return SASL_BADPARAM;

	for (i=0; pr[i].name; i++) {
		mod = (Modifications *)ch_malloc( sizeof(Modifications) );
		mod->sml_op = LDAP_MOD_REPLACE;
		mod->sml_flags = 0;
		ber_str2bv( pr[i].name, 0, 0, &mod->sml_type );
		mod->sml_numvals = pr[i].nvalues;
		mod->sml_values = (struct berval *)ch_malloc( (pr[i].nvalues + 1) *
			sizeof(struct berval));
		for (j=0; j<pr[i].nvalues; j++) {
			ber_str2bv( pr[i].values[j], 0, 1, &mod->sml_values[j]);
		}
		BER_BVZERO( &mod->sml_values[j] );
		mod->sml_nvalues = NULL;
		mod->sml_desc = NULL;
		*modtail = mod;
		modtail = &mod->sml_next;
	}
	*modtail = NULL;

	rc = slap_mods_check( &op, modlist, &text, textbuf, textlen, NULL );

	if ( rc == LDAP_SUCCESS ) {
		rc = slap_mods_no_user_mod_check( &op, modlist,
			&text, textbuf, textlen );

		if ( rc == LDAP_SUCCESS ) {
			if ( conn->c_sasl_bindop ) {
				op.o_hdr = conn->c_sasl_bindop->o_hdr;
			} else {
				op.o_hdr = &oph;
				memset( &oph, 0, sizeof(oph) );
				operation_fake_init( conn, &op, ldap_pvt_thread_pool_context(), 0 );
			}
			op.o_tag = LDAP_REQ_MODIFY;
			op.o_ndn = op.o_req_ndn;
			op.o_callback = &cb;
			slap_op_time( &op.o_time, &op.o_tincr );
			op.o_do_not_cache = 1;
			op.o_is_auth_check = 1;
			op.o_req_dn = op.o_req_ndn;
			op.orm_modlist = modlist;

			rc = op.o_bd->be_modify( &op, &rs );
		}
	}
	slap_mods_free( modlist, 1 );
	return rc != LDAP_SUCCESS ? SASL_FAIL : SASL_OK;
}
コード例 #23
0
ファイル: frontend.c プロジェクト: ajinkya93/netbsd-src
int
frontend_init( void )
{
	/* data */
	frontendDB = &slap_frontendDB;
	frontendDB->bd_self = frontendDB;

	/* ACLs */
	frontendDB->be_dfltaccess = ACL_READ;

	/* limits */
	frontendDB->be_def_limit.lms_t_soft = SLAPD_DEFAULT_TIMELIMIT;	/* backward compatible limits */
	frontendDB->be_def_limit.lms_t_hard = 0;
	frontendDB->be_def_limit.lms_s_soft = SLAPD_DEFAULT_SIZELIMIT;	/* backward compatible limits */
	frontendDB->be_def_limit.lms_s_hard = 0;
	frontendDB->be_def_limit.lms_s_unchecked = -1;			/* no limit on unchecked size */
	frontendDB->be_def_limit.lms_s_pr = 0;				/* page limit */
	frontendDB->be_def_limit.lms_s_pr_hide = 0;			/* don't hide number of entries left */
	frontendDB->be_def_limit.lms_s_pr_total = 0;			/* number of total entries returned by pagedResults equal to hard limit */

	ldap_pvt_thread_mutex_init( &frontendDB->be_pcl_mutex );

	/* suffix */
	frontendDB->be_suffix = ch_calloc( 2, sizeof( struct berval ) );
	ber_str2bv( "", 0, 1, &frontendDB->be_suffix[0] );
	BER_BVZERO( &frontendDB->be_suffix[1] );
	frontendDB->be_nsuffix = ch_calloc( 2, sizeof( struct berval ) );
	ber_str2bv( "", 0, 1, &frontendDB->be_nsuffix[0] );
	BER_BVZERO( &frontendDB->be_nsuffix[1] );

	/* info */
	frontendDB->bd_info = &slap_frontendInfo;

	SLAP_BFLAGS(frontendDB) |= SLAP_BFLAG_FRONTEND;

	/* name */
	frontendDB->bd_info->bi_type = "frontend";

	/* known controls */
	{
		int	i;

		frontendDB->bd_info->bi_controls = slap_known_controls;

		for ( i = 0; slap_known_controls[ i ]; i++ ) {
			int	cid;

			if ( slap_find_control_id( slap_known_controls[ i ], &cid )
					== LDAP_CONTROL_NOT_FOUND )
			{
				assert( 0 );
				return -1;
			}

			frontendDB->bd_info->bi_ctrls[ cid ] = 1;
			frontendDB->be_ctrls[ cid ] = 1;
		}
	}

	/* calls */
	frontendDB->bd_info->bi_op_abandon = fe_op_abandon;
	frontendDB->bd_info->bi_op_add = fe_op_add;
	frontendDB->bd_info->bi_op_bind = fe_op_bind;
	frontendDB->bd_info->bi_op_compare = fe_op_compare;
	frontendDB->bd_info->bi_op_delete = fe_op_delete;
	frontendDB->bd_info->bi_op_modify = fe_op_modify;
	frontendDB->bd_info->bi_op_modrdn = fe_op_modrdn;
	frontendDB->bd_info->bi_op_search = fe_op_search;
	frontendDB->bd_info->bi_extended = fe_extended;
	frontendDB->bd_info->bi_operational = fe_aux_operational;
	frontendDB->bd_info->bi_entry_get_rw = fe_entry_get_rw;
	frontendDB->bd_info->bi_entry_release_rw = fe_entry_release_rw;
	frontendDB->bd_info->bi_access_allowed = fe_access_allowed;
	frontendDB->bd_info->bi_acl_group = fe_acl_group;
	frontendDB->bd_info->bi_acl_attribute = fe_acl_attribute;

#if 0
	/* FIXME: is this too early? */
	return backend_startup_one( frontendDB );
#endif

	return 0;
}
コード例 #24
0
ファイル: sasl.c プロジェクト: swinkelhofer/ad2openldap
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;
}
コード例 #25
0
ファイル: dynlist.c プロジェクト: bhanug/likewise-open
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;
		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 );
				}

				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 );
			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[ attridx ] );
			Debug( LDAP_DEBUG_ANY, "%s: %s.\n",
				c->log, c->cr_msg, 0 );
			return 1;
		}

		attridx++;

		for ( i = attridx; i < c->argc; i++ ) {
			char *arg;
			char *cp;
			AttributeDescription *member_ad = NULL;
			AttributeDescription *mapped_ad = NULL;
			dynlist_map_t *dlmp;
			dynlist_map_t *dlml;


			/*
			 * 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 );
					return 1;
				}
				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 );
				return 1;
			}

			dlmp = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) );
			if ( dlm == NULL ) {
				dlm = dlmp;
				dlml = NULL;
			}
			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 );
					return 1;
				}
				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;
}
コード例 #26
0
int
dnssrv_back_search(
    Operation	*op,
    SlapReply	*rs )
{
	int i;
	int rc;
	char *domain = NULL;
	char *hostlist = NULL;
	char **hosts = NULL;
	char *refdn;
	struct berval nrefdn = BER_BVNULL;
	BerVarray urls = NULL;
	int manageDSAit;

	rs->sr_ref = NULL;

	if ( BER_BVISEMPTY( &op->o_req_ndn ) ) {
		/* FIXME: need some means to determine whether the database
		 * is a glue instance; if we got here with empty DN, then
		 * we passed this same test in dnssrv_back_referrals() */
		if ( !SLAP_GLUE_INSTANCE( op->o_bd ) ) {
			rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed";

		} else {
			rs->sr_err = LDAP_SUCCESS;
		}
		goto done;
	}

	manageDSAit = get_manageDSAit( op );
	/*
	 * FIXME: we may return a referral if manageDSAit is not set
	 */
	if ( !manageDSAit ) {
		send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
				"manageDSAit must be set" );
		goto done;
	}

	if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) {
		rs->sr_err = LDAP_REFERRAL;
		rs->sr_ref = default_referral;
		send_ldap_result( op, rs );
		rs->sr_ref = NULL;
		goto done;
	}

	Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n",
		op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", domain, 0 );

	if( ( rc = ldap_domain2hostlist( domain, &hostlist ) ) ) {
		Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
			rc, 0, 0 );
		send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT,
			"no DNS SRV RR available for DN" );
		goto done;
	}

	hosts = ldap_str2charray( hostlist, " " );

	if( hosts == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 );
		send_ldap_error( op, rs, LDAP_OTHER,
			"problem processing DNS SRV records for DN" );
		goto done;
	}

	for( i=0; hosts[i] != NULL; i++) {
		struct berval url;

		url.bv_len = STRLENOF( "ldap://" ) + strlen(hosts[i]);
		url.bv_val = ch_malloc( url.bv_len + 1 );

		strcpy( url.bv_val, "ldap://" );
		strcpy( &url.bv_val[STRLENOF( "ldap://" )], hosts[i] );

		if( ber_bvarray_add( &urls, &url ) < 0 ) {
			free( url.bv_val );
			send_ldap_error( op, rs, LDAP_OTHER,
			"problem processing DNS SRV records for DN" );
			goto done;
		}
	}

	Statslog( LDAP_DEBUG_STATS,
	    "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
	    op->o_log_prefix, op->o_protocol,
		op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val, 0 );

	Debug( LDAP_DEBUG_TRACE,
		"DNSSRV: ManageDSAit scope=%d dn=\"%s\" -> url=\"%s\"\n",
		op->oq_search.rs_scope,
		op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "",
		urls[0].bv_val );

	rc = ldap_domain2dn(domain, &refdn);

	if( rc != LDAP_SUCCESS ) {
		send_ldap_error( op, rs, LDAP_OTHER,
			"DNS SRV problem processing manageDSAit control" );
		goto done;

	} else {
		struct berval bv;
		bv.bv_val = refdn;
		bv.bv_len = strlen( refdn );

		rc = dnNormalize( 0, NULL, NULL, &bv, &nrefdn, op->o_tmpmemctx );
		if( rc != LDAP_SUCCESS ) {
			send_ldap_error( op, rs, LDAP_OTHER,
				"DNS SRV problem processing manageDSAit control" );
			goto done;
		}
	}

	if( !dn_match( &nrefdn, &op->o_req_ndn ) ) {
		/* requested dn is subordinate */

		Debug( LDAP_DEBUG_TRACE,
			"DNSSRV: dn=\"%s\" subordinate to refdn=\"%s\"\n",
			op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "",
			refdn == NULL ? "" : refdn,
			NULL );

		rs->sr_matched = refdn;
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		send_ldap_result( op, rs );
		rs->sr_matched = NULL;

	} else if ( op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) {
		send_ldap_error( op, rs, LDAP_SUCCESS, NULL );

	} else {
		Entry e = { 0 };
		AttributeDescription *ad_objectClass
			= slap_schema.si_ad_objectClass;
		AttributeDescription *ad_ref = slap_schema.si_ad_ref;
		e.e_name.bv_val = ch_strdup( op->o_req_dn.bv_val );
		e.e_name.bv_len = op->o_req_dn.bv_len;
		e.e_nname.bv_val = ch_strdup( op->o_req_ndn.bv_val );
		e.e_nname.bv_len = op->o_req_ndn.bv_len;

		e.e_attrs = NULL;
		e.e_private = NULL;

		attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_referral->soc_cname, NULL );
		attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_extensibleObject->soc_cname, NULL );

		if ( ad_dc ) {
			char		*p;
			struct berval	bv;

			bv.bv_val = domain;

			p = strchr( bv.bv_val, '.' );
					
			if ( p == bv.bv_val ) {
				bv.bv_len = 1;

			} else if ( p != NULL ) {
				bv.bv_len = p - bv.bv_val;

			} else {
				bv.bv_len = strlen( bv.bv_val );
			}

			attr_merge_normalize_one( &e, ad_dc, &bv, NULL );
		}

		if ( ad_associatedDomain ) {
			struct berval	bv;

			ber_str2bv( domain, 0, 0, &bv );
			attr_merge_normalize_one( &e, ad_associatedDomain, &bv, NULL );
		}

		attr_merge_normalize_one( &e, ad_ref, urls, NULL );

		rc = test_filter( op, &e, op->oq_search.rs_filter ); 

		if( rc == LDAP_COMPARE_TRUE ) {
			rs->sr_entry = &e;
			rs->sr_attrs = op->oq_search.rs_attrs;
			rs->sr_flags = REP_ENTRY_MODIFIABLE;
			send_search_entry( op, rs );
			rs->sr_entry = NULL;
			rs->sr_attrs = NULL;
		}

		entry_clean( &e );

		rs->sr_err = LDAP_SUCCESS;
		send_ldap_result( op, rs );
	}

	if ( refdn ) free( refdn );
	if ( nrefdn.bv_val ) free( nrefdn.bv_val );

done:
	if( domain != NULL ) ch_free( domain );
	if( hostlist != NULL ) ch_free( hostlist );
	if( hosts != NULL ) ldap_charray_free( hosts );
	if( urls != NULL ) ber_bvarray_free( urls );
	return 0;
}
コード例 #27
0
ファイル: dynlist.c プロジェクト: bhanug/likewise-open
static int
dynlist_db_config(
	BackendDB	*be,
	const char	*fname,
	int		lineno,
	int		argc,
	char		**argv )
{
	slap_overinst	*on = (slap_overinst *)be->bd_info;

	int		rc = 0;

	if ( strcasecmp( argv[0], "dynlist-attrset" ) == 0 ) {
		dynlist_info_t		**dlip;
		ObjectClass		*oc;
		AttributeDescription	*ad = NULL,
					*member_ad = NULL;
		dynlist_map_t		*dlm = NULL;
		const char		*text;

		if ( argc < 3 ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
				"invalid arg number #%d.\n",
				fname, lineno, argc );
			return 1;
		}

		oc = oc_find( argv[1] );
		if ( oc == NULL ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
				"unable to find ObjectClass \"%s\"\n",
				fname, lineno, argv[ 1 ] );
			return 1;
		}

		rc = slap_str2ad( argv[2], &ad, &text );
		if ( rc != LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
				"unable to find AttributeDescription \"%s\"\n",
				fname, lineno, argv[2] );
			return 1;
		}

		if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: " DYNLIST_USAGE
				"AttributeDescription \"%s\" "
				"must be a subtype of \"labeledURI\"\n",
				fname, lineno, argv[2] );
			return 1;
		}

		for ( i = 3; i < argc; i++ ) {
			char *arg;
			char *cp;
			AttributeDescription *member_ad = NULL;
			AttributeDescription *mapped_ad = NULL;
			dynlist_map_t *dlmp;
			dynlist_map_t *dlml;


			/*
			 * If no mapped attribute is given, dn is used
			 * for backward compatibility.
			 */
			arg = argv[i];
			if ( cp = strchr( arg, (int)':' ) != NULL ) {
				struct berval bv;
				ber_str2bv( arg, cp - arg, 0, &bv );
				rc = slap_bv2ad( &bv, &mapped_ad, &text );
				if ( rc != LDAP_SUCCESS ) {
					Debug( LDAP_DEBUG_ANY, "%s: line %d: "
						DYNLIST_USAGE
						"unable to find mapped AttributeDescription \"%s\"\n",
						fname, lineno, arg );
					return 1;
				}

				arg = cp + 1;
			}

			rc = slap_str2ad( arg, &member_ad, &text );
			if ( rc != LDAP_SUCCESS ) {
				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
					DYNLIST_USAGE
					"unable to find AttributeDescription \"%s\"\n",
					fname, lineno, arg );
				return 1;
			}

			dlmp = (dynlist_map_t *)ch_calloc( 1, sizeof( dynlist_map_t ) );
			if ( dlm == NULL ) {
				dlm = dlmp;
				dlml = NULL;
			}
			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;
		}

		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 &&
			     dlm->dlm_next == NULL &&
			     dlm->dlm_member_ad == (*dlip)->dli_dlm->dlm_member_ad &&
			     dlm->dlm_mapped_ad == (*dlip)->dli_dlm->dlm_mapped_ad ) {
				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
					DYNLIST_USAGE
					"URL attributeDescription \"%s\" already mapped.\n",
					fname, lineno, ad->ad_cname.bv_val );
#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 = dlm;

		if ( dynlist_build_def_filter( *dlip ) ) {
			dynlist_map_t *dlm = (*dlip)->ldi_dlm;
			dynlist_map_t *dlm_next;

			while ( dlm != NULL ) {
				dlm_next = dlm->dlm_next;
				ch_free( dlm );
				dlm = dlm_next;
			}

			ch_free( *dlip );
			*dlip = NULL;
			return 1;
		}

	/* allow dyngroup syntax */
	} else if ( strcasecmp( argv[0], "dynlist-attrpair" ) == 0 ) {
		dynlist_info_t		**dlip;
		ObjectClass		*oc;
		AttributeDescription	*ad = NULL,
					*member_ad = NULL;
		const char		*text;

		if ( argc != 3 ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
				"\"dynlist-attrpair <member-ad> <URL-ad>\": "
				"invalid arg number #%d.\n",
				fname, lineno, argc );
			return 1;
		}

		oc = oc_find( "groupOfURLs" );
		if ( oc == NULL ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
				"\"dynlist-attrpair <member-ad> <URL-ad>\": "
				"unable to find default ObjectClass \"groupOfURLs\"\n",
				fname, lineno, 0 );
			return 1;
		}

		rc = slap_str2ad( argv[1], &member_ad, &text );
		if ( rc != LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
				"\"dynlist-attrpair <member-ad> <URL-ad>\": "
				"unable to find AttributeDescription \"%s\"\n",
				fname, lineno, argv[1] );
			return 1;
		}

		rc = slap_str2ad( argv[2], &ad, &text );
		if ( rc != LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
				"\"dynlist-attrpair <member-ad> <URL-ad>\": "
				"unable to find AttributeDescription \"%s\"\n",
				fname, lineno, argv[2] );
			return 1;
		}

		if ( !is_at_subtype( ad->ad_type, slap_schema.si_ad_labeledURI->ad_type ) ) {
			Debug( LDAP_DEBUG_ANY, "%s: line %d: "
				"\"dynlist-attrpair <member-ad> <URL-ad>\": "
				"AttributeDescription \"%s\" "
				"must be a subtype of \"labeledURI\"\n",
				fname, lineno, argv[2] );
			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 ) {
				Debug( LDAP_DEBUG_ANY, "%s: line %d: "
					"\"dynlist-attrpair <member-ad> <URL-ad>\": "
					"URL attributeDescription \"%s\" already mapped.\n",
					fname, lineno, ad->ad_cname.bv_val );
#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;

		if ( dynlist_build_def_filter( *dlip ) ) {
			ch_free( (*dlip)->dli_dlm );
			ch_free( *dlip );
			*dlip = NULL;
			return 1;
		}

	} else {
		rc = SLAP_CONF_UNKNOWN;
	}

	return rc;
}
コード例 #28
0
ファイル: constraint.c プロジェクト: verter2015/ReOpenLDAP
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;
}
コード例 #29
0
ファイル: config.c プロジェクト: ajinkya93/netbsd-src
static int
bdb_cf_gen( ConfigArgs *c )
{
	struct bdb_info *bdb = c->be->be_private;
	int rc;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		rc = 0;
		switch( c->type ) {
		case BDB_MODE: {
			char buf[64];
			struct berval bv;
			bv.bv_len = snprintf( buf, sizeof(buf), "0%o", bdb->bi_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 BDB_CHKPT:
			if ( bdb->bi_txn_cp ) {
				char buf[64];
				struct berval bv;
				bv.bv_len = snprintf( buf, sizeof(buf), "%ld %ld",
					(long) bdb->bi_txn_cp_kbyte, (long) bdb->bi_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 BDB_CRYPTFILE:
			if ( bdb->bi_db_crypt_file ) {
				c->value_string = ch_strdup( bdb->bi_db_crypt_file );
			} else {
				rc = 1;
			}
			break;

		/* If a crypt file has been set, its contents are copied here.
		 * But we don't want the key to be incorporated here.
		 */
		case BDB_CRYPTKEY:
			if ( !bdb->bi_db_crypt_file && !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
				value_add_one( &c->rvalue_vals, &bdb->bi_db_crypt_key );
			} else {
				rc = 1;
			}
			break;

		case BDB_DIRECTORY:
			if ( bdb->bi_dbenv_home ) {
				c->value_string = ch_strdup( bdb->bi_dbenv_home );
			} else {
				rc = 1;
			}
			break;

		case BDB_CONFIG:
			if ( !( bdb->bi_flags & BDB_IS_OPEN )
				&& !bdb->bi_db_config )
			{
				char	buf[SLAP_TEXT_BUFLEN];
				FILE *f = fopen( bdb->bi_db_config_path, "r" );
				struct berval bv;

				if ( f ) {
					bdb->bi_flags |= BDB_HAS_CONFIG;
					while ( fgets( buf, sizeof(buf), f )) {
						ber_str2bv( buf, 0, 1, &bv );
						if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\n' ) {
							bv.bv_len--;
							bv.bv_val[bv.bv_len] = '\0';
						}
						/* shouldn't need this, but ... */
						if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\r' ) {
							bv.bv_len--;
							bv.bv_val[bv.bv_len] = '\0';
						}
						ber_bvarray_add( &bdb->bi_db_config, &bv );
					}
					fclose( f );
				}
			}
			if ( bdb->bi_db_config ) {
				int i;
				struct berval bv;

				bv.bv_val = c->log;
				for (i=0; !BER_BVISNULL(&bdb->bi_db_config[i]); i++) {
					bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i,
						bdb->bi_db_config[i].bv_val );
					value_add_one( &c->rvalue_vals, &bv );
				}
			}
			if ( !c->rvalue_vals ) rc = 1;
			break;

		case BDB_NOSYNC:
			if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC )
				c->value_int = 1;
			break;
			
		case BDB_CHECKSUM:
			if ( bdb->bi_flags & BDB_CHKSUM )
				c->value_int = 1;
			break;

		case BDB_INDEX:
			bdb_attr_index_unparse( bdb, &c->rvalue_vals );
			if ( !c->rvalue_vals ) rc = 1;
			break;

		case BDB_LOCKD:
			rc = 1;
			if ( bdb->bi_lock_detect != DB_LOCK_DEFAULT ) {
				int i;
				for (i=0; !BER_BVISNULL(&bdb_lockd[i].word); i++) {
					if ( bdb->bi_lock_detect == (u_int32_t)bdb_lockd[i].mask ) {
						value_add_one( &c->rvalue_vals, &bdb_lockd[i].word );
						rc = 0;
						break;
					}
				}
			}
			break;

		case BDB_SSTACK:
			c->value_int = bdb->bi_search_stack_depth;
			break;

		case BDB_PGSIZE: {
				struct bdb_db_pgsize *ps;
				char buf[SLAP_TEXT_BUFLEN];
				struct berval bv;
				int rc = 1;

				bv.bv_val = buf;
				for ( ps = bdb->bi_pagesizes; ps; ps = ps->bdp_next ) {
					bv.bv_len = sprintf( buf, "%s %d", ps->bdp_name.bv_val,
						ps->bdp_size / 1024 );
					value_add_one( &c->rvalue_vals, &bv );
					rc = 0;

				}
				break;
			}
		}
		return rc;
	} else if ( c->op == LDAP_MOD_DELETE ) {
		rc = 0;
		switch( c->type ) {
		case BDB_MODE:
#if 0
			/* FIXME: does it make any sense to change the mode,
			 * if we don't exec a chmod()? */
			bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE;
			break;
#endif

		/* single-valued no-ops */
		case BDB_LOCKD:
		case BDB_SSTACK:
			break;

		case BDB_CHKPT:
			if ( bdb->bi_txn_cp_task ) {
				struct re_s *re = bdb->bi_txn_cp_task;
				bdb->bi_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 );
			}
			bdb->bi_txn_cp = 0;
			break;
		case BDB_CONFIG:
			if ( c->valx < 0 ) {
				ber_bvarray_free( bdb->bi_db_config );
				bdb->bi_db_config = NULL;
			} else {
				int i = c->valx;
				ch_free( bdb->bi_db_config[i].bv_val );
				for (; bdb->bi_db_config[i].bv_val; i++)
					bdb->bi_db_config[i] = bdb->bi_db_config[i+1];
			}
			bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN;
			c->cleanup = bdb_cf_cleanup;
			break;
		/* Doesn't really make sense to change these on the fly;
		 * the entire DB must be dumped and reloaded
		 */
		case BDB_CRYPTFILE:
			if ( bdb->bi_db_crypt_file ) {
				ch_free( bdb->bi_db_crypt_file );
				bdb->bi_db_crypt_file = NULL;
			}
			/* FALLTHRU */
		case BDB_CRYPTKEY:
			if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) {
				ch_free( bdb->bi_db_crypt_key.bv_val );
				BER_BVZERO( &bdb->bi_db_crypt_key );
			}
			break;
		case BDB_DIRECTORY:
			bdb->bi_flags |= BDB_RE_OPEN;
			bdb->bi_flags ^= BDB_HAS_CONFIG;
			ch_free( bdb->bi_dbenv_home );
			bdb->bi_dbenv_home = NULL;
			ch_free( bdb->bi_db_config_path );
			bdb->bi_db_config_path = NULL;
			c->cleanup = bdb_cf_cleanup;
			ldap_pvt_thread_pool_purgekey( bdb->bi_dbenv );
			break;
		case BDB_NOSYNC:
			bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, 0 );
			break;
		case BDB_CHECKSUM:
			bdb->bi_flags &= ~BDB_CHKSUM;
			break;
		case BDB_INDEX:
			if ( c->valx == -1 ) {
				int i;

				/* delete all (FIXME) */
				for ( i = 0; i < bdb->bi_nattrs; i++ ) {
					bdb->bi_attrs[i]->ai_indexmask |= BDB_INDEX_DELETING;
				}
				bdb->bi_flags |= BDB_DEL_INDEX;
				c->cleanup = bdb_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 )) {
					bdb->bi_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 = bdb_attr_mask( bdb, ad );
						/* if we got here... */
						assert( ai != NULL );

						ai->ai_indexmask |= BDB_INDEX_DELETING;
						bdb->bi_flags |= BDB_DEL_INDEX;
						c->cleanup = bdb_cf_cleanup;
					}

					bv.bv_val[ bv.bv_len ] = sep;
					ldap_charray_free( attrs );
				}
			}
			break;
		/* doesn't make sense on the fly; the DB file must be
		 * recreated
		 */
		case BDB_PGSIZE: {
				struct bdb_db_pgsize *ps, **prev;
				int i;

				for ( i = 0, prev = &bdb->bi_pagesizes, ps = *prev; ps;
					prev = &ps->bdp_next, ps = ps->bdp_next, i++ ) {
					if ( c->valx == -1 || i == c->valx ) {
						*prev = ps->bdp_next;
						ch_free( ps );
						ps = *prev;
						if ( i == c->valx ) break;
					}
				}
			}
			break;
		}
		return rc;
	}

	switch( c->type ) {
	case BDB_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;
			}
			bdb->bi_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));
				}
			}
			bdb->bi_dbenv_mode = mode;
		}
		break;
	case BDB_CHKPT: {
		long	l;
		bdb->bi_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;
		}
		bdb->bi_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;
		}
		bdb->bi_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) && bdb->bi_txn_cp_min ) {
			struct re_s *re = bdb->bi_txn_cp_task;
			if ( re ) {
				re->interval.tv_sec = bdb->bi_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 );
				bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq,
					bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb,
					LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val );
				ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
			}
		}
		} break;

	case BDB_CONFIG: {
		char *ptr = c->line;
		struct berval bv;

		if ( c->op == SLAP_CONFIG_ADD ) {
			ptr += STRLENOF("dbconfig");
			while (!isspace((unsigned char)*ptr)) ptr++;
			while (isspace((unsigned char)*ptr)) ptr++;
		}

		if ( bdb->bi_flags & BDB_IS_OPEN ) {
			bdb->bi_flags |= BDB_UPD_CONFIG|BDB_RE_OPEN;
			c->cleanup = bdb_cf_cleanup;
		} else {
		/* If we're just starting up...
		 */
			FILE *f;
			/* If a DB_CONFIG file exists, or we don't know the path
			 * to the DB_CONFIG file, ignore these directives
			 */
			if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path )
				break;
			f = fopen( bdb->bi_db_config_path, "a" );
			if ( f ) {
				/* FIXME: EBCDIC probably needs special handling */
				fprintf( f, "%s\n", ptr );
				fclose( f );
			}
		}
		ber_str2bv( ptr, 0, 1, &bv );
		ber_bvarray_add( &bdb->bi_db_config, &bv );
		}
		break;

	case BDB_CRYPTFILE:
		rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key );
		if ( rc == 0 ) {
			bdb->bi_db_crypt_file = c->value_string;
		}
		break;

	/* Cannot set key if file was already set */
	case BDB_CRYPTKEY:
		if ( bdb->bi_db_crypt_file ) {
			rc = 1;
		} else {
			bdb->bi_db_crypt_key = c->value_bv;
		}
		break;

	case BDB_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 ( bdb->bi_dbenv_home )
			ch_free( bdb->bi_dbenv_home );
		bdb->bi_dbenv_home = c->value_string;

		/* See if a DB_CONFIG file already exists here */
		if ( bdb->bi_db_config_path )
			ch_free( bdb->bi_db_config_path );
		bdb->bi_db_config_path = ch_malloc( len +
			STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 );
		ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home );
		*ptr++ = LDAP_DIRSEP[0];
		strcpy( ptr, "DB_CONFIG" );

		f = fopen( bdb->bi_db_config_path, "r" );
		if ( f ) {
			bdb->bi_flags |= BDB_HAS_CONFIG;
			fclose(f);
		}
		}
		break;

	case BDB_NOSYNC:
		if ( c->value_int )
			bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC;
		else
			bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC;
		if ( bdb->bi_flags & BDB_IS_OPEN ) {
			bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC,
				c->value_int );
		}
		break;

	case BDB_CHECKSUM:
		if ( c->value_int )
			bdb->bi_flags |= BDB_CHKSUM;
		else
			bdb->bi_flags &= ~BDB_CHKSUM;
		break;

	case BDB_INDEX:
		rc = bdb_attr_index_config( bdb, c->fname, c->lineno,
			c->argc - 1, &c->argv[1], &c->reply);

		if( rc != LDAP_SUCCESS ) return 1;
		if (( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_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 );
			bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000,
				bdb_online_index, c->be,
				LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val );
			ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
		}
		break;

	case BDB_LOCKD:
		rc = verb_to_mask( c->argv[1], bdb_lockd );
		if ( BER_BVISNULL(&bdb_lockd[rc].word) ) {
			fprintf( stderr, "%s: "
				"bad policy (%s) in \"lockDetect <policy>\" line\n",
				c->log, c->argv[1] );
			return 1;
		}
		bdb->bi_lock_detect = (u_int32_t)rc;
		break;

	case BDB_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;
		}
		bdb->bi_search_stack_depth = c->value_int;
		break;

	case BDB_PGSIZE: {
		struct bdb_db_pgsize *ps, **prev;
		int i, s;
		
		s = atoi(c->argv[2]);
		if ( s < 1 || s > 64 ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"%s: size must be > 0 and <= 64: %d",
				c->log, s );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		i = strlen(c->argv[1]);
		ps = ch_malloc( sizeof(struct bdb_db_pgsize) + i + 1 );
		ps->bdp_next = NULL;
		ps->bdp_name.bv_len = i;
		ps->bdp_name.bv_val = (char *)(ps+1);
		strcpy( ps->bdp_name.bv_val, c->argv[1] );
		ps->bdp_size = s * 1024;
		for ( prev = &bdb->bi_pagesizes; *prev; prev = &(*prev)->bdp_next )
			;
		*prev = ps;
		}
		break;
	}
	return 0;
}
コード例 #30
0
ファイル: hdb-ldap.c プロジェクト: dariaphoebe/heimdal
static krb5_error_code
LDAP__lookup_princ(krb5_context context,
		   HDB *db,
		   const char *princname,
		   const char *userid,
		   LDAPMessage **msg)
{
    struct berval namebv, quotedp;
    krb5_error_code ret;
    int rc;
    char *filter = NULL;

    ret = LDAP__connect(context, db);
    if (ret)
	return ret;

    /* 
     * Quote searches that contain filter language, this quote
     * searches for *@REALM, which takes very long time.
     */

    ber_str2bv(princname, 0, 0, &namebv);
    if (ldap_bv2escaped_filter_value(&namebv, &quotedp) != 0) {
	ret = ENOMEM;
	krb5_set_error_message(context, ret, "malloc: out of memory");
	goto out;
    }
    rc = asprintf(&filter,
		  "(&(objectClass=krb5Principal)(krb5PrincipalName=%s))",
		  quotedp.bv_val);
    ber_memfree(quotedp.bv_val);

    if (rc < 0) {
	ret = ENOMEM;
	krb5_set_error_message(context, ret, "malloc: out of memory");
	goto out;
    }

    ret = LDAP_no_size_limit(context, HDB2LDAP(db));
    if (ret)
	goto out;

    rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db),
			   LDAP_SCOPE_SUBTREE, filter,
			   krb5kdcentry_attrs, 0,
			   NULL, NULL, NULL,
			   0, msg);
    if (check_ldap(context, db, rc)) {
	ret = HDB_ERR_NOENTRY;
	krb5_set_error_message(context, ret, "ldap_search_ext_s: "
			      "filter: %s - error: %s",
			      filter, ldap_err2string(rc));
	goto out;
    }

    if (userid && ldap_count_entries(HDB2LDAP(db), *msg) == 0) {
	free(filter);
	filter = NULL;
	ldap_msgfree(*msg);
	*msg = NULL;
	
	ber_str2bv(userid, 0, 0, &namebv);
	if (ldap_bv2escaped_filter_value(&namebv, &quotedp) != 0) {
	    ret = ENOMEM;
	    krb5_set_error_message(context, ret, "malloc: out of memory");
	    goto out;
	}

	rc = asprintf(&filter,
	    "(&(|(objectClass=sambaSamAccount)(objectClass=%s))(uid=%s))",
		      structural_object, quotedp.bv_val);
	ber_memfree(quotedp.bv_val);
	if (rc < 0) {
	    ret = ENOMEM;
	    krb5_set_error_message(context, ret, "asprintf: out of memory");
	    goto out;
	}
	
	ret = LDAP_no_size_limit(context, HDB2LDAP(db));
	if (ret)
	    goto out;

	rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE,
			       filter, krb5kdcentry_attrs, 0,
			       NULL, NULL, NULL,
			       0, msg);
	if (check_ldap(context, db, rc)) {
	    ret = HDB_ERR_NOENTRY;
	    krb5_set_error_message(context, ret,
				   "ldap_search_ext_s: filter: %s error: %s",
				   filter, ldap_err2string(rc));
	    goto out;
	}
    }

    ret = 0;

  out:
    if (filter)
	free(filter);

    return ret;
}