HELP needed... PHP and Active Directory
Results 1 to 15 of 20

Thread: HELP needed... PHP and Active Directory

Hybrid View

  1. #1
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494

    HELP needed... PHP and Active Directory

    Some background is needed. I am trying to retrieve the allowed logon hours for users from AD using the PHP function ldap_get_entries(). The data is stored in AD as a binary string (7 days * 24 hours = 168 bits needed, 168/8=21 bytes of data).
    I am reading the data as a string
    PHP Code:
    $hours=$result_array[$row]["logonhours"][0]) 
    $result_array is the variable that stores the query result, $row is the index in the array
    Everything is fine as long as none of these returned bytes is 0. However, when a 0-byte is encountered, PHP considers that to be the end of the string and therefore truncates it as in this example:
    PHP Code:
    $data="abc".chr(0)."def";
    print 
    $data;
    //outputs "abc" 
    I need a suggestion of how to read and process the data (just need to be able to read the value of each byte) - or if someone already has a working example...
    Protected by Glock. Don't mess with me!

  2. #2
    Chat Operator Matridom's Avatar
    Join Date
    Jan 2002
    Location
    Ontario, Canada
    Posts
    3,778
    can you give the complete example of code?
    <Ferrit> Take 1 live chicken, cut the head off, dance around doing the hokey pokey and chanting: GO AWAY BAD VIRUS, GO AWAY BAD VIRUS
    -----------------------
    Windows 7 Pro x64
    Asus P5QL Deluxe
    Intel Q6600
    nVidia 8800 GTS 320
    6 gigs of Ram
    2x60 gig OCZ Vertex SSD (raid 0)
    WD Black 750 gig
    Antec Tri power 750 Watt PSU
    Lots of fans

  3. #3
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494
    This is the function that creates and displays the logon hours array
    $hrs[] ia an array of 21 integers
    PHP Code:
    //this function works as long as the supplied data in $hrs is valid
    function ldap_get_logonhours($hrs,$gmtoffset)
    {
      
    //init hours array
      
    for($i=0;$i<168;$i++)
        
    $gmthrs[$i]=0;
      for(
    $day=0;$day<7;$day++)
        for(
    $chunk=0;$chunk<3;$chunk++)
        {
          
    //lookup each bit and set bytes in the $gmthrs array
          
    $checkbyte=$hrs[$day*$chunk];
          for(
    $bit=0;$bit<8;$bit++)
          {
            
    $testbyte=pow(2,$bit);
            if((
    $testbyte $checkbyte) != 0)
              
    $gmthrs[$day*24 $chunk*$bit]=1;
          }
        }
      
    //now convert to local hours by adding offset
      
    for($i=0;$i<168;$i++)
      {
        
    $index=$i $gmtoffset;
        if(
    $index>=168)
          
    $index=$index-168;
        if(
    $index<0)
          
    $index=$index+168;
        
    $localhrs[$index]=$gmthrs[$i];
      }
      
    //now display
      
    print "<hr>";
      for(
    $day=0;$day<7;$day++)
      {
        print 
    "day# ".$day." : ";
        for(
    $hr=0;$hr<24;$hr++)
        {
          print 
    $localhrs[$day*24 $hr];
        }
        print 
    "<br>\n";
      }
    //end function ldap_get_logonhours 
    However, the issues are here:
    PHP Code:
    //this is the main code
    $USER_ID "XXXXXXX";
    $PWD "XXXXXX";
    $dn "OU=XXXXXXX,DC=XXXXXXX";
    $ad ldap_connect("ldap://XXXXXXXXXXXXXXXXX")
          or die(
    "Couldn't connect to AD!");
    ldap_set_option($adLDAP_OPT_PROTOCOL_VERSION3);
    ldap_set_option($adLDAP_OPT_REFERRALS0);
    $bd ldap_bind($ad,$USER_ID,$PWD)
          or die(
    "Couldn't bind to AD!");
    $filter "(cn=XXXXXXXX)"//real user name
    $result ldap_search($ad$dn,$filter);
    $result_array ldap_get_entries($ad$result);
    //in a normal search $result_array["count"] should be 1
    for($row 0$row<$result_array["count"]; $row++)
    {
      for(
    $i=0;$i<21;$i++)
       
    $data_hours[$i]=ord(mb_substr($result_array[$row]["logonhours"][0],$i,1));
      
    // issue here with $result_array[$row]["logonhours"][0] - it is treated as string
      // when a NULL character is found it considers end of string and disregards any
      // data after it.
      
    print "data_hours is this:<br>";
      
    print_r($data_hours);
      print 
    "<hr>";
    }
    ldap_get_logonhours($data_hours,-5); // EST time is GMT - 5 hours

    ldap_unbind($ad); 
    Last edited by CeeBee; June 15th, 2005 at 07:59 AM.
    Protected by Glock. Don't mess with me!

  4. #4
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494
    PROBLEM SOLVED!!!
    PHP Code:
    $result ldap_search($ad$dn,$filter);
    $entry=ldap_first_entry($ad,$result);
    $hoursbinary=ldap_get_values_len($ad,$entry,"logonhours");
    $hourshex=bin2hex($hoursbinary[0])."<br>";
    print 
    "hours: ".$hourshex."<br>"//outputs 42-character hex string
    //ready for further processing and conversion to array of integers 
    Protected by Glock. Don't mess with me!

  5. #5
    Chat Operator Matridom's Avatar
    Join Date
    Jan 2002
    Location
    Ontario, Canada
    Posts
    3,778
    Quote Originally Posted by CeeBee
    PROBLEM SOLVED!!!
    PHP Code:
    $result ldap_search($ad$dn,$filter);
    $entry=ldap_first_entry($ad,$result);
    $hoursbinary=ldap_get_values_len($ad,$entry,"logonhours");
    $hourshex=bin2hex($hoursbinary[0])."<br>";
    print 
    "hours: ".$hourshex."<br>"//outputs 42-character hex string
    //ready for further processing and conversion to array of integers 
    kewl
    <Ferrit> Take 1 live chicken, cut the head off, dance around doing the hokey pokey and chanting: GO AWAY BAD VIRUS, GO AWAY BAD VIRUS
    -----------------------
    Windows 7 Pro x64
    Asus P5QL Deluxe
    Intel Q6600
    nVidia 8800 GTS 320
    6 gigs of Ram
    2x60 gig OCZ Vertex SSD (raid 0)
    WD Black 750 gig
    Antec Tri power 750 Watt PSU
    Lots of fans

  6. #6
    Registered User
    Join Date
    Nov 2005
    Posts
    6
    All that is fine but im getting this error at the end

    Fatal error: Call to undefined function: mb_substr() in c:\xxx\xxx\php2.php on line 108

    but how can that be i did it all by following the above sysntax.

  7. #7
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494
    Quote Originally Posted by uchi
    All that is fine but im getting this error at the end

    Fatal error: Call to undefined function: mb_substr() in c:\xxx\xxx\php2.php on line 108

    but how can that be i did it all by following the above sysntax.
    mb_substr() was introduced in PHP 4.0.6. Is your version newer?
    Protected by Glock. Don't mess with me!

  8. #8
    Registered User
    Join Date
    Nov 2005
    Posts
    6

    Post RE: mb_substr()

    Yes, im using a newer version i did checked that.

    anyways wat i want is to logonhours of a user in active directory but i still couldn't do that.

    it seems there is no such a variable called logon hours when i get full details of a user.

    when i used

    $entry is the result array

    print_r($entry);

    it does not show logonhours.

  9. #9
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494
    PHP Code:
    $USER_ID "USER@MYDOMAIN";
    $PWD "PASSWORD";
    $dn "OU=Users,DC=MYDOMAIN";
    $ad ldap_connect("ldap://SERVER.MYDOMAIN")
          or die(
    "Couldn't connect to AD!");
    ldap_set_option($adLDAP_OPT_PROTOCOL_VERSION3);
    ldap_set_option($adLDAP_OPT_REFERRALS0);
    $bd ldap_bind($ad,$USER_ID,$PWD)
          or die(
    "Couldn't bind to AD!");
    $filter "samaccountname=SOMEREALUSERNAME"//real user name
    $result ldap_search($ad$dn,$filter);
    $entry=ldap_first_entry($ad,$result);
    $hoursbinary=ldap_get_values_len($ad,$entry,"logonhours");
    $hourshex=bin2hex($hoursbinary[0]);
    print 
    "hours: ".$hourshex."<br>"
    Outputs (for my test user):
    hours: 00000000f87f00f87f00f87f00f87f00f87f000000
    Protected by Glock. Don't mess with me!

  10. #10
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494
    PHP Code:
    $USER_ID "USER@MYDOMAIN";
    $PWD "PASSWORD";
    $dn "OU=Users,DC=MYDOMAIN";
    $ad ldap_connect("ldap://SERVER.MYDOMAIN")
          or die(
    "Couldn't connect to AD!");
    ldap_set_option($adLDAP_OPT_PROTOCOL_VERSION3);
    ldap_set_option($adLDAP_OPT_REFERRALS0);
    $bd ldap_bind($ad,$USER_ID,$PWD)
          or die(
    "Couldn't bind to AD!");
    $filter "samaccountname=SOMEREALUSERNAME"//real user name
    $result ldap_search($ad$dn,$filter);
    $entry=ldap_first_entry($ad,$result);
    $hoursbinary=ldap_get_values_len($ad,$entry,"logonhours");
    $hourshex=bin2hex($hoursbinary[0]);
    print 
    "hours: ".$hourshex."<br>"
    Outputs (for my test user):
    hours: 00000000f87f00f87f00f87f00f87f00f87f000000
    That is M-F:6AM-6PM (GMT-5), no Sat and Sun in the case of my user.
    Protected by Glock. Don't mess with me!

  11. #11
    Registered User
    Join Date
    Apr 2015
    Posts
    3
    Anyone out there looking for an answer here's what I figured out:


    $eighthourchunks = str_split($hourshex, 2);
    foreach ($eighthourchunks as $chunk){
    $i++;
    $bytes .= strrev(sprintf('%08d',decbin(hexdec('0x' . $chunk))));
    }

    $bytesbegin = substr($bytes, 0, 5);
    $bytesend = substr($bytes, 5);

    $bytes_tz_corrected = $bytesend . $bytesbegin;
    $daysarr = str_split($bytes_tz_corrected, 24);
    $dowMap = array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
    $i = 0;
    foreach ($daysarr as $day){
    echo $dowMap[$i];
    echo ' : ' . $day . '<br>';
    $i++;
    }

  12. #12
    Registered User
    Join Date
    Apr 2015
    Posts
    3
    Hopefully I don't piss too many people off for tacking on to this post.. It just seemed like a good idea to keep this all together.

    So I took the data generated from my last post and created a table. I then used javascript to control that table to recreate functionality similar to what we are all used to seeing in Active Directory where the blue cells represent permitted hours and the gray ones are blocked off hours. Javascript then uses AJAX with post method to return the binary data back to php and php uses pack("C", bindec(strrev($chunk))) in a foreach loop to format it correctly for active directory. My only problem is that I intermittently get the error "Server unwilling to perform 53" and I think it's due to the formatting I'm using. Is there something I should tack on to pack("C", bindec(strrev($chunk))) for it to consistently work?

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •