- http://docs.cloudstack.org/CloudStack_Documentation/Design_Documents/LDAP_Authentication
- http://docs.cloudstack.org/CloudStack_Documentation/Developer's_Guide%3A_CloudStack
First you need to configure LDAP by making an API call with an URL like this:
http://127.0.0.1:8096/client/api?command=ldapConfig&hostname=127.0.0.1&searchbase=ou%3Dpeople%2Co%3DsevenSeas&queryfilter=%28%26%28uid%3D%25u%29%29&binddn=%20cn%3DJohn+Fryer%2Cou%3Dpeople%2Co%3DsevenSeas&bindpass=secret&port=10389&response=jsonOr in a more readable format:
http://127.0.0.1:8096/client/api?command=ldapConfigNote the URL encoded values, here you have the decoded version:
&hostname=127.0.0.1
&searchbase=ou%3Dpeople%2Co%3DsevenSeas
&queryfilter=%28%26%28uid%3D%25u%29%29
&binddn=%20cn%3DJohn+Fryer%2Cou%3Dpeople%2Co%3DsevenSeas
&bindpass=secret
&port=10389
&response=json
http://127.0.0.1:8096/client/api?command=ldapConfigYou can use this link to encode/decode your url -> http://meyerweb.com/eric/tools/dencoder/
&hostname=127.0.0.1
&searchbase=ou=people,o=sevenSeas
&queryfilter=(&(uid=%u))
&binddn= cn=John Fryer,ou=people,o=sevenSeas
&bindpass=secret
&port=10389
&response=json
After you've created your URL (with encoded values) open your browser, login into cloudstack and then fire up your ldap config URL.
Now if you go back to cloudstack and under "Global Settings" search for LDAP and you should see that LDAP is configured.
Now you have to manually create the user accounts with the same logins as in your LDAP server or you can use the CloudStack API to make a script and "sync" your LDAP users into CloudStack, I've written a PHP script that does this.
You'll have to modify it to match your LDAP schema and you can get it after the break.
<?php
//For the LDAP server info:
$ldaphost = "10.10.10.89";
$ldapport = 10389;
$ldaprdn = 'cn=admin,dc=your-domain,dc=com'; // ldap rdn or dn
$ldappass = 'scretpass'; // associated password
/**
* Searches haystack for needle and returns an array of the key path if it is found in the (multidimensional) array, FALSE otherwise.
*
* mixed array_searchRecursive ( mixed needle, array haystack [, bool strict[, array path]] )
*/
function array_searchRecursive( $needle, $haystack, $strict=false, $path=array() )
{
if( !is_array($haystack) ) {
return false;
}
foreach( $haystack as $key => $val ) {
if( is_array($val) && $subPath = array_searchRecursive($needle, $val, $strict, $path) ) {
$path = array_merge($path, array($key), $subPath);
return $path;
} elseif( (!$strict && $val == $needle) || ($strict && $val === $needle) ) {
$path[] = $key;
return $path;
}
}
return false;
}
?>
function getSignature($queryString) {
$secretKey = "-i-RK0waCnGX8RuH_4bFWqc8BHW6c_QfpUjZu4_axwTPz5OW3ILdtO1fH9Q1AvE8-H2HlekeMWI3qlnLF5XBMg";
$hash = @hash_hmac("SHA1", $queryString, $secretKey, true);
$base64encoded = base64_encode($hash);
return urlencode($base64encoded);
}
function request($command, $args = array()) {
$cloudServer = "10.39.31.200:8096";
$apiKey = "ixgpdRFzVI7_JUmRzN45bIZ2hweuBmexlD8WbvcztaDbzv3aWjQ3M450MJuhwAMAvhPtn1A1zOT8AUIc38qctQ";
foreach ($args as $key => $value) {
if ($value == "") {
unset($args[$key]);
}
}
// Building the query
$args['apikey'] = $apiKey;
$args['command'] = $command;
$args['response'] = "json";
ksort($args);
$query = http_build_query($args);
$query = str_replace("+", "%20", $query);
$query .= "&signature=" . getSignature(strtolower($query));
$httpRequest = new HttpRequest();
$httpRequest->setMethod(HTTP_METH_POST);
$url = "http://" . $cloudServer . "?" . $query;
//die($url."\n");
$httpRequest->setUrl($url);
$httpRequest->send();
$code =$httpRequest->getResponseCode();
$data = $httpRequest->getResponseData();
if (empty($data)) {
die("NO_DATA_RECEIVED");
}
//echo $data['body'] . "\n";
$result = @json_decode($data['body']);
if (empty($result)) {
die("NO_VALID_JSON_RECEIVED");
}
//print_r($result);
//die();
$propertyResponse = strtolower($command) . "response";
if (!property_exists($result, $propertyResponse)) {
if (property_exists($result, "errorresponse") && property_exists($result->errorresponse, "errortext")) {
die($result->errorresponse->errortext);
} else {
die("Unable to parse the response. Got code ".$code." and message: " . $data['body']);
}
}
$response = $result->{$propertyResponse};
// list handling : most of lists are on the same pattern as listVirtualMachines :
// { "listvirtualmachinesresponse" : { "virtualmachine" : [ ... ] } }
preg_match('/list(\w+)s/', strtolower($command), $listMatches);
//print_r($listMatches);
//die();
if (!empty($listMatches)) {
$objectName = $listMatches[1];
//echo $objectName."\n";
if (property_exists($response, $objectName)) {
$resultArray = $response->{$objectName};
if (is_array($resultArray)) {
return $resultArray;
}
} else {
// sometimes, the 's' is kept, as in :
// { "listasyncjobsresponse" : { "asyncjobs" : [ ... ] } }
$objectName = $listMatches[1] . "s";
//echo $objectName."\n";
if (property_exists($response, $objectName)) {
$resultArray = $response->{$objectName};
if (is_array($resultArray)) {
return $resultArray;
}
}
}
}
return $response;
}
//Get users from CloudStack
$cloudAccounts = request("listAccounts", array("listall" => "true"));
//print_r($cloudAccounts);
//die();
// Connecting to LDAP
$ldapconn = ldap_connect($ldaphost, $ldapport)
or die("Could not connect to {$ldaphost}");
if ($ldapconn) {
ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, 0);
// binding to ldap server
$ldapbind = ldap_bind($ldapconn, $ldaprdn, $ldappass);
// verify binding
if ($ldapbind) {
echo "LDAP bind successful...\n";
$basedn = "dc=your-domain,dc=com";
$filter="(&(accountstatus=active))";
#$justthese = array("dn","uid", "cn", "mail", "mobile");
#$search = ldap_search($ldapconn, $basedn, $filter, $justthese);
$search = ldap_search($ldapconn, $basedn, $filter);
$info = ldap_get_entries($ldapconn, $search);
if ($info['count'] > 0 ){
//die("Found ".$info['count']. " users!\n");
for ($i = 0; $i < $info['count']; $i++)
{
echo "Porcessing user [" . $info[$i]['uid'][0]."]\n";
//do stuff here
if (array_searchRecursive($info[$i]['uid'][0],$cloudAccounts) === false)
{
//Create user account
$result = request("createAccount", array(
"accounttype" => "0",
"email" => $info[$i]['mail'][0],
"firstname" => $info[$i]['givenname'][0],
"lastname" => $info[$i]['sn'][0],
"password" => $info[$i]['userpassword'][0],
"username" => $info[$i]['uid'][0],
"networkdomain" => "yourdomain",
"timezone" => "Etc/UTC",
));
} else {
echo "User alredy exists!\n";
}
}
} else {
echo "No users found...\n";
}
//Unbind
ldap_unbind($ldapconn);
} else {
echo "LDAP bind failed...\n";
}
}
?>
No comments:
Post a Comment