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

Thread: HELP needed... PHP and Active Directory

  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
    Nov 2005
    Posts
    6

    Unhappy No Luck ...

    Thanks for your support but Im still getting this error.

    Warning: ldap_get_values_len(): Cannot get the value(s) of attribute Decoding error in

    and when i print the whole set of returned attributes it does not display the logonhours variable.

    the rest of the details are ther including expire dates and all.

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

    Got it

    Thanks for all your help i was able to get it.

    but one more prob our country GMT time is +6 so how can retrieve the bits in order as in the following order

    111111111111111111111111
    111111111111111111111111
    111111111111111111111111
    111111111111111111111111
    111111111111111111111111
    111111111111111111111111
    111111111111111111111111

  13. #13
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494
    Quote Originally Posted by uchi
    Thanks for all your help i was able to get it.

    but one more prob our country GMT time is +6 so how can retrieve the bits in order as in the following order
    See my function ldap_get_logonhours($hrs, $gmtoffset) in the above post. It will shift the bits to match your local time. However, if your DC is in a different timezone than the server running php, you will see the hours recorded in the DC.
    Protected by Glock. Don't mess with me!

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

    Post Full 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*3 + $chunk];
    for($bit=0;$bit<8;$bit++)
    {
    $testbyte=pow(2,$bit);
    if(($testbyte & $checkbyte) != 0)
    $gmthrs[$day*24 + $chunk*8 + $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




    $USER_ID = "uchi";


    $PWD = "xxxxx";

    $dn = "OU=tech,DC=apiit,DC=edu";

    $ad = ldap_connect("ldap://localhost")
    or die("Couldn't connect to AD!");



    ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);

    $bd = ldap_bind($ad,$USER_ID."@apiit.edu",$PWD)
    or die("Couldn't bind to AD!");


    $filter = "samaccountname=$USER_ID"; //real user name



    $result = ldap_search($ad, $dn,$filter);


    $entry=ldap_first_entry($ad,$result);

    $name = ldap_get_values($ad, $entry, "samaccountname");

    print_r($name);

    $hoursbinary=ldap_get_values_len($ad,$entry,"logon hours");


    //print_r($hoursbinary);


    $hourshex=bin2hex($hoursbinary[0]);
    print "hours: ".$hourshex."<br>";

    print $hourshex[0];

    print "<hr>";


    for ($i = 6; $i < 42; $i ++ ) {


    if ($i%6 == 0) {

    print "<br>";
    }

    echo base_convert($hourshex[$i], 16, 2);
    print "";

    }

    for ($i = 0; $i < 6; $i ++) {

    if ($i%6 == 0) {

    print "<br>";

    }

    echo base_convert($hourshex[$i], 16, 2);
    print "";
    }


    print "<hr>";


    ldap_get_logonhours($hourshex, 6);


    This is my full code but the function doesn't work properly

    please help me if u can.

    Thanks,
    Uchi

  15. #15
    Registered User CeeBee's Avatar
    Join Date
    Nov 2002
    Location
    USA
    Posts
    2,494
    Let's try to modify the ldap_get_logonhours to return an array containing the logon hours for each day:
    PHP Code:
    function ldap_get_logonhours($hrs,$gmtoffset)
    {
    //input: $hrs = int array[168], $gmtoffset=int
    //output: array[7][24]

    //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 build the array to return
    for($day=0;$day<7;$day++)
    {
    for(
    $hr=0;$hr<24;$hr++)
    {
    $retarray[$day][$hr]=$localhrs[$day*24 $hr];
    }
    }
    return 
    $retarray;
    //end function ldap_get_logonhours 
    now let's see how we can call it:
    PHP Code:
    $USER_ID "uchi";
    $PWD "xxxxx";
    $dn "OU=tech,DC=apiit,DC=edu";
    $ad ldap_connect("ldap://localhost")
    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."@apiit.edu",$PWD)
    or die(
    "Couldn't bind to AD!");
    $filter "samaccountname=$USER_ID"//real user name
    $result ldap_search($ad$dn,$filter);
    $entry=ldap_first_entry($ad,$result);
    $name ldap_get_values($ad$entry"samaccountname");
    print_r($name);

    $hoursbinary=ldap_get_values_len($ad,$entry,"logonhours");
    $hourshex=bin2hex($hoursbinary[0]);

    $hoursarray=ldap_get_logonhours($hourshex6);
    //now hoursarray stores 1 or 0 for each day/hour
    //ex $login_monday_at_11pm=$hoursarray[1][23]; 
    You should be able to handle it from here....
    Protected by Glock. Don't mess with me!

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
  •