Browse Source

Merge password sync code from Bozeman Pass

David Boreham 20 years ago
parent
commit
bd1ac5b306
45 changed files with 1323 additions and 325 deletions
  1. 21 0
      ldap/synctools/Makefile
  2. 11 2
      ldap/synctools/passwordsync/README.txt
  3. 73 18
      ldap/synctools/passwordsync/build.bat
  4. 354 55
      ldap/synctools/passwordsync/passhand.cpp
  5. 17 13
      ldap/synctools/passwordsync/passhand.h
  6. 34 19
      ldap/synctools/passwordsync/passhook/passhook.cpp
  7. 0 4
      ldap/synctools/passwordsync/passhook/passhook.def
  8. 0 5
      ldap/synctools/passwordsync/passhook/passhook.dep
  9. 2 6
      ldap/synctools/passwordsync/passhook/passhook.dsp
  10. 1 6
      ldap/synctools/passwordsync/passhook/passhook.mak
  11. 0 4
      ldap/synctools/passwordsync/passsync.dsw
  12. BIN
      ldap/synctools/passwordsync/passsync.ncb
  13. BIN
      ldap/synctools/passwordsync/passsync.opt
  14. BIN
      ldap/synctools/passwordsync/passsync/MSG00001.bin
  15. 5 3
      ldap/synctools/passwordsync/passsync/dssynch.h
  16. 0 4
      ldap/synctools/passwordsync/passsync/dssynchmsg.h
  17. 379 0
      ldap/synctools/passwordsync/passsync/dssynchmsg.mc
  18. 2 0
      ldap/synctools/passwordsync/passsync/dssynchmsg.rc
  19. 8 6
      ldap/synctools/passwordsync/passsync/ntservice.cpp
  20. 4 3
      ldap/synctools/passwordsync/passsync/ntservice.h
  21. 0 5
      ldap/synctools/passwordsync/passsync/passsync.dep
  22. 5 5
      ldap/synctools/passwordsync/passsync/passsync.dsp
  23. 1 5
      ldap/synctools/passwordsync/passsync/passsync.mak
  24. 67 0
      ldap/synctools/passwordsync/passsync/passsync.rc
  25. 15 0
      ldap/synctools/passwordsync/passsync/resource.h
  26. 1 6
      ldap/synctools/passwordsync/passsync/service.cpp
  27. 1 6
      ldap/synctools/passwordsync/passsync/subuniutil.cpp
  28. 0 5
      ldap/synctools/passwordsync/passsync/subuniutil.h
  29. 3 2
      ldap/synctools/passwordsync/passsync/synchcmds.h
  30. 212 96
      ldap/synctools/passwordsync/passsync/syncserv.cpp
  31. 27 25
      ldap/synctools/passwordsync/passsync/syncserv.h
  32. BIN
      ldap/synctools/passwordsync/wix/Binary/Banner.bmp
  33. BIN
      ldap/synctools/passwordsync/wix/Binary/Complete.ico
  34. BIN
      ldap/synctools/passwordsync/wix/Binary/Custom.ico
  35. BIN
      ldap/synctools/passwordsync/wix/Binary/Dialog.bmp
  36. BIN
      ldap/synctools/passwordsync/wix/Binary/Exclam.ico
  37. BIN
      ldap/synctools/passwordsync/wix/Binary/Info.ico
  38. BIN
      ldap/synctools/passwordsync/wix/Binary/License.rtf
  39. BIN
      ldap/synctools/passwordsync/wix/Binary/New.ico
  40. BIN
      ldap/synctools/passwordsync/wix/Binary/Remove.ico
  41. BIN
      ldap/synctools/passwordsync/wix/Binary/Repair.ico
  42. BIN
      ldap/synctools/passwordsync/wix/Binary/Typical.ico
  43. BIN
      ldap/synctools/passwordsync/wix/Binary/Up.ico
  44. 69 20
      ldap/synctools/passwordsync/wix/PassSync.wxs
  45. 11 2
      ldap/synctools/passwordsync/wix/README.txt

+ 21 - 0
ldap/synctools/Makefile

@@ -0,0 +1,21 @@
+#
+# BEGIN COPYRIGHT BLOCK
+# Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+# Copyright (C) 2005 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+#
+
+# GNU Makefile for Directory Server and Ldap SDK
+#
+BUILD_ROOT = ../../
+include $(BUILD_ROOT)/nsdefs.mk
+include $(BUILD_ROOT)/nsconfig.mk
+
+all: passsync
+
+passsync:
+ifeq ($(ARCH), WINNT)
+	# Do not allow MAKEFLAGS or other environment variables to influence nmake.
+	cd passwordsync; env -i PATH="${PATH}" LIB="${LIB}" INCLUDE="${INCLUDE}" BUILD_DEBUG=${BUILD_DEBUG} build.bat
+endif

+ 11 - 2
ldap/synctools/passwordsync/README.txt

@@ -1,2 +1,11 @@
-1. Download Wix and unzip into Wix folder.
-2. run build.bat.
+1. Download Wix (http://sourceforge.net/projects/wix/) and unzip it into the Wix folder.
+   (steps 2 and 3 can be skipped if ldapserver has been built)
+2. Add the location of the Mozilla LDAP C SDK header files to your INCLUDE path.
+   The LDAP C SDK is a component of the Directory Server and is "pulled"
+   when the Directory Server is built; it can also be obtained individually from Mozilla.
+   e.x. 
+      set INCLUDE=%INCLUDE%;c:\source\dist\WINNT5.0_DBG.OBJ\ldapsdk\include
+3. Add the location of the LDAP C SDK libraries to your LIB path.
+   e.x. 
+      set LIB=%LIB%;c:\source\dist\WINNT5.0_DBG.OBJ\ldapsdk\lib
+4. Run build.bat.

+ 73 - 18
ldap/synctools/passwordsync/build.bat

@@ -1,32 +1,87 @@
-@rem // --- BEGIN COPYRIGHT BLOCK ---
-@rem // Copyright (C) 2005 Red Hat, Inc.
-@rem // All rights reserved.
-@rem // --- END COPYRIGHT BLOCK ---
-
 @echo off
+
+pushd
+
+if NOT [%BUILD_DEBUG%] == [] (
+    if [%BUILD_DEBUG%] == [optimize] (
+        set LIBROOT=..\..\..\..\dist\WINNT5.0_OPT.OBJ
+    ) else (
+        set LIBROOT=..\..\..\..\dist\WINNT5.0_DBG.OBJ
+    )
+)
+
+echo %LIBROOT%
+
+set INCLUDE=%INCLUDE%;%CD%\%LIBROOT%\ldapsdk\include;%CD%\%LIBROOT%\nspr\include;%CD%\%LIBROOT%\nss\include
+set LIB=%LIB%;%CD%\%LIBROOT%\ldapsdk\lib;%CD%\%LIBROOT%\nspr\lib;%CD%\%LIBROOT%\nss\lib
+set PATH=%PATH%;%CD%\%LIBROOT%\wix
+
+set OK=0
+
 cd passsync
+
+:BUILD
 nmake passsync.mak
-copy Debug\passsync.exe ..\Wix
+set /a OK=%OK% + %ERRORLEVEL%
+
+copy /Y Debug\passsync.exe ..\Wix
+set /a OK=%OK% + %ERRORLEVEL%
+
 cd ..\passhook
+
 nmake passhook.mak
-copy Debug\passhook.dll ..\Wix
+set /a OK=%OK% + %ERRORLEVEL%
 
-if EXIST ..\Wix (goto :WIX)
+copy /Y Debug\passhook.dll ..\Wix
+set /a OK=%OK% + %ERRORLEVEL%
 
-goto :EOF
-:WIX
+:PKG
+if NOT EXIST ..\Wix (
+    echo ERROR: Cannot find Wix folder.
+    set OK=1 
+    goto :END )
 
 cd ..\Wix
-if NOT EXIST candle.exe ( 
-	echo ERROR: Wix not properly installed.  See readme.
-	pause
-	exit 1 )
 
-if NOT EXIST light.exe ( 
-	echo ERROR: Wix not properly installed.  See readme.
-	pause
-	exit 1 )
+if EXIST ..\%LIBROOT%\ldapsdk\lib\nsldap32v50.dll (
+    copy /Y ..\%LIBROOT%\ldapsdk\lib\nsldap32v50.dll
+)
+if EXIST ..\%LIBROOT%\ldapsdk\lib\nsldapssl32v50.dll (
+    copy /Y ..\%LIBROOT%\ldapsdk\lib\nsldapssl32v50.dll
+)
+if EXIST ..\%LIBROOT%\ldapsdk\lib\nsldappr32v50.dll (
+    copy /Y ..\%LIBROOT%\ldapsdk\lib\nsldappr32v50.dll
+)
+if EXIST ..\%LIBROOT%\nspr\lib\libnspr4.dll (
+    copy /Y ..\%LIBROOT%\nspr\lib\libnspr4.dll
+)
+if EXIST ..\%LIBROOT%\nspr\lib\libplds4.dll (
+    copy /Y ..\%LIBROOT%\nspr\lib\libplds4.dll
+)
+if EXIST ..\%LIBROOT%\nspr\lib\libplc4.dll (
+    copy /Y ..\%LIBROOT%\nspr\lib\libplc4.dll
+)
+if EXIST ..\%LIBROOT%\nss\lib\nss3.dll (
+    copy /Y ..\%LIBROOT%\nss\lib\nss3.dll
+)
+if EXIST ..\%LIBROOT%\nss\lib\ssl3.dll (
+    copy /Y ..\%LIBROOT%\nss\lib\ssl3.dll
+)
+if EXIST ..\%LIBROOT%\nss\lib\softokn3.dll (
+    copy /Y ..\%LIBROOT%\nss\lib\softokn3.dll
+)
 
 candle PassSync.wxs
+set /a OK=%OK% + %ERRORLEVEL%
+
 light PassSync.wixobj
+set /a OK=%OK% + %ERRORLEVEL%
+
+if NOT [%BUILD_DEBUG%] == [] (
+    if EXIST PassSync.msi (move /Y PassSync.msi PassSync-%BUILD_DEBUG%.msi)
+)
 
+:END
+popd
+if %OK% GTR 1 (set OK=1)
+exit %OK%

+ 354 - 55
ldap/synctools/passwordsync/passhand.cpp

@@ -1,127 +1,426 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// Copyright (C) 2005 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
 // Created: 2-8-2005
 // Author(s): Scott Bridges
 #include "passhand.h"
+#include <time.h>
+
+#define KEY {0xe8, 0xa7, 0x7c, 0xe2, 0x05, 0x63, 0x6a, 0x31}
+#define IV {0xe4, 0xbb, 0x3b, 0xd3, 0xc3, 0x71, 0x2e, 0x58}
+
+void timeStamp(fstream* outFile)
+{
+	if(outFile->is_open())
+	{
+		char dateBuf[32];
+		char timeBuf[32];
+
+		_strdate(dateBuf);
+		_strtime(timeBuf);
+		*outFile << dateBuf << " " << timeBuf << ": ";
+	}
+}
 
 PasswordHandler::PasswordHandler()
 {
+	outLog.open("./passhand.log", ios::out | ios::app);
 }
 
 PasswordHandler::~PasswordHandler()
 {
+	outLog.close();
 }
 
 int PasswordHandler::SaveSet(char* filename)
 {
+	int result = 0;
 	fstream outFile;
 	list<USER_PASS_PAIR>::iterator currentPair;
+	strstream plainTextStream;
+	char* cipherTextBuf;
+	int usernameLen;
+	int passwordLen;
+	int plainTextLen;
+	int cipherTextLen;
+	int resultTextLen = 0;
+	int pairCount = userPassPairs.size();
 
-	outFile.open(filename, ios::out | ios::binary);
-
-	if(!outFile.is_open())
+	if(outLog.is_open())
 	{
-		return -1;
+		timeStamp(&outLog);
+		outLog << "SaveSet: saving " << userPassPairs.size() << " entries to file" << endl;
 	}
 
+	// Write usernames and passwords to a strstream
+	plainTextStream.write((char*)&pairCount, sizeof(pairCount));
 	for(currentPair = userPassPairs.begin(); currentPair != userPassPairs.end(); currentPair++)
 	{
-		outFile.write((char*)&currentPair->username.Length, sizeof(currentPair->username.Length));
-		outFile.write((char*)currentPair->username.Buffer, currentPair->username.Length);
+		// Usernames
+		usernameLen = strlen(currentPair->username) + 1;
+		plainTextStream.write((char*)&usernameLen, sizeof(usernameLen));
+		plainTextStream.write(currentPair->username, usernameLen);
+		
+		// Passwords
+		passwordLen = strlen(currentPair->password) + 1;
+		plainTextStream.write((char*)&passwordLen, sizeof(passwordLen));
+		plainTextStream.write(currentPair->password, passwordLen);
+	}
+
+
+	plainTextLen = plainTextStream.tellp() - plainTextStream.tellg();
+	// cipherTextBuf length must be at least plainTextLen + 8
+	cipherTextLen = plainTextLen + 8;
+
+	cipherTextBuf = (char*)malloc(cipherTextLen);
 
-		outFile.write((char*)&currentPair->password.Length, sizeof(currentPair->password.Length));
-		outFile.write((char*)currentPair->password.Buffer, currentPair->password.Length);
+	if(encrypt(plainTextStream.str(), plainTextLen, cipherTextBuf, cipherTextLen, &resultTextLen) != 0)
+	{
+		result = -1;
+		goto exit;
 	}
 
-	// ToDo: Zero out memory.
+	// Write cipher text to file
+	outFile.open(filename, ios::out | ios::binary);
+	if(!outFile.is_open())
+	{
+		result = -1;
+		goto exit;
+	}
+	outFile.write(cipherTextBuf, resultTextLen);
+	outFile.close();
+
+	// ToDo: zero out memory
+
 	userPassPairs.clear();
 
-	return 0;
+exit:
+	return result;
 }
 
 int PasswordHandler::LoadSet(char* filename)
 {
+	int result = 0;
+	int i;
 	fstream inFile;
 	USER_PASS_PAIR newPair;
-	
-	inFile.open(filename, ios::in | ios::binary);
+	strstream* plainTextStream;
+	char* cipherTextBuf;
+	char* plainTextBuf;
+	int usernameLen;
+	int passwordLen;
+	int plainTextLen;
+	int cipherTextLen;
+	int resultTextLen = 0;
+	int pairCount;
 
+	// Read in cipher text from file
+	inFile.open(filename, ios::in | ios::binary);
 	if(!inFile.is_open())
 	{
-		return -1;
+		result = -1;
+		goto exit;
 	}
+	// Determine file size
+	inFile.seekg(0, ios::end);
+	cipherTextLen = inFile.tellg();
+	inFile.seekg(0, ios::beg);
+	// plainTextLen length must be at least cipherTextLen
+	plainTextLen = cipherTextLen;
+
+	cipherTextBuf = (char*)malloc(cipherTextLen);
+	plainTextBuf = (char*)malloc(plainTextLen);
 
-	while(!inFile.eof())
+	inFile.read(cipherTextBuf, cipherTextLen);
+	inFile.close();
+
+	if(decrypt(cipherTextBuf, cipherTextLen, plainTextBuf, plainTextLen, &resultTextLen) != 0)
 	{
-		inFile.read((char*)&newPair.username.Length, sizeof(newPair.username.Length));
-		newPair.username.Buffer = (unsigned short*)malloc(newPair.username.Length);
-		inFile.read((char*)newPair.username.Buffer, newPair.username.Length);
-		newPair.username.MaximumLength = newPair.username.Length;
+		result = -1;
+		goto exit;
+	}
 
-		inFile.read((char*)&newPair.password.Length, sizeof(newPair.password.Length));
-		newPair.password.Buffer = (unsigned short*)malloc(newPair.password.Length);
-		inFile.read((char*)newPair.password.Buffer, newPair.password.Length);
-		newPair.password.MaximumLength = newPair.password.Length;
+	plainTextStream = new strstream(plainTextBuf, resultTextLen);
 
-		if(!inFile.eof())
-		{
-			userPassPairs.push_back(newPair);
-		}
+	plainTextStream->read((char*)&pairCount, sizeof(pairCount));
+
+	// Read usernames and passwords from a strstream
+	for(i = 0; i < pairCount; i++)
+	{
+		// Username
+		plainTextStream->read((char*)&usernameLen, sizeof(usernameLen));
+		newPair.username = (char*)malloc(usernameLen);
+		plainTextStream->read((char*)newPair.username, usernameLen);
+
+		// Password
+		plainTextStream->read((char*)&passwordLen, sizeof(passwordLen));
+		newPair.password = (char*)malloc(passwordLen);
+		plainTextStream->read((char*)newPair.password, passwordLen);
+
+		userPassPairs.push_back(newPair);
 	}
 
-	return 0;
+	delete plainTextStream;
+
+	if(outLog.is_open())
+	{
+		timeStamp(&outLog);
+		outLog << "LoadSet: "<< userPassPairs.size() << " entries loaded from file" << endl;
+	}
+
+exit:
+	return result;
 }
 
-int PasswordHandler::PushUserPass(PUNICODE_STRING username, PUNICODE_STRING password)
+int PasswordHandler::PushUserPass(char* username, char* password)
 {
 	USER_PASS_PAIR newPair;
 
-	newPair.username.Length = username->Length;
-	newPair.username.Buffer = (unsigned short*)malloc(username->Length);
-	memcpy(newPair.username.Buffer, username->Buffer, username->Length);
-	newPair.username.MaximumLength = newPair.username.Length;
+	newPair.username = (char*)malloc(strlen(username) + 1);
+	strcpy(newPair.username, username);
 
-	newPair.password.Length = password->Length;
-	newPair.password.Buffer = (unsigned short*)malloc(password->Length);
-	memcpy(newPair.password.Buffer, password->Buffer, password->Length);
-	newPair.password.MaximumLength = newPair.password.Length;
+	newPair.password = (char*)malloc(strlen(password) + 1);
+	strcpy(newPair.password, password);
 
 	userPassPairs.push_back(newPair);
 
+	if(outLog.is_open())
+	{
+		timeStamp(&outLog);
+		outLog << "PushUserPass: pushed user password pair, new length " << userPassPairs.size() << endl;
+	}
+
 	return 0;
 }
 
-int PasswordHandler::PeekUserPass(PUNICODE_STRING username, PUNICODE_STRING password)
+int PasswordHandler::PeekUserPass(char* username, char* password)
 {
+	int result = 0;
 	list<USER_PASS_PAIR>::iterator currentPair;
 
-	if(userPassPairs.size() == 0)
+	if(userPassPairs.size() < 1)
 	{
-		return -1;
+		result = -1;
+		goto exit;
 	}
 
 	currentPair = userPassPairs.begin();
+	strcpy(username, currentPair->username);
+	strcpy(password, currentPair->password);
 
-	username->Length = currentPair->username.Length;
-	username->Buffer = (unsigned short*)malloc(username->Length);
-	memcpy(username->Buffer, currentPair->username.Buffer, username->Length);
-	username->MaximumLength = username->Length;
-
-	password->Length = currentPair->password.Length;
-	password->Buffer = (unsigned short*)malloc(password->Length);
-	memcpy(password->Buffer, currentPair->password.Buffer, password->Length);
-	password->MaximumLength = password->Length;
+	if(outLog.is_open())
+	{
+		timeStamp(&outLog);
+		outLog << "PeekUserPass: current length " << userPassPairs.size() << endl;
+	}
 
-	return 0;
+exit:
+	return result;
 }
 
 int PasswordHandler::PopUserPass()
 {
-	// ToDo: Zero out memory.
+	// ToDo: zero out memory.
+
 	userPassPairs.pop_front();
 
+	if(outLog.is_open())
+	{
+		timeStamp(&outLog);
+		outLog << "PopUserPass: popped user password pair, new length " << userPassPairs.size() << endl;
+	}
+
 	return 0;
 }
+
+
+int PasswordHandler::encrypt(char* plainTextBuf, int plainTextLen, char* cipherTextBuf, int cipherTextLen, int* resultTextLen)
+{
+	int result = 0;
+	SECStatus rv1, rv2, rv3;
+	PK11SlotInfo* slot = NULL;
+	PK11SymKey* SymKey = NULL;
+	SECItem* SecParam = NULL;
+	PK11Context* EncContext = NULL;
+	unsigned char gKey[] = KEY;
+	unsigned char gIV[] = IV;
+	PK11SymKey* key = NULL;
+	SECItem keyItem;
+	SECItem	ivItem;
+	CK_MECHANISM_TYPE cipherMech = CKM_DES_CBC_PAD;
+	int offset;
+	int tempTextLen;
+
+	// Initialize NSS
+	rv1 = NSS_NoDB_Init(".");
+	if(rv1 != SECSuccess)
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// Get a key slot
+	slot = PK11_GetInternalKeySlot();
+	if(slot == NULL)
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// Generate a symmetric key
+	keyItem.data = gKey;
+	keyItem.len = sizeof(gKey);
+	SymKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL);
+	if(SymKey == NULL)
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// Set up the PKCS11 encryption paramters
+	ivItem.data = gIV;
+	ivItem.len = sizeof(gIV);
+	SecParam = PK11_ParamFromIV(cipherMech, &ivItem);
+	if(SecParam == NULL)
+	{
+		if(SymKey != NULL)
+		{
+			PK11_FreeSymKey(SymKey);
+		}
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// ToDo: check parameters
+
+
+	// Encrypt
+	tempTextLen = 0;
+	EncContext = PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT, SymKey, SecParam);
+	rv2 = PK11_CipherOp(EncContext, (unsigned char*)cipherTextBuf, &tempTextLen, cipherTextLen, (unsigned char*)plainTextBuf, plainTextLen);
+	offset = tempTextLen;
+	rv3 = PK11_DigestFinal(EncContext, (unsigned char*)cipherTextBuf + offset, (unsigned int*)&tempTextLen, cipherTextLen - offset);
+	*resultTextLen = offset + tempTextLen;
+
+	// Clean up
+	PK11_DestroyContext(EncContext, PR_TRUE);
+	PK11_FreeSymKey(SymKey);
+	SECITEM_FreeItem(SecParam, PR_TRUE);
+
+	if((rv2 != SECSuccess) || (rv2 != SECSuccess))
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+exit:
+	if(outLog.is_open())
+	{
+		if(result == 0)
+		{
+			timeStamp(&outLog);
+			outLog << "encrypt: success" << endl;
+		}
+		else
+		{
+			timeStamp(&outLog);
+			outLog << "encrypt: failure" << endl;
+		}
+	}
+
+	return result;
+}
+
+int PasswordHandler::decrypt(char* cipherTextBuf, int cipherTextLen, char* plainTextBuf, int plainTextLen, int* resultTextLen)
+{
+	int result = 0;
+	SECStatus rv1, rv2, rv3;
+	PK11SlotInfo* slot = NULL;
+	PK11SymKey* SymKey = NULL;
+	SECItem* SecParam = NULL;
+	PK11Context* EncContext = NULL;
+	unsigned char gKey[] = KEY;
+	unsigned char gIV[] = IV;
+	PK11SymKey* key = NULL;
+	SECItem keyItem;
+	SECItem	ivItem;
+	CK_MECHANISM_TYPE cipherMech = CKM_DES_CBC_PAD;
+	int offset;
+	int tempTextLen;
+
+	// Initialize NSS
+	rv1 = NSS_NoDB_Init(".");
+	if(rv1 != SECSuccess)
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// Get a key slot
+	slot = PK11_GetInternalKeySlot();
+	if(slot == NULL)
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// Generate a symmetric key
+	keyItem.data = gKey;
+	keyItem.len = sizeof(gKey);
+	SymKey = PK11_ImportSymKey(slot, cipherMech, PK11_OriginUnwrap, CKA_ENCRYPT, &keyItem, NULL);
+	if(SymKey == NULL)
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// Set up the PKCS11 encryption paramters
+	ivItem.data = gIV;
+	ivItem.len = sizeof(gIV);
+	SecParam = PK11_ParamFromIV(cipherMech, &ivItem);
+	if(SecParam == NULL)
+	{
+		if(SymKey != NULL)
+		{
+			PK11_FreeSymKey(SymKey);
+		}
+		result = PR_GetError();
+		goto exit;
+	}
+
+	// ToDo: check parameters
+
+
+	// Decrypt
+	tempTextLen = 0;
+	EncContext = PK11_CreateContextBySymKey(cipherMech, CKA_DECRYPT, SymKey, SecParam);
+	rv2 = PK11_CipherOp(EncContext, (unsigned char*)plainTextBuf, &tempTextLen, plainTextLen, (unsigned char*)cipherTextBuf, cipherTextLen);
+	offset = tempTextLen;
+	rv3 = PK11_DigestFinal(EncContext, (unsigned char*)plainTextBuf + offset, (unsigned int*)&tempTextLen, plainTextLen - offset);
+	*resultTextLen = offset + tempTextLen;
+
+	// Clean up
+	PK11_DestroyContext(EncContext, PR_TRUE);
+	PK11_FreeSymKey(SymKey);
+	SECITEM_FreeItem(SecParam, PR_TRUE);
+
+	if((rv2 != SECSuccess) || (rv2 != SECSuccess))
+	{
+		result = PR_GetError();
+		goto exit;
+	}
+
+exit:
+	if(outLog.is_open())
+	{
+		if(result == 0)
+		{
+			timeStamp(&outLog);
+			outLog << "decrypt: success" << endl;
+		}
+		else
+		{
+			timeStamp(&outLog);
+			outLog << "decrypt: failure" << endl;
+		}
+	}
+
+	return result;
+}

+ 17 - 13
ldap/synctools/passwordsync/passhand.h

@@ -1,45 +1,49 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// Copyright (C) 2005 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
 // Created: 2-8-2005
 // Author(s): Scott Bridges
 #ifndef _PASSHAND_H_
 #define _PASSHAND_H_
 
 #include <windows.h>
-#include <ntsecapi.h>
+#include <time.h>
+#include <strstream>
 #include <fstream>
 #include <list>
+#include "nss.h"
+#include "pk11func.h"
+#include "prerror.h"
 
 #define PASSHAND_EVENT_NAME "passhand_event"
 
-#define STRSTREAM_BUF_SIZE 1024
+#define PASSHAND_BUF_SIZE 256
 
 using namespace std;
 
 struct USER_PASS_PAIR
 {
-	UNICODE_STRING username;
-	UNICODE_STRING password;
+	char* username;
+	char* password;
 };
 
+void timeStamp(fstream* outFile);
+
 class PasswordHandler
 {
 public:
 	PasswordHandler();
 	~PasswordHandler();
 
-	//WritePassToStorage(PUNICODE_STRING username, PUNICODE_STRING password);
-	//ReadPassFromStorage(PUNICODE_STRING username, PUNICODE_STRING password);
 	int SaveSet(char* filename);
 	int LoadSet(char* filename);
-	int PushUserPass(PUNICODE_STRING username, PUNICODE_STRING password);
-	int PeekUserPass(PUNICODE_STRING username, PUNICODE_STRING password);
+	int PushUserPass(char* username, char* password);
+	int PeekUserPass(char* username, char* password);
 	int PopUserPass();
 private:
+	int encrypt(char* plainTextBuf, int plainTextLen, char* cipherTextBuf, int cipherTextLen, int* resultTextLen);
+	int decrypt(char* cipherTextBuf, int cipherTextLen, char* plainTextBuf, int plainTextLen, int* resultTextLen);
+
 	list<USER_PASS_PAIR> userPassPairs;
+	char* keyPath;
+	fstream outLog;
 };
 
 #endif

+ 34 - 19
ldap/synctools/passwordsync/passhook/passhook.cpp

@@ -1,47 +1,62 @@
-// --- BEGIN COPYRIGHT BLOCK ---
-// Copyright (C) 2005 Red Hat, Inc.
-// All rights reserved.
-// --- END COPYRIGHT BLOCK ---
-
 // Created: 2-8-2005
 // Author(s): Scott Bridges
 #include <windows.h>
 #include <ntsecapi.h>
-#include  "../passhand.h"
+// Work around for enum redefinition
+// Effects nssILockOp enumeration in nssilckt.h
+#define Unlock Unlock_ntsecapi
+#include "../passhand.h"
 
 #ifndef STATUS_SUCCESS
 #define STATUS_SUCCESS  ((NTSTATUS)0x00000000L)
 #endif
 
-NTSTATUS NTAPI PasswordChangeNotify(
-	PUNICODE_STRING UserName,
-	ULONG RelativeId,
-	PUNICODE_STRING Password)
+NTSTATUS NTAPI PasswordChangeNotify(PUNICODE_STRING UserName, ULONG RelativeId, PUNICODE_STRING Password)
 {
-	PasswordHandler ourPasswordHandler;
+	char singleByteUsername[PASSHAND_BUF_SIZE];
+	char singleBytePassword[PASSHAND_BUF_SIZE];
 	HANDLE passhookEventHandle = OpenEvent(EVENT_MODIFY_STATE, FALSE, PASSHAND_EVENT_NAME);
+	PasswordHandler ourPasswordHandler;
+	fstream outLog;
+
+	outLog.open("passhook.log", ios::out | ios::app);
+
+	_snprintf(singleByteUsername, PASSHAND_BUF_SIZE, "%S", UserName->Buffer);
+	singleByteUsername[UserName->Length / 2] = '\0';
+	_snprintf(singleBytePassword, PASSHAND_BUF_SIZE, "%S", Password->Buffer);
+	singleBytePassword[Password->Length / 2] = '\0';
+
+	if(outLog.is_open())
+	{
+		timeStamp(&outLog);
+		outLog << "user " << singleByteUsername << "(" << UserName->Length / 2 << ") " << "password changed" << endl;
+	}
 
 	ourPasswordHandler.LoadSet("passhook.dat");
-	ourPasswordHandler.PushUserPass(UserName, Password);
+	ourPasswordHandler.PushUserPass(singleByteUsername, singleBytePassword);
 	ourPasswordHandler.SaveSet("passhook.dat");
 
 	if(passhookEventHandle == NULL)
 	{
-		// ToDo: Generate event sync service not running.
+		// ToDo: generate event sync service not running.
+		if(outLog.is_open())
+		{
+			timeStamp(&outLog);
+			outLog << "can not get password sync service event handle, service not running" << endl;
+		}
+
 	}
 	else
 	{
 		SetEvent(passhookEventHandle);
 	}
 
+	outLog.close();
+
 	return STATUS_SUCCESS;
 }
 
-BOOL NTAPI PasswordFilter(
-	PUNICODE_STRING UserName,
-	PUNICODE_STRING FullName,
-	PUNICODE_STRING Password,
-	BOOL SetOperation)
+BOOL NTAPI PasswordFilter(PUNICODE_STRING UserName, PUNICODE_STRING FullName, PUNICODE_STRING Password, BOOL SetOperation)
 {
 	return TRUE;
 }
@@ -49,4 +64,4 @@ BOOL NTAPI PasswordFilter(
 BOOL NTAPI InitializeChangeNotify()
 {
 	return TRUE;
-}
+}

+ 0 - 4
ldap/synctools/passwordsync/passhook/passhook.def

@@ -1,7 +1,3 @@
-; --- BEGIN COPYRIGHT BLOCK ---
-; Copyright (C) 2005 Red Hat, Inc.
-; All rights reserved.
-; --- END COPYRIGHT BLOCK ---
 
 LIBRARY passhook
 EXPORTS

+ 0 - 5
ldap/synctools/passwordsync/passhook/passhook.dep

@@ -1,8 +1,3 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-# --- END COPYRIGHT BLOCK ---
-
 # Microsoft Developer Studio Generated Dependency File, included by passhook.mak
 
 ..\passhand.cpp : \

+ 2 - 6
ldap/synctools/passwordsync/passhook/passhook.dsp

@@ -1,8 +1,3 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-# --- END COPYRIGHT BLOCK ---
-
 # Microsoft Developer Studio Project File - Name="passhook" - Package Owner=<4>
 # Microsoft Developer Studio Generated Build File, Format Version 6.00
 # ** DO NOT EDIT **
@@ -70,6 +65,7 @@ LINK32=link.exe
 # PROP Use_Debug_Libraries 1
 # PROP Output_Dir "Debug"
 # PROP Intermediate_Dir "Debug"
+# PROP Ignore_Export_Lib 0
 # PROP Target_Dir ""
 # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PASSHOOK_EXPORTS" /YX /FD /GZ /c
 # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "PASSHOOK_EXPORTS" /YX /FD /GZ /c
@@ -82,7 +78,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 nss3.lib libnspr4.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
 
 !ENDIF 
 

+ 1 - 6
ldap/synctools/passwordsync/passhook/passhook.mak

@@ -1,8 +1,3 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-# --- END COPYRIGHT BLOCK ---
-
 # Microsoft Developer Studio Generated NMAKE File, Based on passhook.dsp
 !IF "$(CFG)" == ""
 CFG=passhook - Win32 Debug
@@ -171,7 +166,7 @@ BSC32_FLAGS=/nologo /o"$(OUTDIR)\passhook.bsc"
 BSC32_SBRS= \
 	
 LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\passhook.pdb" /debug /machine:I386 /def:".\passhook.def" /out:"$(OUTDIR)\passhook.dll" /implib:"$(OUTDIR)\passhook.lib" /pdbtype:sept 
+LINK32_FLAGS=nss3.lib libnspr4.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /incremental:yes /pdb:"$(OUTDIR)\passhook.pdb" /debug /machine:I386 /def:".\passhook.def" /out:"$(OUTDIR)\passhook.dll" /implib:"$(OUTDIR)\passhook.lib" /pdbtype:sept 
 DEF_FILE= \
 	".\passhook.def"
 LINK32_OBJS= \

+ 0 - 4
ldap/synctools/passwordsync/passsync.dsw

@@ -1,8 +1,4 @@
 Microsoft Developer Studio Workspace File, Format Version 6.00
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-# --- END COPYRIGHT BLOCK ---
 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
 
 ###############################################################################

BIN
ldap/synctools/passwordsync/passsync.ncb


BIN
ldap/synctools/passwordsync/passsync.opt


BIN
ldap/synctools/passwordsync/passsync/MSG00001.bin


+ 5 - 3
ldap/synctools/passwordsync/passsync/dssynch.h

@@ -1,10 +1,12 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
+/**
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  * Copyright (C) 2005 Red Hat, Inc.
  * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
-
+ * END COPYRIGHT BLOCK **/
 /***********************************************************************
 **
+**
 ** NAME
 **  DSSynch.h
 **

+ 0 - 4
ldap/synctools/passwordsync/passsync/dssynchmsg.h

@@ -1,7 +1,3 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
 //
 //  Values are 32 bit values layed out as follows:
 //

+ 379 - 0
ldap/synctools/passwordsync/passsync/dssynchmsg.mc

@@ -0,0 +1,379 @@
+
+MessageId=100
+SymbolicName=EVMSG_INSTALLED
+Language=English
+The %1 service was installed.
+.
+
+MessageId=
+SymbolicName=EVMSG_REMOVED
+Language=English
+The %1 service was removed.
+.
+
+MessageId=
+SymbolicName=EVMSG_NOTREMOVED
+Language=English
+The %1 service could not be removed.
+.
+
+MessageId=
+SymbolicName=EVMSG_CTRLHANDLERNOTINSTALLED
+Language=English
+The control handler could not be installed.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDINIT
+Language=English
+The initialization process failed.
+.
+
+MessageId=
+SymbolicName=EVMSG_STARTED
+Language=English
+The service was started.
+.
+
+MessageId=
+SymbolicName=EVMSG_RESTART
+Language=English
+The service was restarted.
+.
+
+MessageId=
+SymbolicName=EVMSG_BADREQUEST
+Language=English
+The service received an unsupported request.
+.
+
+MessageId=
+SymbolicName=EVMSG_SECURITYREGISTER
+Language=English
+The service has registered for security events.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDNOTIFY
+Language=English
+The service failed on waiting for security event.
+.
+
+MessageId=
+SymbolicName=EVMSG_SECURITYNOTIFY
+Language=English
+There was a security event.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDSECURITYNOTIFY
+Language=English
+Failure waiting for security event involving Users.
+.
+
+MessageId=
+SymbolicName=EVMSG_SECURITYAUDITINGENABLED
+Language=English
+Auditing of User and Group Management events has been enabled.
+.
+
+MessageId=
+SymbolicName=EVMSG_SECURITYAUDITINGDISABLED
+Language=English
+Auditing of User and Group Management events has been turned off.
+Notification-based monitoring of user changes has terminated.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDBINDDS
+Language=English
+Failed to bind to Directory Service on %1 at %2.
+.
+
+MessageId=
+SymbolicName=EVMSG_BINDDS
+Language=English
+Connected to Directory Service on %1 at %2.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDGETNTUSERS
+Language=English
+Failed to get user information from NT SAM.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDGETDSUSERS
+Language=English
+Failed to get user information from Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDSETDSTIMESTAMPS
+Language=English
+Failed to set initial time stamps of NT users on Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDGETNTUSERINFO
+Language=English
+Failed to get user information for <%1> from NT.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDADDDSUSER
+Language=English
+Failed to add user <%1> to Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDMODIFYDSUSER
+Language=English
+Failed to modify user <%1> on Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDDELETEDSUSER
+Language=English
+Failed to delete user <%1> on Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDADDNTUSER
+Language=English
+Failed to add user <%1> to NT.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDMODIFYNTUSER
+Language=English
+Failed to modify user <%1> in NT.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDDELETENTUSER
+Language=English
+Failed to delete user <%1> in NT.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDREADEVENTLOG
+Language=English
+Failed reading Security Event Log.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCOMMANDOPEN
+Language=English
+Failed opening command socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCOMMANDREAD
+Language=English
+Failed reading from command socket.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCOMMANDWRITE
+Language=English
+Failed writing to command socket.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDGETKEY
+Language=English
+Failed to get registry key <%1>.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDREADREGVALUE
+Language=English
+Failed to read registry value <%1>.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDWRITEREGVALUE
+Language=English
+Failed to write registry value <%1>.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDSAVESTATUS
+Language=English
+Failed to save status to registry.
+.
+
+MessageId=
+SymbolicName=EVMSG_UserNotFound
+Language=English
+The user name could not be found.
+.
+
+MessageId=
+SymbolicName=EVMSG_UserExists
+Language=English
+The user account already exists.
+.
+
+MessageId=
+SymbolicName=EVMSG_PasswordTooShort
+Language=English
+The password is shorter than required.
+.
+
+MessageId=
+SymbolicName=EVMSG_NameTooLong
+Language=English
+The user name %1 is too long.
+.
+
+MessageId=
+SymbolicName=EVMSG_PasswordHistConflict
+Language=English
+This password cannot be used now.
+.
+
+MessageId=
+SymbolicName=EVMSG_InvalidDatabase
+Language=English
+The security database is corrupted.
+.
+
+MessageId=
+SymbolicName=EVMSG_NetworkError
+Language=English
+A general network error occurred.
+.
+
+MessageId=
+SymbolicName=EVMSG_BadUsername
+Language=English
+The user name or group name parameter is invalid.
+.
+
+MessageId=
+SymbolicName=EVMSG_UserUnkownError
+Language=English
+Unexpected error - number %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_DEBUG
+Language=English
+Debug: %1
+.
+
+MessageId=
+SymbolicName=EVMSG_STOPPED
+Language=English
+The service was stopped.
+.
+
+MessageId=
+SymbolicName=EVMSG_UIDNOTDUPLICATED
+Language=English
+The UID "%1" already exists in the subtree and has not been duplicated.
+.
+
+MessageId=
+SymbolicName=EVMSG_UIDDUPLICATED
+Language=English
+The UID "%1" already exists in the subtree but HAS been duplicated because the user RDN component requires it.  Further action may need to be taken if there are systems using the Directory Server which require unique UIDs.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCONTROLOPEN
+Language=English
+Failed opening control message socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDPREOPOPEN
+Language=English
+Failed opening preoperation processing socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDPOSTOPEN
+Language=English
+Failed opening postoperation processing socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCONTROLWRITE
+Language=English
+Failed writing to control message socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDPREOPWRITE
+Language=English
+Failed writing to preoperation processing socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDPOSTOPWRITE
+Language=English
+Failed writing to postoperation processing socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCONTROLREAD
+Language=English
+Failed reading from control message socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDPREOPREAD
+Language=English
+Failed reading from preoperation processing socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDPOSTOPREAD
+Language=English
+Failed reading from postoperation processing socket at port %1.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCONTROLBADBASE
+Language=English
+The subtree "%1" is invalid.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDGETNTGROUPINFO
+Language=English
+Failed to get group information for <%1> from NT.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDADDDSGROUP
+Language=English
+Failed to add group <%1> to Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDMODIFYDSGROUP
+Language=English
+Failed to modify group <%1> on Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDDELETEDSGROUP
+Language=English
+Failed to delete group <%1> on Directory Server.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCONTROLDUPTREE
+Language=English
+Synch Service control connection rejected by Directory Server, duplicate users base <%1> or groups base <%2>.
+.
+
+MessageId=
+SymbolicName=EVMSG_FAILEDCONTROLSETUP
+Language=English
+Synch Service control connection rejected by Directory Server, users base <%1>, groups base <%2>.
+.

+ 2 - 0
ldap/synctools/passwordsync/passsync/dssynchmsg.rc

@@ -0,0 +1,2 @@
+LANGUAGE 0x9,0x1
+1 11 MSG00001.bin

+ 8 - 6
ldap/synctools/passwordsync/passsync/ntservice.cpp

@@ -1,9 +1,11 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
+/***********************************************************************
+**
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  * Copyright (C) 2005 Red Hat, Inc.
  * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
-
-/***********************************************************************
+ * END COPYRIGHT BLOCK **/
+/*
 **
 ** NAME
 **  NTService.cpp
@@ -290,8 +292,8 @@ void CNTService::LogEvent(WORD wType, DWORD dwID,
 // Modification: 2-8-2005
 //        m_hEventSource = ::RegisterEventSourceW(NULL,  // local machine
 //                                               GetEventName()); // source name
-        m_hEventSource = ::RegisterEventSourceW(NULL,  // local machine
-                                               (const unsigned short *)GetEventName()); // source name
+        m_hEventSource = ::RegisterEventSource(NULL,  // local machine
+                                               GetEventName()); // source name
 // End Change
     }
 

+ 4 - 3
ldap/synctools/passwordsync/passsync/ntservice.h

@@ -1,10 +1,11 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  * Copyright (C) 2005 Red Hat, Inc.
  * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
-
+ * END COPYRIGHT BLOCK **/
 /***********************************************************************
 **
+**
 ** NAME
 **  NTService.h
 **

+ 0 - 5
ldap/synctools/passwordsync/passsync/passsync.dep

@@ -1,8 +1,3 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-# --- END COPYRIGHT BLOCK ---
-
 # Microsoft Developer Studio Generated Dependency File, included by passsync.mak
 
 .\ntservice.cpp : \

+ 5 - 5
ldap/synctools/passwordsync/passsync/passsync.dsp

@@ -1,9 +1,5 @@
 # Microsoft Developer Studio Project File - Name="passsync" - Package Owner=<4>
 # Microsoft Developer Studio Generated Build File, Format Version 6.00
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-# --- END COPYRIGHT BLOCK ---
 # ** DO NOT EDIT **
 
 # TARGTYPE "Win32 (x86) Console Application" 0x0103
@@ -77,7 +73,7 @@ BSC32=bscmake.exe
 # ADD BSC32 /nologo
 LINK32=link.exe
 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 nsldapssl32v50.lib nsldap32v50.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 nss3.lib libplc4.lib libnspr4.lib nsldappr32v50.lib nsldapssl32v50.lib nsldap32v50.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
 
 !ENDIF 
 
@@ -98,6 +94,10 @@ SOURCE=..\passhand.cpp
 # End Source File
 # Begin Source File
 
+SOURCE=.\passsync.rc
+# End Source File
+# Begin Source File
+
 SOURCE=.\service.cpp
 # End Source File
 # Begin Source File

+ 1 - 5
ldap/synctools/passwordsync/passsync/passsync.mak

@@ -1,7 +1,3 @@
-# --- BEGIN COPYRIGHT BLOCK ---
-# Copyright (C) 2005 Red Hat, Inc.
-# All rights reserved.
-# --- END COPYRIGHT BLOCK ---
 # Microsoft Developer Studio Generated NMAKE File, Based on passsync.dsp
 !IF "$(CFG)" == ""
 CFG=passsync - Win32 Debug
@@ -169,7 +165,7 @@ BSC32_FLAGS=/nologo /o"$(OUTDIR)\passsync.bsc"
 BSC32_SBRS= \
 	
 LINK32=link.exe
-LINK32_FLAGS=nsldapssl32v50.lib nsldap32v50.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\passsync.pdb" /debug /machine:I386 /out:"$(OUTDIR)\passsync.exe" /pdbtype:sept 
+LINK32_FLAGS=nss3.lib libplc4.lib libnspr4.lib nsldappr32v50.lib nsldapssl32v50.lib nsldap32v50.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:"$(OUTDIR)\passsync.pdb" /debug /machine:I386 /out:"$(OUTDIR)\passsync.exe" /pdbtype:sept 
 LINK32_OBJS= \
 	"$(INTDIR)\ntservice.obj" \
 	"$(INTDIR)\passhand.obj" \

+ 67 - 0
ldap/synctools/passwordsync/passsync/passsync.rc

@@ -0,0 +1,67 @@
+//Microsoft Developer Studio generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+#include <windows.h>
+#include "dssynchmsg.rc"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "#include ""afxres.h""\r\n"
+    "#include <windows.h>\r\n"
+    "#include ""dssynchmsg.rc""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE DISCARDABLE 
+BEGIN
+    "\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+

+ 15 - 0
ldap/synctools/passwordsync/passsync/resource.h

@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by passsync.rc
+//
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        101
+#define _APS_NEXT_COMMAND_VALUE         40001
+#define _APS_NEXT_CONTROL_VALUE         1000
+#define _APS_NEXT_SYMED_VALUE           101
+#endif
+#endif

+ 1 - 6
ldap/synctools/passwordsync/passsync/service.cpp

@@ -1,13 +1,8 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
-
 // Created: 2-8-2005
 // Author(s): Scott Bridges
 
 #include <windows.h>
-#include <iostream.h>
+#include <iostream>
 #include "syncserv.h"
 #include "dssynchmsg.h"
 // syncserv.h

+ 1 - 6
ldap/synctools/passwordsync/passsync/subuniutil.cpp

@@ -1,8 +1,3 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
 #include "subuniutil.h"
 
 // Copied: 2-8-2005
@@ -61,4 +56,4 @@ StrToUnicode( const char *buf )
 	ASCIIToUnicode( buf, unibuf, sizeof(unibuf) );
 	return _wcsdup( unibuf );
 }
-// End Copy
+// End Copy

+ 0 - 5
ldap/synctools/passwordsync/passsync/subuniutil.h

@@ -1,8 +1,3 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
 #ifndef _SUBUNIUTIL_H_
 #define _SUBUNIUTIL_H_
 

+ 3 - 2
ldap/synctools/passwordsync/passsync/synchcmds.h

@@ -1,10 +1,11 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
+/** BEGIN COPYRIGHT BLOCK
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  * Copyright (C) 2005 Red Hat, Inc.
  * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
+ * END COPYRIGHT BLOCK **/
 /***********************************************************************
 **
+**
 ** NAME
 **  synchcmds.h
 **

+ 212 - 96
ldap/synctools/passwordsync/passsync/syncserv.cpp

@@ -1,147 +1,237 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
- * 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;
+
+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(const TCHAR *serviceName) : CNTService(serviceName)
 {
+	char sysPath[SYNCSERV_BUF_SIZE];
 	HKEY regKey;
 	DWORD type;
 	unsigned long size;
 
-	passhandEventHandle = CreateEvent(NULL, FALSE, FALSE, PASSHAND_EVENT_NAME);
+	passhookEventHandle = CreateEvent(NULL, FALSE, FALSE, PASSHAND_EVENT_NAME);
 
 	pLdapConnection = NULL;
 	results = NULL;
 	currentResult = NULL;
 	lastLdapError = LDAP_SUCCESS;
+	certdbh = NULL;
 
-	dataFilename = "C:\\WINDOWS\\system32\\passhook.dat";
-	logFilename = NULL;
-	multipleModify = true;
-
-	ldapHostName = (char*)malloc(REG_BUF_SIZE);
-	ldpaHostPort = (char*)malloc(REG_BUF_SIZE);
-	ldalAuthUsername = (char*)malloc(REG_BUF_SIZE);
-	ldapAuthPassword = (char*)malloc(REG_BUF_SIZE);
-	ldapSearchBase = (char*)malloc(REG_BUF_SIZE);
-	ldapUsernameField = (char*)malloc(REG_BUF_SIZE);
-	ldapPasswordField = (char*)malloc(REG_BUF_SIZE);
+	multipleModify = SYNCSERV_ALLOW_MULTI_MOD;
+	isRunning = false;
 
 	RegOpenKey(HKEY_LOCAL_MACHINE, "SOFTWARE\\PasswordSync", &regKey);
-	size = REG_BUF_SIZE;
+	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 = REG_BUF_SIZE;
-	RegQueryValueEx(regKey, "Port Number", NULL, &type, (unsigned char*)ldpaHostPort, &size);
-	size = REG_BUF_SIZE;
-	RegQueryValueEx(regKey, "User Name", NULL, &type, (unsigned char*)ldalAuthUsername, &size);
-	size = REG_BUF_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 = REG_BUF_SIZE;
+	size = SYNCSERV_BUF_SIZE;
 	RegQueryValueEx(regKey, "Search Base", NULL, &type, (unsigned char*)ldapSearchBase, &size);
-	size = REG_BUF_SIZE;
+	size = SYNCSERV_BUF_SIZE;
 	RegQueryValueEx(regKey, "User Name Field", NULL, &type, (unsigned char*)ldapUsernameField, &size);
-	size = REG_BUF_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()
 {
-	UNICODE_STRING uUsername;
-	UNICODE_STRING uPassword;
-	char* username;
-	char* password;
+	int result = 0;
+	char username[PASSHAND_BUF_SIZE];
+	char password[PASSHAND_BUF_SIZE];
 	char* dn;
 
 	if(Connect() < 0)
 	{
-		// ToDo: Generate event connection failure.
-		return -1;
+		// 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(&uUsername, &uPassword) > -1)
+	while(ourPasswordHandler.PeekUserPass(username, password) == 0)
 	{
-
-		username = (char*)malloc(uUsername.Length);
-		password = (char*)malloc(uPassword.Length);
-
-		sprintf(username, "%S", uUsername.Buffer);
-		sprintf(password, "%S", uPassword.Buffer);
-
-		results = NULL;
-		currentResult = NULL;
-		if(QueryUsername(username) < 0)
+		if(QueryUsername(username) != 0)
 		{
-			// ToDo: Generate event search failure.
+			// ToDo: generate event search failure.			
+			if(outLog.is_open())
+			{
+				timeStamp(&outLog);
+				outLog << "search for " << username << " failed in SyncPasswords" << endl;
+			}
 		}
 		else
 		{
-			while(dn != NULL)
+			while((dn = GetDN()) != NULL)
 			{
-				if(GetDN(&dn) < 0)
+				if(ModifyPassword(dn, password) != 0)
 				{
-					// ToDo: Generate event multiple results.
+					// ToDo: generate event modify failure.					
+					if(outLog.is_open())
+					{
+						timeStamp(&outLog);
+						outLog << "modify password for " << username << " failed in SyncPasswords" << endl;
+					}
 				}
 				else
 				{
-					if(ModifyPassword(dn, password) < 0)
+					if(outLog.is_open())
 					{
-						// ToDo: Generate event modify failure.
-					}
-					else
-					{
-						ourPasswordHandler.PopUserPass();
+						timeStamp(&outLog);
+						outLog << "password for " << username << " modified" << endl;
+						outLog << "\t" << dn << endl;
 					}
 				}
 			}
 		}
+		// ToDo: zero out buffers
 
-		// ToDo: Zero out buffers
-		free(username);
-		free(password);
+		ourPasswordHandler.PopUserPass();
 	}
 
 	ourPasswordHandler.SaveSet(dataFilename);
 
 	Disconnect();
 
-	return 0;
+exit:
+	return result;
+}
+
+void PassSyncService::OnStop()
+{
+	isRunning = false;
+	SetEvent(passhookEventHandle);
+}
+
+void PassSyncService::OnShutdown()
+{
+	isRunning = false;
+	SetEvent(passhookEventHandle);
 }
 
 void PassSyncService::Run()
 {
-	while(true)
+	isRunning = true;
+	SyncPasswords();
+
+	while(isRunning)
 	{
-		WaitForSingleObject(passhandEventHandle, INFINITE);
+		WaitForSingleObject(passhookEventHandle, INFINITE);
 		SyncPasswords();
-		ResetEvent(passhandEventHandle);
-		//Sleep(60000);
+		ResetEvent(passhookEventHandle);
 	}
 }
 
 int PassSyncService::Connect()
 {
-	pLdapConnection = ldap_init(ldapHostName, atoi(ldpaHostPort));
+	int result = 0;
 
-	lastLdapError = ldap_simple_bind_s(pLdapConnection, ldalAuthUsername, ldapAuthPassword);
-	if(lastLdapError != LDAP_SUCCESS)
+	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)
 	{
-		// ToDo: Log reason for bind failure.
-		return -1;
+		if(outLog.is_open())
+		{
+			timeStamp(&outLog);
+			outLog << "ldapssl_init failed in Connect" << endl;
+		}
+
+		result = -1;
+		goto exit;
 	}
 
-	return 0;
+	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()
@@ -155,9 +245,12 @@ int PassSyncService::Disconnect()
 
 int PassSyncService::QueryUsername(char* username)
 {
-	char* searchFilter = (char*)malloc(strlen(ldapUsernameField) + strlen(username) + 4);
+	int result = 0;
+	char searchFilter[SYNCSERV_BUF_SIZE];
 
-	sprintf(searchFilter, "(%s=%s)", ldapUsernameField, username);
+	results = NULL;
+
+	_snprintf(searchFilter, SYNCSERV_BUF_SIZE, "(%s=%s)", ldapUsernameField, username);
 
 	lastLdapError = ldap_search_ext_s(
 		pLdapConnection,
@@ -172,19 +265,27 @@ int PassSyncService::QueryUsername(char* username)
 		-1,
 		&results);
 
-	free(searchFilter);
-
 	if(lastLdapError != LDAP_SUCCESS)
 	{
-		// ToDo: Log reason for search failure.
-		return -1;
+		// 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;
 	}
 
-	return 0;
+exit:
+	return result;
 }
 
-int PassSyncService::GetDN(char** dn)
+char* PassSyncService::GetDN()
 {
+	char* result = NULL;
+
 	if(multipleModify)
 	{
 		if(currentResult == NULL)
@@ -193,35 +294,44 @@ int PassSyncService::GetDN(char** dn)
 		}
 		else
 		{
-			currentResult = ldap_next_entry(pLdapConnection, results);
-		}
-
-		if(currentResult == NULL)
-		{
-			*dn = NULL;
-			return 0;
+			currentResult = ldap_next_entry(pLdapConnection, currentResult);
 		}
 
-		*dn = ldap_get_dn(pLdapConnection, currentResult);
-		return 0;
+		result = ldap_get_dn(pLdapConnection, currentResult);
 	}
 	else
 	{
-		currentResult = ldap_first_entry(pLdapConnection, results);
-		if(ldap_next_entry(pLdapConnection, results) != NULLMSG)
+		if(currentResult == NULL)
 		{
-			// ToDo: Log that multiple results for username were found.
-			*dn = NULL;
-			return -1;
-		}
+			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;
+			}
 
-		*dn = ldap_get_dn(pLdapConnection, currentResult);
-		return 0;
+			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};
@@ -233,9 +343,15 @@ int PassSyncService::ModifyPassword(char* dn, char* password)
 	lastLdapError = ldap_modify_ext_s(pLdapConnection, dn, mods, NULL, NULL);
 	if(lastLdapError != LDAP_SUCCESS)
 	{
-		// ToDo: Log the reason for the modify failure.
-		return -1;
+		// 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 0;
-}
+	return result;
+}

+ 27 - 25
ldap/synctools/passwordsync/passsync/syncserv.h

@@ -1,20 +1,18 @@
-/* --- BEGIN COPYRIGHT BLOCK ---
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * --- END COPYRIGHT BLOCK --- */
-
 // Created: 2-8-2005
 // Author(s): Scott Bridges
 #ifndef _SYNCSERV_H_
 #define _SYNCSERV_H_
 
 #include <stdio.h>
-#include <ldap.h>
-#include <ldap_ssl.h>
+#include "ldap.h"
+#include "ldap_ssl.h"
+#include "ldappr.h"
 #include "ntservice.h"
 #include "../passhand.h"
 
-#define REG_BUF_SIZE 64
+#define SYNCSERV_BUF_SIZE 256
+#define SYNCSERV_TIMEOUT 10000
+#define SYNCSERV_ALLOW_MULTI_MOD false
 
 class PassSyncService : public CNTService
 {
@@ -22,39 +20,43 @@ public:
 	PassSyncService(const TCHAR* serviceName);
 	~PassSyncService();
 
+	void OnStop();
+	void OnShutdown();
 	void Run();
 
-	// ToDo: Move to private.
+	int SyncPasswords();
+
+private:
 	int Connect();
 	int Disconnect();
 	int QueryUsername(char* username);
-	int GetDN(char** dn);
+	char* GetDN();
 	int ModifyPassword(char* dn, char* password);
 
-	int SyncPasswords();
-
-private:
-
 	PasswordHandler ourPasswordHandler;
-	HANDLE passhandEventHandle;
+	HANDLE passhookEventHandle;
 
 	// LDAP variables
 	LDAP* pLdapConnection;
 	LDAPMessage* results;
 	LDAPMessage* currentResult;
 	int lastLdapError;
+	char certPath[SYNCSERV_BUF_SIZE];
+	char logPath[SYNCSERV_BUF_SIZE];
 
 	// Config variables
-	char* dataFilename;
-	char* logFilename;
-	char* ldapHostName;
-	char* ldpaHostPort;
-	char* ldalAuthUsername;
-	char* ldapAuthPassword;
-	char* ldapSearchBase;
-	char* ldapUsernameField;
-	char* ldapPasswordField;
+	char installPath[SYNCSERV_BUF_SIZE];
+	char dataFilename[SYNCSERV_BUF_SIZE];
+	char ldapHostName[SYNCSERV_BUF_SIZE];
+	char ldapHostPort[SYNCSERV_BUF_SIZE];
+	char ldapAuthUsername[SYNCSERV_BUF_SIZE];
+	char ldapAuthPassword[SYNCSERV_BUF_SIZE];
+	char ldapSearchBase[SYNCSERV_BUF_SIZE];
+	char ldapUsernameField[SYNCSERV_BUF_SIZE];
+	char ldapPasswordField[SYNCSERV_BUF_SIZE];
 	bool multipleModify;
+	bool isRunning;
+	fstream outLog;
 };
 
-#endif
+#endif

BIN
ldap/synctools/passwordsync/wix/Binary/Banner.bmp


BIN
ldap/synctools/passwordsync/wix/Binary/Complete.ico


BIN
ldap/synctools/passwordsync/wix/Binary/Custom.ico


BIN
ldap/synctools/passwordsync/wix/Binary/Dialog.bmp


BIN
ldap/synctools/passwordsync/wix/Binary/Exclam.ico


BIN
ldap/synctools/passwordsync/wix/Binary/Info.ico


BIN
ldap/synctools/passwordsync/wix/Binary/License.rtf


BIN
ldap/synctools/passwordsync/wix/Binary/New.ico


BIN
ldap/synctools/passwordsync/wix/Binary/Remove.ico


BIN
ldap/synctools/passwordsync/wix/Binary/Repair.ico


BIN
ldap/synctools/passwordsync/wix/Binary/Typical.ico


BIN
ldap/synctools/passwordsync/wix/Binary/Up.ico


+ 69 - 20
ldap/synctools/passwordsync/wix/PassSync.wxs

@@ -1,16 +1,12 @@
 <?xml version='1.0' encoding='windows-1252'?>
-<!-- BEGIN COPYRIGHT BLOCK 
- Copyright (C) 2005 Red Hat, Inc.
- All rights reserved.
- END COPYRIGHT BLOCK -->
 <Wix xmlns='http://schemas.microsoft.com/wix/2003/01/wi'>
   <Product Name='Password Sync' Id='DB501C18-86C7-4D14-AEC0-86416A69ABDE'
     Language='1033' Codepage='1252'
-    Version='1.0.0' Manufacturer='Acme Ltd.'>
+    Version='1.0.0' Manufacturer='Brandx'>
 
     <Package Id='????????-????-????-????-????????????' Keywords='Installer'
       Description="Password Synchronization Installer"
-      Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.'
+      Manufacturer='Brandx'
       InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
 
     <Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
@@ -18,13 +14,52 @@
 
     <Directory Id='TARGETDIR' Name='SourceDir'>
 
-	<Directory Id='WinDir' Name='WinDir' LongName='WINDOWS'>
-	    <Directory Id='SysDir' Name='SysDir' LongName='system32'>
-		<Component Id='HelperLibrary' Guid='5C4B892B-6BE3-460D-A14F-75658D16550B'>
+
+	    <Directory Id='SystemFolder' Name='SysDir'>
+
+		<Component Id='HookLibrary' Guid='93790ACE-F522-413C-AEE3-DF05D99BAA6D'>
               <File Id='PasshookDLL' Name='passhook.dll' DiskId='1' src='passhook.dll' Vital='yes' />
             </Component>
+
+		<Component Id='NSLDAPLibrary' Guid='E3B9046B-1B9B-4E19-81F3-0A8D14CF72B2'>
+		  <File Id='NSLDAP' LongName='nsldap32v50.dll' Name='nsldap.dll' DiskId='1' src='nsldap32v50.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSLDAPSSLLibrary' Guid='794345C6-74B8-4917-A2E6-4DC9DCCFECD2'>
+		  <File Id='NSLDAPSSL' LongName='nsldapssl32v50.dll' Name='nsldapss.dll' DiskId='1' src='nsldapssl32v50.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSLDAPPRLibrary' Guid='D6ABE406-7663-4E27-81F3-482860FD6375'>
+		  <File Id='NSLDAPRP' LongName='nsldappr32v50.dll' Name='nsldappr.dll' DiskId='1' src='nsldappr32v50.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSPRLibrary' Guid='7DFF5449-F38C-4C3B-9876-E32A123F1EA5'>
+		  <File Id='NSPR' LongName='libnspr4.dll' Name='libnspr4.dll' DiskId='1' src='libnspr4.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSPRpldsLibrary' Guid='50C89341-754F-4092-8307-129DB119B42E'>
+		  <File Id='NSPRPLDS' LongName='libplds4.dll' Name='libplds4.dll' DiskId='1' src='libplds4.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSPRplcLibrary' Guid='1B8B1D78-E2C1-4F3A-A841-C79FFE26E6E0'>
+		  <File Id='NSPRPLC' LongName='libplc4.dll' Name='libplc4.dll' DiskId='1' src='libplc4.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSSLibrary' Guid='5E122346-6B77-456D-BCC5-76D7FA8AF258'>
+		  <File Id='NSS' LongName='nss3.dll' Name='nss3.dll' DiskId='1' src='nss3.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSSsslLibrary' Guid='A39CC896-F455-4701-9BF0-D1E31C116DE2'>
+		  <File Id='NSSSSL' LongName='ssl3.dll' Name='ssl3.dll' DiskId='1' src='ssl3.dll' Vital='yes' />
+            </Component>
+
+		<Component Id='NSSsoftoknLibrary' Guid='9C57A076-D52A-4E74-A46A-DDF916A7D8BD'>
+		  <File Id='NSSSOFTTOKN' LongName='softokn3.dll' Name='softokn3.dll' DiskId='1' src='softokn3.dll' Vital='yes' />
+            </Component>
+
 	    </Directory>
-	</Directory>
+
+
       <Directory Id='ProgramFilesFolder' Name='PFiles'>
 
           <Directory Id='INSTALLDIR' Name='PassSync' LongName='Password Synchronization'>
@@ -32,22 +67,24 @@
             <Component Id='MainExecutable' Guid='DCEECAA4-83F1-4F22-985B-FDB3C8ABD471'>
               <File Id='PassSyncEXE' Name='PassSync.exe' LongName='passsync.exe' DiskId='1'
                 src='passsync.exe' Vital='yes' />
-              <Shortcut Id="startmenuPassSync" Directory="ProgramMenuDir" Name="PassSync" 
+            <!--  <Shortcut Id="startmenuPassSync" Directory="ProgramMenuDir" Name="PassSync" 
                 LongName="Password Synchronization" Target="MainProgram" WorkingDirectory='INSTALLDIR'
                 Icon="PassSync.exe" IconIndex="0" />
-              <Shortcut Id="desktopPassSync" Directory="DesktopFolder" Name="PassSync"
+                <Shortcut Id="desktopPassSync" Directory="DesktopFolder" Name="PassSync"
                 LongName="Password Synchronization" Target="MainProgram" WorkingDirectory='INSTALLDIR'
                 Icon="PassSync.exe" IconIndex="0" />
+            -->
 
 		  <ServiceInstall Id='PassSyncEXE' Name='PassSync' DisplayName='Password Synchronization' Type='ownProcess' 
 		   Interactive='yes' Start='auto' Vital='yes' ErrorControl='normal'/>
 		  <ServiceControl Id='PassSyncEXE' Name='PassSync' Start='install' Stop='both' Remove='uninstall' Wait='yes'/>
 
-
+		  <Registry Id='InstPath' Root='HKLM' Key='Software\PasswordSync' Name='Install Path' Action='write' Type='string' Value='[INSTALLDIR]' />
 		  <Registry Id='HostName' Root='HKLM' Key='Software\PasswordSync' Name='Host Name' Action='write' Type='string' Value='[HOSTNAME]' />
 		  <Registry Id='PortNum' Root='HKLM' Key='Software\PasswordSync' Name='Port Number' Action='write' Type='string' Value='[PORTNUM]' />
 		  <Registry Id='UserName' Root='HKLM' Key='Software\PasswordSync' Name='User Name' Action='write' Type='string' Value='[USER]' />
 		  <Registry Id='Password' Root='HKLM' Key='Software\PasswordSync' Name='Password' Action='write' Type='string' Value='[PASSWORD]' />
+		  <Registry Id='Certtkn' Root='HKLM' Key='Software\PasswordSync' Name='Cert Token' Action='write' Type='string' Value='[CERTTOKEN]' />
 		  <Registry Id='SrchBase' Root='HKLM' Key='Software\PasswordSync' Name='Search Base' Action='write' Type='string' Value='[SRCHBASE]' />
 		  <Registry Id='UserFld' Root='HKLM' Key='Software\PasswordSync' Name='User Name Field' Action='write' Type='string' Value='ntuserdomainid' />
 		  <Registry Id='PassFld' Root='HKLM' Key='Software\PasswordSync' Name='Password Field' Action='write' Type='string' Value='ntusercomment' />
@@ -59,20 +96,30 @@
           </Directory>
       </Directory>
 
-      <Directory Id="ProgramMenuFolder" Name="PMenu" LongName="Programs">
-        <Directory Id="ProgramMenuDir" Name='Foobar10' LongName="Foobar 1.0" />
-      </Directory>
+      <!-- <Directory Id="ProgramMenuFolder" Name="PMenu" LongName="Programs">
+        <Directory Id="ProgramMenuDir" Name='PassSync' LongName="Password Synchronization Service" />
+    </Directory>
+      -->
 
       <Directory Id="DesktopFolder" Name="Desktop" />
     </Directory>
 
-    <Feature Id='Complete' Title='Foobar 1.0' Description='The complete package.'
+    <Feature Id='Complete' Title='Password Synchronization Service' Description='The complete package.'
       TypicalDefault='install' Display='expand' Level='1'
       ConfigurableDirectory='INSTALLDIR'>
       <Feature Id='MainProgram' Title='Program' Description='The main executable.'
         TypicalDefault='install' Level='1'>
         <ComponentRef Id='MainExecutable' />
-        <ComponentRef Id='HelperLibrary' />
+        <ComponentRef Id='HookLibrary' />
+	  <ComponentRef Id='NSLDAPLibrary' />
+	  <ComponentRef Id='NSLDAPSSLLibrary' />
+	  <ComponentRef Id='NSLDAPPRLibrary' />
+	  <ComponentRef Id='NSPRLibrary' />
+	  <ComponentRef Id='NSPRpldsLibrary' />
+	  <ComponentRef Id='NSPRplcLibrary' />
+	  <ComponentRef Id='NSSLibrary' />
+	  <ComponentRef Id='NSSsslLibrary' />
+	  <ComponentRef Id='NSSsoftoknLibrary' />
       </Feature>
     </Feature>
 
@@ -704,8 +751,10 @@
 	  <Control Id="UserEdit" Type="Edit" X="100" Y="125" Width="220" Height="18" Property="USER"/>
 	  <Control Id="PwdLabel" Type="Text" X="45" Y="154" Width="50" Height="15" TabSkip="no" Text="&amp;Password:"/>
 	  <Control Id="PwdEdit" Type="Edit" Password="yes" X="100" Y="152" Width="220" Height="18" Property="PASSWORD"/>
-	  <Control Id="SBLabel" Type="Text" X="45" Y="181" Width="50" Height="15" TabSkip="no" Text="&amp;Search Base:"/>
-	  <Control Id="SBEdit" Type="Edit" X="100" Y="179" Width="220" Height="18" Property="SRCHBASE"/>
+	  <Control Id="CertLabel" Type="Text" X="45" Y="181" Width="50" Height="15" TabSkip="no" Text="&amp;Cert Token:"/>
+	  <Control Id="CertEdit" Type="Edit" Password="yes" X="100" Y="179" Width="220" Height="18" Property="CERTTOKEN"/>
+	  <Control Id="SBLabel" Type="Text" X="45" Y="208" Width="50" Height="15" TabSkip="no" Text="&amp;Search Base:"/>
+	  <Control Id="SBEdit" Type="Edit" X="100" Y="206" Width="220" Height="18" Property="SRCHBASE"/>
         <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="[ButtonText_Back]">
           <Publish Event="NewDialog" Value="WelcomeDlg">1</Publish>
         </Control>

+ 11 - 2
ldap/synctools/passwordsync/wix/README.txt

@@ -1,2 +1,11 @@
-1. Download Wix and unzip into this folder.
-2. run build.bat in Password Sync folder.
+1. Download Wix (http://sourceforge.net/projects/wix/) and unzip it into the Wix folder.
+   (steps 2 and 3 can be skipped if ldapserver has been built)
+2. Add the location of the Mozilla LDAP C SDK header files to your INCLUDE path.
+   The LDAP C SDK is a component of the Directory Server and is "pulled"
+   when the Directory Server is built; it can also be obtained individually from Mozilla.
+   e.x. 
+      set INCLUDE=%INCLUDE%;c:\source\dist\WINNT5.0_DBG.OBJ\ldapsdk\include
+3. Add the location of the LDAP C SDK libraries to your LIB path.
+   e.x. 
+      set LIB=%LIB%;c:\source\dist\WINNT5.0_DBG.OBJ\ldapsdk\lib
+4. Run build.bat.