As a follow-up for XCP2 vs ACLs
I have very….hm, how to call this stupidity of ACL security model logic….I have repository with permissions inheriting from folder. Folder is created by regular user and ACL assigned to folder is owned by this user, with class set to REGULAR. When another regular user needs to add document to this folder, it is not possible, with DM_SYSOBJECT_E_INVALID_ACL_DOMAIN exception, since folder ACL is regular and thereby not alowed to be used/set by another regular user, only superuser or folder ACL owner. So, ACL from folder may not be inherited to document and document can not be created.
Why, when ACL with its entries should specify exactly who can do smth and with which permissions?
And, why default ACLs created by regular users are not PUBLIC?
And, why cant I set by some docbase configuration that all ACLs created by regular users are PUBLIC?
Well, when I said that fundamentals guide is bit confusing I was too polite, the home truth is that fundamentals guide is a piece of dog crap. Let’s explain that.
From fundamentals guide:
ACLs are either external or internal ACLs:
- External ACLs are created explicitly by users. The name of an external ACL is determined by the user. External ACLs are managed by users, either the user who creates them or superusers.
- Internal ACLs are created by Content Server. Internal ACLs are created in a variety of situations. For example, if a user creates a document and grants access to the document to HenryJ, Content Server assigns an internal ACL to the document. (The internal ACL is derived from the default ACL with the addition of the permission granted to HenryJ.) The names of internal ACL begin with dm_. Internal ACLs are managed by Content Server.
The external and internal ACLs are further characterized as public or private ACLs:
- Public ACLs are available for use by any user in the repository. Public ACLs created by the repository owner are called system ACLs. System ACLs can only be managed by the repository owner. Other public ACLs can be managed by their owners or a user with Sysadmin or Superuser
- Private ACLs are created and owned by a user other than the repository owner. However, unlike public ACLs, private ACLs are available for use only by their owners, and only their owners or a superuser can manage them.
From object reference guide:
acl_class (Integer) specifies whether the ACL is a regular ACL, a template, an instance of a template, or a public ACL. Valid values are:
- 0: Regular ACL
- 1: Template ACL
- 2: Template instance
- 3: Public ACL
r_is_internal (Boolean) indicates whether the ACL was created explicitly by a user or implicitly by the server.
First of all, the classification internal/external seems to be extremely confusing – I would prefer temporary/permanent terms because ACLs with r_is_iternal=TRUE are subject to deleting via dm_clean job, and because dm_clean job uses following query:
SELECT x.r_object_id FROM dm_acl_s x WHERE x.r_is_internal = 1 AND NOT EXISTS ( (SELECT a1.r_object_id FROM dm_acl_s a1, dm_sysobject_s b WHERE a1.object_name = b.acl_name AND a1.owner_name = b.acl_domain AND a1.r_object_id = x.r_object_id) UNION (SELECT a2.r_object_id FROM dm_acl_s a2, dm_user_s c WHERE a2.object_name = c.acl_name AND a2.owner_name = c.acl_domain AND a2.r_object_id = x.r_object_id) UNION (SELECT a3.r_object_id FROM dm_acl_s a3, dmi_type_info_s d WHERE a3.owner_name = d.acl_domain AND a3.object_name = d.acl_name AND a3.r_object_id = x.r_object_id))
it is clear that dm_clean job does not pay attention to the value of acl_class attribute. Next, when does Content Server create temporary ACLs?
- When we directly grant access to sysobject:
API> create,c,dm_document ... 09024be980077401 API> set,c,l,acl_name SET> Global User Default ACL ... OK API> set,c,l,acl_domain SET> dm_dbo ... OK API> save,c,l ... OK API> get,c,l,acl_name ... Global User Default ACL API> grant,c,l,dm_world,AccessPermit,,6 ... OK API> save,c,l ... OK API> get,c,l,acl_name ... dm_45024be980003115
- When we indirectly (via owner_permit/world_permit attributes, or when we take advantage of ACL Templates and assign new alias set to sysobject) grant access to sysobject:
API> set,c,l,world_permit SET> 7 ... OK API> save,c,l ... OK API> get,c,l,acl_name ... dm_45024be980003116
- Other case I will describe further
Now about ACL classes. Frankly speaking, I do not understand the phrase “ACLs available for use” here, because where are following activities which we may or may not to perform with ACLs:
- assign to sysobject
so, I will try to examine all cases. At first, we need to understand what Content Server means under ACL’s owner (the value of owner_name attribute), if you think that it is valid user’s name you are wrong: actually it may be any valid user or group (technically group is also a user because all dm_group records have corresponding dm_user records), or even ‘dm_world’ keyword:
API> create,c,dm_acl ... 45024be980003117 API> set,c,l,owner_name SET> dm_bof_registry ... OK API> save,c,l ... OK API> create,c,dm_acl ... 45024be980003118 API> set,c,l,owner_name SET> dm_superusers ... OK API> save,c,l ... OK API> create,c,dm_acl ... 45024be98000311b // content server replaces dm_dbo // by repository owner name // and further I will do the same API> set,c,l,owner_name SET> dm_dbo ... OK API> save,c,l ... OK API> create,c,dm_acl ... 45024be980003119 API> set,c,l,owner_name SET> dm_world ... OK API> save,c,l ... OK API> create,c,dm_acl ... 45024be98000311a API> set,c,l,owner_name SET> non_existing_user ... OK API> save,c,l ... [DM_ACL_E_USER_NOT_EXIST]error: "The owner_name or accessor_name 'non_existing_user' given in the ACL 'dm_45024be98000311a' does not exist."
And when we are talking that “user is an owner of ACL” this actually means one of following:
- the value of owner_name ACL’s attribute is ‘dm_world’
- the value of owner_name ACL’s attribute is the name of user
- the value of owner_name ACL’s is a valid group and the user is a member of that group
Now the rules:
- Nobody may create ACLs with acl_class=2 and nobody may set value of acl_class to 2:
API> create,c,dm_acl ... 45024be98000312c API> set,c,l,acl_class SET> 2 ... OK API> save,c,l ... [DM_ACL_E_CANT_CHANGE_INSTANCE]error: "The ACL is an instance of an ACL template."
- Nobody but superusers may change value of object_name attribute (have no idea what was the cause of this restriction):
API> retrieve,c,dm_acl where object_name='Global User Default ACL' ... 45024be9800001c6 API> grant,c,l,dm_world,AccessPermit,,7 ... OK API> save,c,l ... OK API> set,c,l,object_name SET> test ... OK API> save,c,l ... [DM_ACL_E_CHANGE_OBJNAME_PRIV]error: "Only SUPERUSER can change object_name." API> retrieve,c,dm_user where user_name=USER ... 11024be980001100 API> get,c,l,user_privileges ... 8
- Regular users are allowed to:
- modify ACL if they belong to ACL’s owner
- set ACL’s owner only to value they belong to
- Sysadmins are allowed to:
- modify ACL if ACL’s owner is dm_dbo, but it is not allowed to set ACL’s owner to value other than sysadmin belongs to
- modify ACL if it’s acl_class is 3 regardless it’s owner
- set ACL’s owner to dm_dbo – this behaviour seems to be inconsistent because in this case efficient permissions of sysadmins are the same as permissions of superusers, except object_name case:
API> fetch,c,45024be980003137 ... OK API> save,c,l ... [DM_ACL_E_NOT_OWNER]error: "The ACL 'dm_45024be980003137' can only be modified by its owner 'dmadmin' or superusers." API> set,c,l,owner_name SET> dm_dbo ... OK API> save,c,l ... OK
- It is possible to assign ACL to sysobject only if one or more of following requirements are met
- ACL’s acl_class is 3
- ACL’s owner_name is dm_dbo
- sysobject’s owner (not current user!) belongs to ACL’s owner:
API> retrieve,c,dm_acl where owner_name='dmadmin' ... 45024be9800001a9 API> get,c,l,acl_class ... 0 API> get,c,l,object_name ... dm_45024be9800001a9 API> create,c,dm_document ... 09024be98007756b API> set,c,l,acl_name SET> dm_45024be9800001a9 ... OK API> set,c,l,acl_domain SET> dmadmin ... OK API> save,c,l ... [DM_SYSOBJECT_E_INVALID_ACL_DOMAIN]error: "The dm_document '' is given an invalid ACL domain 'dmadmin'." // but API> create,c,dm_document ... 09024be98007756c API> set,c,l,acl_name SET> dm_45024be9800001a9 ... OK API> set,c,l,acl_domain SET> dmadmin ... OK API> set,c,l,owner_name SET> dmadmin ... OK API> save,c,l ... OK
- current user is a superuser, in this case Content Server creates new temporary ACL:
API> ?,c,select user_privileges, user_name from dm_user where user_name=USER user_privileges user_name --------------- --------- 16 dmadmin (1 row affected) API> retrieve,c,dm_acl where owner_name='sysadmin' and acl_class=0 ... 45024be980003136 API> get,c,l,object_name ... dm_45024be980003136 API> create,c,dm_document ... 09024be980077580 API> save,c,l ... OK API> get,c,l,acl_name ... dm_45024be980000101 API> set,c,l,acl_name SET> dm_45024be980003136 ... OK API> set,c,l,acl_domain SET> sysadmin ... OK API> save,c,l ... OK API> get,c,l,acl_name ... dm_45024be980003144
As regards to the questions…
Yes, it is not possible to specify default acl_class even in data dictionary:
API> apply,c,,ALLOW_BASE_TYPE_CHANGES,ALLOW_CHANGE_FLAG,B,T ... q0 API> ?,c,q0 result ------------ T (1 row affected) API> ?,c,alter type dm_acl modify (acl_class (SET default=3)) [DM_QUERY2_E_DATA_DICT_ERROR_FOR_ATTR_A_C]error: "The following error(s) occurred processing an ALTER/CREATE statement for type dm_acl, attribute acl_class." [DM_DATA_DICT_E_TYPE_CANNOT_HAVE_DEFAULT_VALUE]error: "You cannot specify a DEFAULT value for any attribute of the system type dm_acl."
Creating TBO for dm_acl is not an option, because temporary ACLs are created on Content Server side. On the other hand nothing prevents you from creating TBOs which will override certain IDfSysObject and IDfUser methods and you will get a full control over what is going on, the only question here is why mature product still does not support basic functionality 🙂 For example, ACL inheritance implemented in xCP2 differs from default CS implementation – when content server recognises that it is not possible to follow rules described above it creates temporary ACL (here I have no idea what behaviour is better: get exception or get different ACLs), that means EMC have spent some time on implemented new functionality, but the result is poor.