Using ACLs in LDAP: Creating a Secure eDirectory Infrastructure Mike Richichi Assistant Director of Academic Technology, Drew University DeveloperNet Volunteer Sysop email@example.com
What We’ll Cover • Review of eDirectory access control • Inheritance • Security principals • Default ACLs • Determining effective rights • Review of LDAP (very brief) • How ACLs are exposed via LDAP • Text representation • LDAP extension for getting effective rights
What We’ll Cover (cont.) • Code examples • C API • LDIF • perl-ldap • Tying it all together • How rights affect your code and what LDAP does • Organizing your tree and rights effectively • Gotchas • Concluding thoughts
Important Compatibility Note • All of this talk is based upon NDS eDirectory 8.5 or later, for any supported OS • C SDK examples run on NetWare, Win32, Solaris, Linux (currently) • Perl code can be run on nearly any system that supports perl-ldap
Access Control in eDirectory • eDirectory has powerful access control capabilities, especially compared to other LDAP directories • Every object can be given rights to every other object • Rights flow down the tree by default, can be blocked by inherited rights filters (IRFs) • Rights are granular (read, write, create) and can apply to specific attributes of an object • Access control rights are enforced in the deepest, darkest corners of eDirectory, and are a fundamental part of eDirectory operation
Security Principals • Every object in eDirectory is a security principal • Can be used in an ACL entry • It may not always be meaningful, or what you think it means • Application can be given rights to a user—what? • Rights are generally given to objects that actually log in to an eDirectory tree, container objects, or objects that objects are security equivalent to • i.e., objects with a key pair that log in to servers, container objects whose leaves inherit their security equivalences, or groups and organizational roles for whom users are security equivlalent to when in the group or occupant of the role • Organizational Units are security principals
Security Equivalences • securityEquals is an attribute of an object whose values are other objects • The objects listed in the attribute have their access control rights added to the object they’re listed in • There are implicit equivalences for all container objects of an object • Equivalences are automatically updated with group membership and organizational role occupation • Security equivalences can be explicitly defined as well • securityEquals is a normal attribute on a user object
Dynamic Groups • Available with eDirectory 8.6.1 and later • Group is defined as an LDAP search filter statement • Users are not explicitly security equivalent to a dynamic group • Special ACL rights mask identifies ACLs that reference dynamic groups, thus triggering the search when object is accessed • TID 10067369 is your friend here
Basic eDirectory Rights • Entry rights • Apply to the “object itself” • Supervisor, Browse, Create, Delete, Rename • Supervisor to the entry implies supervisor to all attributes • Property rights • Apply to specific attributes of the object • Supervisor, Compare, Read, Write, Add Self
Effective Rights Calculations • Rights are calculated by checking granted rights at each level of the tree with the user’s security equivalences (explicit and inherited) • If rights assigned to same object at two levels of tree, one “closest” to the user is the one applied • But effective rights granted through container objects or other security equivalences are still added to total rights ([Public] rights, for instance)
How Are ACLs Applied? • ACLs are assigned via management interfaces • ConsoleOne • LDAP • Etc. • Also are assigned upon object creation as defined by the Default ACL attribute of the object class itself
What Is This Default ACL of Which You Speak? • Default ACL is a property of an object class, defined in the schema, that allows for the automatic assignment of ACLs on object creation • It is not exposed via LDAP, but of course the ACLs assigned are enforced by eDirectory over LDAP • Modifying default ACL cannot be done via LDAP or usual tools • ACLs on the object can be removed or modified after object creation, however
The Default ACL for User (inetOrgPerson) • An object of class inetOrgPerson in LDAP will be created with the following access rights: • [Public] read access to messageServer and groupMembership • [Root] read access to networkAddress • Self read/write to loginScript and printJobConfiguration, and read to all other attributes • Why are these set? I don’t know! • Probably legacy applications/tree behavior—I’m checking it out • This may not be what you want • Are what groups your users are in private information? Do you want them mucking about with their own login scripts?
Standard ACLs on a New Tree • [Public] has entry browse rights to the entire tree ([Root) • Cn=admin,o=Organization has supervisor rights on all entries from [Root] down
Watch Your Apps • Other apps (including Novell’s) may change default rights assignments on your tree. • There may be things you want hidden that are not any longer.
Check Your Default Rights • Your organization probably has policies on what personal data can be shared inside and out of the organization • Universities: FERPA • Discrimination/confidentiality concerns. • There can be good reasons to modify default rights in some environments, but it can make things more difficult • If you remove [Public] entry rights, people have to know who they are, and people cannot browse to other users for rights assignments • Changing browse rights to [Root] from [Public] to [Root] means only authenticated users can browse all objects in the tree • Changing default rights on directory information may make eDirectory less useful as a general directory • But more useful as an institutional tool
What’s the Difference Between [Public] and [Root], Anyway? • [Public] is a syntax for an unauthenticated user • [Root] is any user (authenticated) in the tree • [Public] and [Root] are not ‘real’ objects, but can be assigned in ACLs
The X-NDS_PUBLIC_READ flag • Some attributes in NDS are defined as public read • These attributes are visible regardless of any ACL settings on the object itself • Notably, objectClass • Which sort of makes sense, but probably a good idea to not name attributes “topSecretDecoderRingKey” or something like that
Brief Introduction to LDAP • LDAP is an Internet standard (v3: RFCs 2251-2256) that defines an access methodology to a directory service • It defines authentication, syntax, and operations, as well as methods for extending the basic functionality of the directory • eDirectory is fully LDAP v3 compliant (all MUST statements in protocol description, many MAY)
LDAP SDKs • Programmatic interfaces to the LDAP protocols • If the SDK speaks pure LDAP, then any SDK can be used to speak to any LDAP server • Novell makes SDKs for C and Java • Other vendors make SDKs for other languages • Open source implementations in OpenLDAP (C), Perl, Python, PHP. . .
LDAP Operations • Bind—authenticate to the directory • Unbind—disconnect • Search—basic information finding operation • Modify—modify content of a (add/remove attributes) • Add—add an new object to the directory • Delete—remove an object from the directory • Modify DN—change an object’s distinguished name • Compare—test a value of an attribute • Abandon—finish a connection abruptly • Plus extended operations (defined by schema)
LDAP View of the Tree • The tree consists of objects, attributes, values, and schema • Objects: basic entries in directory, identified by their distinguished name • Attributes: field names of data in an object • Values: Specific pieces of data in attributes • Schema: The rules that define the types of objects, which objects contain other objects, which attributes a type of object has, the format of attribute values
How ACLs Are Manipulated in LDAP • ACL is simply an attribute of an object • Is part of the top object class, so all objects have an ACL • ACLs are multipart attributes • LDAP displays ACLs in a tagged text representation
Default ACL of inetOrgPerson (User) dn: cn=jsmallberries,ou=propulsion,o=yoyodyne ACL: 2#subtree#cn=jsmallberries,ou=propulsion,o=yoyodyne#[All Attributes Rights] ACL: 6#entry#cn=jsmallberries,ou=propulsion,o=yoyodyne#loginScript ACL: 2#entry#[Public]#messageServer ACL: 2#entry#[Root]#groupMembership ACL: 6#entry#cn=jsmallberries,ou=propulsion,o=yoyodyne#printJobConfiguration ACL: 2#entry#[Root]#networkAddress ACL: 2#entry#[Public]#groupMembership ACL: 1#entry#[Public]#cn
Parts of an LDAP ACL ndsAcl = privileges "#" scope "#" subjectname "#" protectedattrname • privileges: bitmask describing rights assigned • scope: either entry or subtree • entry: only for actual object • subtree: for the object and its subordinates • subjectname: DN of object who is getting rights (security principal) • protecteattrname: attributes protected by ACL • [All Attributes Rights]: every attribute of object (and its subordinates if scope is subtree) • [Entry Rights]: Rights to the object itself • Specific attribute: LDAP name of eDirectory attribute
More ACL Examples • 47#entry#cn=admin,o=yoyodyne#mail • 47=32+8+4+2+1= Supervisor; Add/Delete Self; Write, Add, Delete Attrs; Read; Compare • 2#subtree#ou=propulsion,o=yoyodyne#[All Attributes Rights] • 2=2=Read Attributes • Impress your friends! Memorize or quickly compute LDAP ACL bitmasks!
Adding or Removing ACLs • ACLs are just regular attributes on the object and can be added, deleted, or modified like any other attribute. • There are no special calls or routines needed to modify ACLs in LDAP, and any LDAP client or SDK that can read and write attributes can manage eDirectory ACLs • Of course, you need rights to modify the attribute—either supervisory rights to the object or Write rights to the ACL property of the object • Write right to the ACL property of an object is effectively full access to the object itself
How Rights Affect LDAP Search Operations • Searches are done as the authenticated LDAP user (or the defined LDAP proxy user if an anonymous bind)—All eDirectory access rights are enforced • Search will only return results if user has rights to read both the attributes and objects being searched for • Search calls will never fail based on lack of rights to an object or an attribute—they simply return no objects or attributes
LDAP Rights Evaluation • You will not see attributes that you don’t have rights to, so it is like they don’t exist to you • You do know what is possibly there by examining the schema, however. • This is both a curse and a blessing • Make sure you write your application to deal with the fact that different results may be returned based on who is logging in (including things like number of entries and attributes, and getting no attributes returned, or that you were going to use an attribute for something really cool and now it’s not there. . .)
A Note About the LDAP Proxy User • The LDAP Proxy user is a normal user account • It must not have a password assigned to it • People can log in to the tree as LDAP_Proxy • Hide or rename your LDAP_Proxy user • Restrict it to log in only from LDAP servers • Enhancement request: Assign password to LDAP_Proxy, require LDAP server to use it for anonymous binds (store it in the LDAP Server or LDAP Group object) • Since anonymous binds are functionally equivalent to [Public] anyway, consider not using an LDAP proxy user and modifying [Public]’s rights as appropriate
Hey, this Is a Developer Lecture, When Are We Going to See Some Code? • NDK—modifyACL.c • We’ll see code is parsing the ACL string for us to make it more human-readable. • Notice how SDK builds modify statements
LDAP Extension for Get Effective Privileges • An LDAP extension is an additional operation supported by a server to provide additional functionality • LDAP extensions are a part of the LDAP v3 standard
More Sample Code • Extensions/getpriv.c • The SDK hides things like the extension OID, checking the root DSE to see if the schema extension exists, etc.
Using LDIF to manage ACLs dn: cn=jsmallberries,ou=propulsion,o=yoyodyne uid: jsmallberries givenName: John fullName: John Smallberries Language: ENGLISH sn: Smallberries objectClass: inetOrgPerson objectClass: organizationalPerson objectClass: person objectClass: ndsLoginProperties objectClass: top cn: jsmallberries
LDIF of a User, Continued ACL: 2#subtree#cn=jsmallberries,ou=propulsion,o=yoyodyne#[All Attributes Rights] ACL: 6#entry#cn=jsmallberries,ou=propulsion,o=yoyodyne#loginScript ACL: 2#entry#[Public]#messageServer ACL: 2#entry#[Root]#groupMembership ACL: 6#entry#cn=jsmallberries,ou=propulsion,o=yoyodyne#printJobConfiguration ACL: 2#entry#[Root]#networkAddress ACL: 2#entry#[Public]#groupMembership ACL: 1#entry#[Public]#cn ACL: 7#entry#cn=admin,o=yoyodyne#[Entry Rights]
Modifications in LDIF version: 3 dn: cn=jsmallberries,ou=propulsion,o=yoyodyne changetype: modify add: ACL ACL: 47#subtree#[Root]#[All Attributes Rights] - delete: ACL - replace: ACL ACL: 47#subtree#[Root]#[All Attributes Rights]
Using LDIF • ICE • ConsoleOne or command line • LDAP utilities • SDK tools or OpenLDAP
C is Cool, but Perl is Cooler • Net::LDAP Perl module • One of a few Perl LDAP APIs • My personal favorite (no C code, efficient, easy to code) • Installing • Available with standard Linux distros • Or just get it from perl-ldap.sourceforge.net, or from CPAN • Need OpenSSL to do secure binds
Manipulating ACLs in Perl • Read/write attributes • $ldap->modify(dn, changes=>[add => [ACL => “47#subtree#cn=jworfin,ou=propulsion,o=yoyodyne#[All Attributes Rights]”]]);
modifyACL.pl • modifyACL.c ported to Perl
Effective rights in Perl • Perl-LDAP does not support extensions • Of course, when your connection handle object is initialized and you perform the bind on it, LDAP is accessed as the authenticated user.
Other Languages • PHP • Python • Java • Anything else with an LDAP SDK or utilities • They’re just attributes, after all
Defining and Enforcing an eDirectory Security Infrastructure • Understand what eDirectory is doing for you by default • Assess and evaluate what Default ACLs do • Bind to the tree as the anonymous user, see what you find • Periodically redo this, especially after installing new applications • Make sure you understand inheritances and IRFs • Work from the top-down and bottom up
eDirectory Tree Design Considerations • Sociopolitical concerns, structural concerns, geographic concerns • Why does the developer care? • Tree design affects how code is written and implemented • ACLs affect programming design • Usefulness of eDirectory and associated code is enhanced by well-defined security infrastructure
First Principles • KISS • Least privilege • Leverage inheritance whenever possible • Minimize IRFs • Use groups when you can
Keep It Simple, Silly • Design the tree as simply as possible, but with enough structure so that rights assignment can be done in appropriate places for maximum effect • Although applying ACLs to a tree can be done as much as you want, and wherever you want, you’ll go insane trying to keep track of it all if you don’t limit it whenever you can • But, then again, part of the power of eDirectory is the precise control you can give to rights management • Just don’t overdo it
Least Privilege • Always work your security structure from the “nobody gets access to anything” point, and then add just the rights needed to get their job done • When setting up users or groups of users to have enhanced access, add the specific rights necessary • For instance, only the write right to an attribute, not Supervisor to the entire object • Requires a bit more testing, and planning, but it’s your tree at stake.
Leverage Inheritance Whenever Possible • Both in the trustee of an object and the object itself, whenever you can use container objects to apply ACLs, you’ve simplified the total number of rules in your tree, and that’s a good thing • If the tree design is intuitive, inherited rights will be self-documenting
Minimize IRFs • IRFs are great, and one of the things that makes eDirectory the bee’s knees • However, IRFs are hard to debug when something goes wrong, and cause strange things to happen that you’re not necessarily expecting • If you find yourself applying IRFs everywhere to fix problems with inherited ACLs, your tree design is likely not optimal