コード例 #1
0
ファイル: usn.c プロジェクト: benegon/openldap
static int
usn_db_close(
	BackendDB *be,
	ConfigReply *cr
)
{
	slap_overinst	*on = (slap_overinst *)be->bd_info;
	usn_info_t	*ui = on->on_bi.bi_private;
	Connection conn = {0};
	OperationBuffer opbuf;
	Operation *op;
	SlapReply rs = {REP_RESULT};
	void *thrctx;

	Modifications mod;
	slap_callback cb = {0};
	char intbuf[64];
	struct berval bv[2];

	thrctx = ldap_pvt_thread_pool_context();
	connection_fake_init( &conn, &opbuf, thrctx );
	op = &opbuf.ob_op;
	op->o_bd = be;
	BER_BVZERO( &bv[1] );
	bv[0].bv_len = snprintf( intbuf, sizeof(intbuf), "%d", ui->ui_current );
	bv[0].bv_val = intbuf;
	mod.sml_numvals = 1;
	mod.sml_values = bv;
	mod.sml_nvalues = NULL;
	mod.sml_desc = ad_usnChanged;
	mod.sml_op = LDAP_MOD_REPLACE;
	mod.sml_flags = 0;
	mod.sml_next = NULL;

	cb.sc_response = slap_null_cb;
	op->o_tag = LDAP_REQ_MODIFY;
	op->o_callback = &cb;
	op->orm_modlist = &mod;
	op->orm_no_opattrs = 1;
	op->o_dn = be->be_rootdn;
	op->o_ndn = be->be_rootndn;
	op->o_req_dn = op->o_bd->be_suffix[0];
	op->o_req_ndn = op->o_bd->be_nsuffix[0];
	op->o_bd->bd_info = on->on_info->oi_orig;
	op->o_managedsait = SLAP_CONTROL_NONCRITICAL;
	op->o_no_schema_check = 1;
	op->o_bd->be_modify( op, &rs );
	if ( mod.sml_next != NULL ) {
		slap_mods_free( mod.sml_next, 1 );
	}
	return 0;
}
コード例 #2
0
ファイル: nops.c プロジェクト: gosudream/netbsd-src
static void
nops_rm_mod( Modifications **mods, Modifications *mod ) {
	Modifications *next, *m;

	next = mod->sml_next;
	if (*mods == mod) {
		*mods = next;
	} else {
		Modifications *m;

		for (m = *mods; m; m = m->sml_next) {
			if (m->sml_next == mod) {
				m->sml_next = next;
				break;
			}
		}
	}

	mod->sml_next = NULL;
	slap_mods_free(mod, 1);

	return;
}
コード例 #3
0
ファイル: slapi_pblock.c プロジェクト: cptaffe/openldap
static int 
pblock_set( Slapi_PBlock *pb, int param, void *value ) 
{
	int rc = PBLOCK_SUCCESS;

	pblock_lock( pb );	

	switch ( param ) {
	case SLAPI_OPERATION:
		pb->pb_op = (Operation *)value;
		break;
	case SLAPI_OPINITIATED_TIME:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_time = *((long *)value);
		break;
	case SLAPI_OPERATION_ID:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_opid = *((long *)value);
		break;
	case SLAPI_OPERATION_TYPE:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_tag = *((ber_tag_t *)value);
		break;
	case SLAPI_OPERATION_MSGID:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_msgid = *((long *)value);
		break;
	case SLAPI_X_OPERATION_DELETE_GLUE_PARENT:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_delete_glue_parent = *((int *)value);
		break;
	case SLAPI_X_OPERATION_NO_SCHEMA_CHECK:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_no_schema_check = *((int *)value);
		break;
	case SLAPI_X_OPERATION_NO_SUBORDINATE_GLUE:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_no_subordinate_glue = *((int *)value);
		break;
	case SLAPI_REQCONTROLS:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_ctrls = (LDAPControl **)value;
		break;
	case SLAPI_RESCONTROLS: {
		LDAPControl **ctrls = NULL;

		pblock_get_default( pb, param, (void **)&ctrls );
		if ( ctrls != NULL ) {
			/* free old ones first */
			ldap_controls_free( ctrls );
		}
		rc = pblock_set_default( pb, param, value );
		break;
	}
	case SLAPI_ADD_RESCONTROL:
		PBLOCK_ASSERT_OP( pb, 0 );
		rc = pblock_add_control( pb, (LDAPControl *)value );
		break;
	case SLAPI_REQUESTOR_DN:
		PBLOCK_ASSERT_OP( pb, 0 );
		rc = pblock_set_dn( value, &pb->pb_op->o_dn, &pb->pb_op->o_ndn, pb->pb_op->o_tmpmemctx );
		break;
	case SLAPI_MANAGEDSAIT:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_managedsait = *((int *)value);
		break;
	case SLAPI_X_RELAX:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_relax = *((int *)value);
		break;
	case SLAPI_BACKEND:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_op->o_bd = (BackendDB *)value;
		break;
	case SLAPI_CONNECTION:
		pb->pb_conn = (Connection *)value;
		break;
	case SLAPI_X_CONN_SSF:
		PBLOCK_ASSERT_CONN( pb );
		PBLOCK_LOCK_CONN( pb );
		pb->pb_conn->c_ssf = (slap_ssf_t)(long)value;
		PBLOCK_UNLOCK_CONN( pb );
		break;
	case SLAPI_X_CONN_SASL_CONTEXT:
		PBLOCK_ASSERT_CONN( pb );
		PBLOCK_LOCK_CONN( pb );
		pb->pb_conn->c_sasl_authctx = value;
		PBLOCK_UNLOCK_CONN( pb );
		break;
	case SLAPI_TARGET_DN:
		PBLOCK_ASSERT_OP( pb, 0 );
		rc = pblock_set_dn( value, &pb->pb_op->o_req_dn, &pb->pb_op->o_req_ndn, pb->pb_op->o_tmpmemctx );
		break;
	case SLAPI_CONN_ID:
		PBLOCK_ASSERT_CONN( pb );
		PBLOCK_LOCK_CONN( pb );
		pb->pb_conn->c_connid = *((long *)value);
		PBLOCK_UNLOCK_CONN( pb );
		break;
	case SLAPI_CONN_DN:
		PBLOCK_ASSERT_CONN( pb );
		PBLOCK_LOCK_CONN( pb );
		rc = pblock_set_dn( value, &pb->pb_conn->c_dn, &pb->pb_conn->c_ndn, NULL );
		PBLOCK_UNLOCK_CONN( pb );
		break;
	case SLAPI_RESULT_CODE:
	case SLAPI_PLUGIN_INTOP_RESULT:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_rs->sr_err = *((int *)value);
		break;
	case SLAPI_RESULT_TEXT:
		PBLOCK_ASSERT_OP( pb, 0 );
		snprintf( pb->pb_textbuf, sizeof( pb->pb_textbuf ), "%s", (char *)value );
		pb->pb_rs->sr_text = pb->pb_textbuf;
		break;
	case SLAPI_RESULT_MATCHED:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_rs->sr_matched = (char *)value; /* XXX should dup? */
		break;
	case SLAPI_ADD_ENTRY:
		PBLOCK_ASSERT_OP( pb, 0 );
		if ( pb->pb_op->o_tag == LDAP_REQ_ADD )
			pb->pb_op->ora_e = (Slapi_Entry *)value;
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_MODIFY_MODS: {
		Modifications **mlp;
		Modifications *newmods;

		PBLOCK_ASSERT_OP( pb, 0 );
		rc = pblock_set_default( pb, param, value );
		if ( rc != PBLOCK_SUCCESS ) {
			break;
		}

		if ( pb->pb_op->o_tag == LDAP_REQ_MODIFY ) {
			mlp = &pb->pb_op->orm_modlist;
		} else if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
			mlp = &pb->pb_op->ora_modlist;
		} else if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
			mlp = &pb->pb_op->orr_modlist;
		} else {
			break;
		}

		newmods = slapi_int_ldapmods2modifications( pb->pb_op, (LDAPMod **)value );
		if ( newmods != NULL ) {
			slap_mods_free( *mlp, 1 );
			*mlp = newmods;
		}
		break;
	}
	case SLAPI_MODRDN_NEWRDN:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );
		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
			rc = pblock_set_dn( value, &pb->pb_op->orr_newrdn, &pb->pb_op->orr_nnewrdn, pb->pb_op->o_tmpmemctx );
			if ( rc == LDAP_SUCCESS )
				rc = rdn_validate( &pb->pb_op->orr_nnewrdn );
		} else {
			rc = PBLOCK_ERROR;
		}
		break;
	case SLAPI_MODRDN_NEWSUPERIOR:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );
		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN ) {
			if ( value == NULL ) {
				if ( pb->pb_op->orr_newSup != NULL ) {
					pb->pb_op->o_tmpfree( pb->pb_op->orr_newSup, pb->pb_op->o_tmpmemctx );
					BER_BVZERO( pb->pb_op->orr_newSup );
					pb->pb_op->orr_newSup = NULL;
				}
				if ( pb->pb_op->orr_newSup != NULL ) {
					pb->pb_op->o_tmpfree( pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
					BER_BVZERO( pb->pb_op->orr_nnewSup );
					pb->pb_op->orr_nnewSup = NULL;
				}
			} else {
				if ( pb->pb_op->orr_newSup == NULL ) {
					pb->pb_op->orr_newSup = (struct berval *)pb->pb_op->o_tmpalloc(
						sizeof(struct berval), pb->pb_op->o_tmpmemctx );
					BER_BVZERO( pb->pb_op->orr_newSup );
				}
				if ( pb->pb_op->orr_nnewSup == NULL ) {
					pb->pb_op->orr_nnewSup = (struct berval *)pb->pb_op->o_tmpalloc(
						sizeof(struct berval), pb->pb_op->o_tmpmemctx );
					BER_BVZERO( pb->pb_op->orr_nnewSup );
				}
				rc = pblock_set_dn( value, pb->pb_op->orr_newSup, pb->pb_op->orr_nnewSup, pb->pb_op->o_tmpmemctx );
			}
		} else {
			rc = PBLOCK_ERROR;
		}
		break;
	case SLAPI_MODRDN_DELOLDRDN:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );
		if ( pb->pb_op->o_tag == LDAP_REQ_MODRDN )
			pb->pb_op->orr_deleteoldrdn = *((int *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_SEARCH_SCOPE: {
		int scope = *((int *)value);

		PBLOCK_ASSERT_OP( pb, 0 );
		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
			switch ( *((int *)value) ) {
			case LDAP_SCOPE_BASE:
			case LDAP_SCOPE_ONELEVEL:
			case LDAP_SCOPE_SUBTREE:
			case LDAP_SCOPE_SUBORDINATE:
				pb->pb_op->ors_scope = scope;
				break;
			default:
				rc = PBLOCK_ERROR;
				break;
			}
		} else {
			rc = PBLOCK_ERROR;
		}
		break;
	}
	case SLAPI_SEARCH_DEREF:
		PBLOCK_ASSERT_OP( pb, 0 );
		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
			pb->pb_op->ors_deref = *((int *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_SEARCH_SIZELIMIT:
		PBLOCK_ASSERT_OP( pb, 0 );
		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
			pb->pb_op->ors_slimit = *((int *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_SEARCH_TIMELIMIT:
		PBLOCK_ASSERT_OP( pb, 0 );
		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
			pb->pb_op->ors_tlimit = *((int *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_SEARCH_FILTER:
		PBLOCK_ASSERT_OP( pb, 0 );
		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
			pb->pb_op->ors_filter = (Slapi_Filter *)value;
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_SEARCH_STRFILTER:
		PBLOCK_ASSERT_OP( pb, 0 );
		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH ) {
			pb->pb_op->ors_filterstr.bv_val = (char *)value;
			pb->pb_op->ors_filterstr.bv_len = strlen((char *)value);
		} else {
			rc = PBLOCK_ERROR;
		}
		break;
	case SLAPI_SEARCH_ATTRS: {
		AttributeName *an = NULL;
		size_t i = 0, j = 0;
		char **attrs = (char **)value;

		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag != LDAP_REQ_SEARCH ) {
			rc = PBLOCK_ERROR;
			break;
		}
		/* also set mapped attrs */
		rc = pblock_set_default( pb, param, value );
		if ( rc != PBLOCK_SUCCESS ) {
			break;
		}
		if ( pb->pb_op->ors_attrs != NULL ) {
			pb->pb_op->o_tmpfree( pb->pb_op->ors_attrs, pb->pb_op->o_tmpmemctx );
			pb->pb_op->ors_attrs = NULL;
		}
		if ( attrs != NULL ) {
			for ( i = 0; attrs[i] != NULL; i++ )
				;
		}
		if ( i ) {
			an = (AttributeName *)pb->pb_op->o_tmpcalloc( i + 1,
				sizeof(AttributeName), pb->pb_op->o_tmpmemctx );
			for ( i = 0; attrs[i] != NULL; i++ ) {
				an[j].an_desc = NULL;
				an[j].an_oc = NULL;
				an[j].an_flags = 0;
				an[j].an_name.bv_val = attrs[i];
				an[j].an_name.bv_len = strlen( attrs[i] );
				if ( slap_bv2ad( &an[j].an_name, &an[j].an_desc, &pb->pb_rs->sr_text ) == LDAP_SUCCESS ) {
					j++;
				}
			}
			an[j].an_name.bv_val = NULL;
			an[j].an_name.bv_len = 0;
		}	
		pb->pb_op->ors_attrs = an;
		break;
	}
	case SLAPI_SEARCH_ATTRSONLY:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
			pb->pb_op->ors_attrsonly = *((int *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_SEARCH_RESULT_ENTRY:
		PBLOCK_ASSERT_OP( pb, 0 );
		rs_replace_entry( pb->pb_op, pb->pb_rs, NULL, (Slapi_Entry *)value );
		/* TODO: Should REP_ENTRY_MODIFIABLE be set? */
		pb->pb_rs->sr_flags |= REP_ENTRY_MUSTBEFREED;
		break;
	case SLAPI_BIND_RET_SASLCREDS:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_rs->sr_sasldata = (struct berval *)value;
		break;
	case SLAPI_EXT_OP_REQ_OID:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED ) {
			pb->pb_op->ore_reqoid.bv_val = (char *)value;
			pb->pb_op->ore_reqoid.bv_len = strlen((char *)value);
		} else {
			rc = PBLOCK_ERROR;
		}
		break;
	case SLAPI_EXT_OP_REQ_VALUE:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_EXTENDED )
			pb->pb_op->ore_reqdata = (struct berval *)value;
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_EXT_OP_RET_OID:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_rs->sr_rspoid = (char *)value;
		break;
	case SLAPI_EXT_OP_RET_VALUE:
		PBLOCK_ASSERT_OP( pb, 0 );
		pb->pb_rs->sr_rspdata = (struct berval *)value;
		break;
	case SLAPI_BIND_METHOD:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
			pb->pb_op->orb_method = *((int *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_BIND_CREDENTIALS:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_BIND )
			pb->pb_op->orb_cred = *((struct berval *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_COMPARE_TYPE:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE ) {
			const char *text;

			pb->pb_op->orc_ava->aa_desc = NULL;
			rc = slap_str2ad( (char *)value, &pb->pb_op->orc_ava->aa_desc, &text );
		} else {
			rc = PBLOCK_ERROR;
		}
		break;
	case SLAPI_COMPARE_VALUE:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_COMPARE )
			pb->pb_op->orc_ava->aa_value = *((struct berval *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_ABANDON_MSGID:
		PBLOCK_ASSERT_OP( pb, 0 );
		PBLOCK_VALIDATE_IS_INTOP( pb );

		if ( pb->pb_op->o_tag == LDAP_REQ_ABANDON)
			pb->pb_op->orn_msgid = *((int *)value);
		else
			rc = PBLOCK_ERROR;
		break;
	case SLAPI_REQUESTOR_ISROOT:
	case SLAPI_IS_REPLICATED_OPERATION:
	case SLAPI_CONN_AUTHTYPE:
	case SLAPI_CONN_AUTHMETHOD:
	case SLAPI_IS_INTERNAL_OPERATION:
	case SLAPI_X_CONN_IS_UDP:
	case SLAPI_CONN_CLIENTIP:
	case SLAPI_X_CONN_CLIENTPATH:
	case SLAPI_CONN_SERVERIP:
	case SLAPI_X_CONN_SERVERPATH:
	case SLAPI_X_ADD_STRUCTURAL_CLASS:
		/* These parameters cannot be set */
		rc = PBLOCK_ERROR;
		break;
	default:
		rc = pblock_set_default( pb, param, value );
		break;
	}

	pblock_unlock( pb );

	return rc;
}
コード例 #4
0
ファイル: slapi_ops.c プロジェクト: dago/openldap
int
slapi_add_internal_pb( Slapi_PBlock *pb )
{
	SlapReply		*rs;
	Slapi_Entry		*entry_orig = NULL;
	OpExtraDB oex;
	int rc;

	if ( pb == NULL ) {
		return -1;
	}

	PBLOCK_ASSERT_INTOP( pb, LDAP_REQ_ADD );

	rs = pb->pb_rs;

	entry_orig = pb->pb_op->ora_e;
	pb->pb_op->ora_e = NULL;

	/*
	 * The caller can specify a new entry, or a target DN and set
	 * of modifications, but not both.
	 */
	if ( entry_orig != NULL ) {
		if ( pb->pb_op->ora_modlist != NULL || !BER_BVISNULL( &pb->pb_op->o_req_ndn )) {
			rs->sr_err = LDAP_PARAM_ERROR;
			goto cleanup;
		}

		assert( BER_BVISNULL( &pb->pb_op->o_req_dn ) ); /* shouldn't get set */
		ber_dupbv( &pb->pb_op->o_req_dn, &entry_orig->e_name );
		ber_dupbv( &pb->pb_op->o_req_ndn, &entry_orig->e_nname );
	} else if ( pb->pb_op->ora_modlist == NULL || BER_BVISNULL( &pb->pb_op->o_req_ndn )) {
		rs->sr_err = LDAP_PARAM_ERROR;
		goto cleanup;
	}

	pb->pb_op->ora_e = (Entry *)slapi_ch_calloc( 1, sizeof(Entry) );
	ber_dupbv( &pb->pb_op->ora_e->e_name,  &pb->pb_op->o_req_dn );
	ber_dupbv( &pb->pb_op->ora_e->e_nname, &pb->pb_op->o_req_ndn );

	if ( entry_orig != NULL ) {
		assert( pb->pb_op->ora_modlist == NULL );

		rs->sr_err = slap_entry2mods( entry_orig, &pb->pb_op->ora_modlist,
			&rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) );
		if ( rs->sr_err != LDAP_SUCCESS ) {
			goto cleanup;
		}
	} else {
		assert( pb->pb_op->ora_modlist != NULL );
	}

	rs->sr_err = slap_mods_check( pb->pb_op, pb->pb_op->ora_modlist, &rs->sr_text,
		pb->pb_textbuf, sizeof( pb->pb_textbuf ), NULL );
	if ( rs->sr_err != LDAP_SUCCESS ) {
                goto cleanup;
        }

	/* Duplicate the values, because we may call slapi_entry_free() */
	rs->sr_err = slap_mods2entry( pb->pb_op->ora_modlist, &pb->pb_op->ora_e,
		1, 0, &rs->sr_text, pb->pb_textbuf, sizeof( pb->pb_textbuf ) );
	if ( rs->sr_err != LDAP_SUCCESS ) {
		goto cleanup;
	}

	oex.oe.oe_key = (void *)do_add;
	oex.oe_db = NULL;
	LDAP_SLIST_INSERT_HEAD(&pb->pb_op->o_extra, &oex.oe, oe_next);
	rc = slapi_int_func_internal_pb( pb, op_add );
	LDAP_SLIST_REMOVE(&pb->pb_op->o_extra, &oex.oe, OpExtra, oe_next);

	if ( !rc ) {
		if ( pb->pb_op->ora_e != NULL && oex.oe_db != NULL ) {
			BackendDB	*bd = pb->pb_op->o_bd;

			pb->pb_op->o_bd = oex.oe_db;
			be_entry_release_w( pb->pb_op, pb->pb_op->ora_e );
			pb->pb_op->ora_e = NULL;
			pb->pb_op->o_bd = bd;
		}
	}

cleanup:

	if ( pb->pb_op->ora_e != NULL ) {
		slapi_entry_free( pb->pb_op->ora_e );
		pb->pb_op->ora_e = NULL;
	}
	if ( entry_orig != NULL ) {
		pb->pb_op->ora_e = entry_orig;
		slap_mods_free( pb->pb_op->ora_modlist, 1 );
		pb->pb_op->ora_modlist = NULL;
	}

	return 0;
}
コード例 #5
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 );
}
コード例 #6
0
ファイル: modrdn.c プロジェクト: benegon/openldap
int
do_modrdn(
    Operation	*op,
    SlapReply	*rs
)
{
	struct berval	dn = BER_BVNULL;
	struct berval	newrdn = BER_BVNULL;
	struct berval	newSuperior = BER_BVNULL;
	ber_int_t	deloldrdn;

	struct berval pnewSuperior = BER_BVNULL;

	struct berval nnewSuperior = BER_BVNULL;

	ber_len_t	length;

	Debug( LDAP_DEBUG_TRACE, "%s do_modrdn\n",
			op->o_log_prefix, 0, 0 );
	/*
	 * Parse the modrdn request.  It looks like this:
	 *
	 *	ModifyRDNRequest := SEQUENCE {
	 *		entry	DistinguishedName,
	 *		newrdn	RelativeDistinguishedName
	 *		deleteoldrdn	BOOLEAN,
	 *		newSuperior	[0] LDAPDN OPTIONAL (v3 Only!)
	 *	}
	 */

	if ( ber_scanf( op->o_ber, "{mmb", &dn, &newrdn, &deloldrdn )
	    == LBER_ERROR )
	{
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	/* Check for newSuperior parameter, if present scan it */

	if ( ber_peek_tag( op->o_ber, &length ) == LDAP_TAG_NEWSUPERIOR ) {
		if ( op->o_protocol < LDAP_VERSION3 ) {
			/* Connection record indicates v2 but field 
			 * newSuperior is present: report error.
			 */
			Debug( LDAP_DEBUG_ANY,
				"%s do_modrdn: newSuperior requires LDAPv3\n",
				op->o_log_prefix, 0, 0 );

			send_ldap_discon( op, rs,
				LDAP_PROTOCOL_ERROR, "newSuperior requires LDAPv3" );
			rs->sr_err = SLAPD_DISCONNECT;
			goto cleanup;
		}

		if ( ber_scanf( op->o_ber, "m", &newSuperior ) 
		     == LBER_ERROR ) {

			Debug( LDAP_DEBUG_ANY, "%s do_modrdn: ber_scanf(\"m\") failed\n",
				op->o_log_prefix, 0, 0 );

			send_ldap_discon( op, rs,
				LDAP_PROTOCOL_ERROR, "decoding error" );
			rs->sr_err = SLAPD_DISCONNECT;
			goto cleanup;
		}
		op->orr_newSup = &pnewSuperior;
		op->orr_nnewSup = &nnewSuperior;
	}

	Debug( LDAP_DEBUG_ARGS,
	    "do_modrdn: dn (%s) newrdn (%s) newsuperior (%s)\n",
		dn.bv_val, newrdn.bv_val,
		newSuperior.bv_len ? newSuperior.bv_val : "" );

	if ( ber_scanf( op->o_ber, /*{*/ "}") == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs,
			LDAP_PROTOCOL_ERROR, "decoding error" );
		rs->sr_err = SLAPD_DISCONNECT;
		goto cleanup;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		/* get_ctrls has sent results.	Now clean up. */
		goto cleanup;
	} 

	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	/* FIXME: should have/use rdnPretty / rdnNormalize routines */

	rs->sr_err = dnPrettyNormal( NULL, &newrdn, &op->orr_newrdn, &op->orr_nnewrdn, op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: invalid newrdn (%s)\n",
			op->o_log_prefix, newrdn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid new RDN" );
		goto cleanup;
	}

	if( rdn_validate( &op->orr_newrdn ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modrdn: invalid rdn (%s)\n",
			op->o_log_prefix, op->orr_newrdn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid new RDN" );
		goto cleanup;
	}

	if( op->orr_newSup ) {
		rs->sr_err = dnPrettyNormal( NULL, &newSuperior, &pnewSuperior,
			&nnewSuperior, op->o_tmpmemctx );
		if( rs->sr_err != LDAP_SUCCESS ) {
			Debug( LDAP_DEBUG_ANY,
				"%s do_modrdn: invalid newSuperior (%s)\n",
				op->o_log_prefix, newSuperior.bv_val, 0 );
			send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid newSuperior" );
			goto cleanup;
		}
	}

	Statslog( LDAP_DEBUG_STATS, "%s MODRDN dn=\"%s\"\n",
	    op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );

	op->orr_deleteoldrdn = deloldrdn;
	op->orr_modlist = NULL;

	/* prepare modlist of modifications from old/new RDN */
	rs->sr_err = slap_modrdn2mods( op, rs );
	if ( rs->sr_err != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_modrdn( op, rs );

#ifdef LDAP_X_TXN
	if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
		/* skip cleanup */
	}
#endif

cleanup:
	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );

	op->o_tmpfree( op->orr_newrdn.bv_val, op->o_tmpmemctx );	
	op->o_tmpfree( op->orr_nnewrdn.bv_val, op->o_tmpmemctx );	

	if ( op->orr_modlist != NULL )
		slap_mods_free( op->orr_modlist, 1 );

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

	return rs->sr_err;
}
コード例 #7
0
ファイル: modify.c プロジェクト: fcelda/openldap
int
do_modify(
    Operation	*op,
    SlapReply	*rs )
{
	struct berval dn = BER_BVNULL;
	char		textbuf[ SLAP_TEXT_BUFLEN ];
	size_t		textlen = sizeof( textbuf );
#ifdef LDAP_DEBUG
	Modifications	*tmp;
#endif

	Debug( LDAP_DEBUG_TRACE, "%s do_modify\n",
		op->o_log_prefix, 0, 0 );
	/*
	 * Parse the modify request.  It looks like this:
	 *
	 *	ModifyRequest := [APPLICATION 6] SEQUENCE {
	 *		name	DistinguishedName,
	 *		mods	SEQUENCE OF SEQUENCE {
	 *			operation	ENUMERATED {
	 *				add	(0),
	 *				delete	(1),
	 *				replace	(2)
	 *			},
	 *			modification	SEQUENCE {
	 *				type	AttributeType,
	 *				values	SET OF AttributeValue
	 *			}
	 *		}
	 *	}
	 */

	if ( ber_scanf( op->o_ber, "{m" /*}*/, &dn ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	Debug( LDAP_DEBUG_ARGS, "%s do_modify: dn (%s)\n",
		op->o_log_prefix, dn.bv_val, 0 );

	rs->sr_err = slap_parse_modlist( op, rs, op->o_ber, &op->oq_modify );
	if ( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: slap_parse_modlist failed err=%d msg=%s\n",
			op->o_log_prefix, rs->sr_err, rs->sr_text );
		send_ldap_result( op, rs );
		goto cleanup;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		/* get_ctrls has sent results.	Now clean up. */
		goto cleanup;
	}

	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
		op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	op->orm_no_opattrs = 0;

#ifdef LDAP_DEBUG
	Debug( LDAP_DEBUG_ARGS, "%s modifications:\n",
			op->o_log_prefix, 0, 0 );

	for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) {
		Debug( LDAP_DEBUG_ARGS, "\t%s: %s\n",
			tmp->sml_op == LDAP_MOD_ADD ? "add" :
				(tmp->sml_op == LDAP_MOD_INCREMENT ? "increment" :
				(tmp->sml_op == LDAP_MOD_DELETE ? "delete" :
					"replace")), tmp->sml_type.bv_val, 0 );

		if ( tmp->sml_values == NULL ) {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tno values", NULL, NULL );
		} else if ( BER_BVISNULL( &tmp->sml_values[ 0 ] ) ) {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tzero values", NULL, NULL );
		} else if ( BER_BVISNULL( &tmp->sml_values[ 1 ] ) ) {
			Debug( LDAP_DEBUG_ARGS, "%s, length %ld\n",
			   "\t\tone value", (long) tmp->sml_values[0].bv_len, NULL );
		} else {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tmultiple values", NULL, NULL );
		}
	}

	if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
		char abuf[BUFSIZ/2], *ptr = abuf;
		int len = 0;

		Statslog( LDAP_DEBUG_STATS, "%s MOD dn=\"%s\"\n",
			op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );

		for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) {
			if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
				Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
				    op->o_log_prefix, abuf, 0, 0, 0 );

				len = 0;
				ptr = abuf;

				if( 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
					Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
						op->o_log_prefix, tmp->sml_type.bv_val, 0, 0, 0 );
					continue;
				}
			}
			if (len) {
				*ptr++ = ' ';
				len++;
			}
			ptr = lutil_strcopy(ptr, tmp->sml_type.bv_val);
			len += tmp->sml_type.bv_len;
		}
		if (len) {
			Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
	    			op->o_log_prefix, abuf, 0, 0, 0 );
		}
	}
#endif	/* LDAP_DEBUG */

	rs->sr_err = slap_mods_check( op, op->orm_modlist,
		&rs->sr_text, textbuf, textlen, NULL );

	if ( rs->sr_err != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_modify( op, rs );

#ifdef LDAP_X_TXN
	if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
		/* skip cleanup */
		return rs->sr_err;
	}
#endif

cleanup:
	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
	if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist, 1 );

	return rs->sr_err;
}
コード例 #8
0
ファイル: modify.c プロジェクト: fcelda/openldap
int
slap_parse_modlist(
	Operation *op,
	SlapReply *rs,
	BerElement *ber,
	req_modify_s *ms )
{
	ber_tag_t	tag;
	ber_len_t	len;
	char		*last;
	Modifications	**modtail = &ms->rs_mods.rs_modlist;

	ms->rs_mods.rs_modlist = NULL;
	ms->rs_increment = 0;

	rs->sr_err = LDAP_SUCCESS;

	/* collect modifications & save for later */
	for ( tag = ber_first_element( ber, &len, &last );
		tag != LBER_DEFAULT;
		tag = ber_next_element( ber, &len, last ) )
	{
		ber_int_t mop;
		Modifications tmp, *mod;

		tmp.sml_nvalues = NULL;

		if ( ber_scanf( ber, "{e{m[W]}}", &mop,
		    &tmp.sml_type, &tmp.sml_values ) == LBER_ERROR )
		{
			rs->sr_text = "decoding modlist error";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		mod = (Modifications *) ch_malloc( sizeof(Modifications) );
		mod->sml_op = mop;
		mod->sml_flags = 0;
		mod->sml_type = tmp.sml_type;
		mod->sml_values = tmp.sml_values;
		mod->sml_nvalues = NULL;
		mod->sml_desc = NULL;
		mod->sml_next = NULL;
		*modtail = mod;

		switch( mop ) {
		case LDAP_MOD_ADD:
			if ( mod->sml_values == NULL ) {
				rs->sr_text = "modify/add operation requires values";
				rs->sr_err = LDAP_PROTOCOL_ERROR;
				goto done;
			}

			/* fall through */

		case LDAP_MOD_DELETE:
		case LDAP_MOD_REPLACE:
			break;

		case LDAP_MOD_INCREMENT:
			if( op->o_protocol >= LDAP_VERSION3 ) {
				ms->rs_increment++;
				if ( mod->sml_values == NULL ) {
					rs->sr_text = "modify/increment operation requires value";
					rs->sr_err = LDAP_PROTOCOL_ERROR;
					goto done;
				}

				if ( !BER_BVISNULL( &mod->sml_values[ 1 ] ) ) {
					rs->sr_text = "modify/increment operation requires single value";
					rs->sr_err = LDAP_PROTOCOL_ERROR;
					goto done;
				}

				break;
			}
			/* fall thru */

		default:
			rs->sr_text = "unrecognized modify operation";
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			goto done;
		}

		modtail = &mod->sml_next;
	}
	*modtail = NULL;

done:
	if ( rs->sr_err != LDAP_SUCCESS ) {
		slap_mods_free( ms->rs_mods.rs_modlist, 1 );
		ms->rs_mods.rs_modlist = NULL;
		ms->rs_increment = 0;
	}

	return rs->sr_err;
}
コード例 #9
0
ファイル: lastbind.c プロジェクト: verter2015/ReOpenLDAP
static int
lastbind_bind_response( Operation *op, SlapReply *rs )
{
	Modifications *mod = NULL;
	BackendInfo *bi = op->o_bd->bd_info;
	Entry *e;
	int rc;

	/* we're only interested if the bind was successful */
	if ( rs->sr_err != LDAP_SUCCESS )
		return SLAP_CB_CONTINUE;

	rc = be_entry_get_rw( op, &op->o_req_ndn, NULL, NULL, 0, &e );
	op->o_bd->bd_info = bi;

	if ( rc != LDAP_SUCCESS ) {
		return SLAP_CB_CONTINUE;
	}

	{
		lastbind_info *lbi = (lastbind_info *) op->o_callback->sc_private;

		time_t now, bindtime = (time_t)-1;
		Attribute *a;
		Modifications *m;
		char nowstr[ LDAP_LUTIL_GENTIME_BUFSIZE ];
		struct berval timestamp;

		/* get the current time */
		now = slap_get_time();

		/* get authTimestamp attribute, if it exists */
		if ((a = attr_find( e->e_attrs, ad_authTimestamp)) != NULL) {
			bindtime = parse_time( a->a_nvals[0].bv_val );

			if (bindtime != (time_t)-1) {
				/* if the recorded bind time is within our precision, we're done
				 * it doesn't need to be updated (save a write for nothing) */
				if ((now - bindtime) < lbi->timestamp_precision) {
					goto done;
				}
			}
		}

		/* update the authTimestamp in the user's entry with the current time */
		timestamp.bv_val = nowstr;
		timestamp.bv_len = sizeof(nowstr);
		slap_timestamp( &now, &timestamp );

		m = ch_calloc( sizeof(Modifications), 1 );
		m->sml_op = LDAP_MOD_REPLACE;
		m->sml_flags = 0;
		m->sml_type = ad_authTimestamp->ad_cname;
		m->sml_desc = ad_authTimestamp;
		m->sml_numvals = 1;
		m->sml_values = ch_calloc( sizeof(struct berval), 2 );
		m->sml_nvalues = ch_calloc( sizeof(struct berval), 2 );

		ber_dupbv( &m->sml_values[0], &timestamp );
		ber_dupbv( &m->sml_nvalues[0], &timestamp );
		m->sml_next = mod;
		mod = m;
	}

done:
	be_entry_release_r( op, e );

	/* perform the update, if necessary */
	if ( mod ) {
		Operation op2 = *op;
		SlapReply r2 = { REP_RESULT };
		slap_callback cb = { NULL, slap_null_cb, NULL, NULL };

		/* This is a DSA-specific opattr, it never gets replicated. */
		op2.o_tag = LDAP_REQ_MODIFY;
		op2.o_callback = &cb;
		op2.orm_modlist = mod;
		op2.o_dn = op->o_bd->be_rootdn;
		op2.o_ndn = op->o_bd->be_rootndn;
		op2.o_dont_replicate = 1;
		rc = op->o_bd->be_modify( &op2, &r2 );
		slap_mods_free( mod, 1 );
	}

	op->o_bd->bd_info = bi;
	return SLAP_CB_CONTINUE;
}
コード例 #10
0
ファイル: translucent.c プロジェクト: jaredmcneill/netbsd-src
static int translucent_modify(Operation *op, SlapReply *rs) {
	SlapReply nrs = { REP_RESULT };

	slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
	translucent_info *ov = on->on_bi.bi_private;
	Entry *e = NULL, *re = NULL;
	Attribute *a, *ax;
	Modifications *m, **mm;
	BackendDB *db;
	int del, rc, erc = 0;
	slap_callback cb = { 0 };

	Debug(LDAP_DEBUG_TRACE, "==> translucent_modify: %s\n",
		op->o_req_dn.bv_val, 0, 0);

	if(ov->defer_db_open) {
		send_ldap_error(op, rs, LDAP_UNAVAILABLE,
			"remote DB not available");
		return(rs->sr_err);
	}
/*
** fetch entry from the captive backend;
** if it did not exist, fail;
** release it, if captive backend supports this;
**
*/

	db = op->o_bd;
	op->o_bd = &ov->db;
	ov->db.be_acl = op->o_bd->be_acl;
	rc = ov->db.bd_info->bi_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &re);
	op->o_bd = db;
	if(rc != LDAP_SUCCESS || re == NULL ) {
		send_ldap_error((op), rs, LDAP_NO_SUCH_OBJECT,
			"attempt to modify nonexistent local record");
		return(rs->sr_err);
	}
/*
** fetch entry from local backend;
** if it exists:
**	foreach Modification:
**	    if attr not present in local:
**		if Mod == LDAP_MOD_DELETE:
**		    if remote attr not present, return NO_SUCH;
**		    if remote attr present, drop this Mod;
**		else force this Mod to LDAP_MOD_ADD;
**	return CONTINUE;
**
*/

	op->o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;
	rc = be_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &e);
	op->o_bd->bd_info = (BackendInfo *) on;

	if(e && rc == LDAP_SUCCESS) {
		Debug(LDAP_DEBUG_TRACE, "=> translucent_modify: found local entry\n", 0, 0, 0);
		for(mm = &op->orm_modlist; *mm; ) {
			m = *mm;
			for(a = e->e_attrs; a; a = a->a_next)
				if(a->a_desc == m->sml_desc) break;
			if(a) {
				mm = &m->sml_next;
				continue;		/* found local attr */
			}
			if(m->sml_op == LDAP_MOD_DELETE) {
				for(a = re->e_attrs; a; a = a->a_next)
					if(a->a_desc == m->sml_desc) break;
				/* not found remote attr */
				if(!a) {
					erc = LDAP_NO_SUCH_ATTRIBUTE;
					goto release;
				}
				if(ov->strict) {
					erc = LDAP_CONSTRAINT_VIOLATION;
					goto release;
				}
				Debug(LDAP_DEBUG_TRACE,
					"=> translucent_modify: silently dropping delete: %s\n",
					m->sml_desc->ad_cname.bv_val, 0, 0);
				*mm = m->sml_next;
				m->sml_next = NULL;
				slap_mods_free(m, 1);
				continue;
			}
			m->sml_op = LDAP_MOD_ADD;
			mm = &m->sml_next;
		}
		erc = SLAP_CB_CONTINUE;
release:
		if(re) {
			if(ov->db.bd_info->bi_entry_release_rw) {
				op->o_bd = &ov->db;
				ov->db.bd_info->bi_entry_release_rw(op, re, 0);
				op->o_bd = db;
			} else
				entry_free(re);
		}
		op->o_bd->bd_info = (BackendInfo *) on->on_info->oi_orig;
		be_entry_release_r(op, e);
		op->o_bd->bd_info = (BackendInfo *) on;
		if(erc == SLAP_CB_CONTINUE) {
			return(erc);
		} else if(erc) {
			send_ldap_error(op, rs, erc,
				"attempt to delete nonexistent attribute");
			return(erc);
		}
	}

	/* don't leak remote entry copy */
	if(re) {
		if(ov->db.bd_info->bi_entry_release_rw) {
			op->o_bd = &ov->db;
			ov->db.bd_info->bi_entry_release_rw(op, re, 0);
			op->o_bd = db;
		} else
			entry_free(re);
	}
/*
** foreach Modification:
**	if MOD_ADD or MOD_REPLACE, add Attribute;
** if no Modifications were suitable:
**	if strict, throw CONSTRAINT_VIOLATION;
**	else, return early SUCCESS;
** fabricate Entry with new Attribute chain;
** glue_parent() for this Entry;
** call bi_op_add() in local backend;
**
*/

	Debug(LDAP_DEBUG_TRACE, "=> translucent_modify: fabricating local add\n", 0, 0, 0);
	a = NULL;
	for(del = 0, ax = NULL, m = op->orm_modlist; m; m = m->sml_next) {
		Attribute atmp;
		if(((m->sml_op & LDAP_MOD_OP) != LDAP_MOD_ADD) &&
		   ((m->sml_op & LDAP_MOD_OP) != LDAP_MOD_REPLACE)) {
			Debug(LDAP_DEBUG_ANY,
				"=> translucent_modify: silently dropped modification(%d): %s\n",
				m->sml_op, m->sml_desc->ad_cname.bv_val, 0);
			if((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) del++;
			continue;
		}
		atmp.a_desc = m->sml_desc;
		atmp.a_vals = m->sml_values;
		atmp.a_nvals = m->sml_nvalues ? m->sml_nvalues : atmp.a_vals;
		atmp.a_numvals = m->sml_numvals;
		atmp.a_flags = 0;
		a = attr_dup( &atmp );
		a->a_next  = ax;
		ax = a;
	}

	if(del && ov->strict) {
		attrs_free( a );
		send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION,
			"attempt to delete attributes from local database");
		return(rs->sr_err);
	}

	if(!ax) {
		if(ov->strict) {
			send_ldap_error(op, rs, LDAP_CONSTRAINT_VIOLATION,
				"modification contained other than ADD or REPLACE");
			return(rs->sr_err);
		}
		/* rs->sr_text = "no valid modification found"; */
		rs->sr_err = LDAP_SUCCESS;
		send_ldap_result(op, rs);
		return(rs->sr_err);
	}

	e = entry_alloc();
	ber_dupbv( &e->e_name, &op->o_req_dn );
	ber_dupbv( &e->e_nname, &op->o_req_ndn );
	e->e_attrs = a;

	op->o_tag	= LDAP_REQ_ADD;
	cb.sc_response = translucent_tag_cb;
	cb.sc_private = op->orm_modlist;
	op->oq_add.rs_e	= e;

	glue_parent(op);

	cb.sc_next = op->o_callback;
	op->o_callback = &cb;
	rc = on->on_info->oi_orig->bi_op_add(op, &nrs);
	if ( op->ora_e == e )
		entry_free( e );
	op->o_callback = cb.sc_next;

	return(rc);
}
コード例 #11
0
ファイル: autogroup.c プロジェクト: ystk/debian-openldap
/*
** Adds all entries matching the passed filter to the specified group.
** If modify == 1, then we modify the group's entry in the database using be_modify.
** If modify == 0, then, we must supply a rw entry for the group, 
**	because we only modify the entry, without calling be_modify.
** e	- the group entry, to which the members will be added
** age	- the group
** agf	- the filter
*/
static int
autogroup_add_members_from_filter( Operation *op, Entry *e, autogroup_entry_t *age, autogroup_filter_t *agf, int modify)
{
	slap_overinst		*on = (slap_overinst *)op->o_bd->bd_info;
	Operation		o = *op;
	SlapReply		rs = { REP_SEARCH };
	slap_callback		cb = { 0 };
	slap_callback		null_cb = { NULL, slap_null_cb, NULL, NULL };
	autogroup_ga_t		agg;

	Debug(LDAP_DEBUG_TRACE, "==> autogroup_add_members_from_filter <%s>\n",
		age->age_dn.bv_val, 0, 0);

	o.ors_attrsonly = 0;
	o.o_tag = LDAP_REQ_SEARCH;

	o.o_req_dn = agf->agf_dn;
	o.o_req_ndn = agf->agf_ndn;

	o.ors_filterstr = agf->agf_filterstr;
	o.ors_filter = agf->agf_filter;

	o.ors_scope = agf->agf_scope;
	o.ors_deref = LDAP_DEREF_NEVER;
	o.ors_limit = NULL;
	o.ors_tlimit = SLAP_NO_LIMIT;
	o.ors_slimit = SLAP_NO_LIMIT;
	o.ors_attrs =  slap_anlist_no_attrs;

	agg.agg_group = age;
	agg.agg_mod = NULL;
	agg.agg_mod_last = NULL;
	agg.agg_entry = e;
	cb.sc_private = &agg;

	if ( modify == 1 ) {
		cb.sc_response = autogroup_member_search_modify_cb;
	} else {
		cb.sc_response = autogroup_member_search_cb;
	}

	cb.sc_cleanup = NULL;
	cb.sc_next = NULL;

	o.o_callback = &cb;

	o.o_bd->bd_info = (BackendInfo *)on->on_info;
	op->o_bd->be_search( &o, &rs );
	o.o_bd->bd_info = (BackendInfo *)on;	

	if ( modify == 1 ) {
		o = *op;
		o.o_callback = &null_cb;
		o.o_tag = LDAP_REQ_MODIFY;
		o.orm_modlist = agg.agg_mod;
		o.o_req_dn = age->age_dn;
		o.o_req_ndn = age->age_ndn;
		o.o_relax = SLAP_CONTROL_CRITICAL;
		o.o_managedsait = SLAP_CONTROL_NONCRITICAL;
		o.o_permissive_modify = 1;

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

		slap_mods_free(agg.agg_mod, 1);
	}

	return 0;
}
コード例 #12
0
ファイル: pguid.c プロジェクト: ajinkya93/netbsd-src
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;
}
コード例 #13
0
ファイル: sasl.c プロジェクト: MPlatform/mdb
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;
	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);
#ifdef SLAP_AUXPROP_DONTUSECOPY
	int dontUseCopy = 0;
	BackendDB *dontUseCopy_bd = NULL;
#endif /* SLAP_AUXPROP_DONTUSECOPY */

	/* 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];
			}
#ifdef SLAP_AUXPROP_DONTUSECOPY
			if ( slap_dontUseCopy_propnames != NULL ) {
				struct berval bv;
				ber_str2bv( &pr[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 */
		}
	}
	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;

#ifdef SLAP_AUXPROP_DONTUSECOPY
	if ( SLAP_SHADOW( op.o_bd ) && dontUseCopy ) {
		dontUseCopy_bd = op.o_bd;
		op.o_bd = frontendDB;
		op.o_dontUseCopy = SLAP_CONTROL_CRITICAL;
	}
#endif /* SLAP_AUXPROP_DONTUSECOPY */

	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;

			for (;;) {
				SlapReply rs = {REP_RESULT};
				rc = op.o_bd->be_modify( &op, &rs );

#ifdef SLAP_AUXPROP_DONTUSECOPY
				if ( dontUseCopy &&
					rs.sr_err == LDAP_UNAVAILABLE &&
					slap_dontUseCopy_ignore )
				{
					op.o_bd = dontUseCopy_bd;
					op.o_dontUseCopy = SLAP_CONTROL_NONE;
					dontUseCopy = 0;
					continue;
				}
#endif /* SLAP_AUXPROP_DONTUSECOPY */
				break;
			}
		}
	}
	slap_mods_free( modlist, 1 );
	return rc != LDAP_SUCCESS ? SASL_FAIL : SASL_OK;
}
コード例 #14
0
ファイル: add.c プロジェクト: BackupTheBerlios/wl530g-svn
int
do_add( Connection *conn, Operation *op )
{
	BerElement	*ber = op->o_ber;
	char		*last;
	struct berval dn = { 0, NULL };
	ber_len_t	len;
	ber_tag_t	tag;
	Entry		*e;
	Backend		*be;
	Modifications	*modlist = NULL;
	Modifications	**modtail = &modlist;
	Modifications	tmp;
	const char *text;
	int			rc = LDAP_SUCCESS;
	int	manageDSAit;
#ifdef LDAP_SLAPI
	Slapi_PBlock	*pb = NULL;
#endif /* LDAP_SLAPI */

#ifdef NEW_LOGGING
	LDAP_LOG( OPERATION, ENTRY, "do_add: conn %d enter\n", conn->c_connid,0,0 );
#else
	Debug( LDAP_DEBUG_TRACE, "do_add\n", 0, 0, 0 );
#endif
	/*
	 * Parse the add request.  It looks like this:
	 *
	 *	AddRequest := [APPLICATION 14] SEQUENCE {
	 *		name	DistinguishedName,
	 *		attrs	SEQUENCE OF SEQUENCE {
	 *			type	AttributeType,
	 *			values	SET OF AttributeValue
	 *		}
	 *	}
	 */

	/* get the name */
	if ( ber_scanf( ber, "{m", /*}*/ &dn ) == LBER_ERROR ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, ERR, 
			"do_add: conn %d ber_scanf failed\n", conn->c_connid,0,0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
#endif
		send_ldap_disconnect( conn, op,
			LDAP_PROTOCOL_ERROR, "decoding error" );
		return -1;
	}

	e = (Entry *) ch_calloc( 1, sizeof(Entry) );

	rc = dnPrettyNormal( NULL, &dn, &e->e_name, &e->e_nname );

	if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, ERR, 
			"do_add: conn %d invalid dn (%s)\n", conn->c_connid, dn.bv_val, 0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: invalid dn (%s)\n", dn.bv_val, 0, 0 );
#endif
		send_ldap_result( conn, op, rc = LDAP_INVALID_DN_SYNTAX, NULL,
			    "invalid DN", NULL, NULL );
		goto done;
	}

#ifdef NEW_LOGGING
	LDAP_LOG( OPERATION, ARGS, 
		"do_add: conn %d  dn (%s)\n", conn->c_connid, e->e_dn, 0 );
#else
	Debug( LDAP_DEBUG_ARGS, "do_add: dn (%s)\n", e->e_dn, 0, 0 );
#endif

	/* get the attrs */
	for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
	    tag = ber_next_element( ber, &len, last ) )
	{
		Modifications *mod;
		ber_tag_t rtag;

		rtag = ber_scanf( ber, "{m{W}}", &tmp.sml_type, &tmp.sml_bvalues );

		if ( rtag == LBER_ERROR ) {
#ifdef NEW_LOGGING
			LDAP_LOG( OPERATION, ERR, 
				   "do_add: conn %d	 decoding error \n", conn->c_connid, 0, 0 );
#else
			Debug( LDAP_DEBUG_ANY, "do_add: decoding error\n", 0, 0, 0 );
#endif
			send_ldap_disconnect( conn, op,
				LDAP_PROTOCOL_ERROR, "decoding error" );
			rc = -1;
			goto done;
		}

		if ( tmp.sml_bvalues == NULL ) {
#ifdef NEW_LOGGING
			LDAP_LOG( OPERATION, INFO, 
				"do_add: conn %d	 no values for type %s\n",
				conn->c_connid, tmp.sml_type.bv_val, 0 );
#else
			Debug( LDAP_DEBUG_ANY, "no values for type %s\n",
				tmp.sml_type.bv_val, 0, 0 );
#endif
			send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
				NULL, "no values for attribute type", NULL, NULL );
			goto done;
		}
		mod  = (Modifications *) ch_malloc( sizeof(Modifications) );
		
		mod->sml_op = LDAP_MOD_ADD;
		mod->sml_next = NULL;
		mod->sml_desc = NULL;
		mod->sml_type = tmp.sml_type;
		mod->sml_bvalues = tmp.sml_bvalues;

		*modtail = mod;
		modtail = &mod->sml_next;
	}

	if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, ERR, 
			"do_add: conn %d ber_scanf failed\n", conn->c_connid, 0, 0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
#endif
		send_ldap_disconnect( conn, op,
			LDAP_PROTOCOL_ERROR, "decoding error" );
		rc = -1;
		goto done;
	}

	if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
		LDAP_LOG( OPERATION, INFO, 
			"do_add: conn %d get_ctrls failed\n", conn->c_connid, 0, 0 );
#else
		Debug( LDAP_DEBUG_ANY, "do_add: get_ctrls failed\n", 0, 0, 0 );
#endif
		goto done;
	} 

	if ( modlist == NULL ) {
		send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
			NULL, "no attributes provided", NULL, NULL );
		goto done;
	}

	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu ADD dn=\"%s\"\n",
	    op->o_connid, op->o_opid, e->e_dn, 0, 0 );

	if( e->e_nname.bv_len == 0 ) {
		/* protocolError may be a more appropriate error */
		send_ldap_result( conn, op, rc = LDAP_ALREADY_EXISTS,
			NULL, "root DSE already exists",
			NULL, NULL );
		goto done;

	} else if ( bvmatch( &e->e_nname, &global_schemandn ) ) {
		send_ldap_result( conn, op, rc = LDAP_ALREADY_EXISTS,
			NULL, "subschema subentry already exists",
			NULL, NULL );
		goto done;
	}

	manageDSAit = get_manageDSAit( op );

	/*
	 * We could be serving multiple database backends.  Select the
	 * appropriate one, or send a referral to our "referral server"
	 * if we don't hold it.
	 */
	be = select_backend( &e->e_nname, manageDSAit, 0 );
	if ( be == NULL ) {
		BerVarray ref = referral_rewrite( default_referral,
			NULL, &e->e_name, LDAP_SCOPE_DEFAULT );
		if ( ref == NULL ) ref = default_referral;
		if ( ref != NULL ) {
			send_ldap_result( conn, op, rc = LDAP_REFERRAL,
				NULL, NULL, ref, NULL );

			if ( ref != default_referral ) ber_bvarray_free( ref );
		} else {
			send_ldap_result( conn, op,
					rc = LDAP_UNWILLING_TO_PERFORM,
					NULL, "referral missing", NULL, NULL );
		}
		goto done;
	}

	/* check restrictions */
	rc = backend_check_restrictions( be, conn, op, NULL, &text ) ;
	if( rc != LDAP_SUCCESS ) {
		send_ldap_result( conn, op, rc,
			NULL, text, NULL, NULL );
		goto done;
	}

	/* check for referrals */
	rc = backend_check_referrals( be, conn, op, &e->e_name, &e->e_nname );
	if ( rc != LDAP_SUCCESS ) {
		goto done;
	}

#ifdef LDAP_SLAPI
	pb = initAddPlugin( be, conn, op, &dn, e, manageDSAit );
#endif /* LDAP_SLAPI */

	/*
	 * do the add if 1 && (2 || 3)
	 * 1) there is an add function implemented in this backend;
	 * 2) this backend is master for what it holds;
	 * 3) it's a replica and the dn supplied is the updatedn.
	 */
	if ( be->be_add ) {
		/* do the update here */
		int repl_user = be_isupdate(be, &op->o_ndn );
#ifndef SLAPD_MULTIMASTER
		if ( !be->be_update_ndn.bv_len || repl_user )
#endif
		{
			int update = be->be_update_ndn.bv_len;
			char textbuf[SLAP_TEXT_BUFLEN];
			size_t textlen = sizeof textbuf;

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

			if( rc != LDAP_SUCCESS ) {
				send_ldap_result( conn, op, rc,
					NULL, text, NULL, NULL );
				goto done;
			}

			if ( !repl_user ) {
				for( modtail = &modlist;
					*modtail != NULL;
					modtail = &(*modtail)->sml_next )
				{
					assert( (*modtail)->sml_op == LDAP_MOD_ADD );
					assert( (*modtail)->sml_desc != NULL );
				}
				rc = slap_mods_opattrs( be, op, modlist, modtail, &text,
					textbuf, textlen );
				if( rc != LDAP_SUCCESS ) {
					send_ldap_result( conn, op, rc,
						NULL, text, NULL, NULL );
					goto done;
				}
			}

			rc = slap_mods2entry( modlist, &e, repl_user, &text,
				textbuf, textlen );
			if( rc != LDAP_SUCCESS ) {
				send_ldap_result( conn, op, rc,
					NULL, text, NULL, NULL );
				goto done;
			}

#ifdef LDAP_SLAPI
			/*
			 * Call the preoperation plugin here, because the entry
			 * will actually contain something.
			 */
			rc = doPreAddPluginFNs( be, pb );
			if ( rc != LDAP_SUCCESS ) {
				/* plugin will have sent result */
				goto done;
			}
#endif /* LDAP_SLAPI */

			if ( (*be->be_add)( be, conn, op, e ) == 0 ) {
#ifdef SLAPD_MULTIMASTER
				if ( !repl_user )
#endif
				{
					replog( be, op, &e->e_name, &e->e_nname, e );
				}
				be_entry_release_w( be, conn, op, e );
				e = NULL;
			}

#ifndef SLAPD_MULTIMASTER
		} else {
			BerVarray defref;
			BerVarray ref;
#ifdef LDAP_SLAPI
			/*
			 * SLAPI_ADD_ENTRY will be empty, but this may be acceptable
			 * on replicas (for now, it involves the minimum code intrusion).
			 */
			rc = doPreAddPluginFNs( be, pb );
			if ( rc != LDAP_SUCCESS ) {
				/* plugin will have sent result */
				goto done;
			}
#endif /* LDAP_SLAPI */

			defref = be->be_update_refs
				? be->be_update_refs : default_referral;

			if ( defref ) {
				ref = referral_rewrite( defref,
					NULL, &e->e_name, LDAP_SCOPE_DEFAULT );

				send_ldap_result( conn, op, rc = LDAP_REFERRAL,
						NULL, NULL,
						ref ? ref : defref, NULL );

				if ( ref ) ber_bvarray_free( ref );
			} else {
				send_ldap_result( conn, op,
						rc = LDAP_UNWILLING_TO_PERFORM,
						NULL, "referral missing",
						NULL, NULL );
			}
#endif /* SLAPD_MULTIMASTER */
		}
	} else {
#ifdef LDAP_SLAPI
	    rc = doPreAddPluginFNs( be, pb );
	    if ( rc != LDAP_SUCCESS ) {
		/* plugin will have sent result */
		goto done;
	    }
#endif
#ifdef NEW_LOGGING
	    LDAP_LOG( OPERATION, INFO, 
		       "do_add: conn %d	 no backend support\n", conn->c_connid, 0, 0 );
#else
	    Debug( LDAP_DEBUG_ARGS, "	 do_add: no backend support\n", 0, 0, 0 );
#endif
	    send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
			      NULL, "operation not supported within namingContext", NULL, NULL );
	}

#ifdef LDAP_SLAPI
	doPostAddPluginFNs( be, pb );
#endif /* LDAP_SLAPI */

done:
	if( modlist != NULL ) {
		slap_mods_free( modlist );
	}
	if( e != NULL ) {
		entry_free( e );
	}

	return rc;
}
コード例 #15
0
ファイル: pam.c プロジェクト: fcelda/openldap
static int pam_sess(nssov_info *ni,TFILE *fp,Operation *op,int action)
{
	struct berval dn, uid, svc, tty, rhost, ruser;
	int32_t tmpint32;
	char dnc[1024];
	char svcc[256];
	char uidc[32];
	char ttyc[32];
	char rhostc[256];
	char ruserc[32];
	slap_callback cb = {0};
	SlapReply rs = {REP_RESULT};
	char timebuf[LDAP_LUTIL_GENTIME_BUFSIZE];
	struct berval timestamp, bv[2], *nbv;
	time_t stamp;
	Modifications mod;

	READ_STRING(fp,uidc);
	uid.bv_val = uidc;
	uid.bv_len = tmpint32;
	READ_STRING(fp,dnc);
	dn.bv_val = dnc;
	dn.bv_len = tmpint32;
	READ_STRING(fp,svcc);
	svc.bv_val = svcc;
	svc.bv_len = tmpint32;
	READ_STRING(fp,ttyc);
	tty.bv_val = ttyc;
	tty.bv_len = tmpint32;
	READ_STRING(fp,rhostc);
	rhost.bv_val = rhostc;
	rhost.bv_len = tmpint32;
	READ_STRING(fp,ruserc);
	ruser.bv_val = ruserc;
	ruser.bv_len = tmpint32;
	READ_INT32(fp,stamp);

	Debug(LDAP_DEBUG_TRACE,"nssov_pam_sess_%c(%s)\n",
		action==NSLCD_ACTION_PAM_SESS_O ? 'o' : 'c', dn.bv_val,0);

	if (!dn.bv_len || !ni->ni_pam_sessions) return 0;

	{
		int i, found=0;
		for (i=0; !BER_BVISNULL(&ni->ni_pam_sessions[i]); i++) {
			if (ni->ni_pam_sessions[i].bv_len != svc.bv_len)
				continue;
			if (!strcasecmp(ni->ni_pam_sessions[i].bv_val, svc.bv_val)) {
				found = 1;
				break;
			}
		}
		if (!found) return 0;
	}

	slap_op_time( &op->o_time, &op->o_tincr );
	timestamp.bv_len = sizeof(timebuf);
	timestamp.bv_val = timebuf;
	if (action == NSLCD_ACTION_PAM_SESS_O )
		stamp = op->o_time;
	slap_timestamp( &stamp, &timestamp );
	bv[0].bv_len = timestamp.bv_len + global_host_bv.bv_len + svc.bv_len +
		tty.bv_len + ruser.bv_len + rhost.bv_len + STRLENOF("    (@)");
	bv[0].bv_val = op->o_tmpalloc( bv[0].bv_len+1, op->o_tmpmemctx );
	sprintf(bv[0].bv_val, "%s %s %s %s (%s@%s)",
		timestamp.bv_val, global_host_bv.bv_val, svc.bv_val, tty.bv_val,
		ruser.bv_val, rhost.bv_val);
	
	mod.sml_numvals = 1;
	mod.sml_values = bv;
	BER_BVZERO(&bv[1]);
	attr_normalize( ad_loginStatus, bv, &nbv, op->o_tmpmemctx );
	mod.sml_nvalues = nbv;
	mod.sml_desc = ad_loginStatus;
	mod.sml_op = action == NSLCD_ACTION_PAM_SESS_O ? LDAP_MOD_ADD :
		LDAP_MOD_DELETE;
	mod.sml_flags = SLAP_MOD_INTERNAL;
	mod.sml_next = NULL;

	cb.sc_response = slap_null_cb;
	op->o_callback = &cb;
	op->o_tag = LDAP_REQ_MODIFY;
	op->o_dn = op->o_bd->be_rootdn;
	op->o_ndn = op->o_bd->be_rootndn;
	op->orm_modlist = &mod;
	op->orm_no_opattrs = 1;
	op->o_req_dn = dn;
	op->o_req_ndn = dn;
	op->o_bd->be_modify( op, &rs );
	if ( mod.sml_next ) {
		slap_mods_free( mod.sml_next, 1 );
	}
	ber_bvarray_free_x( nbv, op->o_tmpmemctx );

	WRITE_INT32(fp,NSLCD_VERSION);
	WRITE_INT32(fp,action);
	WRITE_INT32(fp,NSLCD_RESULT_BEGIN);
	WRITE_INT32(fp,op->o_time);
	return 0;
}
コード例 #16
0
ファイル: passwd.c プロジェクト: hellyhe/openldap-ga
int passwd_extop(
	Operation *op,
	SlapReply *rs )
{
	struct berval id = {0, NULL}, hash, *rsp = NULL;
	req_pwdexop_s *qpw = &op->oq_pwdexop;
	req_extended_s qext = op->oq_extended;
	Modifications *ml;
	slap_callback cb = { NULL, slap_null_cb, NULL, NULL };
	int i, nhash;
	char **hashes, idNul;
	int rc;
	BackendDB *op_be;
	int freenewpw = 0;
	struct berval dn = BER_BVNULL, ndn = BER_BVNULL;

	assert( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) == 0 );

	if( op->o_dn.bv_len == 0 ) {
		Statslog( LDAP_DEBUG_STATS, "%s PASSMOD\n",
			op->o_log_prefix, 0, 0, 0, 0 );
		rs->sr_text = "only authenticated users may change passwords";
		return LDAP_STRONG_AUTH_REQUIRED;
	}

	qpw->rs_old.bv_len = 0;
	qpw->rs_old.bv_val = NULL;
	qpw->rs_new.bv_len = 0;
	qpw->rs_new.bv_val = NULL;
	qpw->rs_mods = NULL;
	qpw->rs_modtail = NULL;

	rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id,
		&qpw->rs_old, &qpw->rs_new, &rs->sr_text );

	if ( !BER_BVISNULL( &id )) {
		idNul = id.bv_val[id.bv_len];
		id.bv_val[id.bv_len] = '\0';
	}
	if ( rs->sr_err == LDAP_SUCCESS && !BER_BVISEMPTY( &id ) ) {
		Statslog( LDAP_DEBUG_STATS, "%s PASSMOD id=\"%s\"%s%s\n",
			op->o_log_prefix, id.bv_val,
			qpw->rs_old.bv_val ? " old" : "",
			qpw->rs_new.bv_val ? " new" : "", 0 );
	} else {
		Statslog( LDAP_DEBUG_STATS, "%s PASSMOD%s%s\n",
			op->o_log_prefix,
			qpw->rs_old.bv_val ? " old" : "",
			qpw->rs_new.bv_val ? " new" : "", 0, 0 );
	}

	if ( rs->sr_err != LDAP_SUCCESS ) {
		if ( !BER_BVISNULL( &id ))
			id.bv_val[id.bv_len] = idNul;
		return rs->sr_err;
	}

	if ( !BER_BVISEMPTY( &id ) ) {
		rs->sr_err = dnPrettyNormal( NULL, &id, &dn, &ndn, op->o_tmpmemctx );
		id.bv_val[id.bv_len] = idNul;
		if ( rs->sr_err != LDAP_SUCCESS ) {
			rs->sr_text = "Invalid DN";
			rc = rs->sr_err;
			goto error_return;
		}
		op->o_req_dn = dn;
		op->o_req_ndn = ndn;
		op->o_bd = select_backend( &op->o_req_ndn, 1 );

	} else {
		ber_dupbv_x( &dn, &op->o_dn, op->o_tmpmemctx );
		ber_dupbv_x( &ndn, &op->o_ndn, op->o_tmpmemctx );
		op->o_req_dn = dn;
		op->o_req_ndn = ndn;
		ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
		op->o_bd = op->o_conn->c_authz_backend;
		ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
	}

	if( op->o_bd == NULL ) {
		if ( qpw->rs_old.bv_val != NULL ) {
			rs->sr_text = "unwilling to verify old password";
			rc = LDAP_UNWILLING_TO_PERFORM;
			goto error_return;
		}

#ifdef HAVE_CYRUS_SASL
		rc = slap_sasl_setpass( op, rs );
#else
		rs->sr_text = "no authz backend";
		rc = LDAP_OTHER;
#endif
		goto error_return;
	}

	if ( op->o_req_ndn.bv_len == 0 ) {
		rs->sr_text = "no password is associated with the Root DSE";
		rc = LDAP_UNWILLING_TO_PERFORM;
		goto error_return;
	}

	/* If we've got a glued backend, check the real backend */
	op_be = op->o_bd;
	if ( SLAP_GLUE_INSTANCE( op->o_bd )) {
		op->o_bd = select_backend( &op->o_req_ndn, 0 );
	}

	if (backend_check_restrictions( op, rs,
			(struct berval *)&slap_EXOP_MODIFY_PASSWD ) != LDAP_SUCCESS) {
		rc = rs->sr_err;
		goto error_return;
	}

	/* check for referrals */
	if ( backend_check_referrals( op, rs ) != LDAP_SUCCESS ) {
		rc = rs->sr_err;
		goto error_return;
	}

	/* This does not apply to multi-master case */
	if(!( !SLAP_SINGLE_SHADOW( op->o_bd ) || be_isupdate( op ))) {
		/* we SHOULD return a referral in this case */
		BerVarray defref = op->o_bd->be_update_refs
			? op->o_bd->be_update_refs : default_referral; 

		if( defref != NULL ) {
			rs->sr_ref = referral_rewrite( op->o_bd->be_update_refs,
				NULL, NULL, LDAP_SCOPE_DEFAULT );
			if(rs->sr_ref) {
				rs->sr_flags |= REP_REF_MUSTBEFREED;
			} else {
				rs->sr_ref = defref;
			}
			rc = LDAP_REFERRAL;
			goto error_return;

		}

		rs->sr_text = "shadow context; no update referral";
		rc = LDAP_UNWILLING_TO_PERFORM;
		goto error_return;
	}

	/* generate a new password if none was provided */
	if ( qpw->rs_new.bv_len == 0 ) {
		slap_passwd_generate( &qpw->rs_new );
		if ( qpw->rs_new.bv_len ) {
			rsp = slap_passwd_return( &qpw->rs_new );
			freenewpw = 1;
		}
	}
	if ( qpw->rs_new.bv_len == 0 ) {
		rs->sr_text = "password generation failed";
		rc = LDAP_OTHER;
		goto error_return;
	}

	op->o_bd = op_be;

	/* Give the backend a chance to handle this itself */
	if ( op->o_bd->be_extended ) {
		rs->sr_err = op->o_bd->be_extended( op, rs );
		if ( rs->sr_err != LDAP_UNWILLING_TO_PERFORM &&
			rs->sr_err != SLAP_CB_CONTINUE )
		{
			rc = rs->sr_err;
			if ( rsp ) {
				rs->sr_rspdata = rsp;
				rsp = NULL;
			}
			goto error_return;
		}
	}

	/* The backend didn't handle it, so try it here */
	if( op->o_bd && !op->o_bd->be_modify ) {
		rs->sr_text = "operation not supported for current user";
		rc = LDAP_UNWILLING_TO_PERFORM;
		goto error_return;
	}

	if ( qpw->rs_old.bv_val != NULL ) {
		Entry *e = NULL;

		rc = be_entry_get_rw( op, &op->o_req_ndn, NULL,
			slap_schema.si_ad_userPassword, 0, &e );
		if ( rc == LDAP_SUCCESS && e ) {
			Attribute *a = attr_find( e->e_attrs,
				slap_schema.si_ad_userPassword );
			if ( a )
				rc = slap_passwd_check( op, e, a, &qpw->rs_old, &rs->sr_text );
			else
				rc = 1;
			be_entry_release_r( op, e );
			if ( rc == LDAP_SUCCESS )
				goto old_good;
		}
		rs->sr_text = "unwilling to verify old password";
		rc = LDAP_UNWILLING_TO_PERFORM;
		goto error_return;
	}

old_good:
	ml = ch_malloc( sizeof(Modifications) );
	if ( !qpw->rs_modtail ) qpw->rs_modtail = &ml->sml_next;

	if ( default_passwd_hash ) {
		for ( nhash = 0; default_passwd_hash[nhash]; nhash++ );
		hashes = default_passwd_hash;
	} else {
		nhash = 1;
		hashes = (char **)defhash;
	}
	ml->sml_numvals = nhash;
	ml->sml_values = ch_malloc( (nhash+1)*sizeof(struct berval) );
	for ( i=0; hashes[i]; i++ ) {
		slap_passwd_hash_type( &qpw->rs_new, &hash, hashes[i], &rs->sr_text );
		if ( hash.bv_len == 0 ) {
			if ( !rs->sr_text ) {
				rs->sr_text = "password hash failed";
			}
			break;
		}
		ml->sml_values[i] = hash;
	}
	ml->sml_values[i].bv_val = NULL;
	ml->sml_nvalues = NULL;
	ml->sml_desc = slap_schema.si_ad_userPassword;
	ml->sml_type = ml->sml_desc->ad_cname;
	ml->sml_op = LDAP_MOD_REPLACE;
	ml->sml_flags = 0;
	ml->sml_next = qpw->rs_mods;
	qpw->rs_mods = ml;

	if ( hashes[i] ) {
		rs->sr_err = LDAP_OTHER;

	} else {
		slap_callback *sc = op->o_callback;

		op->o_tag = LDAP_REQ_MODIFY;
		op->o_callback = &cb;
		op->orm_modlist = qpw->rs_mods;
		op->orm_no_opattrs = 0;
		
		cb.sc_private = qpw;	/* let Modify know this was pwdMod,
					 * if it cares... */

		rs->sr_err = op->o_bd->be_modify( op, rs );

		/* be_modify() might have shuffled modifications */
		qpw->rs_mods = op->orm_modlist;

		if ( rs->sr_err == LDAP_SUCCESS ) {
			rs->sr_rspdata = rsp;

		} else if ( rsp ) {
			ber_bvfree( rsp );
			rsp = NULL;
		}
		op->o_tag = LDAP_REQ_EXTENDED;
		op->o_callback = sc;
	}

	rc = rs->sr_err;
	op->oq_extended = qext;

error_return:;
	if ( qpw->rs_mods ) {
		slap_mods_free( qpw->rs_mods, 1 );
	}
	if ( freenewpw ) {
		free( qpw->rs_new.bv_val );
	}
	if ( !BER_BVISNULL( &dn ) ) {
		op->o_tmpfree( dn.bv_val, op->o_tmpmemctx );
		BER_BVZERO( &op->o_req_dn );
	}
	if ( !BER_BVISNULL( &ndn ) ) {
		op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
		BER_BVZERO( &op->o_req_ndn );
	}

	return rc;
}
コード例 #17
0
ファイル: vernum.c プロジェクト: ystk/debian-openldap
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;
}
コード例 #18
0
ファイル: dds.c プロジェクト: Smilefant/ReOpenLDAP
static int
dds_op_extended( Operation *op, SlapReply *rs )
{
	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;
	dds_info_t	*di = on->on_bi.bi_private;

	if ( DDS_OFF( di ) ) {
		return SLAP_CB_CONTINUE;
	}

	if ( bvmatch( &op->ore_reqoid, &slap_EXOP_REFRESH ) ) {
		Entry		*e = NULL;
		time_t		ttl;
		BackendDB	db = *op->o_bd;
		SlapReply	rs2 = { REP_RESULT };
		Operation	op2 = *op;
		slap_callback	sc = { 0 };
		Modifications	ttlmod = { { 0 } };
		struct berval	ttlvalues[ 2 ];
		char		ttlbuf[STRLENOF("31557600") + 1];

		rs->sr_err = slap_parse_refresh( op->ore_reqdata, NULL, &ttl,
			&rs->sr_text, NULL );
		assert( rs->sr_err == LDAP_SUCCESS );

		if ( ttl <= 0 || ttl > DDS_RF2589_MAX_TTL ) {
			rs->sr_err = LDAP_PROTOCOL_ERROR;
			rs->sr_text = "invalid time-to-live for dynamicObject";
			return rs->sr_err;
		}

		if ( ttl > di->di_max_ttl ) {
			/* FIXME: I don't understand if this has to be an error,
			 * or an indication that the requested Ttl has been
			 * shortened to di->di_max_ttl >= 1 day */
			rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
			rs->sr_text = "time-to-live for dynamicObject exceeds limit";
			return rs->sr_err;
		}

		if ( di->di_min_ttl && ttl < di->di_min_ttl ) {
			ttl = di->di_min_ttl;
		}

		/* This does not apply to multi-master case */
		if ( !( !SLAP_SINGLE_SHADOW( op->o_bd ) || be_isupdate( op ) ) ) {
			/* we SHOULD return a referral in this case */
			BerVarray defref = op->o_bd->be_update_refs
				? op->o_bd->be_update_refs : default_referral;

			if ( defref != NULL ) {
				rs->sr_ref = referral_rewrite( op->o_bd->be_update_refs,
					NULL, NULL, LDAP_SCOPE_DEFAULT );
				if ( rs->sr_ref ) {
					rs->sr_flags |= REP_REF_MUSTBEFREED;
				} else {
					rs->sr_ref = defref;
				}
				rs->sr_err = LDAP_REFERRAL;

			} else {
				rs->sr_text = "shadow context; no update referral";
				rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			}

			return rs->sr_err;
		}

		assert( !BER_BVISNULL( &op->o_req_ndn ) );



		/* check if exists but not dynamicObject */
		op->o_bd->bd_info = (BackendInfo *)on->on_info;
		rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn,
			slap_schema.si_oc_dynamicObject, NULL, 0, &e );
		if ( rs->sr_err != LDAP_SUCCESS ) {
			rs->sr_err = be_entry_get_rw( op, &op->o_req_ndn,
				NULL, NULL, 0, &e );
			if ( rs->sr_err == LDAP_SUCCESS && e != NULL ) {
				/* return referral only if "disclose"
				 * is granted on the object */
				if ( ! access_allowed( op, e,
						slap_schema.si_ad_entry,
						NULL, ACL_DISCLOSE, NULL ) )
				{
					rs->sr_err = LDAP_NO_SUCH_OBJECT;

				} else {
					rs->sr_err = LDAP_OBJECT_CLASS_VIOLATION;
					rs->sr_text = "refresh operation only applies to dynamic objects";
				}
				be_entry_release_r( op, e );

			} else {
				rs->sr_err = LDAP_NO_SUCH_OBJECT;
			}
			return rs->sr_err;

		} else if ( e != NULL ) {
			be_entry_release_r( op, e );
		}

		/* we require manage privileges on the entryTtl,
		 * and fake a Relax control */
		op2.o_tag = LDAP_REQ_MODIFY;
		op2.o_bd = &db;
		db.bd_info = (BackendInfo *)on->on_info;
		op2.o_callback = &sc;
		sc.sc_response = slap_null_cb;
		op2.o_relax = SLAP_CONTROL_CRITICAL;
		op2.orm_modlist = &ttlmod;

		ttlmod.sml_op = LDAP_MOD_REPLACE;
		ttlmod.sml_flags = SLAP_MOD_MANAGING;
		ttlmod.sml_desc = slap_schema.si_ad_entryTtl;
		ttlmod.sml_values = ttlvalues;
		ttlmod.sml_numvals = 1;
		ttlvalues[ 0 ].bv_val = ttlbuf;
		ttlvalues[ 0 ].bv_len = snprintf( ttlbuf, sizeof( ttlbuf ), "%ld", ttl );
		BER_BVZERO( &ttlvalues[ 1 ] );

		/* the entryExpireTimestamp is added by modify */
		rs->sr_err = slap_biglock_call_be( op_modify, &op2, &rs2 );

		if ( ttlmod.sml_next != NULL ) {
			slap_mods_free( ttlmod.sml_next, 1 );
		}

		if ( rs->sr_err == LDAP_SUCCESS ) {
			int			rc;
			BerElementBuffer	berbuf;
			BerElement		*ber = (BerElement *)&berbuf;

			ber_init_w_nullc( ber, LBER_USE_DER );

			rc = ber_printf( ber, "{tiN}", LDAP_TAG_EXOP_REFRESH_RES_TTL, (int)ttl );

			if ( rc < 0 ) {
				rs->sr_err = LDAP_OTHER;
				rs->sr_text = "internal error";

			} else {
				(void)ber_flatten( ber, &rs->sr_rspdata );
				rs->sr_rspoid = ch_strdup( slap_EXOP_REFRESH.bv_val );

				Log3( LDAP_DEBUG_TRACE, LDAP_LEVEL_INFO,
					"%s REFRESH dn=\"%s\" TTL=%ld\n",
					op->o_log_prefix, op->o_req_ndn.bv_val, ttl );
			}

			ber_free_buf( ber );
		}

		return rs->sr_err;
	}

	return SLAP_CB_CONTINUE;
}