-
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!
-
December 1st, 2005, 12:42 AM
#11
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.
-
December 9th, 2005, 06:38 AM
#12
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
-
December 9th, 2005, 08:28 AM
#13
Registered User
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!
-
December 12th, 2005, 05:16 AM
#14
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
-
December 12th, 2005, 08:50 AM
#15
Registered User
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*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 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($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,"logonhours");
$hourshex=bin2hex($hoursbinary[0]);
$hoursarray=ldap_get_logonhours($hourshex, 6);
//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!
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