Context
I'm trying to interact with an OpenLDAP server, and have some issues understanding the behavior of said server.
note : I don't have admin rights on this server, I am just writing some code that tries to extract lists of users and groups from it.
The specific point about which I have a question :
When I run a query asking for attribute name, I get entries containing cn, sn and givenName, and no name attribute :
# sample output:
$ ldapsearch [options ...] "(|(objectClass=posixAccount)(objectClass=posixGroup))" name
...
# sample users:
dn: uid=id4321,ou=Users,dc=example,dc=com
cn: u1234
sn: Doe
givenName: John
dn: uid=id4322,ou=Users,dc=example,dc=com
cn: u2234
sn: Doe
givenName: Jane
dn: ...
# sample groups:
dn: cn=Domain Users,ou=Groups,dc=example,dc=com
cn: Domain Users
dn: cn=HR,ou=Groups,dc=example,dc=com
cn: HR
dn: ...
Question
Where can I find the correspondance "attribute name in the query" -> "attribute(s) name(s) in the response" ?
If part of that correspondance is in the LDAP or OpenLDAP standard, where is it defined ?
If part of that correspondance comes from the directory config/schema, how can I query for it ?
I have tried to Google with limited success, I'm trying to head to RFCs but I don't know which one to read first.
I think I found the answer to my question :
the attributes name, cn, sn and a bunch of other standard attributes are defined in RFC 4519
an attribute type may have a supertype (for example : the definition of cn is ( 2.5.4.3 NAME 'cn' SUP name ), the definition of sn is ( 2.5.4.4 NAME 'sn' SUP name ) ), and if a search query queries for an attribute, the server may include in its response attributes whose supertype match
so querying for name may return results with a sn, cn, givenName and initials attribute
the definition of "attribute types" and "supertype" is in RFC 4512
Related
I follow the tutorial on how to create groups and users in LDAP Apache Directory Studio.
I use the posixGroup to create a group
to create users inetOrgPerson, posixAccound, shadowAccount
However, entries do not contain gidNumber and uidNumber and can not be added.
How do I add gidNumber for groups and uid Number for users?
I do not get gidNumber when I create it if I try to add it manually:
Error while creating entry
- [LDAP: error code 65 - OBJECT_CLASS_VIOLATION: failed for MessageType : ADD_REQUES java.lang.Exception: [LDAP: error code 65 -
OBJECT_CLASS_VIOLATION: failed for MessageType : ADD_REQUEST Message
ID : 13
Add Request : Entry
dn: cn=Vydaj,ou=Testgroups,dc=test,dc=com
objectClass: posixGroup
objectClass: top
gidNumber: 1000
cn: Vydaj : ERR_277 Attribute gidNumber not declared in objectClasses of entry cn=Vydaj,ou=Testgroups,test,dc=com]
at
org.apache.directory.studio.connection.core.io.api.DirectoryApiConnectionWrapper.checkResponse(DirectoryApiConnectionWrapper.java:1418)
at
org.apache.directory.studio.connection.core.io.api.DirectoryApiConnectionWrapper.access$11(DirectoryApiConnectionWrapper.java:1386)
at
org.apache.directory.studio.connection.core.io.api.DirectoryApiConnectionWrapper$6.run(DirectoryApiConnectionWrapper.java:1009)
at
org.apache.directory.studio.connection.core.io.api.DirectoryApiConnectionWrapper.runAndMonitor(DirectoryApiConnectionWrapper.java:1312)
at
org.apache.directory.studio.connection.core.io.api.DirectoryApiConnectionWrapper.checkConnectionAndRunAndMonitor(DirectoryApiConnectionWrapper.java:1256)
at
org.apache.directory.studio.connection.core.io.api.DirectoryApiConnectionWrapper.createEntry(DirectoryApiConnectionWrapper.java:1031)
at
org.apache.directory.studio.ldapbrowser.core.jobs.CreateEntryRunnable.createEntry(CreateEntryRunnable.java:225)
at
org.apache.directory.studio.ldapbrowser.core.jobs.CreateEntryRunnable.run(CreateEntryRunnable.java:124)
at
org.apache.directory.studio.connection.ui.RunnableContextRunner$1.run(RunnableContextRunner.java:129)
at
org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:119)
[LDAP: error code 65 - OBJECT_CLASS_VIOLATION: failed for
MessageType : ADD_REQUEST Message ID : 13
Add Request : Entry
dn: cn=Vydaj,ou=Testgroups,dc=test,dc=com
objectClass: posixGroup
objectClass: top
gidNumber: 1000
cn: Vydaj : ERR_277 Attribute gidNumber not declared in objectClasses of entry cn=Vydaj,ou=Testgroups,dc=test,dc=com]
You should be able to edit the values within the Apache Directory Studio "Create an Object" wizard -- when you create an object with objectClass posixGroup, you should have an "Integer Editor" where you type the group gidNumber. When you create a user with posixAccount as an objectClass, you'll get a dialog box that has several attributes highlighted in red. Double-clicking the red text, or the empty cell in the "Value" column next to the red text, will allow you to edit that attribute value.
You could always create a general user or group first and then add the appropriate POSIX objectClass and required attributes. Since the objectClass has mandatory attributes, this needs to be performed as a single operation. An example LDIF that takes an inetOrgPerson user account, adds posixAccount as an objectClass, and adds the POSIX attributes (which are mandatory v/s optional depend on your schema definition):
dn: cn=something,ou=someou,o=company
changetype: modify
add: objectClass
objectClass: posixAccount
-
add: uidNumber
uidNumber: 55555
-
add: gidNumber
gidNumber: 555
-
add: homeDirectory
homeDirectory: /home/userid
-
add: loginShell
loginShell: /bin/bash
-
add: gecos
gecos: UserDisplay Name
-
add: description
description: UserDisplay Name
-
Is their any standard way to set user roles and permissions.
Option 1:
Create group and assign members in that.
My people dn is as follows .
DN: uid=55e44a75e4b0f16711714165,ou=people,dc=cofinding,dc=com
I created Groups for roles. and assign members in that
DN: cn=ADMIN,ou=roles,dc=cofinding,dc=com
And added members here who has role ADMIN. Near about 50K members added in ADMIn role.
Option 2 :Add custom Value role in people .e.g. I created dn as user_role
DN: uid=55e44a75e4b0f16711714165,ou=people,dc=cofinding,dc=com
In people we can add user_role=ADMIN,MASTER_ADMIN
Is their any other option or standard practice . As roles are very important in any authentication process.
First of all: roles have nothing to do with authentication, they are used in the authorization process. When authenticating, the system verifies who the user is based on some set of credentials; once this has been established the roles are consulted in the authorization process to determine whether the user should be granted access to some specific resource.
Answering your question on roles: Both ways would work. The first approach is probably the most common one (and most in line with the way things are normally structured in LDAP. Take a look at the groupOfNames and groupOfUniqueNames objectclasses for representing your role). Depending on the use case I would argue that the latter is probably more practical in many cases, but you need to take into account that it's not quite the standard 'LDAP way' of doing things.
There is another option that's kind of a hybrid between options #1 and #2.
Instead of using static groups (Option 1) you can use the so-called dynamic groups, or groups of URLs:
dn: cn=ADMIN,ou=roles,dc=cofinding,dc=com
objectClass: top
objectClass: groupOfURLs
cn: ADMIN
memberURL: ldap:///ou=people,dc=cofinding,dc=com??sub?user_role=ADMIN
The memberURL is a filter that determines which users belong to the group based on a certain attribute value and a base DN. In the example above, every user under ou=people,dc=cofinding,dc=com with the attribute user_role=ADMIN will automatically be added to the ADMIN group. Here is a sample admin user:
dn: uid=55e44a75e4b0f16711714165,ou=people,dc=cofinding,dc=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: John Doe
sn: Doe
uid: 55e44a75e4b0f16711714165
user_role: ADMIN
With this approach you get the best from both options (#1 and #2):
Your group entries don't grow in size.
You can query the group to get the list of members:
$ ldapsearch -p 1389 -D "cn=directory manager" -w password -b "cn=ADMIN,ou=roles,dc=cofinding,dc=com" "(objectClass=groupOfURLs)"
dn: cn=ADMIN,ou=roles,dc=cofinding,dc=com
cn: ADMIN
memberURL: ldap:///ou=people,dc=cofinding,dc=com??sub?user_role=ADMIN
member: uid=55e44a75e4b0f16711714165,ou=people,dc=cofinding,dc=com
You can use the memberOf virtual attribute in your search filters:
(memberOf=cn=ADMIN,ou=roles,dc=cofinding,dc=com)
How can I import userGroups and users from Novel EDirectory to liferay?
Here are the Novel eDirectory Setup details:
Group :
cn group1
member
cn=user1,ou=ABCD,ou=ABC,o=AB
cn=user2,ou=ABCD,ou=ABC,o=AB
objectClass
groupOfNames
Top
User 1:
cn user1
objectClass inetOrgPerson
objectClass ssDEFG
objectClass abcUser
objectClass organizationalPerson
objectClass Person
objectClass ndsLoginProperties
objectClass Top
objectClass DirXML-PasswordSyncStatusUser
objectClass DirXML-ApplicationAttrs
sn user1surname
groupMembership cn=group1,ou=DEFGH,ou=DEFG,ou=ABC,o=AB
groupMembership cn=group2,ou=COURSES,ou=ABC,o=AB
groupMembership cn=group3,ou=DEFGH,ou=DEFG,ou=ABC,o=AB
email test1#test.com
User 2:
cn user2
objectClass inetOrgPerson
objectClass ssDEFG
objectClass abcUser
objectClass organizationalPerson
objectClass Person
objectClass ndsLoginProperties
objectClass Top
objectClass DirXML-PasswordSyncStatusUser
objectClass DirXML-ApplicationAttrs
sn user2surname
groupMembership cn=group1,ou=DEFGH,ou=DEFG,ou=ABC,o=AB
groupMembership cn=group2,ou=COURSES,ou=ABC,o=AB
groupMembership cn=group3,ou=DEFGH,ou=DEFG,ou=ABC,o=AB
email test2#test.com
Here are the Liferay Control panel settings
Base DN : [code]ou=ABCD,ou=ABC,o=AB
User Mapping
Authentication Search Filter : (mail=#email_address#)
Import Search Filter : (&(objectClass=inetOrgPerson)(mail=*))
Screen Name :cn
Password :sn
Email Address :mail
Full Name :fullName
First Name :givenName
Middle Name
Last Name : sn
Job Title :title
Portrait
Group : groupMembership
UUID
Groups
Import Search Filter : (&(objectClass=inetOrgPerson)(mail=*))
Group Mapping
Group Name :company
Description : description
User : groupMembership
Its importing users but not importing user groups,
I tried setting ldap.import.method=user in portal-ext.properties but still its not creating/importing user groups,
NOTE : I can able to see list of groups in Control Panel but I its not importing to Liferay
i also tried ldap.import.method=group, its creating only user groups but not importing any users associated to that group
Advance thanx
For your Group mapping, Group Name should be mapped to CN.
I am not sure what User to groupMembership is meant to be, but the only thing that makes sense is actually User : member
The attribute on the User object is groupMembership, and the attribute on the Group object is member.
I'm coming to LDAP as a possible tool for managing access servers and source code at work, and while I've been able to grasp the basic concepts, like representing users and machines as entities, that create attributes, and defining which attributes should apply to an entity based on the objectClasses applied to them, there are a few errors that still make no sense to me, and I'm hoping someone can help explain how they work.
How do nested groups work?
I can understand what ou(organisational unit)'s are, and I can understand putting people inside them, and using the groupOfNames class to act as a container for members, like this LDIF snippet from zytrax:
# create FIRST Level groups branch
dn: ou=groups,dc=example,dc=com
objectclass:organizationalunit
ou: groups
description: generic groups branch
# create the itpeople entry under groups
dn: cn=itpeople,ou=groups,dc=example,dc=com
objectclass: groupofnames
cn: itpeople
description: IT security group
member: cn=William Smith,ou=people,dc=example,dc=com
# create the hrpeople entry under groups
dn: cn=hrpeople,ou=groups,dc=example,dc=com
objectclass: groupofnames
cn: hrpeople
description: Human Resources group
member: cn=Robert Smith,ou=people,dc=example,dc=com
How would I add further levels of nesting though?
What I'm after is something like this pseudocode here:
ou='Projects' /
description: This top level group has a few people in it that can create new groups, and control who's in them
member: cn=Robert Smith,ou=people,dc=example,dc=com
-- somethingsomethingAbitrarilyNestedGroup='project-name'
member: cn=Robert Smith,ou=people,dc=example,dc=com
-- groupOfNames = 'project-name development'
member: cn=Robert Smith,ou=people,dc=example,dc=com
member: cn=Jane Doe,ou=people,dc=example,dc=com
member: cn=server1$,ou=servers,dc=example,dc=com
-- groupOfNames = 'project-name staging'
member: cn=Jane Doe,ou=people,dc=example,dc=com
member: cn=server2$,ou=servers,dc=example,dc=com
Given this hierarchy,what's the best way to grant access to this group now?
I don't see a simple way to do the arbitrary group nesting here - among the normal classes available, without using an expensive closed source tool, yet it feels like it shouldn't be this complex.
How is this normally done using a tool like OpenLDAP, to let other ldap clients control group membership once they're authenticated as a user with the correct rights? ?
Your question is a bit confused - I'm not sure what you mean "what's the best way to grant access to this group now" in the context of the initial few paragraphs.
Nested groups are dead simple. If you're using the groupOfNames objectClass, just add another member attribute to your parent group, with the value being the DN of the child group.
From your pseudo-code:
# Assuming your "groups" OU already exists...
# First create the child groups
dn: cn=project-name development,ou=groups,dc=example,dc=com
objectclass: groupofnames
cn: project-name development
member: cn=Robert Smith,ou=people,dc=example,dc=com
member: cn=Jane Doe,ou=people,dc=example,dc=com
member: cn=server1$,ou=servers,dc=example,dc=com
dn: cn=project-name staging,ou=groups,dc=example,dc=com
objectclass: groupofnames
cn: project-name development
member: cn=Jane Doe,ou=people,dc=example,dc=com
member: cn=server2$,ou=servers,dc=example,dc=com
# Now create the parent group
dn: 'project-name,ou=groups,dc=example,dc=com'
objectclass: groupofnames
member: cn=Robert Smith,ou=people,dc=example,dc=com
member: cn=project-name staging,ou=groups,dc=example,dc=com
member: cn=project-name development,ou=groups,dc=example,dc=com
Hiearchy within OUs is really only to separate your LDAP tree into "logical" segments based on the structure of your organisation. So, for example, you could stick all your groups for managing the "Development Department" in their own OU, so it's nice and clear what they pertain to. Objects can reference each other, and nest quite happily, by referencing each other with appropriate attributes (in this case, member).
I believe that when referencing user objects you should be using uid= rather than cn=
The problem I have with nesting groups is that many applications that can refer to a group are not familiar with how to search the nested groups for member objects.
I have a OpenLDAP Database and it holds some project objects that look like
dn: cn=Proj1,ou=Project,ou=ua,dc=org
cn: Proj1
objectClass: top
objectClass: posixGroup
member: 001ag
member: 002ag
System: ABEL
System: PCx
Budget: ABEL:1000000:0.3
Budget: PCx:300000:0.3
One can see that the Budget attribute is a ":"-separated string, where the first part holds the name of the system the budget is for, the second part holds some budget (which may change every month) and the last entry is a conversion factor for the budget of that system.
Seeing this, I thought this is bad database design, since attribute values should always be atomic. But how can I improve that in LDAP, so that I can do a direct ldapsearch or a direct ldapmodify of the budget of System "ABEL" instead of writing a script, that will have to parse and split the ":"-separated string?
It's a good idea to break things up into groups as much as you can until you get down to individually distinguishable elements, which in your case would be Systems. As you've realized, having the smallest element in the database be Project is a problem when you have more than one System.
I would put a sub-group for each project inside the main Project group, aka:
- ou=Project
+ ou=proj1
+ ou=proj2
+ ou=proj3
Inside each of these you can have an object for "member" or "System", whichever is the more distinguishable attribute. For the sake of an example I'll assume "member" is the better choice. Following this idea, inside each sub-group you would have objects like this:
- ou=Project
- ou=proj1
- dn: cn=sys1,ou=proj1,ou=Project,ou=ua,dc=org
cn: sys1
objectClass: top
objectClass: posixGroup
member: 001ag
System: ABEL
Budget: 1000000:0.3
- dn: cn=sys2,ou=proj1,ou=Project,ou=ua,dc=org
cn: sys2
objectClass: top
objectClass: posixGroup
member: 002ag
System: PCx
Budget: 300000:0.3
+ proj2
+ proj3
Now each system is its own entity, but the project is still grouped together as a whole.