-
June 14th, 2005, 04:59 PM
#1
Registered User
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!
-
June 15th, 2005, 07:28 AM
#2
Chat Operator
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
-
June 15th, 2005, 07:52 AM
#3
Registered User
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*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
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($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);
$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!
-
June 15th, 2005, 10:42 AM
#4
Registered User
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!
-
June 15th, 2005, 10:50 AM
#5
Chat Operator
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
-
November 22nd, 2005, 08:25 AM
#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.
-
November 22nd, 2005, 08:31 AM
#7
Registered User
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!
-
November 29th, 2005, 12:01 AM
#8
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.
-
November 29th, 2005, 08:48 AM
#9
Registered User
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($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);
$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!
-
November 29th, 2005, 08:51 AM
#10
Registered User
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($ad, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ad, LDAP_OPT_REFERRALS, 0);
$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!
-
April 28th, 2015, 01:50 PM
#11
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++;
}
-
May 11th, 2015, 02:09 PM
#12
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?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|
Bookmarks