I am currently working on a PHP script that will be polling Active Directory to pick out modified objects (people/users), via LDAP.
I'm able to filter on uSNChanged when I have the value, like so:
$previousUsn = '1234';
$ldapCon = ldap_connect('ldap-host');
$ldapBind = ldap_bind($ldapCon, 'ldap-user', 'ldap-password');
$sr = ldap_search($ldapCon, "ou=Users,dc=foo", "uSNChanged >= $previousUsn");
According to this, I should be able to retrieve a highestCommittedUSN attribute that could be used for the initial run of the script. I've been looking around to find out how this can be done using PHP & LDAP, but to no avail.
Alternatively, feel free to suggest completely different methods of retrieving changes in AD.
ldap_read(...) seems to do the trick:
function getHighestCommittedUsn() {
ldap_bind(...);
$sr = ldap_read($ldapCon, null, "(highestcommittedusn=*)", array("highestcommittedusn"));
$rs = ldap_get_entries($ldapCon, $sr);
return $rs[0]["highestcommittedusn"][0];
}
Try setting the search base (second argument) in your ldap_search call to "". That attribute is on a pseudo object called RootDSE.
Perhaps if the biffins function hasn't been initialised correctly? Hmmm try changing the variable type of c_willygham
Related
I have a very old network box, that has PHP4 and a variation of LDAP installed on it.
Querying information isn't normally an issue when the returned results are small, but I'm trying to get all entries in one specific CN
This results in 'Warning: ldap_search() [function.ldap-search]: Partial search results returned: Sizelimit exceeded'
All the suggestions I've read have been for PHP5+ and Active directory, nothing for something this OLD.
I'm hoping you can help.
This is my very simple ldap query. $r is the connection.
$result = ldap_search($r, "cn=location", "(cn=*)");
$entry = ldap_first_entry($r, $result);
do {
$dn = ldap_get_dn($r, $entry);
echo "DN is $dn\n";
}
while ($entry = ldap_next_entry($r, $entry));
ldap_close($r);
This works until I hit the limit. I have tried changing the limit using LDAP_OPT_SIZELIMIT but obviously that didn't help.
What I'm wondering is.. is there any way to count the entries and then process them in smaller more manageable batches using something like :
$sr=ldap_list($r, "cn=location","cn>=".$last_location);
Is that possible ? any other ideas ?
Thanks
According to php.net/manual/...ldap-search, you should set the $sizelimit parameter to 0 to disable the memory limit. It will not, however, override the LDAP server configuration, if that is the cause of the error.
The function call will look something like the following:
ldap_search($r, "cn=location", "(cn=*)", null, 0, 0);
I'm not clear on how the filter parameter works, so you may need to change it if you get an error there.
See the above link for descriptions on all of the parameters for ldap_search().
Im trying to set a working variable i can use later on in my code, ive got an id in the url that references an attribute in an external data feed. You can see a copy of the xml feed HERE
the id comes in the url like this - /page.php?id=52115351
At the moment im setting my working variable as bellow, buts its just being set to the first instance of 'market' rather than being set against the instance thats got the same id as the one in the url.
$wh_odds = $wh_xml->response->williamhill->class->type->market->participant;
$wh_odds_attrib = $wh_odds->attributes();
$wh_odds_attrib['name'];//name
How would i implement $_GET['id'] with this block so that it would be making the working variable $wh_odds_attrib['name'] from the participant of the correct instance of 'market' in the xml feed ?
If you're using simpleXML you could try something like this:
$simpleXml = simplexml_load_file('test.xml');
$marketNode = $simpleXml->xpath("/oxip/response/williamhill/class/type/market[#id='{$_GET['id']}']");
$attributes = $marketNode[0]->participant->attributes();
echo $attributes['name'];
I am not entirely sure what you are attempting to do but you can just assign the $_GET['id'] to whatever you want, ie $id = $_GET['id'] allowing you to use it in string manipulation (via sprintf or whatever).
A little more information about what you are trying to do, would help
I know that CakePHP params easily extracts values from an URL like this one:
http://www.example.com/tester/retrieve_test/good/1/accepted/active
I need to extract values from an URL like this:
http://www.example.com/tester/retrieve_test?status=200&id=1yOhjvRQBgY
I only need the value from this id:
id=1yOhjvRQBgY
I know that in normal PHP $_GET will retrieve this easally, bhut I cant get it to insert the value into my DB, i used this code:
$html->input('Listing/vt_tour', array('value'=>$_GET["id"], 'type'=>'hidden'))
Any ideas guys?
Use this way
echo $this->params['url']['id'];
it's here on cakephp manual http://book.cakephp.org/1.3/en/The-Manual/Developing-with-CakePHP/Controllers.html#the-parameters-attribute-params
You didn't specify the cake version you are using. please always do so. not mentioning it will get you lots of false answers because lots of things change during versions.
if you are using the latest 2.3.0 for example you can use the newly added query method:
$id = $this->request->query('id'); // clean access using getter method
in your controller.
http://book.cakephp.org/2.0/en/controllers/request-response.html#CakeRequest::query
but the old ways also work:
$id = $this->request->params->url['id']; // property access
$id = $this->request->params[url]['id']; // array access
you cannot use named since
$id = $this->request->params['named']['id'] // WRONG
would require your url to be www.example.com/tester/retrieve_test/good/id:012345.
so the answer of havelock is incorrect
then pass your id on to the form defaults - or in your case directly to the save statement after the form submitted (no need to use a hidden field here).
$this->request->data['Listing']['vt_tour'] = $id;
//save
if you really need/want to pass it on to the form, use the else block of $this->request->is(post):
if ($this->request->is(post)) {
//validate and save here
} else {
$this->request->data['Listing']['vt_tour'] = $id;
}
Alternatively you could also use the so called named parameters
$id = $this->params['named']['id'];
So, im making a file hosting site, and am using some form builders to start off with. However, these builders do NOT support PHP. Now, i would like to shrink some URLs, how can i do this in pure HTML, without adding in PHP methods. I am fine with goo[dot]gl, bit.ly, tinyurl.com, or whatever else!
HTML is a Markup Language.
If you want to use some API, or anything more coding-oriented, you have to use a real programming language - you choose : for your purpose PHP would be the best choice.
Now, if you finally decide to use PHP, it's really easy.
Code (for TinyURL) :
<?php
function createTinyUrl($strURL) {
$tinyurl = file_get_contents("http://tinyurl.com/api-create.php?url=".$strURL);
return $tinyurl;
}
?>
Usage :
<?php
$myTinyUrl = createTinyUrl("http://www.yourdomain.com/some-long-url-here");
?>
And that's all! ;-)
If the form builders don't support PHP you need to write it yourself. PHP is very easy to work with.
Here is an example for you. (Assuming you have PHP set up on your web host:)
Save the file with the extension .PHP (or whatever your web host uses - might be .PHP5 for php5) instead of .HTML
You can use the super-global $_GET to accept certain variables from the URL in the address bar ex.:
$short_url = $_GET["q"];
Since i'm getting a variable named 'q', if you access the page with a parameter named 'q' I will have that variable stored ex.:
http://your.site/?q=shorturl # Assumes your index file takes the 'q' variable
Now it is up to you what to do with that variable. The best thing would be to set up a MySQL database so that when you get a value like 'shorturl' you can do a quick SQL query to return the full address ex.:
# Make DB connection
$db = new PDO("mysql:host='X.X.X.X';dbname='mydb'", $user, $secret);
# Function to search database for URL
function getFullURL($short_url) {
$result;
$sql = "SELECT full_url FROM tbl_addresses WHERE short_url='?'";
$query = $db->prepare($sql);
$query->execute(array($short_url));
$rows = $query->rowCount();
if ($rows == 1)
$result = $query->fetchAll();
return $result;
}
There's really not much to it in PHP with MySQL.
Greetings,
I already have a working connection to the AD and can search and retrieve information from it. I've even developed a recursive method by which one can retrieve all groups for a given user. However, I'd like to avoid the recursion if possible. One way to do this is to get the tokenGroups attribute from the AD for the user, which should be a list of the SIDs for the groups that the specified user has membership, whether that membership be direct or indirect.
When I run a search for a user's AD information, though, the tokenGroups attribute isn't even in it. I tried specifically requesting that information (i.e., specifying it using the fourth parameter to ldap_search) but that didn't work, either.
Thanks,
David Kees
Solved my own problem and thought I'd put the answer here so that others might find it. The issue was using the ldap_search() function. The answer was to use the ldap_read() function instead of ldap_search(). The difference is the scope of the request. The search function uses a scope of "sub" (i.e., subtree) while the read function uses "base." The tokenGroups information can only be found when using a scope of "base" so using the correct PHP function was the key.
As I mentioned above, I was working from someone else code in perl to create my solution and the perl script used a function named "search" to do it's LDAP requests which lead me down wrong path.
Thanks to those who took a peek at the question!
--
As per the requests in the comments, here's the basics of the solution in code. I'm extracting from an object that I use so this might not be 100% but it'll be close. Also, variables not declared in this snipped (e.g. $server, $user, $password) are for you to figure out; I won't know your AD credentials anyway!
$ldap = ldap_connect($server);
ldap_bind($ldap, $user, $password);
$tokengroups = ldap_read($ldap, $dn, "CN=*", array("tokengroups")));
$tokengroups = ldap_get_entries($ldap, $tokengroups);
At this point, $tokengroups is our results as an array. it should have count index as well as some other information. To extract the actual groups, you'll need to do something like this:
$groups = array();
if($tokengroups["count"] > 0) {
$groups = $tokengroups[0]["tokengroups"];
unset($groups["count"]);
// if you want the SID's for your groups, you can stop here.
// if you want to decode the SID's then you can do something like this.
// the sid_decode() here: http://www.php.net/manual/en/function.unpack.php#72591
foreach($groups as $i => &$sid) {
$sid = sid_decode($sid);
$sid_dn = ldap_read($ldap, "<SID=$sid>", "CN=*", array("dn"));
if($sid_dn !== false) {
$group = ldap_get_entries($ldap, $sid_dn);
$group = $group["count"] == 1 ? $group[0]["dn"] : NULL;
$groups[$i] = $group;
}
}
}
That's the basics. There's one caveat: you'll probably need to work with the individual or individuals who manage AD accounts at your organization. The first time I tried to get this running (a few years ago, so my memory is somewhat fuzzy) the account that I was given did not have the appropriate authorization to access the token groups information. I'm sure there are other ways to do this, but because I was porting someone else's code for this specific solution, this was how I did it.