Extend LDAP plugin to support AD authentication


  • Moderator

    The current ldap plugin is missing the capability to authenticate via AD using LDAP. This request will document the changes needed to add this capability.


  • Moderator

    George helped me figure out what I was doing wrong. But what you posted Tom is very valuable.


  • Senior Developer

    @Wayne-Workman
    Here’s how mine is setup:

    Connection Name: What do you want to call it – not used for anything in regards to functionality.
    Description: Self explanatory – not used for anything in regards to functionality.
    Server Address: ###Needed### The address of your server.
    Server Port: ###Needed### The port of your server (usually 389).
    Search Base DN: ###Needed### The DN you need to search starting at… For me I’m searching under users common name.
    Group Search DN: ###Needed### The dn you need to start searching for Groups… For me I’m searching under the OU named Groups.
    Admin Group: ###Not required if mobile group is set### This is the group that will be looked at for ldap to be scanning for "FOG Admins"
    Mobile Group: ###Not required if admin is set### This is the group that will be looked at to allow “mobile” users. These users cannot login to the main dashboard but they can login to the mobile page.
    Initial Template: Does not do anything to the DB store. Just a “template” holder.
    User Nam Attribute, what field to search for user names.
    Group member attribute, what field to search for groups.
    Bind DN, Not required as user based element should be able to find.
    Bind Password the bind dn password.
    0_1481746751739_upload-0df64a0d-c188-4747-beec-b20c51d3dd38


  • Moderator

    Working with RC-36,

    I’ve not got it working yet. I’m not sure I fully understand the purpose of these fields or if they are all required or not.

    What I would like is instructions on how to authenticate a user, and require that user to be in a group called “fog_admins”. The group is in one spot in AD, the users are in another spot.

    I’m assuming I path to the group in the group search dn field, and path to the users in the search base dn? Don’t know.

    Admin group is obvious enough.
    I am not worried about the mobile group.

    bind DN is the exact username and pass used to authenticate a user’s credentials, this is clear.


  • Senior Developer

    I’ve pushed into the working-RC-37 branch which, from my limited testing, appears this is now working properly.


  • Senior Developer

    With any luck, this will now work woot woot.


  • Moderator

    I’m trying to setup the LDAP stuff at work right now… some guidance would be appreciated… I’m going to poke around still though.


  • Senior Developer

    I have a windows domain at home now.

    And I’m very close to figuring this out, I hope.


  • Moderator

    I have a windows domain at home…



  • @george1421 @Tom-Elliott if you like tom i will give you tv access to my environment and you can do your experiments if you like?

    Regards X23


  • Moderator

    @Tom-Elliott I do have questions if it is failing on mine because I don’t have some international character set loaded. While I’m not saying that is the case, it is a possibility.

    At home I have a 2012 reference image that is built by mdt. That way I can spin up a new 2012 server quickly and have 3 days before it needs to be activated. Its not an ideal situation, but if you are playing and mess the up the server you can rebuild it quickly. (been there, done that).


  • Senior Developer

    @george1421 I’m downloading a Windows Server 2012 ISO right now.

    I’ll create a domain and this will extend my testing a bit.

    1. I can test the LDAP plugin in a semi real world environment.
    2. I can test client domain joins internally. (Joe created a server for us to use, but i’m always hesitant towards it as it is going straight across the internet).
    3. I can test LDAP Groups in an AD frameset.
    4. I can test mutations and hopefully figure out a solution to this ever going problem. (Or validate with certainty that this will not work).

  • Moderator

    @george1421

    <?php
    
        $user = 'meUser';
        $pass = 'mePassword.1';
        $server = '192.168.1.20';
        $bindDN = 'cn=BindUserisMe,ou=Domain Users,dc=domain,dc=com';
        $bindPass = 'BindPassword.1';
        $searchScope = 2;
    
            // clean up user name we only want the user's short name without any domain component
            // note I did not try to understand the regex expression but I expect there to be
            // issues with non-us english characters, just saying.
            $user = trim(preg_replace('/[^a-zA-Z0-9\-\_@\.]/', '', $user));
    
            // open connection to the server
            $ldapconn = ldap_connect($server,389);
            ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
            ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
    
            $userDN = '';
            $accessLevel = 0;
    		
    		## this line will throw the error. 
            $userSearchDN = 'ou=äDomain Users,DC=domain,dc=com';
     		
            $adminGroup = 'FoG_Admins';
            $userGroup = 'FOG_Users';
            $grpMemberAttr = strtolower('memberOf');
    
            if ( ldap_bind($ldapconn, $bindDN, $bindPass) ) {
                $filter = sprintf('(&(objectCategory=inetOrgPerson)(%s=%s))', 'sAMAccountName', $user);
                // we want to return the user's DN so that we can bind as the user
                // we will get his DN based on his samaccountname for AD
                $attr = array( 'dn' );
    
                switch ($searchScope) {
                    case 1:
                        // LDAP_SCOPE_ONELEVEL search one level down but not base
                        $result = ldap_list($ldapconn, $userSearchDN, $filter, $attr);
                        break;
                    case 2:
                        // LDAP_SCOPE_SUBTREE search base + all subtree (OUs) below
                        $result = ldap_search($ldapconn, $userSearchDN, $filter, $attr);
                        break;
                    default:
                        // LDAP_SCOPE_BASE search base only and don't look any deeper
                        $result = ldap_read($ldapconn, $userSearchDN, $filter, $attr);
                }
    
                // count the number of entries returned
                $retcount = ldap_count_entries($ldapconn, $result);
    
                if ($retcount == 1) {
                    // great we only returned one entry
                    $entries = ldap_get_entries($ldapconn, $result);
                    // pull out the user dn from the entries
                    $userDN = $entries[0]['dn'];
                } else {
                    $userDN = '';
                }
    
            }
    
            if (!$userDN =='') {
                // Now rebind as the user we just found
                if ( ldap_bind($ldapconn, $userDN, $pass) ) {
                    // If we get to here the user is authorized, now lets get the group membership
                    // This time since we know the user DN we can look up the user based on that
                    $filter = '(objectclass=*)';
                    // get what groups this user is a member of
                    $attr = array( $grpMemberAttr );
                    $result = ldap_read($ldapconn, $userDN, $filter, $attr);
    
                    // count the number of entries returned
                    $retcount = ldap_count_entries($ldapconn, $result);
    
                    if ($retcount > 0) {
                        $entries = ldap_get_entries($ldapconn, $result);
    
                        // check groups for membership
                        foreach($entries[0][$grpMemberAttr] as $grps) {
                            // is admin user, set level and break loop
                            if(strpos( $grps, $adminGroup )) { $accessLevel = 2; break; }
    
                           // is user, set level and keep looking just incase user is in both groups
                           if(strpos( $grps, $userGroup )) $accessLevel = 1;
                       }
                    }
                    // close our connection as bindDN
                    ldap_unbind( $ldapconn );
    
                    echo $accessLevel;
    
                } else {
                    print 'unable to bind using user info, user is not authorized in ldap';
    
                }
         } else {
              echo 'User not found in LDAP';
         }
     ?>
    
    

  • Moderator

    @Tom-Elliott said in Extend LDAP plugin to support AD authentication:

    @x23piracy To figure this out more properly, I think I need a means to replicate the issue very specifically.

    Anybody know of any good guides to create my own internal AD Server?

    To find the error its even easier than that. I have a standalone php script that will throw the error, all you need is an ad/ldap server to connect to.



  • @Tom-Elliott i would simply install a windows server with ad roll enabled, afaik simply building an ad should be no rocket science, i don’t know a simplier way, it would be cool if there is a binary out there who could simulate an ad.


  • Senior Developer

    @x23piracy To figure this out more properly, I think I need a means to replicate the issue very specifically.

    Anybody know of any good guides to create my own internal AD Server?



  • @Wayne-Workman hehe sorry for the bad words but i really have to deal with some stupid people calling themselves it experts :D


  • Moderator

    @x23piracy Dude you are hilarious, in a good way.



  • @Tom-Elliott said in Extend LDAP plugin to support AD authentication:

    The mutations are still an issue as I don’t know how to get them to escape. Everything I’ve read online says that >mutations are not allowed to be a part of the dn strings. If I remember correctly, this is where the mutation is currently >stored in your case @x23piracy.

    Sorry, but i cannot change way from the vowel’s and i need to say, i would never use them it was a real expert working in the company before that thougth hey i am a german and best practice is to not use vowels but he gave a shit on it and used them (i really would like to kick his ass).

    Regards X23


  • Senior Developer

    The ldap plugin works as it did before, I don’t know what you need to test.

    There is one caveat and that, currently, if the account isn’t already present the first time you login the return will be “invalid login”.

    The next login, however, will work fine.

    I’ve corrected this particular problem for the next.

    The mutations are still an issue as I don’t know how to get them to escape. Everything I’ve read online says that mutations are not allowed to be a part of the dn strings. If I remember correctly, this is where the mutation is currently stored in your case @x23piracy.


Log in to reply
 

335
Online

38727
Users

10554
Topics

99920
Posts

Looks like your connection to FOG Project was lost, please wait while we try to reconnect.