示例#1
0
static int
regex_matches(
	struct berval	*pat,		/* pattern to expand and match against */
	char		*str,		/* string to match against pattern */
	struct berval	*dn_matches,	/* buffer with $N expansion variables from DN */
	struct berval	*val_matches,	/* buffer with $N expansion variables from val */
	AclRegexMatches	*matches	/* offsets in buffer for $N expansion variables */
)
{
	regex_t re;
	char newbuf[ACL_BUF_SIZE];
	struct berval bv;
	int	rc;

	bv.bv_len = sizeof( newbuf ) - 1;
	bv.bv_val = newbuf;

	if (str == NULL) {
		str = "";
	};

	acl_string_expand( &bv, pat, dn_matches, val_matches, matches );
	rc = regcomp( &re, newbuf, REG_EXTENDED|REG_ICASE );
	if ( rc ) {
		char error[ACL_BUF_SIZE];
		regerror( rc, &re, error, sizeof( error ) );

		Debug( LDAP_DEBUG_TRACE,
		    "compile( \"%s\", \"%s\") failed %s\n",
			pat->bv_val, str, error );
		return( 0 );
	}

	rc = regexec( &re, str, 0, NULL, 0 );
	regfree( &re );

	Debug( LDAP_DEBUG_TRACE,
	    "=> regex_matches: string:	 %s\n", str, 0, 0 );
	Debug( LDAP_DEBUG_TRACE,
	    "=> regex_matches: rc: %d %s\n",
		rc, !rc ? "matches" : "no matches", 0 );
	return( !rc );
}
示例#2
0
static int
aci_group_member (
	struct berval		*subj,
	const struct berval	*defgrpoc,
	const struct berval	*defgrpat,
	Operation		*op,
	Entry			*e,
	int			nmatch,
	regmatch_t		*matches
)
{
	struct berval		subjdn;
	struct berval		grpoc;
	struct berval		grpat;
	ObjectClass		*grp_oc = NULL;
	AttributeDescription	*grp_ad = NULL;
	const char		*text;
	int			rc;

	/* format of string is "{group|role}/objectClassValue/groupAttrName" */
	if ( acl_get_part( subj, 0, '/', &subjdn ) < 0 ) {
		return 0;
	}

	if ( acl_get_part( subj, 1, '/', &grpoc ) < 0 ) {
		grpoc = *defgrpoc;
	}

	if ( acl_get_part( subj, 2, '/', &grpat ) < 0 ) {
		grpat = *defgrpat;
	}

	rc = slap_bv2ad( &grpat, &grp_ad, &text );
	if ( rc != LDAP_SUCCESS ) {
		rc = 0;
		goto done;
	}
	rc = 0;

	grp_oc = oc_bvfind( &grpoc );

	if ( grp_oc != NULL && grp_ad != NULL ) {
		char		buf[ ACI_BUF_SIZE ];
		struct berval	bv, ndn;
		AclRegexMatches amatches = { 0 };

		amatches.dn_count = nmatch;
		memcpy( amatches.dn_data, matches, sizeof( amatches.dn_data ) );

		bv.bv_len = sizeof( buf ) - 1;
		bv.bv_val = (char *)&buf;
		if ( acl_string_expand( &bv, &subjdn,
				&e->e_nname, NULL, &amatches ) )
		{
			rc = LDAP_OTHER;
			goto done;
		}

		if ( dnNormalize( 0, NULL, NULL, &bv, &ndn, op->o_tmpmemctx ) == LDAP_SUCCESS )
		{
			rc = ( backend_group( op, e, &ndn, &op->o_ndn,
				grp_oc, grp_ad ) == 0 );
			slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
		}
	}

done:
	return rc;
}
示例#3
0
static int
pg_dynacl_mask(
	void			*priv,
	Operation		*op,
	Entry			*target,
	AttributeDescription	*desc,
	struct berval		*val,
	int			nmatch,
	regmatch_t		*matches,
	slap_access_t		*grant,
	slap_access_t		*deny )
{
	pg_t		*pg = (pg_t *)priv;
	Entry		*group = NULL,
			*user = NULL;
	int		rc;
	Backend		*be = op->o_bd,
			*group_be = NULL,
			*user_be = NULL;
	struct berval	group_ndn;

	ACL_INVALIDATE( *deny );

	/* get user */
	if ( target && dn_match( &target->e_nname, &op->o_ndn ) ) {
		user = target;
		rc = LDAP_SUCCESS;

	} else {
		user_be = op->o_bd = select_backend( &op->o_ndn, 0 );
		if ( op->o_bd == NULL ) {
			op->o_bd = be;
			return 0;
		}
		rc = be_entry_get_rw( op, &op->o_ndn, pg_posixAccount, pg_uidNumber, 0, &user );
	}

	if ( rc != LDAP_SUCCESS || user == NULL ) {
		op->o_bd = be;
		return 0;
	}

	/* get target */
	if ( pg->pg_style == ACL_STYLE_EXPAND ) {
		char		buf[ 1024 ];
		struct berval	bv;
		AclRegexMatches amatches = { 0 };

		amatches.dn_count = nmatch;
		AC_MEMCPY( amatches.dn_data, matches, sizeof( amatches.dn_data ) );

		bv.bv_len = sizeof( buf ) - 1;
		bv.bv_val = buf;

		if ( acl_string_expand( &bv, &pg->pg_pat,
				&target->e_nname,
				NULL, &amatches ) )
		{
			goto cleanup;
		}

		if ( dnNormalize( 0, NULL, NULL, &bv, &group_ndn,
				op->o_tmpmemctx ) != LDAP_SUCCESS )
		{
			/* did not expand to a valid dn */
			goto cleanup;
		}
		
	} else {
		group_ndn = pg->pg_pat;
	}

	if ( target && dn_match( &target->e_nname, &group_ndn ) ) {
		group = target;
		rc = LDAP_SUCCESS;

	} else {
		group_be = op->o_bd = select_backend( &group_ndn, 0 );
		if ( op->o_bd == NULL ) {
			goto cleanup;
		}
		rc = be_entry_get_rw( op, &group_ndn, pg_posixGroup, pg_memberUid, 0, &group );
	}

	if ( group_ndn.bv_val != pg->pg_pat.bv_val ) {
		op->o_tmpfree( group_ndn.bv_val, op->o_tmpmemctx );
	}

	if ( rc == LDAP_SUCCESS && group != NULL ) {
		Attribute	*a_uid,
				*a_member;

		a_uid = attr_find( user->e_attrs, pg_uidNumber );
		if ( !a_uid || !BER_BVISNULL( &a_uid->a_nvals[ 1 ] ) ) {
			rc = LDAP_NO_SUCH_ATTRIBUTE;

		} else {
			a_member = attr_find( group->e_attrs, pg_memberUid );
			if ( !a_member ) {
				rc = LDAP_NO_SUCH_ATTRIBUTE;

			} else {
				rc = value_find_ex( pg_memberUid,
					SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
					SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
					a_member->a_nvals, &a_uid->a_nvals[ 0 ],
					op->o_tmpmemctx );
			}
		}

	} else {
		rc = LDAP_NO_SUCH_OBJECT;
	}


	if ( rc == LDAP_SUCCESS ) {
		ACL_LVL_ASSIGN_WRITE( *grant );
	}

cleanup:;
	if ( group != NULL && group != target ) {
		op->o_bd = group_be;
		be_entry_release_r( op, group );
		op->o_bd = be;
	}

	if ( user != NULL && user != target ) {
		op->o_bd = user_be;
		be_entry_release_r( op, user );
		op->o_bd = be;
	}

	return 0;
}
示例#4
0
static int
gssattr_dynacl_mask(
	void			*priv,
	Operation		*op,
	Entry			*target,
	AttributeDescription	*desc,
	struct berval		*val,
	int			nmatch,
	regmatch_t		*matches,
	slap_access_t		*grant,
	slap_access_t		*deny )
{
	gssattr_t	*gssattr = (gssattr_t *)priv;
	sasl_conn_t	*sasl_ctx = op->o_conn->c_sasl_authctx;
	gss_name_t	gss_name = GSS_C_NO_NAME;
	OM_uint32	major, minor;
	int		more = -1;
	int		authenticated, complete;
	gss_buffer_desc	attr = GSS_C_EMPTY_BUFFER;
	int		granted = 0;

	ACL_INVALIDATE( *deny );

	if ( sasl_ctx == NULL ||
	     sasl_getprop( sasl_ctx, SASL_GSS_PEER_NAME, (const void **)&gss_name) != 0 ||
	     gss_name == GSS_C_NO_NAME ) {
		return 0;
	}

	attr.length = gssattr->gssattr_name.bv_len;
	attr.value = gssattr->gssattr_name.bv_val;

	while ( more != 0 ) {
		AclRegexMatches amatches = { 0 };
		gss_buffer_desc	gss_value = GSS_C_EMPTY_BUFFER;
		gss_buffer_desc	gss_display_value = GSS_C_EMPTY_BUFFER;
		struct berval bv_value;

		major = gss_get_name_attribute( &minor, gss_name, &attr,
						&authenticated, &complete,
						&gss_value, &gss_display_value, &more );
		if ( GSS_ERROR( major ) ) {
			break;
		} else if ( authenticated == 0 ) {
			gss_release_buffer( &minor, &gss_value );
			gss_release_buffer( &minor, &gss_display_value );
			continue;
		}

		bv_value.bv_len = gss_value.length;
		bv_value.bv_val = (char *)gss_value.value;

		if ( !ber_bvccmp( &gssattr->gssattr_value, '*' ) ) {
			if ( gssattr->gssattr_style != ACL_STYLE_BASE ) {
				amatches.dn_count = nmatch;
				AC_MEMCPY( amatches.dn_data, matches, sizeof( amatches.dn_data ) );
			}

			switch ( gssattr->gssattr_style ) {
			case ACL_STYLE_REGEX:
				/* XXX assumes value NUL terminated */
				granted = regex_matches( &gssattr->gssattr_value, bv_value.bv_val,
							  &target->e_nname, val, &amatches );
				break;
			case ACL_STYLE_EXPAND: {
				struct berval bv;
				char buf[ACL_BUF_SIZE];

				bv.bv_len = sizeof( buf ) - 1;
				bv.bv_val = buf;

				granted = ( acl_string_expand( &bv, &gssattr->gssattr_value,
							       &target->e_nname, val,
							       &amatches ) == 0 ) &&
					  ( ber_bvstrcmp( &bv, &bv_value) == 0 );
				break;
			}
			case ACL_STYLE_BASE:
				granted = ( ber_bvstrcmp( &gssattr->gssattr_value, &bv_value ) == 0 );
				break;
			default:
				assert(0);
				break;
			}
		} else {
			granted = 1;
		}

		gss_release_buffer( &minor, &gss_value );
		gss_release_buffer( &minor, &gss_display_value );

		if ( granted ) {
			break;
		}
	}

	if ( granted ) {
		ACL_LVL_ASSIGN_WRITE( *grant );
	}

	return 0;
}