Esempio n. 1
0
static int
dynacl_aci_parse(
	const char *fname,
	int lineno,
	const char *opts,
	slap_style_t sty,
	const char *right,
	void **privp )
{
	AttributeDescription	*ad = NULL;
	const char		*text = NULL;

	if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
		fprintf( stderr, "%s: line %d: "
			"inappropriate style \"%s\" in \"aci\" by clause\n",
			fname, lineno, style_strings[sty] );
		return -1;
	}

	if ( right != NULL && *right != '\0' ) {
		if ( slap_str2ad( right, &ad, &text ) != LDAP_SUCCESS ) {
			fprintf( stderr,
				"%s: line %d: aci \"%s\": %s\n",
				fname, lineno, right, text );
			return -1;
		}

	} else {
		ad = slap_ad_aci;
	}

	if ( !is_at_syntax( ad->ad_type, SLAPD_ACI_SYNTAX) ) {
		fprintf( stderr, "%s: line %d: "
			"aci \"%s\": inappropriate syntax: %s\n",
			fname, lineno, right,
			ad->ad_type->sat_syntax_oid );
		return -1;
	}

	*privp = (void *)ad;

	return 0;
}
Esempio n. 2
0
/*
 * Do basic attribute type checking and syntax validation.
 */
int slap_mods_check(
	Operation *op,
	Modifications *ml,
	const char **text,
	char *textbuf,
	size_t textlen,
	void *ctx )
{
	int rc;

	for( ; ml != NULL; ml = ml->sml_next ) {
		AttributeDescription *ad = NULL;

		/* convert to attribute description */
		if ( ml->sml_desc == NULL ) {
			rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, text );
			if( rc != LDAP_SUCCESS ) {
				if ( get_no_schema_check( op )) {
					rc = slap_bv2undef_ad( &ml->sml_type, &ml->sml_desc,
						text, 0 );
				}
			}
			if( rc != LDAP_SUCCESS ) {
				snprintf( textbuf, textlen, "%s: %s",
					ml->sml_type.bv_val, *text );
				*text = textbuf;
				return rc;
			}
		}

		ad = ml->sml_desc;

		if( slap_syntax_is_binary( ad->ad_type->sat_syntax )
			&& !slap_ad_is_binary( ad ))
		{
			/* attribute requires binary transfer */
			snprintf( textbuf, textlen,
				"%s: requires ;binary transfer",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_UNDEFINED_TYPE;
		}

		if( !slap_syntax_is_binary( ad->ad_type->sat_syntax )
			&& slap_ad_is_binary( ad ))
		{
			/* attribute does not require binary transfer */
			snprintf( textbuf, textlen,
				"%s: disallows ;binary transfer",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_UNDEFINED_TYPE;
		}

		if( slap_ad_is_tag_range( ad )) {
			/* attribute requires binary transfer */
			snprintf( textbuf, textlen,
				"%s: inappropriate use of tag range option",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_UNDEFINED_TYPE;
		}

#if 0
		if ( is_at_obsolete( ad->ad_type ) &&
			(( ml->sml_op != LDAP_MOD_REPLACE &&
				ml->sml_op != LDAP_MOD_DELETE ) ||
					ml->sml_values != NULL ))
		{
			/*
			 * attribute is obsolete,
			 * only allow replace/delete with no values
			 */
			snprintf( textbuf, textlen,
				"%s: attribute is obsolete",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_CONSTRAINT_VIOLATION;
		}
#endif

		if ( ml->sml_op == LDAP_MOD_INCREMENT &&
#ifdef SLAPD_REAL_SYNTAX
			!is_at_syntax( ad->ad_type, SLAPD_REAL_SYNTAX ) &&
#endif
			!is_at_syntax( ad->ad_type, SLAPD_INTEGER_SYNTAX ) )
		{
			/*
			 * attribute values must be INTEGER or REAL
			 */
			snprintf( textbuf, textlen,
				"%s: attribute syntax inappropriate for increment",
				ml->sml_type.bv_val );
			*text = textbuf;
			return LDAP_CONSTRAINT_VIOLATION;
		}

		/*
		 * check values
		 */
		if( ml->sml_values != NULL ) {
			ber_len_t nvals;
			slap_syntax_validate_func *validate =
				ad->ad_type->sat_syntax->ssyn_validate;
			slap_syntax_transform_func *pretty =
				ad->ad_type->sat_syntax->ssyn_pretty;
 
			if( !pretty && !validate ) {
				*text = "no validator for syntax";
				snprintf( textbuf, textlen,
					"%s: no validator for syntax %s",
					ml->sml_type.bv_val,
					ad->ad_type->sat_syntax->ssyn_oid );
				*text = textbuf;
				return LDAP_INVALID_SYNTAX;
			}

			/*
			 * check that each value is valid per syntax
			 *	and pretty if appropriate
			 */
			for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) {
				struct berval pval;

				if ( pretty ) {
					rc = ordered_value_pretty( ad,
						&ml->sml_values[nvals], &pval, ctx );
				} else {
					rc = ordered_value_validate( ad,
						&ml->sml_values[nvals], ml->sml_op );
				}

				if( rc != 0 ) {
					snprintf( textbuf, textlen,
						"%s: value #%ld invalid per syntax",
						ml->sml_type.bv_val, (long) nvals );
					*text = textbuf;
					return LDAP_INVALID_SYNTAX;
				}

				if( pretty ) {
					ber_memfree_x( ml->sml_values[nvals].bv_val, ctx );
					ml->sml_values[nvals] = pval;
				}
			}
			ml->sml_values[nvals].bv_len = 0;
			ml->sml_numvals = nvals;

			/*
			 * a rough single value check... an additional check is needed
			 * to catch add of single value to existing single valued attribute
			 */
			if ((ml->sml_op == LDAP_MOD_ADD || ml->sml_op == LDAP_MOD_REPLACE)
				&& nvals > 1 && is_at_single_value( ad->ad_type ))
			{
				snprintf( textbuf, textlen,
					"%s: multiple values provided",
					ml->sml_type.bv_val );
				*text = textbuf;
				return LDAP_CONSTRAINT_VIOLATION;
			}

			/* if the type has a normalizer, generate the
			 * normalized values. otherwise leave them NULL.
			 *
			 * this is different from the rule for attributes
			 * in an entry - in an attribute list, the normalized
			 * value is set equal to the non-normalized value
			 * when there is no normalizer.
			 */
			if( nvals && ad->ad_type->sat_equality &&
				ad->ad_type->sat_equality->smr_normalize )
			{
				ml->sml_nvalues = ber_memalloc_x(
					(nvals+1)*sizeof(struct berval), ctx );

				for ( nvals = 0; !BER_BVISNULL( &ml->sml_values[nvals] ); nvals++ ) {
					rc = ordered_value_normalize(
						SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
						ad,
						ad->ad_type->sat_equality,
						&ml->sml_values[nvals], &ml->sml_nvalues[nvals], ctx );
					if ( rc ) {
						Debug( LDAP_DEBUG_ANY,
							"<= str2entry NULL (ssyn_normalize %d)\n",
							rc, 0, 0 );
						snprintf( textbuf, textlen,
							"%s: value #%ld normalization failed",
							ml->sml_type.bv_val, (long) nvals );
						*text = textbuf;
						BER_BVZERO( &ml->sml_nvalues[nvals] );
						return rc;
					}
				}

				BER_BVZERO( &ml->sml_nvalues[nvals] );
			}

			/* check for duplicates, but ignore Deletes.
			 */
			if( nvals > 1 && ml->sml_op != LDAP_MOD_DELETE ) {
				int i;
				rc = slap_sort_vals( ml, text, &i, ctx );
				if ( rc == LDAP_TYPE_OR_VALUE_EXISTS ) {
					/* value exists already */
					snprintf( textbuf, textlen,
						"%s: value #%d provided more than once",
						ml->sml_desc->ad_cname.bv_val, i );
					*text = textbuf;
				}
				if ( rc )
					return rc;
			}
		} else {
			ml->sml_numvals = 0;
		}
	}

	return LDAP_SUCCESS;
}