[Freeipa-devel] [HELP] Regular users should not be able to add OTP tokens with custom name
Ludwig Krispenz
lkrispen at redhat.com
Fri Oct 10 15:30:17 UTC 2014
On 10/10/2014 05:16 PM, thierry bordaz wrote:
> On 10/10/2014 04:38 PM, Ludwig Krispenz wrote:
>>
>> On 10/10/2014 03:58 PM, thierry bordaz wrote:
>>> On 10/09/2014 10:51 PM, Nathaniel McCallum wrote:
>>>> On Thu, 2014-10-09 at 22:22 +0200, thierry bordaz wrote:
>>>>> On 10/09/2014 06:40 PM, Nathaniel McCallum wrote:
>>>>>
>>>>>> On Thu, 2014-10-09 at 18:32 +0200, thierry bordaz wrote:
>>>>>>> On 10/09/2014 06:27 PM, Nathaniel McCallum wrote:
>>>>>>>> On Thu, 2014-10-09 at 14:11 +0200, thierry bordaz wrote:
>>>>>>>>> On 10/08/2014 11:46 PM, Nathaniel McCallum wrote:
>>>>>>>>>
>>>>>>>>>> The background of this email is this bug:
>>>>>>>>>> https://fedorahosted.org/freeipa/ticket/4456
>>>>>>>>>>
>>>>>>>>>> Attached are two patches which solve this issue for admin users (not
>>>>>>>>>> very helpful, I know). They depend on this fix in 389:
>>>>>>>>>> https://fedorahosted.org/389/ticket/47920
>>>>>>>>>>
>>>>>>>>>> There are two outstanding issues:
>>>>>>>>>>
>>>>>>>>>> 1. 389 does not send the post read control for normal users. The
>>>>>>>>>> operation itself succeeds, but no control is sent.
>>>>>>>>>>
>>>>>>>>>> The relevant sections from the log are attached. 389 is denying access
>>>>>>>>>> to the following attributes (* = valid, ! = invalid):
>>>>>>>>>> ! objectClass
>>>>>>>>>> ! ipatokenOTPalgorithm
>>>>>>>>>> ! ipatokenOTPdigits
>>>>>>>>>> * ipatokenOTPkey
>>>>>>>>>> * ipatokenHOTPcounter
>>>>>>>>>> ! ipatokenOwner
>>>>>>>>>> ! managedBy
>>>>>>>>>> ! ipatokenUniqueID
>>>>>>>>> Hello Nathaniel,
>>>>>>>>>
>>>>>>>>> The post read control needs access to the modified entry to
>>>>>>>>> return it.
>>>>>>>>> This access is granted at the condition, the binddn can access
>>>>>>>>> attributes.
>>>>>>>> Agreed and understood.
>>>>>>>>
>>>>>>>>> My understanding is that the target entry is
>>>>>>>>> ipatokenuniqueid=52001946-4f2d-11e4-9127-7831c1d63a78,cn=otp,dc=example,dc=com and the binddn "uid=otp,cn=users,cn=accounts,dc=example,dc=com".
>>>>>>>> Correct.
>>>>>>>>
>>>>>>>>> The only ACI I found that match this target is:
>>>>>>>>> aci: (targetfilter = "(objectClass=ipaToken)")
>>>>>>>>> (targetattrs = "objectclass || description || managedBy || ipatokenUniqueID || ipatokenDisabled
>>>>>>>>> || ipatokenNotBefore || ipatokenNotAfter || ipatokenVendor || ipatokenModel || ipatokenSerial || ipatokenOwner")
>>>>>>>>> (version 3.0; acl "Users/managers can read basic token info"; allow (read, search, compare) userattr = "ipatokenOwner#USERDN" or userattr = "managedBy#USERDN";)
>>>>>>>> Correct.
>>>>>>>>
>>>>>>>>> Do you know if the target entry has 'ipatokenOwner' or
>>>>>>>>> 'managedBy' with the binddn value ?
>>>>>>>> Yes, both. So why is access to objectClass (et cetera) being denied?
>>>>>>> Good question... I will try to reproduce
>>>>>> Thanks!
>>>>> Hello,
>>>>>
>>>>> I tried to reproduce and it seems to work on *master*.
>>>>> I am using the attached ldif file.
>>>>> The test case is to bind as "cn=active
>>>>> guy,cn=accounts,dc=example,dc=com" and to do a modify on
>>>>> "cn=active otp,cn=otp,dc=example,dc=com".
>>>>>
>>>>> The modify updates the 'description' attribute and do a
>>>>> postread (description, cn).
>>>>>
>>>>> The write 'description' is allowed by :
>>>>> dn: cn=otp,dc=example,dc=com
>>>>> aci: (targetfilter =
>>>>> "(objectclass=organizationalPerson)")(target =
>>>>> "ldap:///c
>>>>> n=*,cn=otp,dc=example,dc=com")(targetattr =
>>>>> "objectclass || description || se
>>>>> eAlso")(version 3.0; acl "Active user modify otp
>>>>> entry"; allow (write) userdn
>>>>> ="ldap:///cn=active
>>>>> guy,cn=accounts,dc=example,dc=com";)
>>>>>
>>>>> [09/Oct/2014:22:07:56 +0200] NSACLPlugin - 1.
>>>>> Evaluating ALLOW aci(19) " "Active user modify otp
>>>>> entry""
>>>>> [09/Oct/2014:22:07:56 +0200] NSACLPlugin - conn=2
>>>>> op=16 (main): Allow write on entry(cn=active
>>>>> otp,cn=otp,dc=example,dc=com).attr(description) to
>>>>> cn=active guy,cn=accounts,dc=example,dc=com: allowed
>>>>> by aci(19): aciname= "Active user modify otp entry",
>>>>> acidn="cn=otp,dc=example,dc=com"
>>>>>
>>>>>
>>>>> The postread is allowed by:
>>>>> dn: cn=otp,dc=example,dc=com
>>>>> aci: (targetfilter =
>>>>> "(objectclass=organizationalPerson)") (targetattr =
>>>>> "obje
>>>>> ctclass || description || seeAlso || cn")(version
>>>>> 3.0; acl "Active user can r
>>>>> ead his entries"; allow (read, search, compare)
>>>>> userattr = "seeAlso#USERDN";)
>>>>>
>>>>> [09/Oct/2014:22:07:58 +0200] NSACLPlugin - 1.
>>>>> Evaluating ALLOW aci(21) " "Active user can read his
>>>>> entries""
>>>>> [09/Oct/2014:22:07:58 +0200] NSACLPlugin - Found READ
>>>>> ALLOW in cache
>>>>> [09/Oct/2014:22:07:58 +0200] NSACLPlugin - conn=2
>>>>> op=16 (main): Allow read on entry(cn=active
>>>>> otp,cn=otp,dc=example,dc=com).attr(cn) to cn=active
>>>>> guy,cn=accounts,dc=example,dc=com: cached allow by
>>>>> aci(21)
>>>>>
>>>>> The postread works if I use USERDN or SELFDN.
>>>>>
>>>>> Please let me know the version of 389-ds that you are testing,
>>>>> I will try on that branch
>>>> That is not really the same test at all.
>>>>
>>>> 1. Install FreeIPA from F21 @ example.com
>>>> 2. Excecute: ldapadd -D uid=admin,cn=users,cn=accounts,dc=example,dc=com
>>>> -W -e postread=* <<EOF
>>>> dn: ipatokenuniqueid=foo,cn=otp,dc=example,dc=com
>>>> changetype: add
>>>> objectClass: top
>>>> objectClass: ipaToken
>>>> objectClass: ipaTokenHOTP
>>>> ipatokenUniqueID: foo
>>>> ipatokenOTPalgorithm: sha1
>>>> ipatokenOTPdigits: 6
>>>> ipatokenOTPkey: 00000000
>>>> ipatokenHOTPcounter: 0
>>>> ipatokenOwner: uid=admin,cn=users,cn=accounts,dc=example,dc=com
>>>> managedBy: uid=admin,cn=users,cn=accounts,dc=example,dc=com
>>>> EOF
>>>>
>>>> 3. Create a regular user named 'otp'
>>>> 4. Execute: ldapadd -D uid=otp,cn=users,cn=accounts,dc=example,dc=com -W
>>>> -e postread=* <<EOF
>>>> dn: ipatokenuniqueid=bar,cn=otp,dc=example,dc=com
>>>> changetype: add
>>>> objectClass: top
>>>> objectClass: ipaToken
>>>> objectClass: ipaTokenHOTP
>>>> ipatokenUniqueID: bar
>>>> ipatokenOTPalgorithm: sha1
>>>> ipatokenOTPdigits: 6
>>>> ipatokenOTPkey: 00000000
>>>> ipatokenHOTPcounter: 0
>>>> ipatokenOwner: uid=otp,cn=users,cn=accounts,dc=example,dc=com
>>>> managedBy: uid=otp,cn=users,cn=accounts,dc=example,dc=com
>>>> EOF
>>>>
>>>> RESULTS:
>>>> Step 2 will add the token and return the post read control. Step 4 will
>>>> add the token, but will NOT return the post read control.
>>>>
>>>>
>>> Hi Nathaniel,
>>>
>>> Thanks for the detailed procedure I was able to reproduce the
>>> problem:
>>>
>>> In fact during the step for, the add is successful but the found
>>> ACIs do no grant access to the target entry:
>>>
>>> [09/Oct/2014:21:34:58 -0400] conn=29 fd=82 slot=82 SSL
>>> connection from 10.16.78.124 to 10.16.78.124
>>> [09/Oct/2014:21:34:58 -0400] conn=29 SSL 128-bit AES
>>> [09/Oct/2014:21:34:58 -0400] conn=29 op=0 BIND
>>> dn="uid=otp,cn=users,cn=accounts,dc=example,dc=com"
>>> method=128 version=3
>>> [09/Oct/2014:21:34:58 -0400] conn=29 op=0 RESULT err=0
>>> tag=97 nentries=0 etime=0
>>> dn="uid=otp,cn=users,cn=accounts,dc=example,dc=com"
>>> [09/Oct/2014:21:34:58 -0400] conn=29 op=1 ADD
>>> dn="ipatokenuniqueid=bar,cn=otp,dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] conn=29 op=2 UNBIND
>>> [09/Oct/2014:21:34:59 -0400] conn=29 op=2 fd=82 closed - U1
>>> [09/Oct/2014:21:34:59 -0400] conn=29 op=1 RESULT *err=0*
>>> tag=105 nentries=0 etime=1
>>>
>>> The add was granted because of "Users can create self-managed
>>> tokens"
>>>
>>>
>>> [09/Oct/2014:21:34:58 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Allow add on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(NULL)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: allowed
>>> by aci(16): aciname= "Users can create self-managed tokens",
>>> acidn="dc=example,dc=com"
>>>
>>> Now the postread control was not granted for any of the
>>> attribute of the entry:
>>>
>>> [09/Oct/2014:21:34:58 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*objectClass*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:58 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*ipatokenUniqueID*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*ipatokenOTPalgorithm*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*ipatokenOTPdigits*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*ipatokenOTPkey*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*ipatokenHOTPcounter*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*ipatokenOwner*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(*managedBy*)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>>
>>> Each time the correct aci was selectionned:
>>>
>>>
>>> aci: (targetfilter = "(objectClass=ipaToken)")(targetattrs =
>>> "objectclass || d
>>> escription || managedBy || ipatokenUniqueID ||
>>> ipatokenDisabled || ipatokenNo
>>> tBefore || ipatokenNotAfter || ipatokenVendor ||
>>> ipatokenModel || ipatokenSer
>>> ial || ipatokenOwner")(version 3.0; acl "*Users/managers
>>> can read basic token*
>>> info"; allow (read, search, compare) userattr =
>>> "ipatokenOwner#USERDN" or use
>>> rattr = "managedBy#USERDN";)
>>>
>>> ...
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - Processed
>>> attr:managedBy for
>>> entry:ipatokenuniqueid=bar,cn=otp,dc=example,dc=com
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - 1. Evaluating
>>> ALLOW aci(11) " "*Users/managers can read basic token info*""
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - Found READ SKIP
>>> in cache
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - 2. Evaluating
>>> ALLOW aci(19) " "Admin can manage any entry""
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - Found READ SKIP
>>> in cache
>>> [09/Oct/2014:21:34:59 -0400] NSACLPlugin - conn=29 op=1
>>> (main): Deny read on
>>> entry(ipatokenuniqueid=bar,cn=otp,dc=example,dc=com).attr(managedBy)
>>> to uid=otp,cn=users,cn=accounts,dc=example,dc=com: no aci
>>> matched the subject by aci(19): aciname= "Admin can manage
>>> any entry", acidn="dc=example,dc=com"
>>> [09/Oct/2014:21:34:59 -0400] - process_read_entry_controls:
>>> access to entry not allowed
>>> (ipatokenuniqueid=bar,cn=otp,dc=example,dc=com)
>>>
>>> But for some reason, it evaluations of the READ access was not
>>> accepted.
>>>
>> the key is READ SKIP, looks like it is using cached evaluation of the
>> acis, where the aci did not apply. aci caching is ....
>
> Exact.
> Now If I create two entries x/y and their associated ipatoken
> tokenX/tokenY and play updating
> x update tokenX then y updates tokenY
> x update tokenX then x updates tokenY
> y update tokenY then x updates tokenX
> ...
> each time I got the postread.
so it seems to be related to the add operation. can I have a look at teh
full acl logging for an ADD ?
And I think we need a ticket, is it possible to reproduce without IPA ?
>
> Something curious going on that make ACL_EvalTestRights return
> something different that ACL_RES_ALLOW.
>
>>>
>>> Did you already open a ticket for this problem ?
>>>
>>> thanks
>>> thierry
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/freeipa-devel/attachments/20141010/522d3b6d/attachment.htm>
More information about the Freeipa-devel
mailing list