PHP LDAP to change Active Directory samAccountName? - php

Our policy for people who are terminated/separated or who go on leave of absence involves a handful of changes to their AD account for record keeping purposes and security. One of these changes is renaming the account (login name, display name and dn) to a value that includes the original name with the help desk ticket number appended.
I have been able to use ldap_rename() to change the active directory "name" attribute, thus changing the DN. I can change the displayName attribute using either ldap_modify() or ldap_mod_replace(). What I cannot seem to do is change the samAccountName using any of these. Below is the core of the code I'm using. The errors I get are dependent upon which function I use, and are listed below.
I know there are some nuances to using PHP LDAP with Active Directory, but I find it hard to believe that I have been able to do everything up to and including changing passwords and I can't change the samAccountName... help?
<?php
$connection=ldap_connect(domain.local,389);
ldap_set_option($connection,LDAP_OPT_PROTOCOL_VERSION,3);
ldap_set_option($connection,LDAP_OPT_REFERRALS,0);
ldap_start_tls($connection);
ldap_bind($connection,$username,$password);
$accountName=$_POST["accountName"];
$ticketNumber=$_POST["ticketNumber"];
$baseDn="dc=domain,dc=local";
$attribs=array("samaccountname","dn","name","displayname","description","info","memberof");
$search=ldap_search($connection,$baseDn,"(samaccountname=".$accountName.")",$attribs);
$result=ldap_get_entries($connection,$search);
// ldap_modify returns error 80: Internal (implementation specific) error.
foreach ($result as $account) {
$newValues=array("samaccountname"=>$account["samaccountname"][0]."-".$ticketNumber)
ldap_modify($connection,$account["dn"],$newValues);
}
// ldap_mod_replace returns error 80: Internal (implementation specific) error.)
foreach ($result as $account) {
$newValues=array("samaccountname"=>$account["samaccountname"][0]."-".$ticketNumber)
ldap_mod_replace($connection,$account["dn"],$newValues);
}
?>
So yeah, what is it I'm supposed to be doing to make this happen?

The "implementation specific" error message you're receiving means that your sAMAccountName is invalid because it doesn't meet specific AD restrictions on it. The sAMAccountName attribute cannot be more than 20 characters and cannot contain any of the following: " [ ] : ; | = + * ? < > / \ ,. It might be helpful to see an example username with the ticket number appended.

Related

How to set an access point in ups API wrapper?

I am using the gabrielbull ups api wrapper and it is working fine, except when I want to add an UPS access point; the documentation says I have to declare a "AlternateDeliveryAddress". The access point data should then be printed on the ups label, but they are not appearing.
Since there isn't an example for this case on the wrapper GitHub page, I searched for methods on my own and found one but I have the feeling I forgot something since I don't receive any errors. I tried this code for the specific part. The surrounding code is like in the shipping class example
$address = new \Ups\Entity\Address();
$address->setAddressLine1($ap_addressline1);
$address->setPostalCode($ap_postal);
$address->setCity($ap_city);
$address->setCountryCode($ap_country);
$alternateTo = new \Ups\Entity\AlternateDeliveryAddress;
$alternateTo->setAddress($address);
$alternateTo->setUpsAccessPointId($ap_id);
$alternateTo->setName($ap_name);
$alternateTo->setAttentionName($ap_name);
$shipment->setAlternateDeliveryAddress($alternateTo);
Edit: I got this info of setting up the accesspoint from UPS support. The guy told me to set an alternate address with the AccessPoint data that will be printed at the bottom line of the label (where it's currently missing). If I misunderstood something (though we did a video conference and he showed me the result) and you know another way, feel free to tell me.
Ok after re-reading the official docs I found out what was missing.
If you want to use an accesspoint as address you also have to set the Indication Type via setShipmentIndicationType. There are 2 codes: 01 and 02 depending on the way you want to send it. Ofcourse I didn't add them before...
I haven't finished it yet because I get some errors but that's more about what information ups needs from me and so on. At least I can work with that.
As I mentioned in my initial post I used the example of the api wrapper as base and insert the required part before the request was send:
...
// Set Reference Number
...
// this is the part where you set shipment indication type for the accesspoint
$accesspoint = new \Ups\Entity\ShipmentIndicationType;
$accesspoint->setCode(Ups\Entity\ShipmentIndicationType::CODE_HOLD_FOR_PICKUP_ACCESS_POINT); // for "01"
#$accesspoint->setCode(Ups\Entity\ShipmentIndicationType::CODE_ACCESS_POINT_DELIVERY); // for "02"
$shipment->setShipmentIndicationType($accesspoint);
// Set payment information
...
// Ask for negotiated rates (optional)
...
// Get shipment info
...

How to validate DNSSEC in PHP?

I've been trying to figure out a way to validate DNS records in PHP (oa1) but have come up short.
I can validate a whole domain with this library, but not the individual records: https://github.com/metaregistrar/php-dnssec-validator
In addition, that library only allows for a very small set of TLDs to be validated.
Is there another library out there that can handle this for me, or perhaps something else I should look into?
I've also found this: http://www.phpclasses.org/package/9031-PHP-Validate-DNSSEC-keys-and-calculate-the-DS-record.html
But I have no idea how to get the keys to use in their validating function.
Help please!
UPDATE
So, I ended up using this...
exec('host -t RRSIG ' . $domain, $output);
Returns the RRSIG, or lack thereof, with minimal hassle.
The PHP engine has a fixed set of DNS record types it supports, all defined by the type parameter to dns_get_record. You can double check this list by looking in the engine code that implements DNS queries.
Unfortunately, none of the DNSSEC records are in that pre-defined list. So, you need to rely on a library or an external tool.
I'd use Net_DNS2, as it supports many DNSSEC RR. Example:
$google = new \Net_DNS2_Resolver(['nameservers' => ['8.8.8.8', '8.8.4.4']]);
$google->dnssec = true;
try {
$result = $google->query('kyhwana.org', 'SSHFP');
} catch(\Net_DNS2_Exception $ex) {
die($ex->getMessage());
}
foreach ($result->answer as $answer) {
if ($answer instanceof \Net_DNS2_RR_SSHFP) {
printf(
'%s %d %s %s %d %d %s' . PHP_EOL,
$answer->name,
$answer->ttl,
$answer->class,
$answer->type,
$answer->algorithm,
$answer->fp_type,
$answer->fingerprint
);
} else if ($answer instanceof \Net_DNS2_RR_RRSIG) {
printf('Signed by %s: %s' . PHP_EOL, $answer->signname, $answer->signature);
}
}
Aside: if your domain uses ECDSA algorithm or the SHA-256 fingerprint (like the example above), then you need the latest Net_DNS2 code which fixes Issue #39.
I haven't implemented the code yet but it looks to me like using php to verify the signatures themselves is a mistake. Use a local recursive resolver like unbound on the local server that enforces DNSSEC.
Then in php with the PEAR module Net_DNS2 look for an RRSIG record for the domain of interest. The result should tell you the zone responsible for that record.
Look for a DNSKEY record in that zone. If present, then look for a DS record.
The DS record will come from the parent zone (e.g. .email for deviant.email) and if present indicates DNSSEC is present for the zone.
If DNSSEC is present for the zone, then all the results for the zone are valid if your local recursive nameserver enforces DNSSEC.
I believe with Net_DNS2 that using
r = new Net_DNS2_Resolver(array('nameservers' => array('127.0.0,1')));
r->dnssec = true;
will also result in Net_DNS2 also validating the results if DNSSEC is active - which is indicated by the DS record that comes from the parent zone. But using a recursive resolver (preferably on the webserver) that enforces DNSSEC is probably safest.
Make sure the recursive resolver isn't listening on public interfaces so it doesn't get used in reflective amplification attacks.
Having the same goal (validate DNSSEC in PHP), i ended up with:
exec("drill -k root.keys -TDQ $domain SOA | grep -v '^;;'", $output);
This is doing a complete topdown DNSSEC validation.
You need root keys you can retrieve with:
unbound-anchor # NB: on FreeBSD, use local-unbound-anchor for "base" version
Or "manually":
dig . dnskey > root.keys
To confirm that the record is fully DNSSEC validated, check the last line of exec output:
[S] self sig OK This is not satisfying, probably zone key has not been populated in parent zone
[B] bogus
[T] trusted This means that everything is OK!

Sugarcrm : generating contact from inbound emails

What i have :
Sugarcrm enterprise 6.5.14
I have set the inbound email to automatically generate cases under some conditions.
(it is set in Sugar's administration > Inbound email, it's native, i didn't write any code, juste setting it up).
I saw on /modules/InboundEmail/InboundEmail.php the function handleCreateCase() which i think (but please, confirm it) is used to generate cases.
What i want :
When a case is generated by an inbound email, the function handleCreateCase() is searching for contact ids and retrieves the good contact with this id :
snippet of handleCreateCases() :
if($contactIds = $this->getRelatedId($contactAddr, 'contacts')) {
if(!empty($contactIds) && $c->load_relationship('contacts')) {
$c->contacts->add($contactIds);
} // if
} // if
Now, i would like to add a "Else" condition : if there is no related contact, then create one.
My question is..
How do i code that? Could i customize the InboundEmail module? Will it be taken by Sugar?
Thanks a lot for your patience and your time.

Magento 404 on Admin Page

About a week ago, I was working in a test environment for a new site. I left for an hour, came back, and now cannot get to the admin page, as in ‘http://magento.localhost.com/admin’ results in a No Route 404. I am the only one with access to this, it is not live in any sense. I am using VBox with Ubuntu to host the environment. In terms of possible fixes, so far I have tried…
Making sure core_store, core_store_group, core_website, and customer_group table ids are set to 0 (as described in this and many other articles - http://www.nude-webdesign.com/fix-for-magento-admin-error-404-page-not-found/)
Playing with the /app/code/core/Mage/Core/Controller/Varien/Front.php method _isAdminFrontNameMatched to display the adminPath (it’s ‘admin’)
Cleared the var folder, emptied browser cache. Site’s caching was and is turned off.
Adding 'index.php' to the url still results in a 404.
As per Magento Admin 404, the file 'app/etc/use_cache.ser' doesn't exist for me.
On the day of this occurring, I was simply playing around with some layout files I had copied to a module I made and the theme’s media queries (all of which were reverted to their original state even before this problem started to occur).
Does anyone have any suggestions as to what is wrong here? Any other possible reasons this could be happening?
Thanks for anything.
EDIT 1:06pm 9/10/2013: In response to Alan Storm's method of retrieving controller names that Standard.php is looking for, I was returned many "missing" controller files. However, after downloading a fresh copy of 1.7.0.2 to find those files, they weren't present in their either. Here is my output from Alan's var_dump suggestion in Standard.php:
..."/public_html/app/code/core/Mage/Index/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Paygate/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Paypal/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Widget/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Oauth/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Authorizenet/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Bundle/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Centinel/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Compiler/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Connect/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Downloadable/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/ImportExport/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Api2/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/PageCache/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/XmlConnect/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/Adminhtml/controllers/Controller.php"
..."/public_html/app/code/community/Phoenix/Moneybookers/controllers/Controller.php"
..."/public_html/app/code/core/Mage/Captcha/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/CurrencySymbol/controllers/Adminhtml/Controller.php"
..."/public_html/app/code/core/Mage/CurrencySymbol/controllers/Adminhtml/IndexController.php"
Resolved 3:39pm 9/10/2013: Ok, it's fixed albeit rather bluntly. I took the output of Alan Storm's var_dump suggestion to mean I had created an error somewhere in the core code pool (which is not something I intended on doing, screwing with the default code that is). Unfortunately for sake of exact learning, I then replaced it all with the default core code pool of 1.7.0.2. This was done before Alan updated his original answer with more suggestions that I never investigated. Thanks Alan, you're rad.
A no route 404 error usually indicates Magento can't find the controller file it thinks it should load (usually due to a misconfiguration)
The easiest way to diagnose this is to hop to _validateControllerClassName
#File: app/code/core/Mage/Core/Controller/Varien/Router/Standard.php
protected function _validateControllerClassName($realModule, $controller)
{
$controllerFileName = $this->getControllerFileName($realModule, $controller);
if (!$this->validateControllerFileName($controllerFileName)) {
return false;
}
$controllerClassName = $this->getControllerClassName($realModule, $controller);
if (!$controllerClassName) {
return false;
}
// include controller file if needed
if (!$this->_includeControllerClass($controllerFileName, $controllerClassName)) {
return false;
}
return $controllerClassName;
}
and drop some logging or var_dumps around the return false statments. This should tell you which files Magento is looking for and can't find — it's usually enough to point to the problem.
if (!$this->validateControllerFileName($controllerFileName)) {
var_dump($controllerFileName);
return false;
}
$controllerClassName = $this->getControllerClassName($realModule, $controller);
if (!$controllerClassName) {
var_dump($controllerClassName);
return false;
}
// include controller file if needed
if (!$this->_includeControllerClass($controllerFileName, $controllerClassName)) {
var_dump("Couldn't include: $controllerFileName");
return false;
}
Update: It's normal for Magento look for the controller file in multiple places — every module that registered as containing adminhtml controller files needs to be checked.
However, almost all the controller files being looked for are named /Controller.php. For the default /admin index page this should be IndexController.php. This makes me think your system thinks it's supposed to look for a controller with a blank name, (likely the default controller value since /admin (and not admin/index) is the URL you're using)
There's myriad reasons this could happen — many revolving around a core file being changed or a configuration node in a module set to the wrong value. If the solutions below don't work for you you'll need to try diff-ing your code base vs. a clean one, disabling every custom module and if that fixing things turn modules back on until the problem module is found, or dive deep into debugging Magento routing code to figure out why your system is unhappy.
One common cause for this behavior is an invalid value (or no value at all) being set for a custom admin path at
System -> Configuration -> Admin -> Admin Base URL -> Use Custom Admin Path
If the value for "custom admin path" is blank, or contains and additional /, this could be interfering with the routing.
Since you can't access the admin, try running the following SQL query
select * from core_config_data where path like '%custom_path%';
...
292 default 0 admin/url/use_custom_path 1
293 default 0 admin/url/custom_path admin/
If you see results similar to the above, or admin/url/custom_path is blank/not-present but admin/url/use_custom_path is still 1 — then that's your problem.
Try deleting these configuration values (admin/url/use_custom_path) and (admin/url/use_custom_path) from core_config_data.
If that doesn't apply to your system, per my blank controller theroy my best guess would be for some unknown reason the code at
#File: app/code/core/Mage/Core/Controller/Varien/Router/Admin.php
public function fetchDefault()
{
// set defaults
$d = explode('/', $this->_getDefaultPath());
$this->getFront()->setDefault(array(
'module' => !empty($d[0]) ? $d[0] : '',
'controller' => !empty($d[1]) ? $d[1] : 'index',
'action' => !empty($d[2]) ? $d[2] : 'index'
));
}
is populating the controller key with a blank value.
In my case, my admin was giving me 404 because there's no store set.
I solved it by running the following query
SET SQL_SAFE_UPDATES=0;
SET FOREIGN_KEY_CHECKS=0;
UPDATE `core_store` SET store_id = 0 WHERE code='admin';
UPDATE `core_store_group` SET group_id = 0 WHERE name='Default';
UPDATE `core_website` SET website_id = 0 WHERE code='admin';
UPDATE `customer_group` SET customer_group_id = 0 WHERE customer_group_code='NOT LOGGED IN';
SET FOREIGN_KEY_CHECKS=1;
SET SQL_SAFE_UPDATES=1;
You can check if you get the below error logged in var/log/system.log
ERR (3): Recoverable Error: Argument 1 passed to Mage_Core_Model_Store::setWebsite() must be an instance of Mage_Core_Model_Website, null given, called in /.../app/code/core/Mage/Core/Model/App.php on line 634 and defined in /.../app/code/core/Mage/Core/Model/Store.php on line 395
Before anything check your configuration file ( app/etc/local.xml) and make sure that you have "admin" as value for the frontName tag.
ex.:
<adminhtml>
<args>
<frontName><![CDATA[admin]]></frontName>
</args>
</adminhtml>
Usually when you try http://yoursite.com/admin it gives you the admin area
Try using an url like that http://yoursite.com/index.php/admin
and if it works probably you need to only modify the rewrite rules or follow the suggestions (see the link below)
I got this problem on a shop with custom admin url www.shop.com/customadminroute/ and System -> Configuration -> Web -> URL options -> Add Store Code to Urls: Enabled
In this case the following module should fix it:
https://github.com/romfr/404adminlogin
Thanks to Blog post of Carmen Bremen:
http://neoshops.de/2012/09/07/magento-404-fehlerseite-beim-admin-login/

Accessing custom variables from a .phtml in Magento

I have a file (js.phtml) where my code executes. I need to access some user data. When I error_log($this) in js.phtml, it displays, "Mage_Core_Block_Template" - which is confusing to me. I would expect that to be the parent class, not the value of the class getting passed to my .phtml file.
So, how do I supply the .phtml file with custom objects or methods? I'm super new to Magento and I've just been dropped into a task, so I apologize for possibly using incorrect terminology.
Edit:
My full file path is:
/app/design/frontend//default/template/customer/welcome/js.phtml
There is also a full module dir here:
/app/code/local//Customer/
Edit:
I need access to the users country and userid. It's ok if country is null.
Edit:
I've been doing additional research, it looks like I can do something like this:
Current user in Magento?
But I haven't tried it in code yet ....
Edit: Figured it out:
error_log(print_r(Mage::getSingleton('customer/session')->getCustomer()->getEntityId(), true));
error_log(print_r(Mage::getSingleton('customer/session')->getCustomer()->getCountry(), true));
To get customer ID:
echo Mage::getSingleton('customer/session')->getCustomer()->getId();
To get country - depends from which address. Here's an example of getting the country code from the default billing address:
echo Mage::getSingleton('customer/session')->getCustomer()->getDefaultBillingAddress()->getCountry();
I am somewhat new to Magento, but I think this should work.
$customer = Mage::getSingleton('customer/session')->getCustomer();
That gets the customer object. Then...
echo $customer->getAddresses();
That should get the country somewhere in the address. As for userid...I don't see it on the documentation page..You could try
echo $customer->getAttributes();
And see what is in there. The documentation page is at:
http://docs.magentocommerce.com/Mage_Customer/Mage_Customer_Model_Customer.html

Categories