예제 #1
0
static void
asyncmeta_search_last_result(a_metaconn_t *mc, bm_context_t *bc, int candidate, int sres)
{
	a_metainfo_t	*mi = mc->mc_info;
	Operation *op = bc->op;
	SlapReply *rs = &bc->rs;
	int	   i;
	SlapReply *candidates = bc->candidates;
	char *matched = NULL;

	if ( bc->candidate_match > 0 ) {
		struct berval	pmatched = BER_BVNULL;

		/* we use the first one */
		for ( i = 0; i < mi->mi_ntargets; i++ ) {
			if ( META_IS_CANDIDATE( &candidates[ i ] )
					&& candidates[ i ].sr_matched != NULL )
			{
				struct berval	bv, pbv;
				int		rc;

				/* if we got success, and this target
				 * returned noSuchObject, and its suffix
				 * is a superior of the searchBase,
				 * ignore the matchedDN */
				if ( sres == LDAP_SUCCESS
					&& candidates[ i ].sr_err == LDAP_NO_SUCH_OBJECT
					&& op->o_req_ndn.bv_len > mi->mi_targets[ i ]->mt_nsuffix.bv_len )
				{
					free( (char *)candidates[ i ].sr_matched );
					candidates[ i ].sr_matched = NULL;
					continue;
				}

				ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv );
				rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx );

				if ( rc == LDAP_SUCCESS ) {

					/* NOTE: if they all are superiors
					 * of the baseDN, the shorter is also
					 * superior of the longer... */
					if ( pbv.bv_len > pmatched.bv_len ) {
						if ( !BER_BVISNULL( &pmatched ) ) {
							op->o_tmpfree( pmatched.bv_val, op->o_tmpmemctx );
						}
						pmatched = pbv;

					} else {
						op->o_tmpfree( pbv.bv_val, op->o_tmpmemctx );
					}
				}

				if ( candidates[ i ].sr_matched != NULL ) {
					free( (char *)candidates[ i ].sr_matched );
					candidates[ i ].sr_matched = NULL;
				}
			}
		}

		if ( !BER_BVISNULL( &pmatched ) ) {
			matched = pmatched.bv_val;
		}

	} else if ( sres == LDAP_NO_SUCH_OBJECT ) {
		matched = mi->mi_suffix.bv_val;
	}

	/*
	 * In case we returned at least one entry, we return LDAP_SUCCESS
	 * otherwise, the latter error code we got
	 */

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

		if ( META_BACK_ONERR_REPORT( mi ) ) {
			/*
			 * Report errors, if any
			 *
			 * FIXME: we should handle error codes and return the more
			 * important/reasonable
			 */
			for ( i = 0; i < mi->mi_ntargets; i++ ) {
				if ( !META_IS_CANDIDATE( &candidates[ i ] ) ) {
					continue;
				}

				if ( candidates[ i ].sr_err != LDAP_SUCCESS
					&& candidates[ i ].sr_err != LDAP_NO_SUCH_OBJECT )
				{
					sres = candidates[ i ].sr_err;
					break;
				}
			}
		}
	}
	Debug( LDAP_DEBUG_TRACE,
	       "%s asyncmeta_search_last_result(\"%d\"): "
	       ".\n",
	       op->o_log_prefix, candidate );
	rs->sr_err = sres;
	rs->sr_matched = ( sres == LDAP_SUCCESS ? NULL : matched );
	rs->sr_text =  ( sres == LDAP_SUCCESS ? NULL : candidates[candidate].sr_text );
	rs->sr_ref = ( sres == LDAP_REFERRAL ? rs->sr_v2ref : NULL );
	asyncmeta_send_ldap_result(bc, op, rs);
	rs->sr_text = NULL;
	rs->sr_matched = NULL;
	rs->sr_ref = NULL;
}
예제 #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.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;
}
예제 #3
0
파일: slapi_ops.c 프로젝트: dago/openldap
void
slapi_int_connection_done_pb( Slapi_PBlock *pb )
{
	Connection		*conn;
	Operation		*op;

	PBLOCK_ASSERT_INTOP( pb, 0 );

	conn = pb->pb_conn;
	op = pb->pb_op;

	/* free allocated DNs */
	if ( !BER_BVISNULL( &op->o_dn ) )
		op->o_tmpfree( op->o_dn.bv_val, op->o_tmpmemctx );
	if ( !BER_BVISNULL( &op->o_ndn ) )
		op->o_tmpfree( op->o_ndn.bv_val, op->o_tmpmemctx );

	if ( !BER_BVISNULL( &op->o_req_dn ) )
		op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	if ( !BER_BVISNULL( &op->o_req_ndn ) )
		op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );

	switch ( op->o_tag ) {
	case LDAP_REQ_MODRDN:
		if ( !BER_BVISNULL( &op->orr_newrdn ))
			op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );
		if ( !BER_BVISNULL( &op->orr_nnewrdn ))
			op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );
		if ( op->orr_newSup != NULL ) {
			assert( !BER_BVISNULL( op->orr_newSup ) );
			op->o_tmpfree( op->orr_newSup->bv_val, op->o_tmpmemctx );
			op->o_tmpfree( op->orr_newSup, op->o_tmpmemctx );
		}
		if ( op->orr_nnewSup != NULL ) {
			assert( !BER_BVISNULL( op->orr_nnewSup ) );
			op->o_tmpfree( op->orr_nnewSup->bv_val, op->o_tmpmemctx );
			op->o_tmpfree( op->orr_nnewSup, op->o_tmpmemctx );
		}
		slap_mods_free( op->orr_modlist, 1 );
		break;
	case LDAP_REQ_ADD:
		slap_mods_free( op->ora_modlist, 0 );
		break;
	case LDAP_REQ_MODIFY:
		slap_mods_free( op->orm_modlist, 1 );
		break;
	case LDAP_REQ_SEARCH:
		if ( op->ors_attrs != NULL ) {
			op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
			op->ors_attrs = NULL;
		}
		break;
	default:
		break;
	}

	slapi_ch_free_string( &conn->c_authmech.bv_val );
	slapi_ch_free_string( &conn->c_dn.bv_val );
	slapi_ch_free_string( &conn->c_ndn.bv_val );
	slapi_ch_free_string( &conn->c_peer_domain.bv_val );
	slapi_ch_free_string( &conn->c_peer_name.bv_val );

	if ( conn->c_sb != NULL ) {
		ber_sockbuf_free( conn->c_sb );
	}

	slapi_int_free_object_extensions( SLAPI_X_EXT_OPERATION, op );
	slapi_int_free_object_extensions( SLAPI_X_EXT_CONNECTION, conn );

	slapi_ch_free( (void **)&pb->pb_op->o_callback );
	slapi_ch_free( (void **)&pb->pb_op );
	slapi_ch_free( (void **)&pb->pb_conn );
	slapi_ch_free( (void **)&pb->pb_rs );
}
예제 #4
0
int asyncmeta_handle_common_result(LDAPMessage *msg, a_metaconn_t *mc, bm_context_t *bc, int candidate)
{
	a_metainfo_t	*mi;
	a_metatarget_t	*mt;
	a_metasingleconn_t *msc;
	const char	*save_text = NULL,
		*save_matched = NULL;
	BerVarray	save_ref = NULL;
	LDAPControl	**save_ctrls = NULL;
	void		*matched_ctx = NULL;

	char		*matched = NULL;
	char		*text = NULL;
	char		**refs = NULL;
	LDAPControl	**ctrls = NULL;
	Operation *op;
	SlapReply *rs;
	int		rc;

	mi = mc->mc_info;
	mt = mi->mi_targets[ candidate ];
	msc = &mc->mc_conns[ candidate ];

	op = bc->op;
	rs = &bc->rs;
	save_text = rs->sr_text,
	save_matched = rs->sr_matched;
	save_ref = rs->sr_ref;
	save_ctrls = rs->sr_ctrls;
	rs->sr_text = NULL;
	rs->sr_matched = NULL;
	rs->sr_ref = NULL;
	rs->sr_ctrls = NULL;

	/* only touch when activity actually took place... */
	if ( mi->mi_idle_timeout != 0 ) {
		asyncmeta_set_msc_time(msc);
	}

	rc = ldap_parse_result( msc->msc_ldr, msg, &rs->sr_err,
				&matched, &text, &refs, &ctrls, 0 );

	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 asyncmeta_handle_common_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 asyncmeta_handle_common_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;
	}

	/* 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 ) ) {
		asyncmeta_quarantine( op, mi, rs, candidate );
	}

	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 || rs->sr_err == LDAP_SERVER_DOWN ) {
		if ( rs->sr_text == NULL ) {
				rs->sr_text = "Target is unavailable";
			}
	}

	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	asyncmeta_drop_bc( mc, bc);
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );

	if ( op->o_conn ) {
		asyncmeta_send_ldap_result(bc, 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;
	rc = (LDAP_ERR_OK( rs->sr_err ) ? LDAP_SUCCESS : rs->sr_err);
	ldap_pvt_thread_mutex_lock( &mc->mc_om_mutex );
	asyncmeta_clear_bm_context(bc);
	ldap_pvt_thread_mutex_unlock( &mc->mc_om_mutex );
	return rc;
}
예제 #5
0
int
slapauth( int argc, char **argv )
{
    int			rc = EXIT_SUCCESS;
    const char		*progname = "slapauth";
    Connection		conn = {0};
    OperationBuffer	opbuf;
    Operation		*op;

    slap_tool_init( progname, SLAPAUTH, argc, argv );

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

    connection_fake_init( &conn, &opbuf, &conn );
    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;
}
예제 #6
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;
}
예제 #7
0
/* 
** Do a search for all the groups in the
** database, and add them to out internal list.
*/
static int
autogroup_db_open(
	BackendDB	*be,
	ConfigReply	*cr )
{
	slap_overinst			*on = (slap_overinst *) be->bd_info;
	autogroup_info_t		*agi = on->on_bi.bi_private;
	autogroup_def_t		*agd;
	autogroup_sc_t		ags;
	Operation		*op;
	SlapReply		rs = { REP_RESULT };
	slap_callback		cb = { 0 };

	void				*thrctx = ldap_pvt_thread_pool_context();
	Connection			conn = { 0 };
	OperationBuffer 	opbuf;

	Debug( LDAP_DEBUG_TRACE, "==> autogroup_db_open\n", 0, 0, 0);

	if ( agi == NULL ) {
		return 0;
	}

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

	op->ors_attrsonly = 0;
	op->o_tag = LDAP_REQ_SEARCH;
	op->o_dn = be->be_rootdn;
	op->o_ndn = be->be_rootndn;

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

	op->ors_scope = LDAP_SCOPE_SUBTREE;
	op->ors_deref = LDAP_DEREF_NEVER;
	op->ors_limit = NULL;
	op->ors_tlimit = SLAP_NO_LIMIT;
	op->ors_slimit = SLAP_NO_LIMIT;
	op->ors_attrs =  slap_anlist_no_attrs;

	op->o_bd = be;
	op->o_bd->bd_info = (BackendInfo *)on->on_info;

	ags.ags_info = agi;
	cb.sc_private = &ags;
	cb.sc_response = autogroup_group_add_cb;
	cb.sc_cleanup = NULL;
	cb.sc_next = NULL;

	op->o_callback = &cb;

	for (agd = agi->agi_def ; agd ; agd = agd->agd_next) {

		autogroup_build_def_filter(agd, op);

		ags.ags_def = agd;

		op->o_bd->be_search( op, &rs );

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

	return 0;
}
예제 #8
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.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;
}
예제 #9
0
파일: sasl.c 프로젝트: MPlatform/mdb
static int
#else
static void
#endif
slap_auxprop_lookup(
	void *glob_context,
	sasl_server_params_t *sparams,
	unsigned flags,
	const char *user,
	unsigned ulen)
{
	OperationBuffer opbuf = {{ NULL }};
	Operation *op = (Operation *)&opbuf;
	int i, doit = 0;
	Connection *conn = NULL;
	lookup_info sl;
	int rc = LDAP_SUCCESS;
#ifdef SLAP_AUXPROP_DONTUSECOPY
	int dontUseCopy = 0;
	BackendDB *dontUseCopy_bd = NULL;
#endif /* SLAP_AUXPROP_DONTUSECOPY */

	sl.list = sparams->utils->prop_get( sparams->propctx );
	sl.sparams = sparams;
	sl.flags = flags;

	/* Find our DN and conn first */
	for( i = 0; sl.list[i].name; i++ ) {
		if ( sl.list[i].name[0] == '*' ) {
			if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) {
				if ( sl.list[i].values && sl.list[i].values[0] )
					AC_MEMCPY( &conn, sl.list[i].values[0], sizeof( conn ) );
				continue;
			}
			if ( flags & SASL_AUXPROP_AUTHZID ) {
				if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZLEN] )) {
					if ( sl.list[i].values && sl.list[i].values[0] )
						AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0],
							sizeof( op->o_req_ndn.bv_len ) );
				} else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZ] )) {
					if ( sl.list[i].values )
						op->o_req_ndn.bv_val = (char *)sl.list[i].values[0];
					break;
				}
			}

			if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHCLEN] )) {
				if ( sl.list[i].values && sl.list[i].values[0] )
					AC_MEMCPY( &op->o_req_ndn.bv_len, sl.list[i].values[0],
						sizeof( op->o_req_ndn.bv_len ) );
			} else if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
				if ( sl.list[i].values ) {
					op->o_req_ndn.bv_val = (char *)sl.list[i].values[0];
					if ( !(flags & SASL_AUXPROP_AUTHZID) )
						break;
				}
			}
#ifdef SLAP_AUXPROP_DONTUSECOPY
			if ( slap_dontUseCopy_propnames != NULL ) {
				int j;
				struct berval bv;
				ber_str2bv( &sl.list[i].name[1], 0, 1, &bv );
				for ( j = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ j ]); j++ ) {
					if ( bvmatch( &bv, &slap_dontUseCopy_propnames[ j ] ) ) {
						dontUseCopy = 1;
						break;
					}
				}
			}
#endif /* SLAP_AUXPROP_DONTUSECOPY */
		}
	}

	/* Now see what else needs to be fetched */
	for( i = 0; sl.list[i].name; i++ ) {
		const char *name = sl.list[i].name;

		if ( name[0] == '*' ) {
			if ( flags & SASL_AUXPROP_AUTHZID ) continue;
			/* Skip our private properties */
			if ( !strcmp( name, slap_propnames[0] )) {
				i += SLAP_SASL_PROP_COUNT - 1;
				continue;
			}
			name++;
		} else if ( !(flags & SASL_AUXPROP_AUTHZID ) )
			continue;

		if ( sl.list[i].values ) {
			if ( !(flags & SASL_AUXPROP_OVERRIDE) ) continue;
		}
		doit = 1;
		break;
	}

	if (doit) {
		slap_callback cb = { NULL, sasl_ap_lookup, NULL, NULL };

		cb.sc_private = &sl;

		op->o_bd = select_backend( &op->o_req_ndn, 1 );

		if ( op->o_bd ) {
			/* For rootdn, see if we can use the rootpw */
			if ( be_isroot_dn( op->o_bd, &op->o_req_ndn ) &&
				!BER_BVISEMPTY( &op->o_bd->be_rootpw )) {
				struct berval cbv = BER_BVNULL;

				/* If there's a recognized scheme, see if it's CLEARTEXT */
				if ( lutil_passwd_scheme( op->o_bd->be_rootpw.bv_val )) {
					if ( !strncasecmp( op->o_bd->be_rootpw.bv_val,
						sc_cleartext.bv_val, sc_cleartext.bv_len )) {

						/* If it's CLEARTEXT, skip past scheme spec */
						cbv.bv_len = op->o_bd->be_rootpw.bv_len -
							sc_cleartext.bv_len;
						if ( cbv.bv_len ) {
							cbv.bv_val = op->o_bd->be_rootpw.bv_val +
								sc_cleartext.bv_len;
						}
					}
				/* No scheme, use the whole value */
				} else {
					cbv = op->o_bd->be_rootpw;
				}
				if ( !BER_BVISEMPTY( &cbv )) {
					for( i = 0; sl.list[i].name; i++ ) {
						const char *name = sl.list[i].name;

						if ( name[0] == '*' ) {
							if ( flags & SASL_AUXPROP_AUTHZID ) continue;
								name++;
						} else if ( !(flags & SASL_AUXPROP_AUTHZID ) )
							continue;

						if ( !strcasecmp(name,"userPassword") ) {
							sl.sparams->utils->prop_set( sl.sparams->propctx,
								sl.list[i].name, cbv.bv_val, cbv.bv_len );
							break;
						}
					}
				}
			}

#ifdef SLAP_AUXPROP_DONTUSECOPY
			if ( SLAP_SHADOW( op->o_bd ) && dontUseCopy ) {
				dontUseCopy_bd = op->o_bd;
				op->o_bd = frontendDB;
			}

retry_dontUseCopy:;
#endif /* SLAP_AUXPROP_DONTUSECOPY */

			if ( op->o_bd->be_search ) {
				SlapReply rs = {REP_RESULT};
#ifdef SLAP_AUXPROP_DONTUSECOPY
				LDAPControl **save_ctrls = NULL, c;
				int save_dontUseCopy;
#endif /* SLAP_AUXPROP_DONTUSECOPY */

				op->o_hdr = conn->c_sasl_bindop->o_hdr;
				op->o_controls = opbuf.ob_controls;
				op->o_tag = LDAP_REQ_SEARCH;
				op->o_dn = conn->c_ndn;
				op->o_ndn = conn->c_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->ors_scope = LDAP_SCOPE_BASE;
				op->ors_deref = LDAP_DEREF_NEVER;
				op->ors_tlimit = SLAP_NO_LIMIT;
				op->ors_slimit = 1;
				op->ors_filter = &generic_filter;
				op->ors_filterstr = generic_filterstr;
				op->o_authz = conn->c_authz;
				/* FIXME: we want all attributes, right? */
				op->ors_attrs = NULL;

#ifdef SLAP_AUXPROP_DONTUSECOPY
				if ( dontUseCopy ) {
					save_dontUseCopy = op->o_dontUseCopy;
					if ( !op->o_dontUseCopy ) {
						int cnt = 0;
						save_ctrls = op->o_ctrls;
						if ( op->o_ctrls ) {
							for ( ; op->o_ctrls[ cnt ]; cnt++ )
								;
						}
						op->o_ctrls = op->o_tmpcalloc( sizeof(LDAPControl *), cnt + 2, op->o_tmpmemctx );
						if ( cnt ) {
							for ( cnt = 0; save_ctrls[ cnt ]; cnt++ ) {
								op->o_ctrls[ cnt ] = save_ctrls[ cnt ];
							}
						}
						c.ldctl_oid = LDAP_CONTROL_DONTUSECOPY;
						c.ldctl_iscritical = 1;
						BER_BVZERO( &c.ldctl_value );
						op->o_ctrls[ cnt ] = &c;
					}
					op->o_dontUseCopy = SLAP_CONTROL_CRITICAL;
				}
#endif /* SLAP_AUXPROP_DONTUSECOPY */

				rc = op->o_bd->be_search( op, &rs );

#ifdef SLAP_AUXPROP_DONTUSECOPY
				if ( dontUseCopy ) {
					if ( save_ctrls != op->o_ctrls ) {
						op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx );
						op->o_ctrls = save_ctrls;
						op->o_dontUseCopy = save_dontUseCopy;
					}

					if ( rs.sr_err == LDAP_UNAVAILABLE && slap_dontUseCopy_ignore )
					{
						op->o_bd = dontUseCopy_bd;
						dontUseCopy = 0;
						goto retry_dontUseCopy;
					}
				}
#endif /* SLAP_AUXPROP_DONTUSECOPY */
			}
		}
	}
#if SASL_VERSION_FULL >= 0x020118
	return rc != LDAP_SUCCESS ? SASL_FAIL : SASL_OK;
#endif
}
예제 #10
0
파일: dds.c 프로젝트: Smilefant/ReOpenLDAP
/* 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;
}
예제 #11
0
파일: dds.c 프로젝트: Smilefant/ReOpenLDAP
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;
}