Description of problem: [Scenarios need to be supported] Nathan Kinder wrote: An admin (or user who has been delegated the proper rights) in IPA will access the web UI to create a new user. We want to be able to know what fields that admin user is allowed to write/modify for a "user" entry. We should know the objectclass(es) that define a "user" at this point as well as where in the tree the user will be created. The second scenario is where an admin (of some sort) has the right to edit certain things about existing user entries. In the web UI, the admin will bring up a user entry. We want the editable fields to be actual text boxes in the UI, whereas read-only fields will be something that is not editable, such as labels. [Additional input] Rob Crittenden wrote: We create our own ACI's that may grant certain groups (or users) to write attributes of other groups (or users). We need to be able to determine attribute by attribute if those are writable as well. Additionally this applies to both existing and new entries. I think the dummy idea is the way to go but it needs to support both entire entries as well as non-existent attributes in existing entries. [Implementation] Rich Megginson wrote: We know which acis would apply to the entry if it really existed (just like with an ADD operation). If we have the list of attributes, that's all we should need to get the ACI information. If the request just uses "*" for all attributes, then I suppose we could return the list of all attributes in the entire schema (except operational attributes) that could apply. There are a couple of optimizations we could use for this admittedly bad case: 1) Have some configuration that allows the admin to define the list of attributes and/or objectclasses to consult when a GER request comes in with no attributes. 2) Extend the existing control or create a new control that allows you to pass in the list of objectclasses 3) OpenLDAP has a special way to specify all of the attributes in the objectclass - if you specify @inetOrgPerson in the attr list, this means "every attribute referenced by the inetOrgPerson objectclass". I'm not sure if you can differentiate between allowed and required attributes, or how it handles inheritance (I'm assuming it uses both the allowed and require attrs, and it uses all of the attrs defined in every superclass). Note that OpenLDAP also has the special "+" attribute which means "all operational attributes which could apply to this entry".
I have already asked a similar question/request of an enhancement in FDS user list on 12 aug 2007. And exactly for the same reasons - in order to easily determine what attributes to show (and whether they are editable/readable) in web interface of a delegated administrator. here is my original message : -------------------------------------------------------------------- I've tried to figure out how to know in advance whether the authentified user has the right to write into a certain attribute of another user (without being directory manager). In other words, how a user may view his rights on any entry/attribute in the directory. That is, for example, i am authentified as a user uid=ai,ou=users,dc=example,dc=com and i want to know whether i have the write privilege on the attribute 'description' of the entry uid=toto,ou=users,dc=example,dc=com. The only way to find it out is to ACTUALLY WRITE to that attribute (and delete this written value afterwards) and see whether i succeed. I've read the documentation about the "get effective rights" extension and it turns out that it permits only to find the rights of the OTHER users on YOUR attributes (if i take the example of the previous paragraph, the user uid=ai can only find out what other users can do with his attributes). So the question is whether there is a way for a simple user (NOT Directory Manager) to see his rights on other entries' attributes (much like, for example, aclRights attribute in SunONE) without actually reading/writing to that attributes?
I've looked through the code of the acleffectiverights.c. For the user to be able to see his/her own permissions on other entries here are the proposed changes : --- acleffectiverights.c 2008-03-16 17:22:14.000000000 +0100 +++ acleffectiverights-patched.c 2008-03-16 17:36:37.000000000 +0100 @@ -90,7 +90,7 @@ } static int -_ger_g_permission_granted ( Slapi_PBlock *pb, Slapi_Entry *e, char **errbuf ) +_ger_g_permission_granted ( Slapi_PBlock *pb, Slapi_Entry *e, char **errbuf, const char *subjectdn ) { char *proxydn = NULL; Slapi_DN *requestor_sdn, *entry_sdn; @@ -151,6 +151,13 @@ goto bailout; } + if ( strcmp ( slapi_sdn_get_dn(requestor_sdn), subjectdn ) == 0) + { + /* Requestor should see his own permission rights on any entry */ + rc = LDAP_SUCCESS; + goto bailout; + } + aclutil_str_appened ( errbuf, "get-effective-rights: requestor has no g permission on the entry" ); slapi_log_error (SLAPI_LOG_ACL, plugin_name, "_ger_g_permission_granted: %s\n", *errbuf); @@ -681,7 +688,7 @@ * The requestor should have g permission on the entry * to get the effective rights. */ - rc = _ger_g_permission_granted (pb, e, errbuf); + rc = _ger_g_permission_granted (pb, e, errbuf, subjectndn); if ( rc != LDAP_SUCCESS ) { goto bailout;
Thank you, Andrey, for the patch. I'm adding your patch with a minor change in the code review request I'm attaching next.
Created attachment 309953 [details] cvs diffs Files: ldap/servers/slapd/charray.c ldap/servers/slapd/opshared.c ldap/servers/slapd/pblock.c ldap/servers/slapd/result.c ldap/servers/slapd/schema.c ldap/servers/slapd/search.c ldap/servers/slapd/slapi-plugin.h ldap/servers/slapd/slapi-private.h ldap/servers/plugins/acl/acleffectiverights.c ldap/servers/plugins/chainingdb/cb_config.c ldap/servers/plugins/chainingdb/cb_controls.c ldap/servers/plugins/chainingdb/cb_instance.c Change descriptions: [slapd/charray.c] new: charray_merge_nodup -- merge 2 string arrays skipping the duplicates modified: charray_remove -- introduced "freeit" flag. If true, the removed string is freed. (The API is used only in chainingdb. The change is applied to the plugin.) [slapd/opshared.c] modified: check OP_FLAG_GET_EFFECTIVE_RIGHTS in the iterate to support "@<objectclass>". It's needed to do at the location since we have to call acl plugin even when no entries are returned from the search. If no entries are returned and "@<objectclass>" is found in the attribute list, acl effective rights code generates the corresponding template entry. [slapd/pblock.c] place to store gerattrs is added (SLAPI_SEARCH_GERATTRS), where gerattrs is an array of strings which store "...@<objectclass>". [slapd/result.c] moved OP_FLAG_GET_EFFECTIVE_RIGHTS checking to iterate (opshared.c) [slapd/schema.c] new: slapi_schema_list_objectclass_attributes -- return the required and/or allowed attributes belonging to the given objectclass. This is used to support "*" and "+" in the get effective rights. new: slapi_schema_get_superior_name -- return the superior objectclass name of the given objectclass. [slapd/search.c] if "<attr>@<objectclass>" is found in the attribute list, cut the <attr> part out and added to the attrs array (pblock SLAPI_SEARCH_ATTRS) and store the original string to the gerattrs (pblock SLAPI_SEARCH_GERATTRS). [plugin/acl/acleffectiverights.c] modified: _ger_g_permission_granted -- if the requester and the subject user are identical, give "g" permission modified: _ger_parse_control -- replaced strcpy with memmove since strcpy does not guarantee the result of the overlap copy. modified: _ger_get_attrs_rights -- support "*" (all attributes belonging to the object) and "+" (operational attributes). If repeated attributes are found in the given attribute list, they are reduced to one. new: _ger_generate_template_entry -- generate a template entry if "@<objectclass>" is passed. [pluginc/cb/*] adjusted to the updated charray_remove. Please see also this wiki page for the overview and test cases. http://directory.fedoraproject.org/wiki/Get_Effective_Rights_for_non-present_attributes
At https://bugzilla.redhat.com/attachment.cgi?id=309953&action=diff#ldap/servers/slapd/schema.c_sec2 Is it safe to access oc->oc_required or other fields inside oc outside of the oc_lock ? https://bugzilla.redhat.com/attachment.cgi?id=309953&action=diff#ldap/servers/plugins/acl/acleffectiverights.c_sec3 If subjectdn is normalized, we should compare it to slapi_sdn_get_ndn(requestor_sdn) - otherwise, have to normalize subjectdn first - recommend using slapi_sdn_compare() in that case.
Created attachment 310288 [details] revised diffs (schema.c, acleffective (In reply to comment #5) > At > https://bugzilla.redhat.com/attachment.cgi?id=309953&action=diff#ldap/servers/slapd/schema.c_sec2 > > Is it safe to access oc->oc_required or other fields inside oc outside of the > oc_lock ? Oops. I put the lines referring the field of oc inside of the oc_lock (2 places). > > https://bugzilla.redhat.com/attachment.cgi?id=309953&action=diff#ldap/servers/plugins/acl/acleffectiverights.c_sec3 > > If subjectdn is normalized, we should compare it to > slapi_sdn_get_ndn(requestor_sdn) I replaced slapi_sdn_get_dn with slapi_sdn_get_ndn. And this test has passed: $ ldapsearch -p 10390 -D "uid=pusEr104,dc=eXample, dc=com" -w puser104 -b "dc=example,dc=com" -J "1.3.6.1.4.1.42.2.27.9.5.2:false:dn: uid=pUsEr104, dc=exAmple, dc=com" -e "(uid=puser105)" "*"
Created attachment 310471 [details] cvs commit message Reviewed by Rich (Thank you!!) Checked in into the CVS HEAD.
*** Bug 245830 has been marked as a duplicate of this bug. ***
functionality implemented and GER automated acceptance tests enhanced to cover new functionality.
An advisory has been issued which should help the problem described in this bug report. This report is therefore being closed with a resolution of ERRATA. For more information on therefore solution and/or where to find the updated files, please follow the link below. You may reopen this bug report if the solution does not work for you. http://rhn.redhat.com/errata/RHEA-2009-0455.html