| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357 |
- // Created: 2-8-2005
- // Author(s): Scott Bridges
- #include "syncserv.h"
- #include "prerror.h"
- static char* certdbh;
- 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", ®Key);
- 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(const TCHAR *serviceName) : CNTService(serviceName)
- {
- char sysPath[SYNCSERV_BUF_SIZE];
- HKEY regKey;
- DWORD type;
- unsigned long size;
- passhookEventHandle = CreateEvent(NULL, FALSE, FALSE, PASSHAND_EVENT_NAME);
- pLdapConnection = NULL;
- results = NULL;
- currentResult = NULL;
- lastLdapError = LDAP_SUCCESS;
- certdbh = NULL;
- multipleModify = SYNCSERV_ALLOW_MULTI_MOD;
- isRunning = false;
- RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\PasswordSync", ®Key);
- 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 << "begin log" << endl;
- }
- PK11_SetPasswordFunc(passwdcb);
- }
- PassSyncService::~PassSyncService()
- {
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "end log" << endl;
- }
- outLog.close();
- }
- int PassSyncService::SyncPasswords()
- {
- int result = 0;
- char username[PASSHAND_BUF_SIZE];
- char password[PASSHAND_BUF_SIZE];
- char* dn;
- if(Connect() < 0)
- {
- // ToDo: generate event connection failure.
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "can not connect to ldap server in SyncPasswords" << endl;
- }
- result = -1;
- goto exit;
- }
- ourPasswordHandler.LoadSet(dataFilename);
- while(ourPasswordHandler.PeekUserPass(username, password) == 0)
- {
- if(QueryUsername(username) != 0)
- {
- // ToDo: generate event search failure.
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "search for " << username << " failed in SyncPasswords" << endl;
- }
- }
- else
- {
- while((dn = GetDN()) != NULL)
- {
- if(ModifyPassword(dn, password) != 0)
- {
- // ToDo: generate event modify failure.
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "modify password for " << username << " failed in SyncPasswords" << endl;
- }
- }
- else
- {
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "password for " << username << " modified" << endl;
- outLog << "\t" << dn << endl;
- }
- }
- }
- }
- // ToDo: zero out buffers
- ourPasswordHandler.PopUserPass();
- }
- ourPasswordHandler.SaveSet(dataFilename);
- Disconnect();
- exit:
- return result;
- }
- void PassSyncService::OnStop()
- {
- isRunning = false;
- SetEvent(passhookEventHandle);
- }
- void PassSyncService::OnShutdown()
- {
- isRunning = false;
- SetEvent(passhookEventHandle);
- }
- void PassSyncService::Run()
- {
- isRunning = true;
- SyncPasswords();
- while(isRunning)
- {
- WaitForSingleObject(passhookEventHandle, INFINITE);
- SyncPasswords();
- ResetEvent(passhookEventHandle);
- }
- }
- int PassSyncService::Connect()
- {
- int result = 0;
- if(ldapssl_client_init(certPath, &certdbh) != 0)
- {
- result = PR_GetError();
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "ldapssl_client_init failed in Connect" << endl;
- outLog << "\t" << result << ": " << ldapssl_err2string(result) << endl;
- }
- result = GetLastError();
- result = -1;
- goto exit;
- }
- pLdapConnection = ldapssl_init(ldapHostName, atoi(ldapHostPort), 1);
- if(pLdapConnection == NULL)
- {
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "ldapssl_init failed in Connect" << endl;
- }
- result = -1;
- goto exit;
- }
- lastLdapError = ldap_simple_bind_s(pLdapConnection, ldapAuthUsername, ldapAuthPassword);
- if(lastLdapError != LDAP_SUCCESS)
- {
- // ToDo: log reason for bind failure.
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "ldap error in Connect" << endl;
- outLog << "\t" << lastLdapError << ": " << ldapssl_err2string(lastLdapError) << endl;
- }
- result = -1;
- goto exit;
- }
- exit:
- return result;
- }
- int PassSyncService::Disconnect()
- {
- ldap_unbind(pLdapConnection);
- pLdapConnection = NULL;
- return 0;
- }
- int PassSyncService::QueryUsername(char* username)
- {
- int result = 0;
- char searchFilter[SYNCSERV_BUF_SIZE];
- results = NULL;
- _snprintf(searchFilter, SYNCSERV_BUF_SIZE, "(%s=%s)", ldapUsernameField, username);
- lastLdapError = ldap_search_ext_s(
- pLdapConnection,
- ldapSearchBase,
- LDAP_SCOPE_ONELEVEL,
- searchFilter,
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- -1,
- &results);
- if(lastLdapError != LDAP_SUCCESS)
- {
- // ToDo: log reason for search failure.
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "ldap error in QueryUsername" << endl;
- outLog << "\t" << lastLdapError << ": " << ldapssl_err2string(lastLdapError) << endl;
- }
- result = -1;
- goto exit;
- }
- exit:
- return result;
- }
- char* PassSyncService::GetDN()
- {
- char* result = NULL;
- if(multipleModify)
- {
- if(currentResult == NULL)
- {
- currentResult = ldap_first_entry(pLdapConnection, results);
- }
- else
- {
- currentResult = ldap_next_entry(pLdapConnection, currentResult);
- }
- result = ldap_get_dn(pLdapConnection, currentResult);
- }
- else
- {
- if(currentResult == NULL)
- {
- currentResult = ldap_first_entry(pLdapConnection, results);
- if(ldap_next_entry(pLdapConnection, currentResult) != NULLMSG)
- {
- // Too many results
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "too many results in GetDN" << endl;
- }
- currentResult = NULL;
- goto exit;
- }
- result = ldap_get_dn(pLdapConnection, currentResult);
- }
- else
- {
- currentResult = NULL;
- goto exit;
- }
- }
- exit:
- return result;
- }
- 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(pLdapConnection, dn, mods, NULL, NULL);
- if(lastLdapError != LDAP_SUCCESS)
- {
- // ToDo: log the reason for the modify failure.
- if(outLog.is_open())
- {
- timeStamp(&outLog);
- outLog << "ldap error in ModifyPassword" << endl;
- outLog << "\t" << lastLdapError << ": " << ldapssl_err2string(lastLdapError) << endl;
- }
- result = -1;
- }
- return result;
- }
|