Exemplo n.º 1
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;
}
Exemplo n.º 2
0
static int
idattr_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 )
{
    idattr_t		*id = (idattr_t *)priv;
    Entry   *user = NULL;
    int		rc = LDAP_INSUFFICIENT_ACCESS;
    int		user_rc = LDAP_INSUFFICIENT_ACCESS;
    int		target_rc = LDAP_INSUFFICIENT_ACCESS;
    Backend		*be = op->o_bd,
                 *group_be = NULL,
                  *user_be = NULL;
    AttributeDescription *searchAttr = NULL;
    ObjectClass *searchObject = NULL;
    struct berval *searchTarget = NULL;
    Entry *searchEntry = NULL;

    ACL_INVALIDATE( *deny );

    Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: pat(%s) type(%d) op(%d)\n", id->idattr_pat.bv_val, id->idattr_type, id->idattr_ops );

    Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: target(%s) op->o_ndn(%s)\n", target->e_nname.bv_val, op->o_ndn.bv_val, 0 );

    if (id->idattr_ops && (id->idattr_ops != op->o_tag)) {
        Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask:  Operation Not Allowed - Ops allowed (%d), Requested Op (%d)\n", id->idattr_ops, op->o_tag, 0 );
        // LDAP_INSUFFICIENT_ACCESS
        return 0;
    }

    if (!op->o_conn->c_authz.c_sai_krb5_auth_data_provisioned) {
        user_be = op->o_bd = select_backend( &op->o_ndn, 0);
        if ( op->o_bd == NULL ) {
            Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: op->o_bd == NULL \n", 0, 0, 0 );
            op->o_bd = be;
            return 0;
        }
    }
    // check ACL TYPE
    Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: idattr_type(%d)\n", id->idattr_type, 0, 0 );
    if (id->idattr_type == UUID_TYPE || id->idattr_type == OWNER_TYPE) {
        searchAttr = idattr_uuid;
        searchObject = idattr_extensible_object;
        searchTarget = &op->o_ndn;
    } else if (id->idattr_type == SID_TYPE) {
        searchAttr = idattr_sid;
        searchObject = idattr_extensible_object;
        searchTarget = &op->o_conn->c_authz.sai_ndn;
    } else if (id->idattr_type == SELFWRITE_TYPE) {
        searchAttr = id->idattr_selfattrDesc;
        searchObject = idattr_extensible_object;
        searchTarget = &op->o_ndn;
    } else if (id->idattr_type == USERS_TYPE) {
        if (BER_BVISEMPTY( &op->o_ndn )) {
            // LDAP_INSUFFICIENT_ACCESS
            op->o_bd = be;
            return 0;
        } else {
            // check for APPLYTO clause
            if (id->idattr_applyto) {
                rc = idattr_check_applyto(op, target, searchAttr, id);
            } else {
                rc =  LDAP_SUCCESS;
            }
            goto assignaccess;
        }
    } else {
        Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: unknown idattr_type(%s)\n", id->idattr_type, 0, 0 );
        // LDAP_INSUFFICIENT_ACCESS
        return 0;
    }
    if (op->o_conn->c_authz.c_sai_krb5_auth_data_provisioned) {
        user_rc = LDAP_SUCCESS;
    } else if (searchAttr) {
        // lookup user record
        user_rc = be_entry_get_rw( op, searchTarget, NULL, searchAttr, 0, &user );

        Debug( LDAP_DEBUG_ACL, "idattr_dynacl_mask: be_entry_get_rw user_rc(%d) user(%x) \n", user_rc, user, 0 );

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

    if ( user_rc == LDAP_SUCCESS || user != NULL ) {
        user_rc = idattr_check_isuser(op, user, searchAttr, id);

        if (user_rc == LDAP_SUCCESS) {
            switch ( id->idattr_type ) {
            case SELFWRITE_TYPE:
                user_rc = idattr_check_selfwrite(op, target, user, val, id);
                break;
            case OWNER_TYPE:
                user_rc = idattr_check_isowner(op, user, target, searchAttr, id);
                break;
            case UUID_TYPE:
            case SID_TYPE:
                user_rc = LDAP_SUCCESS;
                break;
            default:
                break;
            }

            if (user_rc == LDAP_SUCCESS) {
                if (id->idattr_applyto) {
                    rc = idattr_check_applyto(op, target, searchAttr, id);
                } else {
                    rc = LDAP_SUCCESS;
                }
            }
        }
    } else {
        rc = LDAP_NO_SUCH_OBJECT;
    }

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

cleanup:

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

    return 0;
}
Exemplo n.º 3
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;
}