コード例 #1
0
ファイル: ad.c プロジェクト: cptaffe/openldap
int ad_inlist(
	AttributeDescription *desc,
	AttributeName *attrs )
{
	if (! attrs ) return 0;

	for( ; attrs->an_name.bv_val; attrs++ ) {
		AttributeType *a;
		ObjectClass *oc;
		
		if ( attrs->an_desc ) {
			int lr;

			if ( desc == attrs->an_desc ) {
				return 1;
			}

			/*
			 * EXTENSION: if requested description is preceeded by
			 * a '-' character, do not match on subtypes.
			 */
			if ( attrs->an_name.bv_val[0] == '-' ) {
				continue;
			}
			
			/* Is this a subtype of the requested attr? */
			for (a = desc->ad_type; a; a=a->sat_sup) {
				if ( a == attrs->an_desc->ad_type )
					break;
			}
			if ( !a ) {
				continue;
			}
			/* Does desc support all the requested flags? */
			lr = desc->ad_tags.bv_len ? SLAP_DESC_TAG_RANGE : 0;
			if(( attrs->an_desc->ad_flags & (desc->ad_flags | lr))
				!= attrs->an_desc->ad_flags ) {
				continue;
			}
			/* Do the descs have compatible tags? */
			if ( attrs->an_desc->ad_tags.bv_len == 0 ) {
				return 1;
			}
			if ( desc->ad_tags.bv_len == 0) {
				continue;
			}
			if ( is_ad_subtags( &desc->ad_tags,
				&attrs->an_desc->ad_tags ) ) {
				return 1;
			}
			continue;
		}

		if ( ber_bvccmp( &attrs->an_name, '*' ) ) {
			if ( !is_at_operational( desc->ad_type ) ) {
				return 1;
			}
			continue;
		}

		if ( ber_bvccmp( &attrs->an_name, '+' ) ) {
			if ( is_at_operational( desc->ad_type ) ) {
				return 1;
			}
			continue;
		}

		/*
		 * EXTENSION: see if requested description is @objectClass
		 * if so, return attributes which the class requires/allows
		 * else if requested description is !objectClass, return
		 * attributes which the class does not require/allow
		 */
		if ( !( attrs->an_flags & SLAP_AN_OCINITED )) {
			if( attrs->an_name.bv_val ) {
				switch( attrs->an_name.bv_val[0] ) {
				case '@': /* @objectClass */
				case '+': /* +objectClass (deprecated) */
				case '!': { /* exclude */
						struct berval ocname;
						ocname.bv_len = attrs->an_name.bv_len - 1;
						ocname.bv_val = &attrs->an_name.bv_val[1];
						oc = oc_bvfind( &ocname );
						if ( oc && attrs->an_name.bv_val[0] == '!' ) {
							attrs->an_flags |= SLAP_AN_OCEXCLUDE;
						} else {
							attrs->an_flags &= ~SLAP_AN_OCEXCLUDE;
						}
					} break;

				default: /* old (deprecated) way */
					oc = oc_bvfind( &attrs->an_name );
				}
				attrs->an_oc = oc;
			}
			attrs->an_flags |= SLAP_AN_OCINITED;
		}
		oc = attrs->an_oc;
		if( oc != NULL ) {
			if ( attrs->an_flags & SLAP_AN_OCEXCLUDE ) {
				if ( oc == slap_schema.si_oc_extensibleObject ) {
					/* extensibleObject allows the return of anything */
					return 0;
				}

				if( oc->soc_required ) {
					/* allow return of required attributes */
					int i;
				
   					for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
						for (a = desc->ad_type; a; a=a->sat_sup) {
							if ( a == oc->soc_required[i] ) {
								return 0;
							}
						}
					}
				}

				if( oc->soc_allowed ) {
					/* allow return of allowed attributes */
					int i;
   					for ( i = 0; oc->soc_allowed[i] != NULL; i++ ) {
						for (a = desc->ad_type; a; a=a->sat_sup) {
							if ( a == oc->soc_allowed[i] ) {
								return 0;
							}
						}
					}
				}

				return 1;
			}
			
			if ( oc == slap_schema.si_oc_extensibleObject ) {
				/* extensibleObject allows the return of anything */
				return 1;
			}

			if( oc->soc_required ) {
				/* allow return of required attributes */
				int i;
				
   				for ( i = 0; oc->soc_required[i] != NULL; i++ ) {
					for (a = desc->ad_type; a; a=a->sat_sup) {
						if ( a == oc->soc_required[i] ) {
							return 1;
						}
					}
				}
			}

			if( oc->soc_allowed ) {
				/* allow return of allowed attributes */
				int i;
   				for ( i = 0; oc->soc_allowed[i] != NULL; i++ ) {
					for (a = desc->ad_type; a; a=a->sat_sup) {
						if ( a == oc->soc_allowed[i] ) {
							return 1;
						}
					}
				}
			}

		} else {
			const char      *text;

			/* give it a chance of being retrieved by a proxy... */
			(void)slap_bv2undef_ad( &attrs->an_name,
				&attrs->an_desc, &text,
				SLAP_AD_PROXIED|SLAP_AD_NOINSERT );
		}
	}

	return 0;
}
コード例 #2
0
ファイル: gssacl.c プロジェクト: jaredmcneill/netbsd-src
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;
}