Simplifying LDAP Group Management Using MidPoint: Part II – Posix Groups

Unix/Linux servers can be configured to authenticate and authorize against LDAP server, by using LDAP accounts and groups. With some Identity Management solutions you can put users to these groups, but you need to manage the groups by the native LDAP tools. This is not the case with midPoint! MidPoint allows you to create not only LDAP accounts, but also the groups so it can become the ultimate tool for IT administrators or even for users with limited IT skills, really simplifying the LDAP group management.

In this post I will show you how midPoint configuration of so called “metaroles” can be used also for LDAP group management of Posix groups (posixGroup) as projections of midPoint roles and how to extend LDAP accounts (inetOrgPerson) with auxiliary object classes such as “posixAccount”. For everything we will use just Resource Schema Handling and Generic synchronization.

The complete scenario setup and description is here. So we assume that the configuration in midPoint is already uploaded, including the two metaroles.

In the previous blog we have discussed the standard LDAP group management. Now we extend the LDAP group management to cover Posix groups. We will create a new role representing a group for managing access to Linux server named “Athena”. We assume that the server has been configured using PAM to use LDAP accounts and groups instead of its local databases (/etc/passwd and /etc/group) and that the account membership in the group “athena-users” will allow the account to log in to the server using SSH.

Let’s create the role “LDAP Unix Group – Access to Athena”. The role will be created as a Posix group (posixGroup). The scenario is configured to use the “identifier” attribute of the role as the “cn” attribute of the new group. So we go to Roles – New role and fill the following attributes of the “Basic” tab:

  1. Name: LDAP Unix Group – Access to Athena
  2. Identifier: athena-users
Creating UNIX group, step 1

Creating UNIX group, step 1

No more attributes are necessary on this tab. Then, switch to the tab”Assignments” and assign a role named “LDAP Unix Group Metarole”. This is the second of two metaroles created to support this scenario. The metaroles act as “role templates” and contain all required mappings in addition to the mappings in the resource schema handling. Then save the form.

Creating UNIX group, step 2

Creating UNIX group, step 2

The metarole assigned to the “LDAP Unix Group – Access to Athena” role causes the creation of a new group in LDAP with DN: “cn=athena-users,ou=unixgroups,dc=example,dc=com”. Please note that “identifier” attribute was used in DN and for “cn” attribute, and that the group has objectClass: “posixGroup” and is placed in “ou=unixgroups,dc=example,dc=com”. This is different from the standard groups created in the previous example, because we want these groups to be stored in different container.

Created UNIX group (posixGroup)

Created UNIX group (posixGroup)

Now we have created new roles with the LDAP group projections (one of each type), so let’s create new midPoint user and assign him/her the first role we have created. Go to Users – New user and create user. You can also use the same user from the previous blog. Fill at least the following attributes of the “Basic” tab:

  1. Name: jsmith
  2. Given Name: John
  3. Family Name: Smith
  4. Full Name: John Smith
  5. Password: secret123

In the previous post, we have used standard LDAP account attributes and standard LDAP group membership. But we want this user to be able to log in to the Linux server “athena”, remember? So we need to put his/her account to the previously created posixGroup. Also, as this account will be used instead of local Linux account, we need to populate the Linux/Unix-related attributes (homeDirectory, uidNumber, gidNumber etc.). All this will be achieved automatically if we assign the user the previously created role “LDAP Unix Group – Access to Athena”, which itself has assigned the “LDAP Unix Group Metarole”. We are NOT assigning the metarole! Save the form after you assign the “LDAP Unix Group – Access to Athena” to the user.

Extending LDAP account with posixAccount attributes and group membership

Extending LDAP account with posixAccount attributes and group membership

You can edit the same user to check that new attributes have been filled for the OpenLDAP account, and the “Associations” now display both groups: “cn=wiki-users,ou=groups,dc=example,dc=com” (assigned independently in the previous blog post, indicated as LDAP Group) as well as “cn=athena-users,ou=unixgroups,dc=example,dc=com” (indicated as UNIX Group).

Extended LDAP account with posixAccount attributes and group membership, result in midPoint

Extended LDAP account with posixAccount attributes and group membership, result in midPoint

You can also check the account in LDAP. It has been extended with auxiliary object class “posixAccount”, and the required attributes have been computed by the mappings in the “LDAP Unix Group Metarole”.

Extended LDAP account with posixAccount attributes and group membership, result in LDAP

Extended LDAP account with posixAccount attributes and group membership, result in LDAP

Also the group “cn=athena-users,ou=unixgroups,dc=example,dc=com” now has a new member “jsmith” (the membership in the posixGroup is done using user’s uid, not DN).

posixGroup populated by membership

posixGroup populated by membership

The really interesting part is that the LDAP account was first created with standard objectClass: inetOrgPerson, and only after assigning the role “LDAP Unix Group – Access to Athena” the account was extended with the auxiliary object class “posixAccount”. The same account is used, no new one was created. You can assign any number of roles that will put the user in one or more standard groups or Posix groups, and the auxiliary attributes will be computed whenever the account should have the “posixAccount” object class. After the last role for Linux group is unassigned from the user, his account will lose the “posixAcount” object class and all its attributes, reverting back to standard “inetOrgPerson” object class.

As you can see, creating the midPoint roles is still very easy. Even for the complete LDAP group management for Posix groups as well. You can create a number of such roles in very short time, you don’t need to create them directly in LDAP server. You can also easily assign the roles to your users and allow them to access your Linux/Unix servers configured for LDAP.

More info and complete scenario documentation can be found here. Please refer to Roles, Metaroles and Generic Synchronization to get more information about the concepts of metaroles.

4 thoughts on “Simplifying LDAP Group Management Using MidPoint: Part II – Posix Groups

  • sequences never work on 3.7.2. this example cant be replicated. losing my faith on midpoint as an usable tool.

  • all versions I’ve tested provide the same result .
    2018-07-05 18:10:31,096 [] [http-nio-8080-exec-10] INFO (com.evolveum.midpoint.model.impl.importer.ObjectImporter): Imported object sequence:7d4acb8c-65e3-11e5-9ef4-6382ba96fe6c(Unix UID numbers)

    2018-07-05 18:10:40,419 [] [http-nio-8080-exec-6] INFO (com.evolveum.midpoint.model.impl.importer.ObjectImporter): Imported object sequence:02cb7caa-6618-11e5-87a5-7b6c6776a63e(Unix GID numbers)

    2018-07-05 18:10:54,277 [] [http-nio-8080-exec-3] INFO (com.evolveum.midpoint.model.impl.importer.ObjectImporter): Imported object resource:9d5d62a6-49bb-11e6-ac4d-3c970e44b9e2(OpenLDAP posix)
    .

    2018-07-05 18:11:06,805 [] [http-nio-8080-exec-10] INFO (com.evolveum.midpoint.model.impl.importer.ObjectImporter): Imported object role:1568ec1e-36cc-11e6-a052-3c970e44b9e2(LDAP Group Metarole)
    2018-07-05 18:11:12,580 [] [http-nio-8080-exec-6] INFO (com.evolveum.midpoint.model.impl.importer.ObjectImporter): Imported object role:31ea66ac-1a8e-11e5-8ab8-001e8c717e5b(LDAP Unix Group Metarole)

    2018-07-05 18:13:26,651 [] [pool-4-thread-5] ERROR (com.evolveum.midpoint.web.component.progress.ProgressPanel): Error executing changes.
    com.evolveum.midpoint.util.exception.SchemaException: No target item that would conform to the path extension/gidNumber in mapping ‘sequenceGID’ in role:31ea66ac-1a8e-11e5-8ab8-001e8c717e5b(LDAP Unix Group Metarole) in delta for role:null(ldap athenea group)
    at com.evolveum.midpoint.model.common.mapping.MappingImpl.parseTarget(MappingImpl.java:948)
    at com.evolveum.midpoint.model.common.mapping.MappingImpl.getOutputPath(MappingImpl.java:968)
    at com.evolveum.midpoint.model.impl.lens.projector.MappingEvaluator.createFocusMapping(MappingEvaluator.java:691)
    at com.evolveum.midpoint.model.impl.lens.projector.MappingEvaluator.createFocusMapping(MappingEvaluator.java:602)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluateFocusMappings(AssignmentEvaluator.java:534)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluateSegmentContent(AssignmentEvaluator.java:356)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluateFromSegment(AssignmentEvaluator.java:319)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluateInducement(AssignmentEvaluator.java:882)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluateSegmentTarget(AssignmentEvaluator.java:752)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluateSegmentContent(AssignmentEvaluator.java:411)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluateFromSegment(AssignmentEvaluator.java:319)
    at com.evolveum.midpoint.model.impl.lens.AssignmentEvaluator.evaluate(AssignmentEvaluator.java:230)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.AssignmentTripleEvaluator.evaluateAssignment(AssignmentTripleEvaluator.java:523)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.AssignmentTripleEvaluator.processAssignment(AssignmentTripleEvaluator.java:315)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.AssignmentTripleEvaluator.processAllAssignments(AssignmentTripleEvaluator.java:165)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.AssignmentProcessor.processAssignmentsProjectionsWithFocus(AssignmentProcessor.java:244)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.AssignmentProcessor.processAssignmentsProjections(AssignmentProcessor.java:174)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.FocusProcessor.lambda$processFocusFocus$4(FocusProcessor.java:229)
    at com.evolveum.midpoint.model.impl.lens.ClockworkMedic.partialExecute(ClockworkMedic.java:170)
    at com.evolveum.midpoint.model.impl.lens.ClockworkMedic.partialExecute(ClockworkMedic.java:150)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.FocusProcessor.processFocusFocus(FocusProcessor.java:228)
    at com.evolveum.midpoint.model.impl.lens.projector.focus.FocusProcessor.processFocus(FocusProcessor.java:123)
    at com.evolveum.midpoint.model.impl.lens.projector.Projector.lambda$projectInternal$1(Projector.java:214)
    at com.evolveum.midpoint.model.impl.lens.ClockworkMedic.partialExecute(ClockworkMedic.java:170)
    at com.evolveum.midpoint.model.impl.lens.projector.Projector.projectInternal(Projector.java:212)
    at com.evolveum.midpoint.model.impl.lens.projector.Projector.project(Projector.java:101)
    at com.evolveum.midpoint.model.impl.lens.Clockwork.click(Clockwork.java:437)
    at com.evolveum.midpoint.model.impl.lens.Clockwork.run(Clockwork.java:196)
    at com.evolveum.midpoint.model.impl.controller.ModelController.executeChanges(ModelController.java:547)
    at com.evolveum.midpoint.web.component.progress.ProgressPanel$14.callWithContextPrepared(ProgressPanel.java:605)
    at com.evolveum.midpoint.web.component.progress.ProgressPanel$14.callWithContextPrepared(ProgressPanel.java:591)
    at com.evolveum.midpoint.web.component.SecurityContextAwareCallable.call(SecurityContextAwareCallable.java:59)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Leave a Reply