iTop 支持以ldap的方式验证,而微软的Active Directory 本质上也是一个ldap服务器,所以可以通过ldap协议导入AD用户。本文以iTop 2.3.3为例,亲测可用。


新建文件itop/webservices/AD_import_accounts.php,内容见后文,


在命令行运行一下命令(密码根据需要修改)

php AD_import_accounts.php --auth_user=admin --auth_pwd=123456


或者以admin身份登录itop,访问http://ip/itop/webservices/AD_import_accounts.php 也可。



进入itop数据库,运行以下sql语句可以验证用户是否已经添加;

select * from priv_user ;


附: AD_import_accounts.php,具体内容如下,注意修改31-35行



 * @author      Romain Quetiez 
 * @author      Denis Flaven 
 * @license     http://www.opensource.org/licenses/gpl-3.0.html LGPL
 */

////////////////////////////////////////////////////////////////////////////////
// Configuration parameters: adjust them to connect to your AD server
// And configure the mapping between AD groups and iTop profiles
$aConfig = array(
                    // Configuration of the Active Directory connection
                    'host'     => '10.0.0.1', // IP or FQDN of your domain controller
                    'port'     => '389', // LDAP port, 398=LDAP, 636= LDAPS
                    'dn'       => 'DC=abc,DC=com', // Domain DN
                    'username'    => 'admin', // username with read access
                    'password'    => 'LDAP@admin', // password for above

                     // Query to retrieve and filter the users from AD
                     // Example: retrieve all users from the AD Group "iTop Users"
                         //'ldap_query' => '(&(objectCategory=user)(memberOf=CN=iTop Users,CN=Users,DC=combodo,DC=net))',
                         // Example 2: retrieves ALL the users from AD
                     'ldap_query' => '(&(objectCategory=user))', // Retrieve all users

                     // Which field to use as the iTop login samaccountname or userprincipalname ?
                     'login' => 'samaccountname',
                     //'login' => 'userprincipalname',

                     // Mapping between the AD groups and the iTop profiles
                    'profiles_mapping' => array(
                        //AD Group Name => iTop Profile Name
                                                'ITSM_Administrator' => 'Administrator',
                                                'ITSM_ChangeApprover' => 'Change Approver',
                                                'ITSM_ChangeImplementor' => 'Change Implementor',
                                                'ITSM_ChangeSupervisor' => 'Change Supervisor',
                                                'ITSM_ConfigurationManager' => 'Configuration Manager',
                                                'ITSM_DocumentAuthor' => 'Document author',
                                                'ITSM_PortalPowerUser' => 'Portal power user',
                                                'ITSM_PortalUser' => 'Portal user',
                                                'ITSM_ProblemManager' => 'Problem Manager',
                                                'ITSM_ServiceDeskAgent' => 'Service Desk Agent',
                                                'ITSM_ServiceManager' => 'Service Manager',
                                                'ITSM_SupportAgent' => 'Support Agent',
                            ),

                    // Since each iTop user must have at least one profile, assign the profile
                    // Below to users for which there was no match in the above mapping
                    'default_profile' => 'Portal user',
                    'default_language' => 'ZH CN', // Default language for creating new users

                    'default_organization' => 2, // ID of the default organization for creating new contacts
                );
// End of configuration
////////////////////////////////////////////////////////////////////////////////

if (file_exists('../approot.inc.php'))
{
    // iTop 1.0.2
    include('../approot.inc.php');
}
else // iTop 1.0 & 1.0.1
{
    define('APPROOT', '../');
}
require_once(APPROOT.'application/application.inc.php');
require_once(APPROOT.'application/webpage.class.inc.php');
require_once(APPROOT.'application/csvpage.class.inc.php');
require_once(APPROOT.'application/clipage.class.inc.php');
require_once(APPROOT.'application/startup.inc.php');
 
// List of attributes to retrieve
$aAttribs = array(
    'samaccountname',
    'sn',
    'givenname',
    'userprincipalname',
    'cn',
    'memberof',
    'mail',
);
 
$g_aUsersCache = null;       // Cache of all the iTop users to speed up searches
$g_aProfilesCache = null;    // Cache of all iTop profiles
 
/**
 * Helper function to read attributes from LDAP data
 * @param hash The LDAP data for one item as returned by ldap_search
 * @param string The name of the attribute to retrieve
 * @return mixed null if no such attribute, a scalar or a array depending on the
 *                    number of values for the attribute.
 */   
function ReadLdapValue($aEntry, $sValueName)
{
    if (array_key_exists($sValueName, $aEntry))
    {
        $iCount = $aEntry[$sValueName]['count'];
        switch($iCount)
        {
            case 0:
            // No value, return null
            return null;
             
            case 1:
            // Just one value, return it
            return $aEntry[$sValueName][0];
             
            default:
            // Many values, return all of them as an array
            // except the 'count' entry
            $aValues = $aEntry[$sValueName];
            unset($aValues['count']);
            return $aValues;
        }
    }
    return null;
}
/**
 * Helper function that processes 1 user at a time
 * @param $aData hash The input data from Active Directory
 * @param $index integer The index of the current user in the AD query (for reporting)
 * @param $aConfig hash The configuration parameter
 * @param $oChange CMDBChange Change to record all the changes or null if simulation mode
 * @return string The action undertaken 'created', 'synchronized', 'error' 
 */ 
function ProcessUser($aData, $index, $aConfig, $oChange = null)
{
    $sAction = 'error';
     
    $sUserLogin = $aData['samaccountname'];
    if (!is_array($aData['memberof']))
    {
        $aADGroups = array($aData['memberof']);
    }
    else
    {
        $aADGroups = $aData['memberof'];
    }
    $aITopProfiles = array(); 
    foreach($aADGroups as $sGroupString)
    {
        $aMatches = array();
        $sShortGroupString = '';
        if (preg_match('/^CN=([^,]+)/', $sGroupString, $aMatches))
        {
            $sShortGroupString = $aMatches[1];
        }
        //echo "

GroupString: $sGroupString => $sShortGroupString

";         if (isset($aConfig['profiles_mapping'][$sShortGroupString]))         {             $aITopProfiles[] = $aConfig['profiles_mapping'][$sShortGroupString];         }     }     if (count($aITopProfiles) == 0)     {         // Each user must have at least one profile         // Assign the 'default_profile' to this user         $aITopProfiles[] = $aConfig['default_profile'];     }     echo "

User#{$index}: {$aData['cn']}

\n";     echo "";     foreach($aData as $sAttrib => $value)     {         echo "$sAttrib";         echo "";         if (is_array($value))         {             echo implode('
', $value);         }         else         {             echo htmlentities($value);         }         echo "
\n";     }     echo "iTop Profiles";     echo "";     echo implode('
', $aITopProfiles);     echo "
\n";     echo "
";     $sLogin = $aData[$aConfig['login']];     $oITopUser = GetUserByLogin($sLogin);     if ($oITopUser == null)     {         // Check if a contact needs to be created or not         $oPerson = GetPersonByEmail($aData['mail']);         if (is_object($oPerson))         {             echo "

A person with the email='{$aData['mail']}' was found ".$oPerson->GetHyperlink().". This person will be used when creating the account.

";         }         else if ($oPerson == null)         {             echo "

A new person will be created.

";             $oPerson = new Person();             $oPerson->Set('name', $aData['sn']);             $oPerson->Set('first_name', $aData['givenname']);             $oPerson->Set('email', $aData['mail']);             $oPerson->Set('org_id', $aConfig['default_organization']);             if ($oChange != null)             {                 $oPerson->DBInsertTracked($oChange);             }         }         else         {             // Error ! Several matches found ??             throw new Exception($oPerson);         }         $sAction = 'created';         echo "

User $sLogin will be created in iTop

";         $oITopUser = new UserLDAP;         $oITopUser->Set('login', $sLogin);         $oITopUser->Set('contactid', $oPerson->GetKey());         $oITopUser->Set('language', $aConfig['default_language']);         // Update the profiles         $oLinkSet = DBObjectSet::FromScratch('URP_UserProfile');         foreach($aITopProfiles as $sProfile)         {             $oLink = new URP_UserProfile;             $iProfileId = GetProfileByName($sProfile);             if ($iProfileId != null)             {                 $oLink->Set('profileid', $iProfileId);                 $oLinkSet->AddObject($oLink);             }             else             {                 echo "

Error: the profile '$sProfile' does not exist in iTop, verify the profiles_mapping configuration!

";             }         }         $oITopUser->Set('profile_list', $oLinkSet);         if ($oChange != null)         {             $oITopUser->DBInsertTracked($oChange);         }     }     else if(is_object($oITopUser))     {         $sAction = 'synchronized';         echo "

User $sLogin (UserLDAP::".$oITopUser->GetKey().") will be synchronized in iTop

";         // Update the profiles         $oLinkSet = DBObjectSet::FromScratch('URP_UserProfile');         $oITopUser->Set('login', $sLogin);         foreach($aITopProfiles as $sProfile)         {             $oLink = new URP_UserProfile;             $iProfileId = GetProfileByName($sProfile);             if ($iProfileId != null)             {                 $oLink->Set('profileid', $iProfileId);                 $oLinkSet->AddObject($oLink);             }             else             {                 echo "

Error: the profile '$sProfile' does not exist in iTop, verify the profiles_mapping configuration!

";             }         }         $oITopUser->Set('profile_list', $oLinkSet);         if ($oChange != null)         {             $oITopUser->DBUpdateTracked($oChange);         }     }     else     {         // Error, another kind of user already exists with the same login ?         echo "Error: $oITopUser";     }     return $sAction; }   /**  * Search the given user (identified by its login) in the iTop database  * @param $sLogin string The login of the user  * @return mixed null => nothing found, object => the user to synchronize, string => error message  */ function GetUserByLogin($sLogin) {     global $g_aUsersCache;     $result = null;     if ($g_aUsersCache == null) InitUsersCache();     if (isset($g_aUsersCache[$sLogin]))     {         $oUser = $g_aUsersCache[$sLogin];         if (get_class($oUser) != 'UserLDAP')         {             $result = "A user with the same login ($sLogin), but not managed by LDAP already exists in iTop, the AD record will be ignored.";         }         else         {             $result = $oUser;         }     }     return $result; }   /**  * Initializes the cache for quickly searching iTop users  * @param none  * @return integer Number of users fetched from iTop    */ function InitUsersCache() {     global $g_aUsersCache;     $sOQL = "SELECT User";     $oSearch = DBObjectSearch::FromOQL($sOQL);     $oSet = new CMDBObjectSet($oSearch);     $iRet = $oSet->Count();     while($oUser = $oSet->Fetch())     {         $g_aUsersCache[$oUser->Get('login')] = $oUser;     }     return $iRet; }   /**  * Retrieves the ID of a profile (in iTop) base on its name  * @param $sProfile string Name of the profile  * @return integer ID of the profile, or null is not found  */ function GetProfileByName($sProfileName) {     global $g_aProfilesCache;     $iRet = null;     if ($g_aProfilesCache == null) InitProfilesCache();           if (isset($g_aProfilesCache[$sProfileName]))     {         $iRet = $g_aProfilesCache[$sProfileName];     }     return $iRet; }   /**  * Initializes the cache of the iTop profiles  * @param none  * @return void  */ function InitProfilesCache() {     global $g_aProfilesCache;     $sOQL = "SELECT URP_Profiles";     $oSearch = DBObjectSearch::FromOQL($sOQL);     $oSet = new CMDBObjectSet($oSearch);     while($oProfile = $oSet->Fetch())     {         $g_aProfilesCache[$oProfile->GetName()] = $oProfile->GetKey();     } }   /**  * Search for a Person by email address  * @param $sEmail string  * @return mixed Person (if found) or null (not found) or string (error)  */ function GetPersonByEmail($sEmail) {     static $oSearch = null; // OQL Query cache     $person = null;     if ($oSearch == null)     {         $sOQL = 'SELECT Person WHERE email = :email';         $oSearch = DBObjectSearch::FromOQL($sOQL);     }     $oSet = new CMDBObjectSet($oSearch, array(), array('email' => $sEmail));     switch($oSet->Count())     {         case 0:         $person = null;         break;                   case 1:         $person = $oSet->Fetch();         break;                   default:         $person = ' several matches found: '.$oSet->Count()." persons have the email address '$sEmail'";     }     return $person;     }              /******************************************************************************  *  * Main program  *    ******************************************************************************/ if (utils::IsModeCLI()) {     $sAuthUser = utils::ReadParam('auth_user', 'admin_user', true);     $sAuthPwd = utils::ReadParam('auth_pwd', 'admin_user_password', true);     if (UserRights::CheckCredentials($sAuthUser, $sAuthPwd))     {         UserRights::Login($sAuthUser); // Login & set the user's language     }     else     {         echo "Access restricted or wrong credentials ('$sAuthUser')";         exit;     } } else {     $_SESSION['login_mode'] = 'basic';     require_once('../application/loginwebpage.class.inc.php');     LoginWebPage::DoLogin(); // Check user rights and prompt if needed       $sCSVData = utils::ReadPostedParam('csvdata'); } if (!UserRights::IsAdministrator()) {     echo '

Access is restricted to administrators

';     exit; } // By default, run in simulation mode (i.e do nothing) $bSimulationMode = utils::ReadParam('simulation', 0, true); $oMyChange = null; if (!$bSimulationMode) {     $oMyChange = MetaModel::NewObject("CMDBChange");     $oMyChange->Set("date", time());     if (UserRights::IsImpersonated())     {         $sUserString = Dict::Format('UI:Archive_User_OnBehalfOf_User', UserRights::GetRealUser(), UserRights::GetUser());     }     else     {         $sUserString = UserRights::GetUser();     }     $oMyChange->Set("userinfo", $sUserString);     $oMyChange->DBInsert(); } else {     echo "Simulation mode -- no action will be performed";     echo "

Set the parameter simulation=0 to trigger the actual execution.

"; }  $ad = ldap_connect($aConfig['host'], $aConfig['port']) or die( "Could not connect to {$aConfig['host']} on port {$aConfig['port']}!" ); echo "

Connected to {$aConfig['host']} on port {$aConfig['port']}

\n"; // Set version number ldap_set_option($ad, LDAP_OPT_PROTOCOL_VERSION, 3) or die ("Could not set ldap protocol"); ldap_set_option($ad, LDAP_OPT_REFERRALS,0) or die ("could no se the ldap referrals");   // Binding to ldap server $bd = ldap_bind($ad, $aConfig['username'], $aConfig['password']) or die ("Could not bind"); echo "

Identified as {$aConfig['username']}

\n";   $sLdapSearch = $aConfig['ldap_query'];   echo "

LDAP Query: '$sLdapSearch'

"; $search = ldap_search($ad, $aConfig['dn'], $sLdapSearch /*, $aAttribs*/) or die ("ldap search failed");   $entries = ldap_get_entries($ad, $search); $index = 1; $aStatistics = array(     'created' => 0,     'synchronized' => 0,     'error' => 0, ); $iCreated = 0; $iSynchronized = 0; $iErrors = 0;     if ($entries["count"] > 0) {     $iITopUsers = InitUsersCache();     echo "

{$entries["count"]} user(s) found in Active Directory, $iITopUsers (including non-LDAP users) found in iTop.

\n";     foreach($entries as $key => $aEntry)     {         //echo "
$key\n";
        //print_r($aEntry);
        //echo "
\n";         if (strcmp($key,'count') != 0)         {             $aData = array();             foreach($aAttribs as $sName)             {                 $aData[$sName] = ReadLdapValue($aEntry, $sName);             }             if (empty($aData['mail']))             {                 $aData['mail'] = $aData['userprincipalname'];             }             try             {                 $sAction = ProcessUser($aData, $index, $aConfig, $oMyChange);             }             catch(Exception $e)             {                 echo "

An error occured while processing $index: ".$e->getMessage()."

";                 $sAction = 'error';             }             echo "
\n";             $aStatistics[$sAction]++;             $index++;         }     } } else {     echo "

Nothing found !

\n";     echo "

LDAP query was: $sLdapSearch

\n"; } ldap_unbind($ad); if ($bSimulationMode) {     echo "Simulation mode -- no action was performed"; } echo "

Statistics:

"; echo ""; foreach($aStatistics as $sKey => $iValue) {     echo "$sKey\n";     echo "$iValue\n"; } echo "
"; ?>