Exemplo n.º 1
0
Arquivo: vc.c Projeto: Joywar/openldap
static int
vc_exop(
	Operation	*op,
	SlapReply	*rs )
{
	int rc = LDAP_SUCCESS;
	ber_tag_t tag;
	ber_len_t len = -1;
	BerElementBuffer berbuf;
	BerElement *ber = (BerElement *)&berbuf;
	struct berval reqdata = BER_BVNULL;

	struct berval cookie = BER_BVNULL;
	struct berval bdn = BER_BVNULL;
	ber_tag_t authtag;
	struct berval cred = BER_BVNULL;
	struct berval ndn = BER_BVNULL;
	struct berval mechanism = BER_BVNULL;

	vc_conn_t *conn = NULL;
	vc_cb_t vc = { 0 };
	slap_callback sc = { 0 };
	SlapReply rs2 = { 0 };

	if ( op->ore_reqdata == NULL || op->ore_reqdata->bv_len == 0 ) {
		rs->sr_text = "empty request data field in VerifyCredentials exop";
		return LDAP_PROTOCOL_ERROR;
	}

	/* optimistic */
	rs->sr_err = LDAP_SUCCESS;

	ber_dupbv_x( &reqdata, op->ore_reqdata, op->o_tmpmemctx );

	/* ber_init2 uses reqdata directly, doesn't allocate new buffers */
	ber_init2( ber, &reqdata, 0 );

	tag = ber_scanf( ber, "{" /*}*/ );
	if ( tag != LBER_SEQUENCE ) {
		rs->sr_err = LDAP_PROTOCOL_ERROR;
		goto done;
	}

	tag = ber_peek_tag( ber, &len );
	if ( tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE ) {
		/*
		 * cookie: the pointer to the connection
		 * of this operation
		 */

		ber_scanf( ber, "m", &cookie );
		if ( cookie.bv_len != sizeof(Connection *) ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}
	}

	/* DN, authtag */
	tag = ber_scanf( ber, "mt", &bdn, &authtag );
	if ( tag == LBER_ERROR ) {
		rs->sr_err = LDAP_PROTOCOL_ERROR;
		goto done;
	}

	rc = dnNormalize( 0, NULL, NULL, &bdn, &ndn, op->o_tmpmemctx );
	if ( rc != LDAP_SUCCESS ) {
		rs->sr_err = LDAP_PROTOCOL_ERROR;
		goto done;
	}

	switch ( authtag ) {
	case LDAP_AUTH_SIMPLE:
		/* cookie only makes sense for SASL bind (so far) */
		if ( !BER_BVISNULL( &cookie ) ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		tag = ber_scanf( ber, "m", &cred );
		if ( tag == LBER_ERROR ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}
		break;

	case LDAP_AUTH_SASL:
		tag = ber_scanf( ber, "{s" /*}*/ , &mechanism );
		if ( tag == LBER_ERROR || 
			BER_BVISNULL( &mechanism ) || BER_BVISEMPTY( &mechanism ) )
		{
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		tag = ber_peek_tag( ber, &len );
		if ( tag == LBER_OCTETSTRING ) {
			ber_scanf( ber, "m", &cred );
		}

		tag = ber_scanf( ber, /*{*/ "}" );
		break;

	default:
		rs->sr_err = LDAP_PROTOCOL_ERROR;
		goto done;
	}

	if ( !BER_BVISNULL( &cookie ) ) {
		vc_conn_t tmp = { 0 };

		AC_MEMCPY( (char *)&tmp.conn, (const char *)cookie.bv_val, cookie.bv_len );
		ldap_pvt_thread_mutex_lock( &vc_mutex );
		conn = (vc_conn_t *)avl_find( vc_tree, (caddr_t)&tmp, vc_conn_cmp );
		if ( conn == NULL || ( conn != NULL && conn->refcnt != 0 ) ) {
			conn = NULL;
			ldap_pvt_thread_mutex_unlock( &vc_mutex );
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}
		conn->refcnt++;
		ldap_pvt_thread_mutex_unlock( &vc_mutex );

	} else {
		void *thrctx;

		conn = (vc_conn_t *)SLAP_CALLOC( 1, sizeof( vc_conn_t ) );
		conn->refcnt = 1;

		thrctx = ldap_pvt_thread_pool_context();
		connection_fake_init2( &conn->connbuf, &conn->opbuf, thrctx, 0 );
		conn->op = &conn->opbuf.ob_op;
		snprintf( conn->op->o_log_prefix, sizeof( conn->op->o_log_prefix ),
			"%s VERIFYCREDENTIALS", op->o_log_prefix );
	}

	conn->op->o_tag = LDAP_REQ_BIND;
	memset( &conn->op->oq_bind, 0, sizeof( conn->op->oq_bind ) );
	conn->op->o_req_dn = ndn;
	conn->op->o_req_ndn = ndn;
	conn->op->o_protocol = LDAP_VERSION3;
	conn->op->orb_method = authtag;
	conn->op->o_callback = ≻

	/* TODO: controls */
	tag = ber_peek_tag( ber, &len );
	if ( tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS ) {
		conn->op->o_ber = ber;
		rc = get_ctrls2( conn->op, &rs2, 0, LDAP_TAG_EXOP_VERIFY_CREDENTIALS_CONTROLS );
		if ( rc != LDAP_SUCCESS ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}
	}

	tag = ber_skip_tag( ber, &len );
	if ( len || tag != LBER_DEFAULT ) {
		rs->sr_err = LDAP_PROTOCOL_ERROR;
		goto done;
	}

	switch ( authtag ) {
	case LDAP_AUTH_SIMPLE:
		break;

	case LDAP_AUTH_SASL:
		conn->op->orb_mech = mechanism;
		break;
	}

	conn->op->orb_cred = cred;
	sc.sc_response = vc_cb;
	sc.sc_private = &vc;

	conn->op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_bind( conn->op, &rs2 );

	if ( conn->op->o_conn->c_sasl_bind_in_progress ) {
		rc = vc_create_response( conn, rs2.sr_err, rs2.sr_text,
			!BER_BVISEMPTY( &vc.sasldata ) ? &vc.sasldata : NULL,
			NULL,
			vc.ctrls, &rs->sr_rspdata );

	} else {
		rc = vc_create_response( NULL, rs2.sr_err, rs2.sr_text,
			NULL,
			&conn->op->o_conn->c_dn,
			vc.ctrls, &rs->sr_rspdata );
	}

	if ( rc != 0 ) {
		rs->sr_err = LDAP_OTHER;
		goto done;
	}

	if ( !BER_BVISNULL( &conn->op->o_conn->c_dn ) &&
		conn->op->o_conn->c_dn.bv_val != conn->op->o_conn->c_ndn.bv_val )
		ber_memfree( conn->op->o_conn->c_dn.bv_val );
	if ( !BER_BVISNULL( &conn->op->o_conn->c_ndn ) )
		ber_memfree( conn->op->o_conn->c_ndn.bv_val );

done:;
	if ( conn ) {
		if ( conn->op->o_conn->c_sasl_bind_in_progress ) {
			if ( conn->conn == NULL ) {
				conn->conn = conn;
				conn->refcnt--;
				ldap_pvt_thread_mutex_lock( &vc_mutex );
				rc = avl_insert( &vc_tree, (caddr_t)conn,
					vc_conn_cmp, vc_conn_dup );
				ldap_pvt_thread_mutex_unlock( &vc_mutex );
				assert( rc == 0 );

			} else {
				ldap_pvt_thread_mutex_lock( &vc_mutex );
				conn->refcnt--;
				ldap_pvt_thread_mutex_unlock( &vc_mutex );
			}

		} else {
			if ( conn->conn != NULL ) {
				vc_conn_t *tmp;

				ldap_pvt_thread_mutex_lock( &vc_mutex );
				tmp = avl_delete( &vc_tree, (caddr_t)conn, vc_conn_cmp );
				ldap_pvt_thread_mutex_unlock( &vc_mutex );
			}
			SLAP_FREE( conn );
		}
	}

	if ( vc.ctrls ) {
		ldap_controls_free( vc.ctrls );
		vc.ctrls = NULL;
	}

	if ( !BER_BVISNULL( &ndn ) ) {
		op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
		BER_BVZERO( &ndn );
	}

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

        return rs->sr_err;
}
Exemplo n.º 2
0
static int
vernum_repair( BackendDB *be )
{
	slap_overinst *on = (slap_overinst *)be->bd_info;
	vernum_t *vn = (vernum_t *)on->on_bi.bi_private;
	void *ctx = ldap_pvt_thread_pool_context();
	Connection conn = { 0 };
	OperationBuffer opbuf;
	Operation *op;
	BackendDB db;
	slap_callback sc = { 0 };
	vernum_repair_cb_t rcb = { 0 };
	SlapReply rs = { REP_RESULT };
	vernum_mod_t *rmod;
	int nrepaired = 0;

	connection_fake_init2( &conn, &opbuf, ctx, 0 );
	op = &opbuf.ob_op;

	op->o_tag = LDAP_REQ_SEARCH;
	memset( &op->oq_search, 0, sizeof( op->oq_search ) );

	assert( !BER_BVISNULL( &be->be_nsuffix[ 0 ] ) );

	op->o_bd = select_backend( &be->be_nsuffix[ 0 ], 0 );
	assert( op->o_bd != NULL );
	assert( op->o_bd->be_nsuffix != NULL );

	op->o_req_dn = op->o_bd->be_suffix[ 0 ];
	op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ];

	op->o_dn = op->o_bd->be_rootdn;
	op->o_ndn = op->o_bd->be_rootndn;

	op->ors_scope = LDAP_SCOPE_SUBTREE;
	op->ors_tlimit = SLAP_NO_LIMIT;
	op->ors_slimit = SLAP_NO_LIMIT;
	op->ors_attrs = slap_anlist_no_attrs;

	op->ors_filterstr.bv_len = STRLENOF( "(&(=*)(!(=*)))" )
		+ vn->vn_attr->ad_cname.bv_len
		+ vn->vn_vernum->ad_cname.bv_len;
	op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx );
	snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1,
		"(&(%s=*)(!(%s=*)))",
		vn->vn_attr->ad_cname.bv_val,
		vn->vn_vernum->ad_cname.bv_val );

	op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );
	if ( op->ors_filter == NULL ) {
		rs.sr_err = LDAP_OTHER;
		goto done_search;
	}
	
	op->o_callback = ≻
	sc.sc_response = vernum_repair_cb;
	sc.sc_private = &rcb;
	rcb.bd = &db;
	db = *be;
	db.bd_info = (BackendInfo *)on;

	(void)op->o_bd->bd_info->bi_op_search( op, &rs );

	op->o_tag = LDAP_REQ_MODIFY;
	sc.sc_response = slap_null_cb;
	sc.sc_private = NULL;
	memset( &op->oq_modify, 0, sizeof( req_modify_s ) );

	for ( rmod = rcb.mods; rmod != NULL; ) {
		vernum_mod_t *rnext;
		Modifications mod;
		struct berval vals[2] = { BER_BVNULL };
		SlapReply rs2 = { REP_RESULT };

		mod.sml_flags = SLAP_MOD_INTERNAL;
		mod.sml_op = LDAP_MOD_REPLACE;
		mod.sml_desc = vn->vn_vernum;
		mod.sml_type = vn->vn_vernum->ad_cname;
		mod.sml_values = vals;
		mod.sml_values[0] = val_init;
		mod.sml_nvalues = NULL;
		mod.sml_numvals = 1;
		mod.sml_next = NULL;

		op->o_req_dn = rmod->ndn;
		op->o_req_ndn = rmod->ndn;

		op->orm_modlist = &mod;

		op->o_bd->be_modify( op, &rs2 );

		slap_mods_free( op->orm_modlist->sml_next, 1 );
		if ( rs2.sr_err == LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_TRACE, "%s: vernum_repair: entry DN=\"%s\" repaired\n",
				op->o_log_prefix, rmod->ndn.bv_val, 0 );
			nrepaired++;

		} else {
			Debug( LDAP_DEBUG_ANY, "%s: vernum_repair: entry DN=\"%s\" repair failed (%d)\n",
				op->o_log_prefix, rmod->ndn.bv_val, rs2.sr_err );
		}

		rnext = rmod->next;
		op->o_tmpfree( rmod, op->o_tmpmemctx );
		rmod = rnext;
	}

done_search:;
	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
	filter_free_x( op, op->ors_filter, 1 );

	Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
		"vernum: repaired=%d\n", nrepaired );

	return 0;
}
Exemplo n.º 3
0
static int
autoca_db_open(
	BackendDB *be,
	ConfigReply *cr
)
{
	slap_overinst *on = (slap_overinst *)be->bd_info;
	autoca_info *ai = on->on_bi.bi_private;

	Connection conn = { 0 };
	OperationBuffer opbuf;
	Operation *op;
	void *thrctx;
	Entry *e;
	Attribute *a;
	int rc;

	if (slapMode & SLAP_TOOL_MODE)
		return 0;

	if ( ! *aca_attr2[0].ad ) {
		int i, code;
		const char *text;

		for ( i=0; aca_attr2[i].at; i++ ) {
			code = slap_str2ad( aca_attr2[i].at, aca_attr2[i].ad, &text );
			if ( code ) return code;
		}

		/* Schema may not be loaded, ignore if missing */
		slap_str2ad( "ipHostNumber", &ad_ipaddr, &text );

		for ( i=0; aca_ocs[i].ot; i++ ) {
			code = register_oc( aca_ocs[i].ot, aca_ocs[i].oc, 0 );
			if ( code ) return code;
		}
	}

	thrctx = ldap_pvt_thread_pool_context();
	connection_fake_init2( &conn, &opbuf, thrctx, 0 );
	op = &opbuf.ob_op;
	op->o_bd = be;
	op->o_dn = be->be_rootdn;
	op->o_ndn = be->be_rootndn;
	rc = overlay_entry_get_ov( op, be->be_nsuffix, NULL, 
		NULL, 0, &e, on );

	if ( e ) {
		int gotoc = 0, gotat = 0;
		if ( is_entry_objectclass( e, oc_caObj, 0 )) {
			gotoc = 1;
			a = attr_find( e->e_attrs, ad_caPkey );
			if ( a ) {
				const unsigned char *pp;
				pp = (unsigned char *)a->a_vals[0].bv_val;
				ai->ai_pkey = d2i_AutoPrivateKey( NULL, &pp, a->a_vals[0].bv_len );
				if ( ai->ai_pkey )
				{
					a = attr_find( e->e_attrs, ad_caCert );
					if ( a )
					{
						pp = (unsigned char *)a->a_vals[0].bv_val;
						ai->ai_cert = d2i_X509( NULL, &pp, a->a_vals[0].bv_len );
						/* If TLS wasn't configured yet, set this as our CA */
						if ( !slap_tls_ctx )
							autoca_setca( a->a_vals );
					}
				}
				gotat = 1;
			}
		}
		overlay_entry_release_ov( op, e, 0, on );
		/* generate attrs, store... */
		if ( !gotat ) {
			genargs args;
			saveargs arg2;

			args.issuer_cert = NULL;
			args.issuer_pkey = NULL;
			args.subjectDN = &be->be_suffix[0];
			args.cert_exts = CAexts;
			args.more_exts = NULL;
			args.keybits = ai->ai_cakeybits;
			args.days = ai->ai_cadays;

			rc = autoca_gencert( op, &args );
			if ( rc )
				return -1;

			ai->ai_cert = args.newcert;
			ai->ai_pkey = args.newpkey;

			arg2.dn = be->be_suffix;
			arg2.ndn = be->be_nsuffix;
			arg2.isca = 1;
			if ( !gotoc )
				arg2.oc = oc_caObj;
			else
				arg2.oc = NULL;
			arg2.on = on;
			arg2.dercert = &args.dercert;
			arg2.derpkey = &args.derpkey;

			autoca_savecert( op, &arg2 );

			/* If TLS wasn't configured yet, set this as our CA */
			if ( !slap_tls_ctx )
				autoca_setca( &args.dercert );

			op->o_tmpfree( args.dercert.bv_val, op->o_tmpmemctx );
			op->o_tmpfree( args.derpkey.bv_val, op->o_tmpmemctx );
		}
	}

	return 0;
}
Exemplo n.º 4
0
static int
pguid_repair( BackendDB *be )
{
	slap_overinst *on = (slap_overinst *)be->bd_info;
	void *ctx = ldap_pvt_thread_pool_context();
	Connection conn = { 0 };
	OperationBuffer opbuf;
	Operation *op;
	slap_callback sc = { 0 };
	pguid_repair_cb_t pcb = { 0 };
	SlapReply rs = { REP_RESULT };
	pguid_mod_t *pmod;
	int nrepaired = 0;

	connection_fake_init2( &conn, &opbuf, ctx, 0 );
	op = &opbuf.ob_op;

	op->o_tag = LDAP_REQ_SEARCH;
	memset( &op->oq_search, 0, sizeof( op->oq_search ) );

	op->o_bd = select_backend( &be->be_nsuffix[ 0 ], 0 );

	op->o_req_dn = op->o_bd->be_suffix[ 0 ];
	op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ];

	op->o_dn = op->o_bd->be_rootdn;
	op->o_ndn = op->o_bd->be_rootndn;

	op->ors_scope = LDAP_SCOPE_SUBORDINATE;
	op->ors_tlimit = SLAP_NO_LIMIT;
	op->ors_slimit = SLAP_NO_LIMIT;
	op->ors_attrs = slap_anlist_no_attrs;

	op->ors_filterstr.bv_len = STRLENOF( "(!(=*))" ) + ad_parentUUID->ad_cname.bv_len;
	op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx );
	snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1,
		"(!(%s=*))", ad_parentUUID->ad_cname.bv_val );

	op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );
	if ( op->ors_filter == NULL ) {
		rs.sr_err = LDAP_OTHER;
		goto done_search;
	}
	
	op->o_callback = ≻
	sc.sc_response = pguid_repair_cb;
	sc.sc_private = &pcb;
	pcb.on = on;

	(void)op->o_bd->bd_info->bi_op_search( op, &rs );

	op->o_tag = LDAP_REQ_MODIFY;
	sc.sc_response = slap_null_cb;
	sc.sc_private = NULL;
	memset( &op->oq_modify, 0, sizeof( req_modify_s ) );

	for ( pmod = pcb.mods; pmod != NULL; ) {
		pguid_mod_t *pnext;

		Modifications *mod;
		SlapReply rs2 = { REP_RESULT };

		mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
		mod->sml_flags = SLAP_MOD_INTERNAL;
		mod->sml_op = LDAP_MOD_REPLACE;
		mod->sml_desc = ad_parentUUID;
		mod->sml_type = ad_parentUUID->ad_cname;
		mod->sml_values = ch_malloc( sizeof( struct berval ) * 2 );
		mod->sml_nvalues = NULL;
		mod->sml_numvals = 1;
		mod->sml_next = NULL;

		ber_dupbv( &mod->sml_values[0], &pmod->pguid );
		BER_BVZERO( &mod->sml_values[1] );

		op->o_req_dn = pmod->ndn;
		op->o_req_ndn = pmod->ndn;

		op->orm_modlist = mod;
		op->o_bd->be_modify( op, &rs2 );
		slap_mods_free( op->orm_modlist, 1 );
		if ( rs2.sr_err == LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_TRACE, "%s: pguid_repair: entry DN=\"%s\" repaired\n",
				op->o_log_prefix, pmod->ndn.bv_val, 0 );
			nrepaired++;

		} else {
			Debug( LDAP_DEBUG_ANY, "%s: pguid_repair: entry DN=\"%s\" repair failed (%d)\n",
				op->o_log_prefix, pmod->ndn.bv_val, rs2.sr_err );
		}

		pnext = pmod->next;
		op->o_tmpfree( pmod, op->o_tmpmemctx );
		pmod = pnext;
	}

done_search:;
	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
	filter_free_x( op, op->ors_filter, 1 );

	Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
		"pguid: repaired=%d\n", nrepaired );

	return rs.sr_err;
}
Exemplo n.º 5
0
Arquivo: init.c Projeto: dago/openldap
int
backsql_db_open(
	BackendDB 	*bd,
	ConfigReply	*cr )
{
	backsql_info 	*bi = (backsql_info*)bd->be_private;
	struct berbuf	bb = BB_NULL;

	Connection	conn = { 0 };
	OperationBuffer opbuf;
	Operation*	op;
	SQLHDBC		dbh = SQL_NULL_HDBC;
	void		*thrctx = ldap_pvt_thread_pool_context();

	Debug( LDAP_DEBUG_TRACE, "==>backsql_db_open(): "
		"testing RDBMS connection\n", 0, 0, 0 );
	if ( bi->sql_dbname == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"datasource name not specified "
			"(use \"dbname\" directive in slapd.conf)\n", 0, 0, 0 );
		return 1;
	}

	if ( bi->sql_concat_func == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"concat func not specified (use \"concat_pattern\" "
			"directive in slapd.conf)\n", 0, 0, 0 );

		if ( backsql_split_pattern( backsql_def_concat_func, 
				&bi->sql_concat_func, 2 ) ) {
			Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
				"unable to parse pattern \"%s\"",
				backsql_def_concat_func, 0, 0 );
			return 1;
		}
	}

	/*
	 * see back-sql.h for default values
	 */
	if ( BER_BVISNULL( &bi->sql_aliasing ) ) {
		ber_str2bv( BACKSQL_ALIASING,
			STRLENOF( BACKSQL_ALIASING ),
			1, &bi->sql_aliasing );
	}

	if ( BER_BVISNULL( &bi->sql_aliasing_quote ) ) {
		ber_str2bv( BACKSQL_ALIASING_QUOTE,
			STRLENOF( BACKSQL_ALIASING_QUOTE ),
			1, &bi->sql_aliasing_quote );
	}

	/*
	 * Prepare cast string as required
	 */
	if ( bi->sql_upper_func.bv_val ) {
		char buf[1024];

		if ( BACKSQL_UPPER_NEEDS_CAST( bi ) ) {
			snprintf( buf, sizeof( buf ), 
				"%s(cast (" /* ? as varchar(%d))) */ , 
				bi->sql_upper_func.bv_val );
			ber_str2bv( buf, 0, 1, &bi->sql_upper_func_open );

			snprintf( buf, sizeof( buf ),
				/* (cast(? */ " as varchar(%d)))",
				BACKSQL_MAX_DN_LEN );
			ber_str2bv( buf, 0, 1, &bi->sql_upper_func_close );

		} else {
			snprintf( buf, sizeof( buf ), "%s(" /* ?) */ ,
					bi->sql_upper_func.bv_val );
			ber_str2bv( buf, 0, 1, &bi->sql_upper_func_open );

			ber_str2bv( /* (? */ ")", 0, 1, &bi->sql_upper_func_close );
		}
	}

	/* normalize filter values only if necessary */
	bi->sql_caseIgnoreMatch = mr_find( "caseIgnoreMatch" );
	assert( bi->sql_caseIgnoreMatch != NULL );

	bi->sql_telephoneNumberMatch = mr_find( "telephoneNumberMatch" );
	assert( bi->sql_telephoneNumberMatch != NULL );

	if ( bi->sql_dbuser == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"user name not specified "
			"(use \"dbuser\" directive in slapd.conf)\n", 0, 0, 0 );
		return 1;
	}
	
	if ( BER_BVISNULL( &bi->sql_subtree_cond ) ) {
		/*
		 * Prepare concat function for subtree search condition
		 */
		struct berval	concat;
		struct berval	values[] = {
			BER_BVC( "'%'" ),
			BER_BVC( "?" ),
			BER_BVNULL
		};
		struct berbuf	bb = BB_NULL;

		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"subtree search SQL condition not specified "
			"(use \"subtree_cond\" directive in slapd.conf); "
			"preparing default\n", 
			0, 0, 0);

		if ( backsql_prepare_pattern( bi->sql_concat_func, values, 
				&concat ) ) {
			Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
				"unable to prepare CONCAT pattern for subtree search",
				0, 0, 0 );
			return 1;
		}
			
		if ( bi->sql_upper_func.bv_val ) {

			/*
			 * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%',?))
			 */

			backsql_strfcat_x( &bb, NULL, "blbbb",
					&bi->sql_upper_func,
					(ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ),
						"(ldap_entries.dn) LIKE ",
					&bi->sql_upper_func_open,
					&concat,
					&bi->sql_upper_func_close );

		} else {

			/*
			 * ldap_entries.dn LIKE CONCAT('%',?)
			 */

			backsql_strfcat_x( &bb, NULL, "lb",
					(ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ),
						"ldap_entries.dn LIKE ",
					&concat );
		}

		ch_free( concat.bv_val );

		bi->sql_subtree_cond = bb.bb_val;
			
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" as default \"subtree_cond\"\n",
			bi->sql_subtree_cond.bv_val, 0, 0 );
	}

	if ( bi->sql_children_cond.bv_val == NULL ) {
		/*
		 * Prepare concat function for children search condition
		 */
		struct berval	concat;
		struct berval	values[] = {
			BER_BVC( "'%,'" ),
			BER_BVC( "?" ),
			BER_BVNULL
		};
		struct berbuf	bb = BB_NULL;

		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"children search SQL condition not specified "
			"(use \"children_cond\" directive in slapd.conf); "
			"preparing default\n", 
			0, 0, 0);

		if ( backsql_prepare_pattern( bi->sql_concat_func, values, 
				&concat ) ) {
			Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
				"unable to prepare CONCAT pattern for children search", 0, 0, 0 );
			return 1;
		}
			
		if ( bi->sql_upper_func.bv_val ) {

			/*
			 * UPPER(ldap_entries.dn) LIKE UPPER(CONCAT('%,',?))
			 */

			backsql_strfcat_x( &bb, NULL, "blbbb",
					&bi->sql_upper_func,
					(ber_len_t)STRLENOF( "(ldap_entries.dn) LIKE " ),
						"(ldap_entries.dn) LIKE ",
					&bi->sql_upper_func_open,
					&concat,
					&bi->sql_upper_func_close );

		} else {

			/*
			 * ldap_entries.dn LIKE CONCAT('%,',?)
			 */

			backsql_strfcat_x( &bb, NULL, "lb",
					(ber_len_t)STRLENOF( "ldap_entries.dn LIKE " ),
						"ldap_entries.dn LIKE ",
					&concat );
		}

		ch_free( concat.bv_val );

		bi->sql_children_cond = bb.bb_val;
			
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" as default \"children_cond\"\n",
			bi->sql_children_cond.bv_val, 0, 0 );
	}

	if ( bi->sql_dn_match_cond.bv_val == NULL ) {
		/*
		 * Prepare concat function for dn match search condition
		 */
		struct berbuf	bb = BB_NULL;

		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"DN match search SQL condition not specified "
			"(use \"dn_match_cond\" directive in slapd.conf); "
			"preparing default\n", 
			0, 0, 0);

		if ( bi->sql_upper_func.bv_val ) {

			/*
			 * UPPER(ldap_entries.dn)=?
			 */

			backsql_strfcat_x( &bb, NULL, "blbcb",
					&bi->sql_upper_func,
					(ber_len_t)STRLENOF( "(ldap_entries.dn)=" ),
						"(ldap_entries.dn)=",
					&bi->sql_upper_func_open,
					'?',
					&bi->sql_upper_func_close );

		} else {

			/*
			 * ldap_entries.dn=?
			 */

			backsql_strfcat_x( &bb, NULL, "l",
					(ber_len_t)STRLENOF( "ldap_entries.dn=?" ),
						"ldap_entries.dn=?" );
		}

		bi->sql_dn_match_cond = bb.bb_val;
			
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" as default \"dn_match_cond\"\n",
			bi->sql_dn_match_cond.bv_val, 0, 0 );
	}

	if ( bi->sql_oc_query == NULL ) {
		if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) {
			bi->sql_oc_query =
				ch_strdup( backsql_def_needs_select_oc_query );

		} else {
			bi->sql_oc_query = ch_strdup( backsql_def_oc_query );
		}

		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"objectclass mapping SQL statement not specified "
			"(use \"oc_query\" directive in slapd.conf)\n", 
			0, 0, 0 );
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" by default\n", bi->sql_oc_query, 0, 0 );
	}
	
	if ( bi->sql_at_query == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"attribute mapping SQL statement not specified "
			"(use \"at_query\" directive in slapd.conf)\n",
			0, 0, 0 );
		Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" by default\n",
			backsql_def_at_query, 0, 0 );
		bi->sql_at_query = ch_strdup( backsql_def_at_query );
	}
	
	if ( bi->sql_insentry_stmt == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"entry insertion SQL statement not specified "
			"(use \"insentry_stmt\" directive in slapd.conf)\n",
			0, 0, 0 );
		Debug(LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" by default\n",
			backsql_def_insentry_stmt, 0, 0 );
		bi->sql_insentry_stmt = ch_strdup( backsql_def_insentry_stmt );
	}
	
	if ( bi->sql_delentry_stmt == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"entry deletion SQL statement not specified "
			"(use \"delentry_stmt\" directive in slapd.conf)\n",
			0, 0, 0 );
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" by default\n",
			backsql_def_delentry_stmt, 0, 0 );
		bi->sql_delentry_stmt = ch_strdup( backsql_def_delentry_stmt );
	}

	if ( bi->sql_renentry_stmt == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"entry deletion SQL statement not specified "
			"(use \"renentry_stmt\" directive in slapd.conf)\n",
			0, 0, 0 );
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" by default\n",
			backsql_def_renentry_stmt, 0, 0 );
		bi->sql_renentry_stmt = ch_strdup( backsql_def_renentry_stmt );
	}

	if ( bi->sql_delobjclasses_stmt == NULL ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"objclasses deletion SQL statement not specified "
			"(use \"delobjclasses_stmt\" directive in slapd.conf)\n",
			0, 0, 0 );
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"setting \"%s\" by default\n",
			backsql_def_delobjclasses_stmt, 0, 0 );
		bi->sql_delobjclasses_stmt = ch_strdup( backsql_def_delobjclasses_stmt );
	}

	/* This should just be to force schema loading */
	connection_fake_init2( &conn, &opbuf, thrctx, 0 );
	op = &opbuf.ob_op;
	op->o_bd = bd;
	if ( backsql_get_db_conn( op, &dbh ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"connection failed, exiting\n", 0, 0, 0 );
		return 1;
	}
	if ( backsql_load_schema_map( bi, dbh ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"schema mapping failed, exiting\n", 0, 0, 0 );
		return 1;
	}
	if ( backsql_free_db_conn( op, dbh ) != SQL_SUCCESS ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"connection free failed\n", 0, 0, 0 );
	}
	if ( !BACKSQL_SCHEMA_LOADED( bi ) ) {
		Debug( LDAP_DEBUG_TRACE, "backsql_db_open(): "
			"test failed, schema map not loaded - exiting\n",
			0, 0, 0 );
		return 1;
	}

	/*
	 * Prepare ID selection query
	 */
	if ( bi->sql_id_query == NULL ) {
		/* no custom id_query provided */
		if ( bi->sql_upper_func.bv_val == NULL ) {
			backsql_strcat_x( &bb, NULL, backsql_id_query, "dn=?", NULL );

		} else {
			if ( BACKSQL_HAS_LDAPINFO_DN_RU( bi ) ) {
				backsql_strcat_x( &bb, NULL, backsql_id_query,
						"dn_ru=?", NULL );
			} else {
				if ( BACKSQL_USE_REVERSE_DN( bi ) ) {
					backsql_strfcat_x( &bb, NULL, "sbl",
							backsql_id_query,
							&bi->sql_upper_func, 
							(ber_len_t)STRLENOF( "(dn)=?" ), "(dn)=?" );
				} else {
					backsql_strfcat_x( &bb, NULL, "sblbcb",
							backsql_id_query,
							&bi->sql_upper_func, 
							(ber_len_t)STRLENOF( "(dn)=" ), "(dn)=",
							&bi->sql_upper_func_open, 
							'?', 
							&bi->sql_upper_func_close );
				}
			}
		}
		bi->sql_id_query = bb.bb_val.bv_val;
	}

	/*
	 * Prepare children count query
	 */
	BER_BVZERO( &bb.bb_val );
	bb.bb_len = 0;
	backsql_strfcat_x( &bb, NULL, "sbsb",
			"SELECT COUNT(distinct subordinates.id) "
			"FROM ldap_entries,ldap_entries ",
			&bi->sql_aliasing, "subordinates "
			"WHERE subordinates.parent=ldap_entries.id AND ",
			&bi->sql_dn_match_cond );
	bi->sql_has_children_query = bb.bb_val.bv_val;
 
	/*
	 * Prepare DN and objectClass aliasing bit of query
	 */
	BER_BVZERO( &bb.bb_val );
	bb.bb_len = 0;
	backsql_strfcat_x( &bb, NULL, "sbbsbsbbsb",
			" ", &bi->sql_aliasing, &bi->sql_aliasing_quote,
			"objectClass", &bi->sql_aliasing_quote,
			",ldap_entries.dn ", &bi->sql_aliasing,
			&bi->sql_aliasing_quote, "dn", &bi->sql_aliasing_quote );
	bi->sql_dn_oc_aliasing = bb.bb_val;
 
	/* should never happen! */
	assert( bd->be_nsuffix != NULL );
	
	if ( BER_BVISNULL( &bd->be_nsuffix[ 1 ] ) ) {
		/* enable if only one suffix is defined */
		bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT;
	}

	bi->sql_flags |= BSQLF_CHECK_SCHEMA;
	
	Debug( LDAP_DEBUG_TRACE, "<==backsql_db_open(): "
		"test succeeded, schema map loaded\n", 0, 0, 0 );
	return 0;
}
Exemplo n.º 6
0
/* count dynamic objects existing in the database at startup */
static int
dds_count( void *ctx, BackendDB *be )
{
	slap_overinst	*on = (slap_overinst *)be->bd_info;
	dds_info_t	*di = (dds_info_t *)on->on_bi.bi_private;

	Connection	conn = { 0 };
	OperationBuffer opbuf;
	Operation	*op;
	slap_callback	sc = { 0 };
	SlapReply	rs = { REP_RESULT };

	int		rc;
	char		*extra = "";

	connection_fake_init2( &conn, &opbuf, ctx, 0 );
	op = &opbuf.ob_op;

	op->o_tag = LDAP_REQ_SEARCH;
	memset( &op->oq_search, 0, sizeof( op->oq_search ) );

	op->o_bd = be;

	op->o_req_dn = op->o_bd->be_suffix[ 0 ];
	op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ];

	op->o_dn = op->o_bd->be_rootdn;
	op->o_ndn = op->o_bd->be_rootndn;

	op->ors_scope = LDAP_SCOPE_SUBTREE;
	op->ors_tlimit = SLAP_NO_LIMIT;
	op->ors_slimit = SLAP_NO_LIMIT;
	op->ors_attrs = slap_anlist_no_attrs;

	op->ors_filterstr.bv_len = STRLENOF( "(objectClass=" ")" )
		+ slap_schema.si_oc_dynamicObject->soc_cname.bv_len;
	op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx );
	snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1,
		"(objectClass=%s)",
		slap_schema.si_oc_dynamicObject->soc_cname.bv_val );

	op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );
	if ( op->ors_filter == NULL ) {
		rs.sr_err = LDAP_OTHER;
		goto done_search;
	}

	op->o_callback = &sc;
	sc.sc_response = dds_count_cb;
	sc.sc_private = &di->di_num_dynamicObjects;
	di->di_num_dynamicObjects = 0;

	op->o_bd->bd_info = (BackendInfo *)on->on_info;
	(void)op->o_bd->bd_info->bi_op_search( op, &rs );
	op->o_bd->bd_info = (BackendInfo *)on;

done_search:;
	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
	filter_free_x( op, op->ors_filter, 1 );

	rc = rs.sr_err;
	switch ( rs.sr_err ) {
	case LDAP_SUCCESS:
		Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
			"DDS non-expired=%d\n",
			di->di_num_dynamicObjects );
		break;

	case LDAP_NO_SUCH_OBJECT:
		/* (ITS#5267) database not created yet? */
		rs.sr_err = LDAP_SUCCESS;
		extra = " (ignored)";
		/* fallthru */

	default:
		Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
			"DDS non-expired objects lookup failed err=%d%s\n",
			rc, extra );
		break;
	}

	return rs.sr_err;
}
Exemplo n.º 7
0
static int
dds_expire( void *ctx, dds_info_t *di )
{
	Connection	conn = { 0 };
	OperationBuffer opbuf;
	Operation	*op;
	slap_callback	sc = { 0 };
	dds_cb_t	dc = { 0 };
	dds_expire_t	*de = NULL, **dep;
	SlapReply	rs = { REP_RESULT };

	time_t		expire;
	char		tsbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
	struct berval	ts;

	int		ndeletes, ntotdeletes;

	int		rc;
	char		*extra = "";

	connection_fake_init2( &conn, &opbuf, ctx, 0 );
	op = &opbuf.ob_op;

	op->o_tag = LDAP_REQ_SEARCH;
	memset( &op->oq_search, 0, sizeof( op->oq_search ) );

	op->o_bd = select_backend( &di->di_nsuffix[ 0 ], 0 );

	op->o_req_dn = op->o_bd->be_suffix[ 0 ];
	op->o_req_ndn = op->o_bd->be_nsuffix[ 0 ];

	op->o_dn = op->o_bd->be_rootdn;
	op->o_ndn = op->o_bd->be_rootndn;

	op->ors_scope = LDAP_SCOPE_SUBTREE;
	op->ors_tlimit = DDS_INTERVAL( di )/2 + 1;
	op->ors_slimit = SLAP_NO_LIMIT;
	op->ors_attrs = slap_anlist_no_attrs;

	expire = slap_get_time() - di->di_tolerance;
	ts.bv_val = tsbuf;
	ts.bv_len = sizeof( tsbuf );
	slap_timestamp( &expire, &ts );

	op->ors_filterstr.bv_len = STRLENOF( "(&(objectClass=" ")(" "<=" "))" )
		+ slap_schema.si_oc_dynamicObject->soc_cname.bv_len
		+ ad_entryExpireTimestamp->ad_cname.bv_len
		+ ts.bv_len;
	op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx );
	snprintf( op->ors_filterstr.bv_val, op->ors_filterstr.bv_len + 1,
		"(&(objectClass=%s)(%s<=%s))",
		slap_schema.si_oc_dynamicObject->soc_cname.bv_val,
		ad_entryExpireTimestamp->ad_cname.bv_val, ts.bv_val );

	op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );
	if ( op->ors_filter == NULL ) {
		rs.sr_err = LDAP_OTHER;
		goto done_search;
	}

	op->o_callback = &sc;
	sc.sc_response = dds_expire_cb;
	sc.sc_private = &dc;

	(void)op->o_bd->bd_info->bi_op_search( op, &rs );

done_search:;
	op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
	filter_free_x( op, op->ors_filter, 1 );

	rc = rs.sr_err;
	switch ( rs.sr_err ) {
	case LDAP_SUCCESS:
		break;

	case LDAP_NO_SUCH_OBJECT:
		/* (ITS#5267) database not created yet? */
		rs.sr_err = LDAP_SUCCESS;
		extra = " (ignored)";
		/* fallthru */

	default:
		Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_ERR,
			"DDS expired objects lookup failed err=%d%s\n",
			rc, extra );
		goto done;
	}

	op->o_tag = LDAP_REQ_DELETE;
	op->o_callback = &sc;
	sc.sc_response = slap_null_cb;
	sc.sc_private = NULL;

	slap_biglock_acquire(op->o_bd);
	for ( ntotdeletes = 0, ndeletes = 1; dc.dc_ndnlist != NULL  && ndeletes > 0; ) {
		ndeletes = 0;

		for ( dep = &dc.dc_ndnlist; *dep != NULL; ) {
			de = *dep;

			op->o_req_dn = de->de_ndn;
			op->o_req_ndn = de->de_ndn;
			(void)op->o_bd->bd_info->bi_op_delete( op, &rs );
			switch ( rs.sr_err ) {
			case LDAP_SUCCESS:
				Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
					"DDS dn=\"%s\" expired.\n",
					de->de_ndn.bv_val );
				ndeletes++;
				break;

			case LDAP_NOT_ALLOWED_ON_NONLEAF:
				Log1( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE,
					"DDS dn=\"%s\" is non-leaf; "
					"deferring.\n",
					de->de_ndn.bv_val );
				dep = &de->de_next;
				de = NULL;
				break;

			default:
				Log2( LDAP_DEBUG_ANY, LDAP_LEVEL_NOTICE,
					"DDS dn=\"%s\" err=%d; "
					"deferring.\n",
					de->de_ndn.bv_val, rs.sr_err );
				break;
			}

			if ( de != NULL ) {
				*dep = de->de_next;
				op->o_tmpfree( de, op->o_tmpmemctx );
			}
		}

		ntotdeletes += ndeletes;
	}
	slap_biglock_release(op->o_bd);

	rs.sr_err = LDAP_SUCCESS;

	Log1( LDAP_DEBUG_STATS, LDAP_LEVEL_INFO,
		"DDS expired=%d\n", ntotdeletes );

done:;
	return rs.sr_err;
}