• Recent
  • Unsolved
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Register
  • Login
  • Recent
  • Unsolved
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Register
  • Login

Extend LDAP plugin to support AD authentication

Scheduled Pinned Locked Moved Solved
Feature Request
8
64
28.1k
Loading More Posts
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G
    george1421 Moderator
    last edited by Sep 15, 2016, 12:12 AM

    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.

    1 Reply Last reply Reply Quote 2
    • G
      george1421 Moderator @george1421
      last edited by george1421 Sep 14, 2016, 6:08 AM Sep 14, 2016, 12:00 PM

      @george1421

      Just documenting the ldap requirements from another FOSS application pfsense here. These are the typical fields I would expect to see for any type of LDAP authentication against AD.

      0_1473854335685_ldap1.png

      0_1473854350564_ldap2.png

      0_1473854879663_ldap3.png

      1 Reply Last reply Reply Quote 0
      • G
        george1421 Moderator
        last edited by george1421 Sep 14, 2016, 7:06 PM Sep 14, 2016, 12:45 PM

        The ldap query might look something like this

        ref: http://stackoverflow.com/questions/1032351/how-to-write-ldap-query-to-test-if-user-is-member-of-a-group

        (&(objectClass=user)(sAMAccountName=yourUserName)
          (memberof=CN=YourGroup,OU=Users,DC=YourDomain,DC=com))
        

        Translated into fields

        (&(objectClass=user)({User naming attribute}={UserID})
          ({Group member attribute}={Group naming attribute}={Group name},{Base DN}))
        

        I do have to say I have not looked at the php code yet to see if this can be reverse engineered into the code. I’m just collecting examples of the process right now.

        Use php to query ldap with group membership
        ref: https://samjlevy.com/use-php-and-ldap-to-get-a-users-group-membership-including-the-primary-group/

        This is ref is a bit more onpoint than the above ref: https://samjlevy.com/php-login-script-using-ldap-verify-group-membership/

        <?php
        // Initialize session
        session_start();
         
        function authenticate($user, $password) {
        	if(empty($user) || empty($password)) return false;
         
        	// Active Directory server
        	$ldap_host = "server.college.school.edu";
         
        	// Active Directory DN
        	$ldap_dn = "OU=Departments,DC=college,DC=school,DC=edu";
         
        	// Active Directory user group
        	$ldap_user_group = "WebUsers";
         
        	// Active Directory manager group
        	$ldap_manager_group = "WebManagers";
         
        	// Domain, for purposes of constructing $user
        	$ldap_usr_dom = '@college.school.edu';
         
        	// connect to active directory
        	$ldap = ldap_connect($ldap_host);
         
        	// verify user and password
        	if($bind = @ldap_bind($ldap, $user.$ldap_usr_dom, $password)) {
        		// valid
        		// check presence in groups
        		$filter = "(sAMAccountName=".$user.")";
        		$attr = array("memberof");
        		$result = ldap_search($ldap, $ldap_dn, $filter, $attr) or exit("Unable to search LDAP server");
        		$entries = ldap_get_entries($ldap, $result);
        		ldap_unbind($ldap);
         
        		// check groups
        		foreach($entries[0]['memberof'] as $grps) {
        			// is manager, break loop
        			if(strpos($grps, $ldap_manager_group)) { $access = 2; break; }
         
        			// is user
        			if(strpos($grps, $ldap_user_group)) $access = 1;
        		}
         
        		if($access != 0) {
        			// establish session variables
        			$_SESSION['user'] = $user;
        			$_SESSION['access'] = $access;
        			return true;
        		} else {
        			// user has no rights
        			return false;
        		}
         
        	} else {
        		// invalid name or password
        		return false;
        	}
        }
        ?>
        
        1 Reply Last reply Reply Quote 0
        • G
          george1421 Moderator @Tom Elliott
          last edited by george1421 Sep 14, 2016, 6:59 PM Sep 15, 2016, 12:14 AM

          This post is deleted!
          T 1 Reply Last reply Sep 15, 2016, 12:15 AM Reply Quote 0
          • T
            Tom Elliott @george1421
            last edited by george1421 Sep 14, 2016, 6:58 PM Sep 15, 2016, 12:15 AM

            This post is deleted!
            1 Reply Last reply Reply Quote 0
            • G
              george1421 Moderator
              last edited by Sep 17, 2016, 9:33 PM

              Well here is my proof of concept code. In AD I setup two groups FOG_Admins and FOG_Users. The script outputs the following
              false := user is not authorized
              1 := User is authorized and is in the FOG_Users group
              2 := User is authorized and is in the FOG_Admins group

              I was going to go with the whole bindDN and bindPassword route, but that also meant that I would have to save the bindPass value in the database. To do that I would have to come up with a way to protect (encrypt) the password and all that. So I flipped the script around to use the person who is logging, their credentials to query AD.

              The next steps here are to intergrate the script below into ldapAuth (which shouldn’t be hard at all) then update the database fields, and other creations bits. The last part will be to mess with the ldap gui interface which has me a bit confused on the layout.

              But at the end of the day this is surely possible to get fog to authenticate against AD.

              <?php
              
                  function ldapParseDn($dn) {
                      /**
                       * Returns array of: array (
                       *     [CN] => array( username )
                       *     [OU] => array( UNITNAME, Region, Country )
                       *     [DC] => array ( subdomain, domain, com )
                       * )
                      **/
              
                      $parsr=ldap_explode_dn($dn, 0);
                      $out = array();
                      foreach($parsr as $key=>$value) {
                          if(FALSE !== strstr($value, '=')) {
                              list($prefix,$data) = explode("=",$value);
                              $prefix = strtoupper($prefix);
                              $data=preg_replace("/\\\([0-9A-Fa-f]{2})/e", "''.chr(hexdec('\\1')).''", $data);
                              if(isset($current_prefix) && $prefix == $current_prefix) {
                                  $out[$prefix][] = $data;
                              } else {
                                  $current_prefix = $prefix;
                                  $out[$prefix][] = $data;
                              }
                          }
                      }
                      return $out;
                  }
              
                  $user = 'testuser';
                  $pass = 'testuser.1';
                  $server = '192.168.1.5';
              
                      // 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);
              
                      $accessLevel = 0;
                      // test to confirm that script will handle mixed case
                      $userSearchDN = 'ou=nyc,dc=domain,DC=com';
                      $adminGroup = 'FOG_Admins';
                      $userGroup = 'FOG_Users';
                      // test to confirm that script will handle mixed case
                      $grpMemberAttr = strtolower('memberOf');
              
                      $entries = ldapParseDN($userSearchDN);
                      $userDomain = implode(".",$entries['DC']);
                      $userDN = sprintf('%s@%s', $user, $userDomain);
              
                      if ( ldap_bind($ldapconn, $userDN, $pass) ) {
                          // If we get to here the user is authorized, now lets get the group membership
                          $filter = sprintf('(&(objectCategory=person)(%s=%s))', 'sAMAccountName', $user);
              
                          $attr = array( $grpMemberAttr );
                          $result = ldap_search($ldapconn, $userSearchDN, $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 );
              
                          print $accessLevel;
              
                      } else {
                          print 'unable to bind using user info, user is not authorized in ldap';
              
                      }
               ?>
              
              
              
              W 1 Reply Last reply Sep 17, 2016, 9:39 PM Reply Quote 1
              • W
                Wayne Workman @george1421
                last edited by Sep 17, 2016, 9:39 PM

                @george1421 However will these changes be reverse compatible with ldap still?

                Please help us build the FOG community with everyone involved. It's not just about coding - way more we need people to test things, update documentation and most importantly work on uniting the community of people enjoying and working on FOG!
                Daily Clean Installation Results:
                https://fogtesting.fogproject.us/
                FOG Reporting:
                https://fog-external-reporting-results.fogproject.us/

                G 1 Reply Last reply Sep 17, 2016, 10:48 PM Reply Quote 0
                • G
                  george1421 Moderator @Wayne Workman
                  last edited by Sep 17, 2016, 10:48 PM

                  @Wayne-Workman Not sure I understand?

                  The intent is to make/change the ldap plugin to work with AD/OpenLDAP/and the novel one. Unfortunately I have to add some fields to the database to fill in the assumptions in the code. So one I prove it out (we) need to decide if I update the current ldap plugin code (requiring users that have it installed already, to uninstall and reinstall+configure it) or to create a whole new (enhanced) ldap plugin. That decision will be up to the developers on how they want to handle it. Right now I’m doing a proof of concept (on my production server) to answer can it work.

                  Testing so far has been very positive. Right now I ran into a roadblock with the hooks that I need to work through. But the problem here is my ignorance of how hooks work not a coding problem.

                  W 1 Reply Last reply Sep 18, 2016, 1:36 AM Reply Quote 1
                  • W
                    Wayne Workman @george1421
                    last edited by Sep 18, 2016, 1:36 AM

                    @george1421 Well of course I am all for eliminating assumptions. Writing code that works for one person’s setup is not a solution. And I get what you’re doing now. Just do your thing George.

                    Please help us build the FOG community with everyone involved. It's not just about coding - way more we need people to test things, update documentation and most importantly work on uniting the community of people enjoying and working on FOG!
                    Daily Clean Installation Results:
                    https://fogtesting.fogproject.us/
                    FOG Reporting:
                    https://fog-external-reporting-results.fogproject.us/

                    1 Reply Last reply Reply Quote 0
                    • L
                      Lee Rowlett Developer
                      last edited by Sep 18, 2016, 8:52 AM

                      what issues are you having with the hooks? @george1421? happy to assist where possible

                      G 1 Reply Last reply Sep 18, 2016, 11:56 AM Reply Quote 1
                      • G
                        george1421 Moderator @Lee Rowlett
                        last edited by Sep 18, 2016, 11:56 AM

                        @Lee-Rowlett Thank you for the offer. Tom offered to look at the code last night. I think he found out what I did wrong/needed.

                        1 Reply Last reply Reply Quote 1
                        • T
                          Tom Elliott
                          last edited by Sep 18, 2016, 5:30 PM

                          I’ve added the suggested changes to the main ldap plugin. This is by no means ready to actually be used, @george1421 and I are going to be testing the crap out of this, but the progress is quite significant. Of course @Lee-Rowlett or anybody who is willing to give a test and feedback about failings and areas that may need improvement please run it and test it. It is currently under the working-RC-11 branch on GIT. I hope to have a completed, mostly working, ready for the RC-11 release.

                          1 Reply Last reply Reply Quote 0
                          • T
                            Tom Elliott
                            last edited by Sep 18, 2016, 5:53 PM

                            Just for tracking purposes for those that would like to try this:

                            https://github.com/FOGProject/fogproject/tree/working-RC-11

                            Under packages/web/lib/plugins/ldap you will find the plugin.

                            Easiest way to get it would be to simply install the ldap plugin after installing working-RC-11 branch. I don’t recommend this only because while it’s a “WIP” and addresses bugs and minor improvements/fixes around what’s being found from RC-10, it’s also meaning those on RC-11 would be returning info that’s rather irrelevant for the time being. I’d prefer people to work on RC-10 and get a thorough list of bugs and issues to work out. That said, any of the developers and moderators that would like to install please do, I can fix the things I miss due to it not being in the “mainstream” of things which can help make RC-11 that much more suitable for environments.

                            This one exception (ldap) is the only thing I’d like to see people testing from RC-11 as it could use VAST amounts of improvements and make using FOG in an AD Environment that much easier to control.

                            For example, with the new modifications (once fully completed), you can define ldap authentication from eDirectory, openldap, ldap, and Active directory. You can associate groups in your ldap choice to allow users mobile access, and your IT team admin access. I hope something like SSO of this sort will make it into FOG 2.0 as well, which is why I’m kind of excited for this plugin to get revamped.

                            @Fernando-Gietz, @george1421, and myself have had the most authoring done for this plugin and have been added to the author’s of this plugin. @x23piracy You helped tremendously a few months ago with testing and providing an open test ring for me to use although it may not have accomplished what the two of us had hoped for.

                            Thank you @george1421 for actually kind of kickstarting this plugin back into shape. Thank you @Fernando-Gietz for actually establishing the basis of the plugin.

                            Anybody who would like to try this out so we can make it much better, please do and keep us posted. Please, for the time being, don’t post this into bugs though. I’m aware of the issues LDAP plugin currently has which is kind of why the work has been started to make it into a truly usable plugin.

                            1 Reply Last reply Reply Quote 2
                            • G
                              george1421 Moderator
                              last edited by Sep 18, 2016, 10:42 PM

                              I’m going to start a debugging session in a few minutes with this new ldap code. I would consider the current state as alpha code.

                              Todo items:

                              1. Review the code to ensure it still flows like I intended.
                              2. Load the modified code into my production environment and confirm it works as the proof of concept code does.
                              3. Work with changing case of groups, dn paths to make sure all case sensitivity is gone.
                              4. Clean up the web gui configuration page. Currently there are fields that don’t have any impact on the code (binddn, bindpass, searchscope). The elements were built in place in case we needed to create a more complex ldap auth.

                              This code does make a few assumptions about the target environment. I did use less complex logic to keep the lines of code down. It should work well for the different ldap backends. Only testing will tell.

                              1 Reply Last reply Reply Quote 1
                              • G
                                george1421 Moderator
                                last edited by Sep 20, 2016, 8:47 PM

                                Its been a few days since I posted an update to this. I’ve been debugging and have the ldap authentication working with AD. So the actual ldap authentication is working fine. I’ve run into a snag passing the authorized flag back to fog. I’m sure that can be worked out soon. Beyond that I’ve been testing with RC8 code. Once that is working I’ll stand up a new RC11 instance of FOG and confirm. In the end we are making progress with an end in sight.

                                A 1 Reply Last reply Sep 20, 2016, 8:52 PM Reply Quote 1
                                • A
                                  adukes40 @george1421
                                  last edited by Sep 20, 2016, 8:52 PM

                                  @george1421 Is this stricly to allow signing into the FOG Gui with AD credentials or will we be able to interact with AD via fog. Like assigning snapins to certain AD groups.

                                  G 1 Reply Last reply Sep 20, 2016, 8:54 PM Reply Quote 0
                                  • G
                                    george1421 Moderator @adukes40
                                    last edited by george1421 Sep 20, 2016, 2:56 PM Sep 20, 2016, 8:54 PM

                                    @adukes40 This is only for user login. So far I’ve only tested via the web gui.

                                    A 1 Reply Last reply Sep 20, 2016, 8:57 PM Reply Quote 1
                                    • A
                                      adukes40 @george1421
                                      last edited by Sep 20, 2016, 8:57 PM

                                      @george1421 would it be able to spawn from there? I have no idea how in depth it is. Im just generally curious.

                                      G 1 Reply Last reply Sep 20, 2016, 9:01 PM Reply Quote 0
                                      • G
                                        george1421 Moderator @adukes40
                                        last edited by Sep 20, 2016, 9:01 PM

                                        @adukes40 While anything is possible it would be a lot of work, and it would then tie FOG to requiring an AD infrastructure.

                                        I can say from a programming standpoint the code that FOG is built on can communicate with ldap pretty easily. So its possible to do. The issue is having enough motivation to pull it off. I looked at the ldap plugin that was in fog and have experience with programming queries to LDAP so there wasn’t a huge learning curve to update the plugin, plus what was there was sound already, they were just missing a few things.

                                        1 Reply Last reply Reply Quote 1
                                        • J
                                          JJ Fullmer Testers
                                          last edited by Sep 21, 2016, 8:00 PM

                                          I did a little testing on this and wasn’t able to add a ldap server. Put in all the information and I just get “LDAP ID # is not valid” I got ID 1 and 2 as invalid with 2 attempts at adding a server. @Tom-Elliott said that you might want to know.

                                          Have you tried the FogApi powershell module? It's pretty cool IMHO
                                          https://github.com/darksidemilk/FogApi
                                          https://fogapi.readthedocs.io/en/latest/
                                          https://www.powershellgallery.com/packages/FogApi
                                          https://forums.fogproject.org/topic/12026/powershell-api-module

                                          G 2 Replies Last reply Sep 21, 2016, 8:37 PM Reply Quote 0
                                          • 1
                                          • 2
                                          • 3
                                          • 4
                                          • 1 / 4
                                          1 / 4
                                          • First post
                                            10/64
                                            Last post

                                          159

                                          Online

                                          12.0k

                                          Users

                                          17.3k

                                          Topics

                                          155.2k

                                          Posts
                                          Copyright © 2012-2024 FOG Project