/** * Fetch the host from LDAP and initialize the object * * @return void */ function fetchHostInfo() { global $wgAuth; global $wgOpenStackManagerLDAPInstanceBaseDN; $this->ip = $wgAuth->getLdapEscapedString($this->ip); $result = LdapAuthenticationPlugin::ldap_search($wgAuth->ldapconn, $wgOpenStackManagerLDAPInstanceBaseDN, '(dc=' . $this->ip . ')'); $this->hostInfo = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); if ($this->hostInfo["count"] == "0") { $this->hostInfo = null; } else { $this->hostDN = $this->hostInfo[0]['dn']; } }
/** * 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; } }
/** * Binds as $userdn with $password. This can be called with only the ldap * connection resource for an anonymous bind. * * @param string $userdn * @param string $password * @return bool * @access private */ function bindAs($userdn = null, $password = null) { // Let's see if the user can authenticate. if ($userdn == null || $password == null) { $bind = LdapAuthenticationPlugin::ldap_bind($this->ldapconn); } else { $bind = LdapAuthenticationPlugin::ldap_bind($this->ldapconn, $userdn, $password); } if (!$bind) { $this->printDebug("Failed to bind as {$userdn}", NONSENSITIVE); return false; } $this->boundAs = $userdn; return true; }
/** * 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; } }
static function AbortNewAccount($user, &$message) { global $wgRequest; global $wgAuth; global $wgUser; $shellaccountname = $wgRequest->getText('shellaccountname'); if (!preg_match("/^[a-z][a-z0-9\\-_]*\$/", $shellaccountname)) { $wgAuth->printDebug("Invalid shell name {$shellaccountname}", NONSENSITIVE); $message = wfMessage('openstackmanager-shellaccountvalidationfail')->parse(); return false; } $base = USERDN; $result = LdapAuthenticationPlugin::ldap_search($wgAuth->ldapconn, $base, "(uid={$shellaccountname})"); if ($result) { $entries = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); if ((int) $entries['count'] > 0) { $wgAuth->printDebug("User {$shellaccountname} already exists.", NONSENSITIVE); $message = wfMessage('openstackmanager-shellaccountexists')->parse(); return false; } } if (class_exists('TitleBlacklist')) { return TitleBlacklistHooks::acceptNewUserName($shellaccountname, $wgUser, $message, $override = false, $log = true); } else { return true; } }
/** * 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; } }
/** * Update puppet classes and variables for this host. * * @param $puppetinfo * @return bool */ function modifyPuppetConfiguration($puppetinfo) { global $wgAuth; global $wgOpenStackManagerPuppetOptions; $hostEntry = array(); if ($wgOpenStackManagerPuppetOptions['enabled']) { if (isset($puppetinfo['classes'])) { foreach ($puppetinfo['classes'] as $class) { $hostEntry['puppetclass'][] = $class; } } if (isset($puppetinfo['variables'])) { foreach ($puppetinfo['variables'] as $variable => $value) { $hostEntry['puppetvar'][] = $variable . '=' . $value; } } $oldpuppetinfo = $this->getPuppetConfiguration(); if (isset($oldpuppetinfo['puppetvar'])) { $wgAuth->printDebug("Checking for preexisting variables", NONSENSITIVE); foreach ($oldpuppetinfo['puppetvar'] as $variable => $value) { $wgAuth->printDebug("Found {$variable}", NONSENSITIVE); if ($variable === "instanceproject" || $variable === "instancename") { $hostEntry['puppetvar'][] = $variable . '=' . $value; } } } if ($hostEntry) { $success = LdapAuthenticationPlugin::ldap_modify($wgAuth->ldapconn, $this->hostDN, $hostEntry); if ($success) { $this->fetchHostInfo(); $wgAuth->printDebug("Successfully modified puppet configuration for host", NONSENSITIVE); return true; } else { $wgAuth->printDebug("Failed to modify puppet configuration for host", NONSENSITIVE); return false; } } else { $wgAuth->printDebug("No hostEntry when trying to modify puppet configuration", NONSENSITIVE); return false; } } return false; }
/** * Sets up the SSL authentication piece of the LDAP plugin. * * @access public */ function AutoAuthSetup() { global $LDAPSSLUsername; global $Hooks; global $Auth; global $LDAPAutoAuthMethod; $Auth = new LdapAuthenticationPlugin(); $Auth->printDebug("Entering AutoAuthSetup.", 1); //We may add quite a few different auto authenticate methods in the //future, let's make it easy to support. switch ($LDAPAutoAuthMethod) { case "smartcard": $Auth->printDebug("Allowing smartcard authentication.", 1); $Auth->printDebug("wgLDAPSSLUsername = {$LDAPSSLUsername}", 2); if ($LDAPSSLUsername != null) { $Auth->printDebug("wgLDAPSSLUsername is not null, adding hooks.", 1); $Hooks['AutoAuthenticate'][] = 'SSLAuth'; /* Hook for magical authN */ $Hooks['PersonalUrls'][] = 'NoLogout'; /* Disallow logout link */ } break; default: $Auth->printDebug("Not using any AutoAuthentication methods .", 1); } }
/** * 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; } }
/** * Sets up the SSL authentication piece of the LDAP plugin. * * @access public */ function AutoAuthSetup() { global $wgLDAPAutoAuthUsername; global $wgLDAPSSLUsername; global $wgLDAPAutoAuthDomain; global $wgLDAPSmartcardDomain; global $wgHooks; global $wgAuth; global $wgVersion; $wgAuth = new LdapAuthenticationPlugin(); $wgAuth->printDebug("Entering AutoAuthSetup.", NONSENSITIVE); //Set configuration options for backwards compatibility if (isset($wgLDAPSSLUsername)) { $wgAuth->printDebug('Setting $wgLDAPAutoAuthUsername to $wgLDAPSSLUsername; please change your configuration to fix this deprecated configuration variable.', NONSENSITIVE); $wgLDAPAutoAuthUsername = $wgLDAPSSLUsername; } if (isset($wgLDAPSmartcardDomain)) { $wgAuth->printDebug('Setting $wgLDAPAutoAuthDomain to $wgLDAPSmartcardDomain; please change your configuration to fix this deprecated configuration variable.', NONSENSITIVE); $wgLDAPAutoAuthDomain = $wgLDAPSmartcardDomain; } if ($wgLDAPAutoAuthUsername != null) { $wgAuth->printDebug("wgLDAPAutoAuthUsername is not null, adding hooks.", NONSENSITIVE); if (version_compare($wgVersion, '1.14.0', '<')) { $wgHooks['UserLoadFromSession'][] = 'LdapAutoAuthentication::Authenticate'; } else { $wgHooks['UserLoadAfterLoadFromSession'][] = 'LdapAutoAuthentication::Authenticate'; } $wgHooks['PersonalUrls'][] = 'LdapAutoAuthentication::NoLogout'; /* Disallow logout link */ } }
public function execute() { global $wgOpenStackManagerLDAPUsername; global $wgAuth; $user = new OpenStackNovaUser($wgOpenStackManagerLDAPUsername); $projects = OpenStackNovaProject::getAllProjects(); $failedSync = false; $attempt_count = 0; $synced_count = 0; $failed_count = 0; /** * @var $project OpenStackNovaProject */ foreach ($projects as $project) { // actually load the project info from ldap // (getAllProjects() doesn't do this) $project->fetchProjectInfo(); $projectName = $project->getProjectName(); $oldServiceGroupOUDN = 'ou=groups,' . $project->getProjectDN(); $oldServiceUserOUDN = 'ou=people,' . $project->getProjectDN(); $result = LdapAuthenticationPlugin::ldap_search($wgAuth->ldapconn, $oldServiceGroupOUDN, '(objectclass=groupofnames)'); if ($result) { $this->serviceGroups = array(); $groupList = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); if (isset($groupList)) { array_shift($groupList); foreach ($groupList as $groupEntry) { $deleteme = "cn=" . $groupEntry['cn'][0] . "," . $oldServiceGroupOUDN; print "needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } } } } $result = LdapAuthenticationPlugin::ldap_search($wgAuth->ldapconn, $oldServiceUserOUDN, '(objectclass=person)'); if ($result) { $this->serviceGroups = array(); $groupList = LdapAuthenticationPlugin::ldap_get_entries($wgAuth->ldapconn, $result); if (isset($groupList)) { array_shift($groupList); foreach ($groupList as $groupEntry) { $deleteme = "uid=" . $groupEntry['cn'][0] . "," . $oldServiceUserOUDN; print "user needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } } } } $deleteme = $oldServiceGroupOUDN; print "ou needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } $deleteme = $oldServiceUserOUDN; print "ou needs deleting: " . $deleteme . "..."; $attempt_count++; $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $deleteme); if ($success) { $synced_count++; print "done.\n"; } else { $failed_count++; print "FAILED\n"; } } $this->output("{$attempt_count} items needed cleanup. {$synced_count} removed, {$failed_count} failed.\n"); $this->output("Done.\n"); return $failed_count == 0; }
/** * 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 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; }
/** * @static * @param $groupName * @param $project OpenStackNovaProject * @return bool */ static function deleteServiceGroup($groupName, $project) { global $wgAuth; global $wgMemc; $group = self::getServiceGroupByName($groupName, $project); if (!$group) { $wgAuth->printDebug("We are trying to delete a nonexistent service group, {$groupName}", NONSENSITIVE); return false; } # Delete our special member. $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $group->getSpecialUserDN()); if ($success) { $wgAuth->printDebug("Successfully deleted service user {$groupName}", NONSENSITIVE); } else { $wgAuth->printDebug("Failed to delete service user {$groupName}", NONSENSITIVE); return false; } # Now delete the group. $success = LdapAuthenticationPlugin::ldap_delete($wgAuth->ldapconn, $group->groupDN); if ($success) { $wgAuth->printDebug("Successfully deleted service group {$groupName}", NONSENSITIVE); $key = wfMemcKey('openstackmanager', 'servicegroup', $groupName); $wgMemc->delete($key); } else { $wgAuth->printDebug("Failed to delete service group {$groupName}", NONSENSITIVE); return false; } return true; }
/** * 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 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; } }