[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: SASL authentication for OpenLDAP (ITS#477)



At 02:40 PM 3/13/00 -0500, Mark Adamson wrote:
>My thesis defense:

And my thesis like rebuttal :-)


[a little reorderring...]

>> I also think we need to further discuss appropriate separation
>> of authentication identities, authorization identities, and
>> subject DN (for ACLs).
>
>Yes, this loops back into the whole bindDN / authenticationDN /
>authorizationDN issue.

user provided bind DN != subject DN.  More below... likely need
to have this discussion up front.

>
>> ldap.h: ldap_negotiated_sasl_bind()
>>   should not eliminate binddn as argument.  routine should
>>   independent specification of bindDN, authcId, and authzId.
>>   Note: it usually for bind == NULL and authzId is often
>>   NULL, but authcId is rarely NULL.
>> 
>>   should remove if(!authzId) authzId = authcId statement,
>>   an empty authzId field should be sent instead.
>
>I looked at this and the SASL code and as far as I can tell, SASL
>authentication can only use 2 DNs, not 3.

Actually, bind uses one DN.  SASL uses two identities, an authentication
and an authorization identity.  The authentication identity is usually
an arbitrary UTF-8 string.  The authorization identity string must conform to
the AuthMeth draft.  As the forms of the identities differ (and that the
relationship may not be direct), you cannot do an assignment.  Also, note,
that client need not specify an authorization identity (the server will
imply an authorization identity when not specified).

>The bindDN gets sent with the
>first bind call, and it gets put in c_cdn in the server's Connection
>structure.

This needs to change.  Note that the c_cdn is the subject DN used for
ACLs.  It should be filed in until after the authentication completes.
The value of c_cdn should be derived from the authorization identity
(which may be derived from the authentication identity).

During SASL bind, the client provided bind DN is only used to limit
realm selection (the server may support numerous realms, the bind DN
can be used to limit the number of realms returned to the client).
The bind DN must not otherwise be used.

>SASL can then use the authorizationId in the SASL_CB_USER
>callback.

I think the authentication identity as the SASL "username".  (note
that AuthMeth vs SASL vs Cyrus terminology might differ).

>The 3rd DN that was in negotiated_bin(), called authenticationId
>and used in the SASL_CB_AUTH, was never used.

This, I believe, is the authorization identity.  Now, authorization
strings are application specific.  So, I am not sure what Cyrus expects
here.  I'll have to read the docs.  It may be okay to leave it empty
when no authorization id is provided by the client. 
 
>I wanted the server side SASL to force an authorization from the SASL name
>to the bindDN, so that server side binds are always to a DN (keep LDAP
>binds in the LDAP namespace).

Note above comment about limited use of the client provided bind DN.

Note that neither the authentication or authorization identities may be DNs
and the authorization identity may be implied by the authentication identity.

Once authenticated identitiy and the authorization identity (implied
or explicit) are validated, the server must then map the authorization
identity to a DN for use with ACLs.

>That's why I did the "if !authzId" statement.

Again, the implied authorization identity associated with the authentication
identity may not be equal to the authentication identity.  Regardless, they
are of different forms and hence cannot be simply assigned.

>On the server, when the PROXY callback is being set up, the
>"context" stored contains both the Connection structure AND the bindDN the
>client used. The callback function then receives the SASL ID, the
>authorizationID, the Connection, and the original bindDN.
>The function
>makes sure the bindDN maps to the SASL ID, then a second check is done to
>see if the bound DN is allowed to change to the authorization ID (if an
>authorization change was requested)

See above comments.

>  If you prefer that server side binds can be made to arbitrary names
>outside the LDAP namespace, this can be changed around.

authentication identities are specific to the SASL service, not LDAP.
authorization identities may or may not be specific to LDAP.

>But that does
>bring up some concerns. If I bind as some name in the SASL namespace, such
>as "postman@cmu.edu", and I request that I be allowed to act on the behalf
>of another identity, how does slapd know if "postman" is allowed to do
>that, and where is that information stored

Depends on the SASL service.  If the SASL service manages both authentication
and authorization information, then this can be delegated to the SASL service.
If the SASL service does not manage authorization information, then we must
provide an "authorization" mechanism.  We then can map the authorization
identity to a DN for use with ACLs.

>By making all binds happen in
>the LDAP namespace, such information can be stored as attributes.

The whole point of SASL is to take authentication and authorization
out of the LDAP namespace.  The information that drives this can
still be represented in the directory.
>
>
>> options.c:
>>   change should be extraneous
>
>It's not.

#define ld_version              ld_options.ldo_version

>> 
>> sasl.c
>>   don't remove param error detection
>
>There is an assert() for that param just above. One or the other can go.

No, the assert is implicitly conditionally.  We prefer to have both
the assert() and the param checks in the code (and without additional
#ifdefs).