/** * @param $ip */ function __construct($ip) { global $wgAuth; $this->domainCache = null; $this->ip = $ip; OpenStackNovaLdapConnection::connect(); $this->fetchHostInfo(); }
public function execute() { global $wgAuth; global $wgOpenStackManagerLDAPUsername; global $wgOpenStackManagerLDAPUserPassword; if ($this->hasOption('all-instances')) { if ($this->hasOption('region')) { $this->error("--all-instances cannot be used with --region.\n", true); } $instancelist = array(); $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $userNova = OpenStackNovaController::newFromUser($user); $projects = OpenStackNovaProject::getAllProjects(); $userNova->setProject('bastion'); $userNova->authenticate($wgOpenStackManagerLDAPUsername, $wgOpenStackManagerLDAPUserPassword); $regions = $userNova->getRegions('compute'); foreach ($regions as $region) { foreach ($projects as $project) { $projectName = $project->getProjectName(); $userNova->setProject($projectName); $userNova->setRegion($region); $instances = $userNova->getInstances(); if ($instances) { foreach ($instances as $instance) { $instancelist[] = array($region, $instance->getInstanceName(), $projectName); } } } } } elseif ($this->hasOption('name')) { if (!$this->hasOption('region')) { $this->error("--name requires --region.\n", true); } if (!$this->hasOption('project')) { $this->error("--name requires --project.\n", true); } $instancelist = array(array($this->getOption('region'), $this->getOption('name'), $this->getOption('project'))); } else { $this->error("Must specify either --name or --all-instances.\n", true); } if (!class_exists('OpenStackNovaHost')) { $this->error("Couldn't find OpenStackNovaHost class.\n", true); } OpenStackNovaLdapConnection::connect(); foreach ($instancelist as $instancepair) { list($instanceregion, $instancename, $instanceproject) = $instancepair; $host = OpenStackNovaHost::getHostByNameAndProject($instancename, $instanceproject, $instanceregion); if (!$host) { print "Skipping {$instancename}.{$instanceproject}.{$instanceregion}; not found.\n"; continue; } print "\nFor instance {$instancename} in region {$instanceregion} and project {$instanceproject}:\n\n"; $namefqdn = $instancename . '.' . $instanceproject . '.' . $instanceregion . '.' . 'wmflabs'; $host->addAssociatedDomain($namefqdn); } }
/** * @param $instancename * @param $instanceproject * @param $region */ function __construct($instancename, $instanceproject, $region) { global $wgAuth; $this->instancename = $wgAuth->getLdapEscapedString($instancename); $this->instanceproject = $wgAuth->getLdapEscapedString($instanceproject); $this->region = $region; $this->domainCache = null; OpenStackNovaLdapConnection::connect(); $this->fetchHostInfo(); }
/** * Deletes a sudo policy based on the policy name. * * @static * @param $sudoername * @return bool */ static function deleteSudoer( $sudoername ) { global $wgAuth; OpenStackNovaLdapConnection::connect(); $sudoer = new OpenStackNovaSudoer( $sudoername ); if ( ! $sudoer ) { $wgAuth->printDebug( "Sudoer $sudoername does not exist", NONSENSITIVE ); return false; } $dn = $sudoer->sudoerDN; $success = LdapAuthenticationPlugin::ldap_delete( $wgAuth->ldapconn, $dn ); if ( $success ) { $wgAuth->printDebug( "Successfully deleted sudoer $sudoername", NONSENSITIVE ); return true; } else { $wgAuth->printDebug( "Failed to delete sudoer $sudoername", NONSENSITIVE ); return false; } }
/** * Deletes a project group based on project name. * * @param $projectname String * @return bool */ static function deleteProjectGroup($projectname) { global $wgAuth; global $wgOpenStackManagerLDAPProjectGroupBaseDN; OpenStackNovaLdapConnection::connect(); $projectGroupName = self::$prefix . $projectname; $projectGroupDN = 'cn=' . $projectGroupName . ',' . $wgOpenStackManagerLDAPProjectGroupBaseDN; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $projectGroupDN); if ($success) { $wgAuth->printDebug("Successfully deleted project group {$projectGroupDN}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to delete project group {$projectGroupDN}: " . ldap_error($wgAuth->ldapconn), NONSENSITIVE); } return $success; }
/** * Deletes a sudo policy based on the policy name. * * @static * @param $sudoername * @param $projectName * @return bool */ static function deleteSudoer($sudoername, $projectName) { global $wgAuth; global $wgMemc; OpenStackNovaLdapConnection::connect(); $project = OpenStackNovaProject::getProjectByName($projectName); $sudoer = new OpenStackNovaSudoer($sudoername, $project); if (!$sudoer) { $wgAuth->printDebug("Sudoer {$sudoername} does not exist", NONSENSITIVE); return false; } $dn = $sudoer->sudoerDN; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $dn); if ($success) { $wgAuth->printDebug("Successfully deleted sudoer {$sudoername}", NONSENSITIVE); $key = wfMemcKey('openstackmanager', 'sudoerinfo', $projectName . $sudoername); $wgMemc->delete($key); return true; } else { $wgAuth->printDebug("Failed to delete sudoer {$sudoername}", NONSENSITIVE); return false; } }
/** * Hook to add objectclasses and attributes for users that already exist, but have * missing information. * * @static * @param $auth * @return bool */ static function LDAPSetNovaInfo( $auth ) { global $wgMemc; OpenStackNovaLdapConnection::connect(); $result = LdapAuthenticationPlugin::ldap_read( $auth->ldapconn, $auth->userInfo[0]['dn'], '(objectclass=*)', array( 'secretkey', 'accesskey', 'objectclass' ) ); $userInfo = LdapAuthenticationPlugin::ldap_get_entries( $auth->ldapconn, $result ); if ( !isset( $userInfo[0]['accesskey'] ) or !isset( $userInfo[0]['secretkey'] ) ) { $objectclasses = $userInfo[0]['objectclass']; # First entry is a count array_shift( $objectclasses ); if ( !in_array( 'novauser', $objectclasses ) ) { $values['objectclass'] = array(); # ldap_modify for objectclasses requires the array indexes be sequential. # It is stupid, yes. foreach ( $objectclasses as $objectclass ) { $values['objectclass'][] = $objectclass; } $values['objectclass'][] = 'novauser'; } $values['accesskey'] = OpenStackNovaUser::uuid4(); $values['secretkey'] = OpenStackNovaUser::uuid4(); $values['isnovaadmin'] = 'FALSE'; $success = LdapAuthenticationPlugin::ldap_modify( $auth->ldapconn, $auth->userdn, $values ); if ( $success ) { $key = wfMemcKey( 'ldapauthentication', 'userinfo', $auth->userdn ); $wgMemc->delete( $key ); $auth->printDebug( "Successfully modified the user's nova attributes", NONSENSITIVE ); return true; } else { $auth->printDebug( "Failed to modify the user's nova attributes.", NONSENSITIVE ); # Always return true, other hooks should still run, even if this fails return true; } } else { $auth->printDebug( "User has accesskey and secretkey set.", NONSENSITIVE ); return true; } }
/** * @param string $username */ function __construct($username = '') { $this->username = $username; OpenStackNovaLdapConnection::connect(); $this->fetchUserInfo(); }
/** * Pulls all projects from LDAP and adds them as MediaWiki namespaces. Also adds * associated talk namespaces. This function must be called from LocalSettings. * * @static * @return void */ static function addNamespaces() { global $wgAuth; global $wgOpenStackManagerLDAPProjectBaseDN; global $wgExtraNamespaces; OpenStackNovaLdapConnection::connect(); $result = LdapAuthenticationPlugin::ldap_search($wgAuth->ldapconn, $wgOpenStackManagerLDAPProjectBaseDN, 'owner=*'); $entries = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); if ($entries) { array_shift($entries); foreach ($entries as $entry) { $id = (int) $entry['gidnumber'][0]; $talkid = $id + 1; $name = ucwords($entry['cn'][0]); $wgAuth->printDebug("Adding namespace {$name}", NONSENSITIVE); $wgExtraNamespaces[$id] = $name; $wgExtraNamespaces[$talkid] = $name . '_talk'; } } else { $wgAuth->printDebug("Failed to find projects", NONSENSITIVE); } }
/** * @static * @param $rolename * @param $project OpenStackNovaProject * @return bool */ static function createRole( $rolename, $project ) { global $wgAuth; OpenStackNovaLdapConnection::connect(); $role = array(); $role['objectclass'][] = 'groupofnames'; $role['cn'] = $rolename; $roledn = 'cn=' . $rolename . ',' . $project->projectDN; $success = LdapAuthenticationPlugin::ldap_add( $wgAuth->ldapconn, $roledn, $role ); # TODO: If role addition fails, find a way to fail gracefully # Though, if the project was added successfully, it is unlikely # that role addition will fail. if ( $success ) { $wgAuth->printDebug( "Successfully added role $rolename", NONSENSITIVE ); return true; } else { $wgAuth->printDebug( "Failed to add role $rolename", NONSENSITIVE ); return false; } }
/** * @static * @param $groupName * @param $project OpenStackNovaProject * @param $initialUser * @return null|OpenStackNovaServiceGroup */ static function createServiceGroup($inGroupName, $project, $initialUser) { global $wgAuth; global $wgOpenStackManagerLDAPUser; global $wgOpenStackManagerLDAPDefaultShell; global $wgOpenStackManagerLDAPServiceGroupBaseDN; global $wgMemc; OpenStackNovaLdapConnection::connect(); $projectPrefix = $project->getProjectName() . '.'; # We don't want naming collisions between service groups and actual groups # or users. So, prepend $projectPrefix to the requested group name. if (strpos($inGroupName, $projectPrefix, 0) === 0) { # The user was clever and already added the prefix. $groupName = $inGroupName; $simpleGroupName = substr($inGroupName, strlen($projectPrefix)); } else { $groupName = $projectPrefix . $inGroupName; $simpleGroupName = $inGroupName; } if ($initialUser) { $user = new OpenStackNovaUser($initialUser); if (!$user->userDN) { $wgAuth->printDebug("Unable to find initial user {$initialUser} for new group {$groupName}", NONSENSITIVE); return null; } $initialUserDN = $user->userDN; } $key = wfMemcKey('openstackmanager', 'servicegroup', $groupName); $wgMemc->delete($key); $group = array(); $group['objectclass'][] = 'posixgroup'; $group['objectclass'][] = 'groupofnames'; $group['cn'] = $groupName; $groupdn = 'cn=' . $groupName . ',' . $wgOpenStackManagerLDAPServiceGroupBaseDN; $group['gidnumber'] = OpenStackNovaUser::getNextIdNumber($wgAuth, 'gidnumber'); $group['member'] = array(); if ($initialUser) { $group['member'][] = $initialUserDN; } $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $groupdn, $group); if ($success) { $wgAuth->printDebug("Successfully added service group {$groupdn}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to add service group {$groupdn}", NONSENSITIVE); return null; } # stamp out regular expressions! $homeDir = $project->getServiceGroupHomedirPattern(); $homeDir = str_ireplace('%u', $simpleGroupName, $homeDir); $homeDir = str_ireplace('%p', $projectPrefix, $homeDir); # Now create the special SG member $newGroup = self::getServiceGroupByName($groupName, $project); $userdn = $newGroup->getSpecialUserDN(); $user = array(); $user['objectclass'][] = 'shadowaccount'; $user['objectclass'][] = 'posixaccount'; $user['objectclass'][] = 'person'; $user['objectclass'][] = 'top'; $user['loginshell'] = $wgOpenStackManagerLDAPDefaultShell; $user['homedirectory'] = $homeDir; $user['uidnumber'] = $group['gidnumber']; $user['gidnumber'] = $group['gidnumber']; $user['uid'] = $groupName; $user['sn'] = $groupName; $user['cn'] = $groupName; $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $userdn, $user); if ($success) { $wgAuth->printDebug("Successfully created service user {$userdn}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to create service user {$userdn}", NONSENSITIVE); return null; } # Create Sudo policy so that the service user can chown files in its homedir if (OpenStackNovaSudoer::createSudoer($groupName . '-chmod', $project->getProjectName(), array($groupName), array(), array('/bin/chown -R ' . $groupName . '\\:' . $groupName . ' ' . $homeDir), array('!authenticate'))) { $wgAuth->printDebug("Successfully created chmod sudo policy for {$groupName}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to creat chmod sudo policy for {$groupName}", NONSENSITIVE); } # Create Sudo policy so that members of the group can sudo as the service user if (OpenStackNovaSudoer::createSudoer('runas-' . $groupName, $project->getProjectName(), array("%" . $groupName), array($groupName), array('ALL'), array('!authenticate'))) { $wgAuth->printDebug("Successfully created run-as sudo policy for {$groupName}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to creat run-as sudo policy for {$groupName}", NONSENSITIVE); } return $newGroup; }
/** * Adds a host entry based on the hostname, IP addrss, and a domain. Returns null * if the entry already exists, or if the additional fails. This function should be used * for adding public DNS entries. * * @static * @param $hostname * @param $ip * @param $domain OpenStackNovaDomain * @return bool|null|OpenStackNovaHost */ static function addPublicHost($hostname, $ip, $domain) { global $wgAuth; global $wgOpenStackManagerLDAPInstanceBaseDN; OpenStackNovaLdapConnection::connect(); $domainname = $domain->getFullyQualifiedDomainName(); $host = OpenStackNovaHost::getHostByPublicIP($ip); if ($host) { $wgAuth->printDebug("Failed to add public host {$hostname} as the DNS entry already exists", NONSENSITIVE); return null; } $hostEntry = array(); $hostEntry['objectclass'][] = 'dcobject'; $hostEntry['objectclass'][] = 'dnsdomain'; $hostEntry['objectclass'][] = 'domainrelatedobject'; $hostEntry['dc'] = $ip; $hostEntry['arecord'] = $ip; $hostEntry['associateddomain'][] = $hostname . '.' . $domainname; $dn = 'dc=' . $ip . ',' . $wgOpenStackManagerLDAPInstanceBaseDN; $success = LdapAuthenticationPlugin::ldap_add($wgAuth->ldapconn, $dn, $hostEntry); if ($success) { $domain->updateSOA(); $wgAuth->printDebug("Successfully added public host {$hostname}", NONSENSITIVE); return new OpenStackNovaHost(false, null, $ip); } else { $wgAuth->printDebug("Failed to add public host {$hostname} with dn = {$dn}", NONSENSITIVE); return null; } }
/** * Deletes a domain based on the domain's short name. Will fail to * delete the domain if any host entries still exist in the domain. * * @static * @param $domainname * @return bool */ static function deleteDomain( $domainname ) { global $wgAuth; OpenStackNovaLdapConnection::connect(); $domain = new OpenStackNovaDomain( $domainname ); if ( ! $domain ) { $wgAuth->printDebug( "Domain $domainname does not exist", NONSENSITIVE ); return false; } $dn = $domain->domainDN; # Domains can have records as sub entries. If sub-entries exist, fail. $result = LdapAuthenticationPlugin::ldap_list( $wgAuth->ldapconn, $dn, 'objectclass=*' ); $hosts = LdapAuthenticationPlugin::ldap_get_entries( $wgAuth->ldapconn, $result ); if ( $hosts['count'] != "0" ) { $wgAuth->printDebug( "Failed to delete domain $domainname, since it had sub entries", NONSENSITIVE ); return false; } $success = LdapAuthenticationPlugin::ldap_delete( $wgAuth->ldapconn, $dn ); if ( $success ) { $wgAuth->printDebug( "Successfully deleted domain $domainname", NONSENSITIVE ); return true; } else { $wgAuth->printDebug( "Failed to delete domain $domainname, since it had sub entries", NONSENSITIVE ); return false; } }
/** * Deletes a project based on project name. This function will also delete all roles * associated with the project. * * @param $projectname String * @return bool */ static function deleteProject($projectname) { global $wgAuth; OpenStackNovaLdapConnection::connect(); $project = new OpenStackNovaProject($projectname); if (!$project) { return false; } $dn = $project->projectDN; # Projects can have roles as sub-entries, we need to delete them first $result = LdapAuthenticationPlugin::ldap_list($wgAuth->ldapconn, $dn, 'objectclass=*'); $roles = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); array_shift($roles); foreach ($roles as $role) { $roledn = $role['dn']; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $roledn); if ($success) { $wgAuth->printDebug("Successfully deleted role {$roledn}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to delete role {$roledn}", NONSENSITIVE); } } # Projects can have a separate group entry. If so, delete it now. if (OpenStackNovaProject::useProjectGroup()) { OpenStackNovaProjectGroup::deleteProjectGroup($projectname); } # Projects have a sudo OU and sudoers entries below that OU, we must delete them first $sudoers = OpenStackNovaSudoer::getAllSudoersByProject($project->getProjectName()); foreach ($sudoers as $sudoer) { $success = OpenStackNovaSudoer::deleteSudoer($sudoer->getSudoerName(), $project->getProjectName()); if ($success) { $wgAuth->printDebug("Successfully deleted sudoer " . $sudoer->getSudoerName(), NONSENSITIVE); } else { $wgAuth->printDebug("Failed to delete sudoer " . $sudoer->getSudoerName(), NONSENSITIVE); } } $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $project->getSudoersDN()); if ($success) { $wgAuth->printDebug("Successfully deleted sudoers OU " . $project->getSudoersDN(), NONSENSITIVE); } else { $wgAuth->printDebug("Failed to delete sudoers OU " . $project->getSudoersDN(), NONSENSITIVE); } # And, we need to clean up service groups. $servicegroups = $project->getServiceGroups(); foreach ($servicegroups as $group) { $groupName = $group->groupName; $success = OpenStackNovaServiceGroup::deleteServiceGroup($groupName, $project); if ($success) { $wgAuth->printDebug("Successfully deleted service group " . $groupName, NONSENSITIVE); } else { $wgAuth->printDebug("Failed to delete servie group " . $groupName, NONSENSITIVE); } } $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $dn); if ($success) { $wgAuth->printDebug("Successfully deleted project {$projectname}", NONSENSITIVE); return true; } else { $wgAuth->printDebug("Failed to delete project {$projectname}", NONSENSITIVE); return false; } }