summaryrefslogtreecommitdiffstats
path: root/ldap/synctools/passwordsync/passsync/syncserv.cpp
diff options
context:
space:
mode:
authorNathan Kinder <nkinder@redhat.com>2006-08-28 18:17:26 +0000
committerNathan Kinder <nkinder@redhat.com>2006-08-28 18:17:26 +0000
commit9cc92a20535293b4fd9be90e626d5daccc5d923e (patch)
treef74baed88b15d6d1206fa4b24c5821516b2b2346 /ldap/synctools/passwordsync/passsync/syncserv.cpp
parent2f59fa4c73e006af32a402dac503635188a017b4 (diff)
downloadds-9cc92a20535293b4fd9be90e626d5daccc5d923e.tar.gz
ds-9cc92a20535293b4fd9be90e626d5daccc5d923e.tar.xz
ds-9cc92a20535293b4fd9be90e626d5daccc5d923e.zip
204355 - Remove winsync code from ldapserver tree
Diffstat (limited to 'ldap/synctools/passwordsync/passsync/syncserv.cpp')
-rw-r--r--ldap/synctools/passwordsync/passsync/syncserv.cpp670
1 files changed, 0 insertions, 670 deletions
diff --git a/ldap/synctools/passwordsync/passsync/syncserv.cpp b/ldap/synctools/passwordsync/passsync/syncserv.cpp
deleted file mode 100644
index bac518e8..00000000
--- a/ldap/synctools/passwordsync/passsync/syncserv.cpp
+++ /dev/null
@@ -1,670 +0,0 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
-
-// Created: 2-8-2005
-// Author(s): Scott Bridges
-#include "syncserv.h"
-
-#include "prerror.h"
-static char* certdbh;
-
-// ****************************************************************
-// passwdcb
-// ****************************************************************
-char* passwdcb(PK11SlotInfo* info, PRBool retry, void* arg)
-{
- char* result = NULL;
- unsigned long resultLen = 0;
- DWORD type;
- HKEY regKey;
-
- if (!retry)
- {
- RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\PasswordSync", &regKey);
- RegQueryValueEx(regKey, "Install Path", NULL, &type, NULL, &resultLen);
- result = (char*)malloc(resultLen);
- RegQueryValueEx(regKey, "Cert Token", NULL, &type, (unsigned char*)result, &resultLen);
- RegCloseKey(regKey);
- }
-
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::PassSyncService
-// ****************************************************************
-PassSyncService::PassSyncService(const TCHAR *serviceName) : CNTService(serviceName)
-{
- char sysPath[SYNCSERV_BUF_SIZE];
- char tempRegBuff[SYNCSERV_BUF_SIZE];
- HKEY regKey;
- DWORD type;
- unsigned long size;
-
- passhookEventHandle = CreateEvent(NULL, FALSE, FALSE, PASSHAND_EVENT_NAME);
- mainLdapConnection = NULL;
- results = NULL;
- currentResult = NULL;
- lastLdapError = LDAP_SUCCESS;
- certdbh = NULL;
-
- RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\PasswordSync", &regKey);
-
- size = SYNCSERV_BUF_SIZE;
- if(RegQueryValueEx(regKey, "Log Level", NULL, &type, (unsigned char*)tempRegBuff, &size) == ERROR_SUCCESS)
- {
- logLevel = (unsigned long)atoi(tempRegBuff);
- }
- else
- {
- logLevel = 0;
- }
-
- size = SYNCSERV_BUF_SIZE;
- if(RegQueryValueEx(regKey, "Time To Live", NULL, &type, (unsigned char*)tempRegBuff, &size) == ERROR_SUCCESS)
- {
- maxBackoffTime = (unsigned long)atoi(tempRegBuff);
- }
- else
- {
- maxBackoffTime = (1 << 12) * SYNCSERV_BASE_BACKOFF_LEN;
- }
-
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "Install Path", NULL, &type, (unsigned char*)installPath, &size);
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "Host Name", NULL, &type, (unsigned char*)ldapHostName, &size);
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "Port Number", NULL, &type, (unsigned char*)ldapHostPort, &size);
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "User Name", NULL, &type, (unsigned char*)ldapAuthUsername, &size);
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "Password", NULL, &type, (unsigned char*)ldapAuthPassword, &size);
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "Search Base", NULL, &type, (unsigned char*)ldapSearchBase, &size);
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "User Name Field", NULL, &type, (unsigned char*)ldapUsernameField, &size);
- size = SYNCSERV_BUF_SIZE;
- RegQueryValueEx(regKey, "Password Field", NULL, &type, (unsigned char*)ldapPasswordField, &size);
- RegCloseKey(regKey);
-
- ExpandEnvironmentStrings("%SystemRoot%", sysPath, SYNCSERV_BUF_SIZE);
- _snprintf(certPath, SYNCSERV_BUF_SIZE, "%s", installPath);
- _snprintf(logPath, SYNCSERV_BUF_SIZE, "%spasssync.log", installPath);
- _snprintf(dataFilename, SYNCSERV_BUF_SIZE, "%s\\system32\\passhook.dat", sysPath);
-
- outLog.open(logPath, ios::out | ios::app);
-
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "PassSync service started" << endl;
- }
-
- PK11_SetPasswordFunc(passwdcb);
-
- isRunning = false;
-}
-
-// ****************************************************************
-// PassSyncService::~PassSyncService
-// ****************************************************************
-PassSyncService::~PassSyncService()
-{
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "PassSync service stopped" << endl;
- }
- outLog.close();
-}
-
-// ****************************************************************
-//
-// ****************************************************************
-void PassSyncService::OnStop()
-{
- isRunning = false;
- SetEvent(passhookEventHandle);
-}
-
-// ****************************************************************
-//
-// ****************************************************************
-void PassSyncService::OnShutdown()
-{
- isRunning = false;
- SetEvent(passhookEventHandle);
-}
-
-// ****************************************************************
-// PassSyncService::Run
-// ****************************************************************
-void PassSyncService::Run()
-{
- isRunning = true;
-
- // Initialize NSS
- if(ldapssl_client_init(certPath, &certdbh) != 0)
- {
- timeStamp(&outLog);
- outLog << "Error initializing SSL: err=" << PR_GetError() << endl;
- timeStamp(&outLog);
- outLog << "Ensure that your SSL is setup correctly" << endl;
-
- goto exit;
- }
-
- SyncPasswords();
-
- while(isRunning)
- {
- if(passInfoList.empty())
- {
- if(logLevel > 0) {
- timeStamp(&outLog);
- outLog << "Password list is empty. Waiting for passhook event" << endl;
- }
- WaitForSingleObject(passhookEventHandle, INFINITE);
- if(logLevel > 0) {
- timeStamp(&outLog);
- outLog << "Received passhook event. Attempting sync" << endl;
- }
- }
- else
- {
- if(logLevel > 0) {
- timeStamp(&outLog);
- outLog << "Backing off for " << BackoffTime(GetMinBackoff()) << "ms" << endl;
- }
- WaitForSingleObject(passhookEventHandle, BackoffTime(GetMinBackoff()));
- if(logLevel > 0) {
- timeStamp(&outLog);
- outLog << "Backoff time expired. Attempting sync" << endl;
- }
- }
-
- SyncPasswords();
- UpdateBackoff();
-
- ResetEvent(passhookEventHandle);
- }
-
- if(passInfoList.size() > 0)
- {
- if(saveSet(&passInfoList, dataFilename) == 0)
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << passInfoList.size() << " entries saved to data file" << endl;
- }
- }
- else
- {
- timeStamp(&outLog);
- outLog << "Failed to save entries to data file" << endl;
- }
- }
-
-exit:
- CloseHandle(passhookEventHandle);
-}
-
-// ****************************************************************
-// PassSyncService::SyncPasswords
-// ****************************************************************
-int PassSyncService::SyncPasswords()
-{
- int result = 0;
- PASS_INFO_LIST emptyPassInfoList;
- PASS_INFO_LIST_ITERATOR currentPassInfo;
- PASS_INFO_LIST_ITERATOR tempPassInfo;
- char* dn;
- int tempSize = passInfoList.size();
-
- if(loadSet(&passInfoList, dataFilename) == 0)
- {
- if((passInfoList.size() - tempSize) > 0)
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << passInfoList.size() - tempSize << " new entries loaded from data file" << endl;
- }
-
- if(saveSet(&emptyPassInfoList, dataFilename) == 0)
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Cleared contents of data file" << endl;
- }
- }
- else
- {
- timeStamp(&outLog);
- outLog << "Failed to clear contents of data file" << endl;
- }
- }
- }
- else
- {
- timeStamp(&outLog);
- outLog << "Failed to load entries from file" << endl;
- }
-
- if(passInfoList.size() > 0)
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Password list has " << passInfoList.size() << " entries" << endl;
- }
- }
-
- if(Connect(&mainLdapConnection, ldapAuthUsername, ldapAuthPassword) < 0)
- {
- // log connection failure.
- timeStamp(&outLog);
- outLog << "Can not connect to ldap server in SyncPasswords" << endl;
-
- goto exit;
- }
-
- currentPassInfo = passInfoList.begin();
- while(currentPassInfo != passInfoList.end())
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Attempting to sync password for " << currentPassInfo->username << endl;
- }
-
- if(QueryUsername(currentPassInfo->username) == 0)
- {
- while((dn = GetDN()) != NULL)
- {
- if(FutureOccurrence(currentPassInfo))
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Newer password changes for " << currentPassInfo->username << " exist" << endl;
- }
- }
- else if(MultipleResults() && !SYNCSERV_ALLOW_MULTI_MOD)
- {
- timeStamp(&outLog);
- outLog << "Multiple results not allowed: " << currentPassInfo->username << endl;
- }
- else if(CanBind(dn, currentPassInfo->password))
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Password match, no modify performed: " << currentPassInfo->username << endl;
- }
- }
- else if(ModifyPassword(dn, currentPassInfo->password) != 0)
- {
- // log modify failure.
- timeStamp(&outLog);
- outLog << "Modify password failed for remote entry: " << dn << endl;
- // defer this change for later
- timeStamp(&outLog);
- outLog << "Deferring password change for " << currentPassInfo->username << endl;
- currentPassInfo++;
- continue;
- }
- else
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Password modified for remote entry: " << dn << endl;
- }
- }
- tempPassInfo = currentPassInfo;
- currentPassInfo++;
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Removing password change from list" << endl;
- }
- passInfoList.erase(tempPassInfo);
- }
- }
- else
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Deferring password change for " << currentPassInfo->username << endl;
- }
- currentPassInfo++;
- }
- }
-
-exit:
- if(mainLdapConnection != NULL)
- {
- Disconnect(&mainLdapConnection);
- }
-
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::Connect
-// ****************************************************************
-int PassSyncService::Connect(LDAP** connection, char* dn, char* auth)
-{
- int result = 0;
-
- *connection = ldapssl_init(ldapHostName, atoi(ldapHostPort), 1);
-
- if(*connection == NULL)
- {
- timeStamp(&outLog);
- outLog << "ldapssl_init failed in Connect" << endl;
-
- result = -1;
- goto exit;
- }
-
- lastLdapError = ldap_simple_bind_s(*connection, dn, auth);
-
- if(lastLdapError != LDAP_SUCCESS)
- {
- // Log error if we're binding as ldapAuthUsername
- if(strcmp(dn, ldapAuthUsername) == 0)
- {
- timeStamp(&outLog);
- outLog << "Ldap bind error in Connect" << endl;
- outLog << "\t" << lastLdapError << ": " << ldap_err2string(lastLdapError) << endl;
- }
-
- result = -1;
- goto exit;
- }
-
-exit:
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::Disconnect
-// ****************************************************************
-int PassSyncService::Disconnect(LDAP** connection)
-{
- ldap_unbind(*connection);
-
- *connection = NULL;
-
- return 0;
-}
-
-// ****************************************************************
-// PassSyncService::QueryUsername
-// ****************************************************************
-int PassSyncService::QueryUsername(char* username)
-{
- int result = 0;
- char searchFilter[SYNCSERV_BUF_SIZE];
-
- results = NULL;
-
- _snprintf(searchFilter, SYNCSERV_BUF_SIZE, "(%s=%s)", ldapUsernameField, username);
-
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "Searching for (" << ldapUsernameField << "=" << username << ")" << endl;
- }
-
- lastLdapError = ldap_search_ext_s(mainLdapConnection, ldapSearchBase, LDAP_SCOPE_SUBTREE, searchFilter, NULL, 0, NULL, NULL, NULL, -1, &results);
-
- if(lastLdapError != LDAP_SUCCESS)
- {
- // log reason for search failure.
- timeStamp(&outLog);
- outLog << "Ldap error in QueryUsername" << endl;
- outLog << "\t" << lastLdapError << ": " << ldap_err2string(lastLdapError) << endl;
- result = -1;
- goto exit;
- }
-
- if(ldap_first_entry(mainLdapConnection, results) == NULL)
- {
- if(logLevel > 0)
- {
- timeStamp(&outLog);
- outLog << "There are no entries that match: " << username << endl;
- }
- result = -1;
- goto exit;
- }
-
-exit:
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::GetDN
-// ****************************************************************
-char* PassSyncService::GetDN()
-{
- char* result = NULL;
-
- if(currentResult == NULL)
- {
- currentResult = ldap_first_entry(mainLdapConnection, results);
- }
- else
- {
- currentResult = ldap_next_entry(mainLdapConnection, currentResult);
- }
-
- result = ldap_get_dn(mainLdapConnection, currentResult);
-
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::ModifyPassword
-// ****************************************************************
-int PassSyncService::ModifyPassword(char* dn, char* password)
-{
- int result = 0;
- LDAPMod passMod;
- LDAPMod* mods[2] = {&passMod, NULL};
- char* modValues[2] = {password, NULL};
-
- passMod.mod_type = ldapPasswordField;
- passMod.mod_op = LDAP_MOD_REPLACE;
- passMod.mod_values = modValues;
-
- lastLdapError = ldap_modify_ext_s(mainLdapConnection, dn, mods, NULL, NULL);
- if(lastLdapError != LDAP_SUCCESS)
- {
- // log reason for modify failure.
- timeStamp(&outLog);
- outLog << "Ldap error in ModifyPassword" << endl;
- outLog << "\t" << lastLdapError << ": " << ldap_err2string(lastLdapError) << endl;
- result = -1;
- }
-
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::FutureOccurrence
-// ****************************************************************
-bool PassSyncService::FutureOccurrence(PASS_INFO_LIST_ITERATOR startingPassInfo)
-{
- bool result = false;
- PASS_INFO_LIST_ITERATOR currentPassInfo;
-
- if((startingPassInfo != NULL) && (startingPassInfo != passInfoList.end()))
- {
- currentPassInfo = startingPassInfo;
- currentPassInfo++;
-
- while((currentPassInfo != passInfoList.end()) && (!result))
- {
- if(strcmp(currentPassInfo->username, startingPassInfo->username) == 0)
- {
- result = true;
- }
-
- currentPassInfo++;
- }
- }
-
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::MultipleResults
-// ****************************************************************
-bool PassSyncService::MultipleResults()
-{
- bool result = false;
-
- if(ldap_next_entry(mainLdapConnection, ldap_first_entry(mainLdapConnection, results)) != NULL)
- {
- result = true;
- }
-
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::CanBind
-// ****************************************************************
-bool PassSyncService::CanBind(char* dn, char* password)
-{
- bool result;
- LDAP* tempConnection = NULL;
-
- if(Connect(&tempConnection, dn, password) == 0)
- {
- result = true;
- }
- else
- {
- result = false;
- }
-
- if(tempConnection != NULL)
- {
- Disconnect(&tempConnection);
- }
-
- return result;
-}
-
-// ****************************************************************
-// PassSyncService::BackoffTime
-// ****************************************************************
-unsigned long PassSyncService::BackoffTime(int backoff)
-{
- unsigned long backoffTime = 0;
-
- if(backoff > 0)
- {
- backoffTime = (1 << backoff) * SYNCSERV_BASE_BACKOFF_LEN;
- }
-
- return backoffTime;
-}
-
-// ****************************************************************
-// PassSyncService::UpdateBackoff
-// ****************************************************************
-void PassSyncService::UpdateBackoff()
-{
- PASS_INFO_LIST_ITERATOR currentPassInfo;
- PASS_INFO_LIST_ITERATOR tempPassInfo;
- time_t currentTime;
-
- time(&currentTime);
-
- currentPassInfo = passInfoList.begin();
- while(currentPassInfo != passInfoList.end())
- {
- if(((unsigned long)currentPassInfo->atTime + (BackoffTime(currentPassInfo->backoffCount) / 1000)) <= (unsigned long)currentTime)
- {
- currentPassInfo->backoffCount++;
- }
-
- if(((unsigned long)currentTime - (unsigned long)currentPassInfo->atTime) > (maxBackoffTime / 1000))
- {
- timeStamp(&outLog);
- outLog << "Abandoning password change for " << currentPassInfo->username << ", backoff expired" << endl;
-
- tempPassInfo = currentPassInfo;
- currentPassInfo++;
- passInfoList.erase(tempPassInfo);
- }
- else
- {
- currentPassInfo++;
- }
- }
-}
-
-// ****************************************************************
-// PassSyncService::GetMinBackoff
-// ****************************************************************
-int PassSyncService::GetMinBackoff()
-{
- PASS_INFO_LIST_ITERATOR currentPassInfo;
-
- unsigned long minBackoff = INFINITE;
-
- for(currentPassInfo = passInfoList.begin(); currentPassInfo != passInfoList.end(); currentPassInfo++)
- {
- if((unsigned long)currentPassInfo->backoffCount < minBackoff)
- {
- minBackoff = currentPassInfo->backoffCount;
- }
- }
-
- return minBackoff;
-}