├── Main ├── AdmPwd │ ├── ReadMe.txt │ ├── AdmPwdMsg.rc │ ├── MSG00409.bin │ ├── AdmPwd.def │ ├── AdminAccount.h │ ├── resource.h │ ├── Computer.h │ ├── stdafx.h │ ├── Constants.h │ ├── AdmPwd.h │ ├── targetver.h │ ├── AdmPwdMsg.mc │ ├── AdmPwd.vcxproj.filters │ ├── Config.cpp │ ├── AdmPwd.rc │ ├── Config.h │ ├── AdminAccount.cpp │ ├── AdmPwdMsg.h │ ├── PasswordGenerator.h │ ├── stdafx.cpp │ ├── Computer.cpp │ └── AdmPwd.cpp ├── Solution Items │ ├── app.ico │ ├── Version.h │ └── GlobalAssemblyInfo.cs ├── AdmPwd.Setup │ ├── UI │ │ ├── UIBannerBmp.jpg │ │ └── UIDialogBmp.jpg │ ├── AdmPwd.Setup.x86.wxi │ ├── AdmPwd.Setup.ARM64.wxi │ ├── AdmPwd.Setup.x64.wxi │ ├── AdmPwd.Setup.wixproj │ └── AdmPwd.Setup.wxs ├── AdmPwd.Setup.CustomActions │ ├── resource.h │ ├── CustomAction.def │ ├── AdmPwd.Setup.CustomActions.rc │ ├── stdafx.h │ ├── stdafx.cpp │ ├── GenerateRandomPassword.cpp │ ├── targetver.h │ ├── AdmPwd.Setup.CustomActions.vcxproj.filters │ ├── GetAdminsGroupName.cpp │ └── AdmPwd.Setup.CustomActions.vcxproj ├── AdmPwd.UI │ ├── app.config │ ├── Properties │ │ ├── Settings.settings │ │ ├── AssemblyInfo.cs │ │ ├── Settings.Designer.cs │ │ ├── Resources.Designer.cs │ │ └── Resources.resx │ ├── Program.cs │ ├── Form1.cs │ ├── AdmPwd.UI.csproj │ └── Form1.Designer.cs ├── AdmPwd.PS │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── AdmPwd.PS.psd1 │ ├── AdmPwd.PS.csproj │ └── AdmPwd.PS.format.ps1xml ├── AdmPwd.Utils │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── AdmPwd.Utils.csproj │ └── PSTypes.cs ├── _Other │ ├── AD_Schema │ │ └── AdmPwd_SchemaUpdate.ldf │ └── ADMX │ │ ├── en-US │ │ └── AdmPwd.adml │ │ └── AdmPwd.admx └── AdmPwd.sln ├── README.md ├── .gitattributes ├── .gitignore └── LICENSE /Main/AdmPwd/ReadMe.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwdMsg.rc: -------------------------------------------------------------------------------- 1 | LANGUAGE 0x9,0x1 2 | 1 11 "MSG00409.bin" 3 | -------------------------------------------------------------------------------- /Main/AdmPwd/MSG00409.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyCorbel/admpwd/HEAD/Main/AdmPwd/MSG00409.bin -------------------------------------------------------------------------------- /Main/Solution Items/app.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyCorbel/admpwd/HEAD/Main/Solution Items/app.ico -------------------------------------------------------------------------------- /Main/AdmPwd.Setup/UI/UIBannerBmp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyCorbel/admpwd/HEAD/Main/AdmPwd.Setup/UI/UIBannerBmp.jpg -------------------------------------------------------------------------------- /Main/AdmPwd.Setup/UI/UIDialogBmp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyCorbel/admpwd/HEAD/Main/AdmPwd.Setup/UI/UIDialogBmp.jpg -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyCorbel/admpwd/HEAD/Main/AdmPwd.Setup.CustomActions/resource.h -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwd.def: -------------------------------------------------------------------------------- 1 | LIBRARY "AdmPwd" 2 | EXPORTS 3 | DllMain @1 4 | ProcessGroupPolicy @4 5 | DllRegisterServer PRIVATE 6 | DllUnregisterServer PRIVATE 7 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/CustomAction.def: -------------------------------------------------------------------------------- 1 | LIBRARY "AdmPwd.Setup.CustomActions.dll" 2 | 3 | EXPORTS 4 | 5 | GenerateRandomPassword 6 | GetAdminsGroupName 7 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/AdmPwd.Setup.CustomActions.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GreyCorbel/admpwd/HEAD/Main/AdmPwd.Setup.CustomActions/AdmPwd.Setup.CustomActions.rc -------------------------------------------------------------------------------- /Main/AdmPwd.UI/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Main/Solution Items/Version.h: -------------------------------------------------------------------------------- 1 | #define FILEVER 6,3,2,0 2 | #define PRODUCTVER 6,3,2,0 3 | 4 | #define FileVersion "6.3.2.0" 5 | #define ProductVersion "6.3.2.0" 6 | 7 | #define COMPANYNAME "GreyCorbel Solutions" 8 | #define COPYRIGHT "Copyright (C) 2016 - 2023 Jiri Formacek, GreyCorbel Solutions" 9 | #define PRODUCT "AdmPwd" 10 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdminAccount.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class AdminAccount 3 | { 4 | public: 5 | AdminAccount(_In_ TCHAR* AccountName); 6 | ~AdminAccount(); 7 | HRESULT ResetPassword(_In_ LPCTSTR NewPasword); 8 | HRESULT HasPasswordEverManaged(_Out_ bool *pResult); 9 | 10 | //Account name length 11 | __declspec(property(get = GET_AccountNameLength)) DWORD AccountNameLength; 12 | DWORD GET_AccountNameLength() { 13 | return _AccountNameLength; 14 | }; 15 | private: 16 | TCHAR * _AccountName; 17 | 18 | DWORD _AccountNameLength; 19 | }; 20 | 21 | -------------------------------------------------------------------------------- /Main/AdmPwd/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by AdmPwd.rc 4 | // 5 | #define IDS_ATTR_PWD 104 6 | #define IDS_ATTR_PWD_TIMESTAMP 105 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 105 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /Main/AdmPwd/Computer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | class Computer 3 | { 4 | public: 5 | Computer(); 6 | ~Computer(); 7 | 8 | HRESULT ReportPassword(_In_ LPCTSTR password, _In_ FILETIME* timestamp, _In_ DWORD dwPasswordAge); 9 | HRESULT Load(); 10 | //password complexity 11 | __declspec(property(get = GET_PasswordExpirationTimestamp)) unsigned __int64 PasswordExpirationTimestamp; 12 | unsigned __int64 GET_PasswordExpirationTimestamp() { 13 | return _pwdExpiration; 14 | }; 15 | 16 | private: 17 | unsigned __int64 _pwdExpiration; 18 | 19 | LDAP* _conn; 20 | LPTSTR _dn; 21 | 22 | }; 23 | 24 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Windows.Forms; 5 | using System.DirectoryServices.Protocols; 6 | 7 | namespace AdmPwd.UI 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Form1()); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /Main/AdmPwd/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | //#include 19 | #include 20 | #include 21 | // WiX Header Files: 22 | #include 23 | 24 | 25 | // TODO: reference additional headers your program requires here 26 | #define MAX_PWD_COMPLEXITY 4 27 | #define PWD_LENGTH 16 28 | 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # AdmPwd project 2 | This is source code for AdmPwd project that has been previously hosted on MSDN gallery - project has been used as base for Microsoft branded LAPS solution. 3 | 4 | Enhancements over Microsoft LAPS: 5 | * usage of CNG instead of CryptoAPI for crypto operations 6 | * password management on ARM64 machines 7 | * installer supported on pure 64-bit Windows without WoW64 8 | * Support for automatic password change of managed local admin account on fresh install on new machine that reuses computer account of machine where password was previously managed 9 | 10 | Moved to github so as make it easier to allow cooperation, contribution and development of the solution. For details on current functionality, see release note for releases. 11 | 12 | Feel free to fork and bring updates 13 | 14 | --Jiri 15 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // AdmPwd.Setup.CustomActions.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | wchar_t* DICTIONARY [] = { L"ABCDEFGHIJKLMNOPQRSTUVWXYZ", L"abcdefghijklmnopqrstuvwxyz", L"0123456789", L",.-+;!#&@{}[]+$/()%|" }; 8 | 9 | // DllMain - Initialize and cleanup WiX custom action utils. 10 | extern "C" BOOL WINAPI DllMain( 11 | __in HINSTANCE hInst, 12 | __in ULONG ulReason, 13 | __in LPVOID 14 | ) 15 | { 16 | switch (ulReason) 17 | { 18 | case DLL_PROCESS_ATTACH: 19 | WcaGlobalInitialize(hInst); 20 | break; 21 | 22 | case DLL_PROCESS_DETACH: 23 | WcaGlobalFinalize(); 24 | break; 25 | } 26 | 27 | return TRUE; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /Main/Solution Items/GlobalAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // Version information for an assembly consists of the following four values: 6 | // 7 | // Major Version 8 | // Minor Version 9 | // Build Number 10 | // Revision 11 | // 12 | // You can specify all the values or you can default the Build and Revision Numbers 13 | // by using the '*' as shown below: 14 | // [assembly: AssemblyVersion("1.0.*")] 15 | 16 | [assembly: AssemblyVersion("6.3.2.0")] 17 | [assembly: AssemblyFileVersion("6.3.2.0")] 18 | 19 | [assembly: AssemblyCompany("")] 20 | [assembly: AssemblyCopyright("")] 21 | [assembly: AssemblyTrademark("")] 22 | 23 | #if DEBUG 24 | [assembly: AssemblyConfiguration("Debug")] 25 | #else 26 | [assembly: AssemblyConfiguration("Release")] 27 | #endif 28 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/GenerateRandomPassword.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "stdafx.h" 3 | #include "..\AdmPwd\PasswordGenerator.h" 4 | 5 | 6 | UINT __stdcall GenerateRandomPassword(MSIHANDLE hInstall) 7 | { 8 | HRESULT hr = S_OK; 9 | UINT er = ERROR_SUCCESS; 10 | PasswordGenerator gen(MAX_PWD_COMPLEXITY, PWD_LENGTH); 11 | 12 | hr = WcaInitialize(hInstall, "GenerateRandomPassword"); 13 | ExitOnFailure(hr, "Failed to initialize"); 14 | 15 | WcaLog(LOGMSG_STANDARD, "Initialized."); 16 | 17 | gen.Generate(); 18 | LPCTSTR newPwd = gen.Password; 19 | WcaLog(LOGMSG_STANDARD, "Password generated."); 20 | 21 | hr=WcaSetProperty(L"INITIALPASSWORD", newPwd); 22 | ExitOnFailure(hr, "Failed to set InitialPassword property"); 23 | 24 | WcaLog(LOGMSG_STANDARD, "InitialPassword property set."); 25 | 26 | LExit: 27 | er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; 28 | return WcaFinalize(er); 29 | } 30 | 31 | 32 | -------------------------------------------------------------------------------- /Main/AdmPwd.PS/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("AdmPwd.PS")] 10 | [assembly: AssemblyDescription("Powershell module for AdmPwd")] 11 | [assembly: AssemblyProduct("AdmPwd.PS")] 12 | [assembly: AssemblyCulture("")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("b45c749f-a212-46b0-a3b3-68b962ef54ad")] 21 | -------------------------------------------------------------------------------- /Main/AdmPwd.Utils/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | 6 | // General Information about an assembly is controlled through the following 7 | // set of attributes. Change these attribute values to modify the information 8 | // associated with an assembly. 9 | [assembly: AssemblyTitle("AdmPwd.Utils")] 10 | [assembly: AssemblyDescription("Shared code for AdmPwd UI and AdmPwd Powershell module")] 11 | [assembly: AssemblyProduct("AdmPwd.Utils")] 12 | [assembly: AssemblyCulture("")] 13 | [assembly: CLSCompliant(true)] 14 | 15 | // Setting ComVisible to false makes the types in this assembly not visible 16 | // to COM components. If you need to access a type in this assembly from 17 | // COM, set the ComVisible attribute to true on that type. 18 | [assembly: ComVisible(false)] 19 | 20 | // The following GUID is for the ID of the typelib if this project is exposed to COM 21 | [assembly: Guid("1c670bbd-76c2-4a0c-b30c-12806d9c10f6")] 22 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("AdmPwd.UI")] 9 | [assembly: AssemblyDescription("UI for AdmPwd management")] 10 | [assembly: AssemblyProduct("AdmPwd.UI")] 11 | [assembly: AssemblyCulture("")] 12 | [assembly:System.Resources.NeutralResourcesLanguage("en-US")] 13 | [assembly: System.CLSCompliant(true)] 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("8ae99be2-63bb-45fb-93ef-4c14d63d6f7c")] 21 | -------------------------------------------------------------------------------- /Main/AdmPwd/Constants.h: -------------------------------------------------------------------------------- 1 | //Constants used in the project 2 | #ifndef ADMPWD_CONSTANTS 3 | #define ADMPWD_CONSTANTS 4 | //extension Eventlog message file registration place 5 | #define GPEXT_REG_PATH_EVT L"System\\CurrentControlSet\\Services\\EventLog\\Application\\AdmPwd" 6 | //installation support 7 | #define FINAL_FILE_EXTENSION _T(".dll") 8 | //name of entry point 9 | #define ENTRY_POINT L"ProcessGroupPolicy" 10 | //name of extension - event source for application log 11 | #define EXTENSION_NAME L"AdmPwd" 12 | 13 | 14 | //buffer size for event log messages 15 | #define MAX_MSG_LEN 256 16 | //maximum length of AD attribute name 17 | #define MAX_ATTR_NAME 256 18 | //maximum lenghts of directory time string - yyyyMMddhhmmss + trailing null 19 | #define MAX_TIMESTAMP_LENGTH 18 20 | 21 | //ticks in single day 22 | #define TICKS_IN_DAY ((ULONGLONG)86400 * (ULONGLONG)10000000) 23 | 24 | // structure for Event logging 25 | typedef struct _LOGDATA { 26 | DWORD dwID; 27 | HRESULT hr; 28 | DWORD dwLogLevel; 29 | DWORD info1; 30 | } LOGDATA, *LPLOGDATA; 31 | 32 | #endif // !ADMPWD_CONSTANTS -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwd.h: -------------------------------------------------------------------------------- 1 | // The following ifdef block is the standard way of creating macros which make exporting 2 | // from a DLL simpler. All files within this DLL are compiled with the ADMPWD_EXPORTS 3 | // symbol defined on the command line. this symbol should not be defined on any project 4 | // that uses this DLL. This way any other project whose source files include this file see 5 | // ADMPWD_API functions as being imported from a DLL, whereas this DLL sees symbols 6 | // defined with this macro as being exported. 7 | #ifdef ADMPWD_EXPORTS 8 | #define ADMPWD_API __declspec(dllexport) 9 | #else 10 | #define ADMPWD_API __declspec(dllimport) 11 | #endif 12 | 13 | //forward declarations 14 | ADMPWD_API DWORD APIENTRY ProcessGroupPolicy(_In_ DWORD dwFlags, _In_ HANDLE hToken, _In_ HKEY hKeyRoot, _In_ PGROUP_POLICY_OBJECT pDeletedGPOList, _In_ PGROUP_POLICY_OBJECT pChangedGPOList, _In_ ASYNCCOMPLETIONHANDLE pHandle, _In_ BOOL* pbAbort, _In_ PFNSTATUSMESSAGECALLBACK pStatusCallback); 15 | 16 | void LogAppEvent(_In_ LPLOGDATA pLogData); 17 | 18 | ULONGLONG CompareTimestamp(_In_ ULONGLONG pTimestamp); 19 | void GetTimestamp(_Out_ ULONGLONG *pTimestamp); 20 | 21 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace AdmPwd.UI.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup/AdmPwd.Setup.x86.wxi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup/AdmPwd.Setup.ARM64.wxi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup/AdmPwd.Setup.x64.wxi: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /Main/AdmPwd/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // The following macros define the minimum required platform. The minimum required platform 4 | // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 5 | // your application. The macros work by enabling all features available on platform versions up to and 6 | // including the version specified. 7 | 8 | // Modify the following defines if you have to target a platform prior to the ones specified below. 9 | // Refer to MSDN for the latest info on corresponding values for different platforms. 10 | #ifndef WINVER // Specifies that the minimum required platform is Windows Vista. 11 | #define WINVER _WIN32_WINNT_WINXP // Change this to the appropriate value to target other versions of Windows. 12 | #endif 13 | 14 | #ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. 15 | #define _WIN32_WINNT _WIN32_WINNT_WINXP // Change this to the appropriate value to target other versions of Windows. 16 | #endif 17 | 18 | #ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. 19 | #define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. 20 | #endif 21 | 22 | #ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. 23 | #define _WIN32_IE _WIN32_IE_IE60SP1 // Change this to the appropriate value to target other versions of IE. 24 | #endif 25 | 26 | #define SECURITY_WIN32 -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // The following macros define the minimum required platform. The minimum required platform 4 | // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 5 | // your application. The macros work by enabling all features available on platform versions up to and 6 | // including the version specified. 7 | 8 | // Modify the following defines if you have to target a platform prior to the ones specified below. 9 | // Refer to MSDN for the latest info on corresponding values for different platforms. 10 | #ifndef WINVER // Specifies that the minimum required platform is Windows 2000. 11 | #define WINVER _WIN32_WINNT_WINXP // Change this to the appropriate value to target other versions of Windows. 12 | #endif 13 | 14 | #ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows 2000. 15 | #define _WIN32_WINNT _WIN32_WINNT_WINXP // Change this to the appropriate value to target other versions of Windows. 16 | #endif 17 | 18 | #ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 5.0. 19 | #define _WIN32_IE _WIN32_IE_IE60SP1 // Change this to the appropriate value to target other versions of IE. 20 | #endif 21 | 22 | #ifndef _WIN32_MSI // Specifies that the minimum required MSI version is MSI 3.1 23 | #define _WIN32_MSI 310 // Change this to the appropriate value to target other versions of MSI. 24 | #endif 25 | 26 | //#define SECURITY_WIN32 -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/AdmPwd.Setup.CustomActions.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | 29 | 30 | Source Files 31 | 32 | 33 | 34 | 35 | Header Files 36 | 37 | 38 | Header Files 39 | 40 | 41 | Header Files 42 | 43 | 44 | Header Files 45 | 46 | 47 | 48 | 49 | Resource Files 50 | 51 | 52 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/GetAdminsGroupName.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "stdafx.h" 3 | 4 | 5 | UINT __stdcall GetAdminsGroupName(MSIHANDLE hInstall) 6 | { 7 | HRESULT hr = S_OK; 8 | UINT er = ERROR_SUCCESS; 9 | 10 | //group name 11 | TCHAR* _name = nullptr; 12 | //authority name 13 | TCHAR* _domainName = nullptr; 14 | 15 | //sid of admins group 16 | SID* adminsSid = nullptr; 17 | 18 | DWORD dwNameSize = 0, dwDomainSize = 0; 19 | 20 | BOOL bRslt; 21 | DWORD err = 0; 22 | 23 | 24 | hr = WcaInitialize(hInstall, "GetAdminsGroupName"); 25 | ExitOnFailure(hr, "Failed to initialize"); 26 | 27 | WcaLog(LOGMSG_STANDARD, "Initialized."); 28 | 29 | 30 | bRslt = ConvertStringSidToSid(_T("BA"), (PSID*) &adminsSid); 31 | if (!bRslt) 32 | { 33 | hr = HRESULT_FROM_WIN32(GetLastError()); 34 | goto Cleanup; 35 | } 36 | 37 | SID_NAME_USE snu; 38 | bRslt = LookupAccountSid(NULL, adminsSid, _name, &dwNameSize, _domainName, &dwDomainSize, &snu); 39 | if (!bRslt) 40 | { 41 | err = GetLastError(); 42 | if (err != ERROR_INSUFFICIENT_BUFFER) 43 | { 44 | hr = HRESULT_FROM_WIN32(err); 45 | goto Cleanup; 46 | } 47 | } 48 | _name = new(std::nothrow) TCHAR[dwNameSize]; 49 | _domainName = new(std::nothrow) TCHAR[dwDomainSize]; 50 | if (_name == nullptr || _domainName == nullptr) 51 | { 52 | hr = HRESULT_FROM_WIN32(GetLastError()); 53 | goto Cleanup; 54 | } 55 | bRslt = LookupAccountSid(NULL, adminsSid, _name, &dwNameSize, _domainName, &dwDomainSize, &snu); 56 | if (!bRslt) 57 | { 58 | hr = HRESULT_FROM_WIN32(GetLastError()); 59 | goto Cleanup; 60 | } 61 | 62 | hr = WcaSetProperty(L"ADMINSGROUPNAME", _name); 63 | ExitOnFailure(hr, "Failed to set AdminsGroupName property"); 64 | 65 | WcaLog(LOGMSG_STANDARD, "AdminsGroupName property set."); 66 | 67 | 68 | Cleanup: 69 | if (adminsSid != nullptr) 70 | LocalFree(adminsSid); 71 | if (_name != nullptr) 72 | delete [] _name; 73 | if (_domainName != nullptr) 74 | delete [] _domainName; 75 | 76 | LExit: 77 | er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; 78 | return WcaFinalize(er); 79 | 80 | } -------------------------------------------------------------------------------- /Main/_Other/AD_Schema/AdmPwd_SchemaUpdate.ldf: -------------------------------------------------------------------------------- 1 | # 2 | # Schema extension definition for AdmPwd extension 3 | # New attributes: 4 | # ms-MCS-AdmPwd - string containing the password 5 | # ms-MCS-AdmPwdExpirationTime 8 byte integer containing UTC filetime of password expiration time 6 | # 7 | # New classes: 8 | # [None] 9 | # 10 | # Schema root: 1.2.840.113556.1.8000.2554.50051.45980.28112.18903.35903.6685103.1224907 11 | # 1 ... classes 12 | # 2 ... attributes 13 | # 14 | # v 1.0, 16.5.2012, Jiri Formacek, Microsoft | Services 15 | # 16 | version: 1 17 | 18 | dn: CN=ms-MCS-AdmPwd,CN=X 19 | changetype: Add 20 | objectClass: attributeSchema 21 | ldapDisplayName: ms-MCS-AdmPwd 22 | adminDisplayName: ms-MCS-AdmPwd 23 | adminDescription: Stores password of local Administrator account on workstation 24 | attributeId: 1.2.840.113556.1.8000.2554.50051.45980.28112.18903.35903.6685103.1224907.2.1 25 | #Syntax=Printable case sensitive string 26 | attributeSyntax: 2.5.5.5 27 | omSyntax: 19 28 | isSingleValued: TRUE 29 | systemOnly: FALSE 30 | #do not index this attribute, confidential attribute, preserved on tombstone 31 | #change to 136 if you have RODC and WANT replicate admin passwords to RODC 32 | searchFlags: 904 33 | #change to TRUE if you have multiple domains in forest and want to search against GC from admin web 34 | isMemberOfPartialAttributeSet: FALSE 35 | showInAdvancedViewOnly: FALSE 36 | 37 | dn: CN=ms-MCS-AdmPwdExpirationTime,CN=X 38 | changetype: Add 39 | objectClass: attributeSchema 40 | ldapDisplayName: ms-MCS-AdmPwdExpirationTime 41 | adminDisplayName: ms-MCS-AdmPwdExpirationTime 42 | adminDescription: Stores timestamp of last password change 43 | attributeId: 1.2.840.113556.1.8000.2554.50051.45980.28112.18903.35903.6685103.1224907.2.2 44 | #Syntax=Large Integer 45 | attributeSyntax: 2.5.5.16 46 | omSyntax: 65 47 | isSingleValued: TRUE 48 | systemOnly: FALSE 49 | #do not index this attribute 50 | searchFlags: 0 51 | #change to TRUE if you have multiple domains in forest and want to search against GC from admin web 52 | isMemberOfPartialAttributeSet: FALSE 53 | showInAdvancedViewOnly: FALSE 54 | 55 | # add attributes to schema 56 | 57 | dn: 58 | changetype: Modify 59 | add: schemaUpdateNow 60 | schemaUpdateNow: 1 61 | - 62 | 63 | # add new attributes to optional attributes set of computer object 64 | 65 | dn: CN=computer,CN=X 66 | changetype: Modify 67 | add: mayContain 68 | mayContain: ms-MCS-AdmPwd 69 | mayContain: ms-MCS-AdmPwdExpirationTime 70 | - 71 | 72 | # Perform schema update 73 | 74 | dn: 75 | changetype: Modify 76 | add: schemaUpdateNow 77 | schemaUpdateNow: 1 78 | - 79 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwdMsg.mc: -------------------------------------------------------------------------------- 1 | SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS 2 | Informational=0x1:STATUS_SEVERITY_INFORMATIONAL 3 | Warning=0x2:STATUS_SEVERITY_WARNING 4 | Error=0x3:STATUS_SEVERITY_ERROR 5 | ) 6 | 7 | LanguageNames=(English=0x409:MSG00409) 8 | 9 | ;//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 10 | ;// 1 - 10 ... Error events 11 | ;//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 12 | MessageId=2 Severity=Error SymbolicName=S_GET_COMPUTER 13 | Language=English 14 | Could not get computer object from AD. Error %1. 15 | . 16 | 17 | MessageId=3 Severity=Error SymbolicName=S_GET_ADMIN 18 | Language=English 19 | Could not get local Administrator account. Error %1. 20 | . 21 | 22 | MessageId=4 Severity=Error SymbolicName=S_GET_TIMESTAMP 23 | Language=English 24 | Could not get password expiration timestamp from computer account in AD. Error %1. 25 | . 26 | 27 | MessageId=6 Severity=Error SymbolicName=S_CHANGE_PWD 28 | Language=English 29 | Could not reset local Administrator's password. Error %1. 30 | . 31 | 32 | MessageId=7 Severity=Error SymbolicName=S_REPORT_PWD 33 | Language=English 34 | Could not write changed password to AD. Error %1. 35 | . 36 | 37 | MessageId=10 Severity=Warning SymbolicName=S_EXPIRATION_TOO_LONG 38 | Language=English 39 | Password expiration too long for computer (%1 days). Resetting password now. 40 | . 41 | 42 | ;//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 43 | ;// 11 - 20 ... Informational events 44 | ;//;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 45 | MessageId=11 Severity=Informational SymbolicName=S_CHANGE_PWD_NOT_YET 46 | Language=English 47 | It is not necessary to change password yet. Days to change: %1. 48 | . 49 | 50 | MessageId=12 Severity=Informational SymbolicName=S_CHANGE_PWD_SUCCESS 51 | Language=English 52 | Local Administrator's password has been changed. 53 | . 54 | 55 | MessageId=13 Severity=Informational SymbolicName=S_REPORT_PWD_SUCCESS 56 | Language=English 57 | Local Administrator's password has been reported to AD. 58 | . 59 | 60 | MessageId=14 Severity=Informational SymbolicName=S_FINISHED 61 | Language=English 62 | Finished successfully. 63 | . 64 | 65 | MessageId=15 Severity=Informational SymbolicName=S_STARTED 66 | Language=English 67 | Beginning processing. 68 | . 69 | 70 | MessageId=16 Severity=Informational SymbolicName=S_NOT_ENABLED 71 | Language=English 72 | Admin account management not enabled, exiting. 73 | . 74 | 75 | MessageId=17 Severity=Informational SymbolicName=S_NEVER_MANAGED 76 | Language=English 77 | Admin account was never managed. Changing the password now. 78 | . 79 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /Main/AdmPwd.Utils/AdmPwd.Utils.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B} 8 | Library 9 | Properties 10 | AdmPwd.Utils 11 | AdmPwd.Utils 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Properties\GlobalAssemblyInfo.cs 49 | 50 | 51 | 52 | 53 | 54 | 55 | 62 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwd.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | 35 | 36 | Source Files 37 | 38 | 39 | 40 | 41 | Header Files 42 | 43 | 44 | Header Files 45 | 46 | 47 | Header Files 48 | 49 | 50 | Header Files 51 | 52 | 53 | Header Files 54 | 55 | 56 | Header Files 57 | 58 | 59 | Header Files 60 | 61 | 62 | Header Files 63 | 64 | 65 | Header Files 66 | 67 | 68 | Header Files 69 | 70 | 71 | 72 | 73 | Resource Files 74 | 75 | 76 | Resource Files 77 | 78 | 79 | 80 | 81 | Source Files 82 | 83 | 84 | -------------------------------------------------------------------------------- /Main/AdmPwd.PS/AdmPwd.PS.psd1: -------------------------------------------------------------------------------- 1 | # 2 | # Module manifest for module 'AdmPwd.PS' 3 | # 4 | # Generated by: Jiri Formacek - MSFT 5 | # 6 | # Generated on: 3.12.2012 7 | # 8 | 9 | @{ 10 | 11 | # Script module or binary module file associated with this manifest 12 | RootModule = '.\AdmPwd.PS.dll' 13 | 14 | # Version number of this module. 15 | ModuleVersion = '6.3.1.0' 16 | 17 | # ID used to uniquely identify this module 18 | GUID = '11869C0C-4440-4560-AA89-9EEF0C0224FA' 19 | 20 | # Author of this module 21 | Author = 'Jiri Formacek - GreyCorbel Solutions' 22 | 23 | # Company or vendor of this module 24 | CompanyName = 'GreyCorbel Solutions' 25 | 26 | # Copyright statement for this module 27 | Copyright = '' 28 | 29 | # Description of the functionality provided by this module 30 | Description = 'Provides cmdlets for configuration and usage of Local admin password management solution' 31 | 32 | # Minimum version of the Windows PowerShell engine required by this module 33 | PowerShellVersion = '' 34 | 35 | # Name of the Windows PowerShell host required by this module 36 | PowerShellHostName = '' 37 | 38 | # Minimum version of the Windows PowerShell host required by this module 39 | PowerShellHostVersion = '' 40 | 41 | # Minimum version of the .NET Framework required by this module 42 | DotNetFrameworkVersion = '' 43 | 44 | # Minimum version of the common language runtime (CLR) required by this module 45 | CLRVersion = '' 46 | 47 | # Processor architecture (None, X86, Amd64, IA64) required by this module 48 | ProcessorArchitecture = '' 49 | 50 | # Modules that must be imported into the global environment prior to importing this module 51 | RequiredModules = @() 52 | 53 | # Assemblies that must be loaded prior to importing this module 54 | RequiredAssemblies = @() 55 | 56 | # Script files (.ps1) that are run in the caller's environment prior to importing this module 57 | ScriptsToProcess = @() 58 | 59 | # Type files (.ps1xml) to be loaded when importing this module 60 | TypesToProcess = @() 61 | 62 | # Format files (.ps1xml) to be loaded when importing this module 63 | FormatsToProcess = @('AdmPwd.PS.format.ps1xml') 64 | 65 | # Modules to import as nested modules of the module specified in ModuleToProcess 66 | NestedModules = @() 67 | 68 | # Functions to export from this module 69 | FunctionsToExport = @() 70 | 71 | # Cmdlets to export from this module 72 | CmdletsToExport = @('Update-AdmPwdADSchema', 73 | 'Get-AdmPwdPassword', 74 | 'Reset-AdmPwdPassword', 75 | 'Set-AdmPwdComputerSelfPermission', 76 | 'Find-AdmPwdExtendedRights', 77 | 'Set-AdmPwdAuditing', 78 | 'Set-AdmPwdReadPasswordPermission', 79 | 'Set-AdmPwdResetPasswordPermission' 80 | ) 81 | 82 | # Variables to export from this module 83 | VariablesToExport = @() 84 | 85 | # Aliases to export from this module 86 | AliasesToExport = @() 87 | 88 | # List of all modules packaged with this module 89 | ModuleList = @() 90 | 91 | # List of all files packaged with this module 92 | FileList = @('AdmPwd.PS.dll','AdmPwd.Utils.dll','AdmPwd.PS.format.ps1xml') 93 | 94 | # Private data to pass to the module specified in ModuleToProcess 95 | PrivateData = '' 96 | 97 | } 98 | 99 | -------------------------------------------------------------------------------- /Main/_Other/ADMX/en-US/AdmPwd.adml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | AdmPwd 9 | Enable local admin password management 10 | 11 | Enables management of password for local administrator account 12 | 13 | If you enable this setting, local administrator password is managed 14 | 15 | If you disable or not configure this setting, local administrator password is NOT managed 16 | 17 | Password Settings 18 | 19 | Configures AdmPwd password parameters 20 | 21 | Password complexity: which characters are used when generating a new password 22 | Default: Large letters + small letters + numbers + special characters 23 | 24 | Password length 25 | Minimum: 12 characters 26 | Maximum: 64 characters 27 | Default: 12 characters 28 | 29 | Password age in days 30 | Minimum: 1 day 31 | Maximum: 365 days 32 | Default: 30 days 33 | 34 | At least Microsoft Windows XP Professional or Windows Server 2003 family 35 | Large letters 36 | Large letters + small letters 37 | Large letters + small letters + numbers 38 | Large letters + small letters + numbers + specials 39 | Customize administrator account name 40 | 41 | Administrator account name: name of the local account you want to manage password for. 42 | DO NOT configure when you use built-in admin account 43 | Account is auto-detected by well-known SID 44 | Built-In account can be renamed 45 | DO configure when you use custom local admin account 46 | 47 | Do not allow password expiration time longer than required by policy 48 | 49 | When you enable this setting, planned password expiration longer than password age dictated by "Password Settings" policy is NOT allowed. When such expiration is detected, password is changed immediately and password expiration is set according to policy. 50 | 51 | When you disable or not configure this setting, password expiration time may be longer than required by "Password Settings" policy. 52 | 53 | 54 | 55 | 56 | Password Complexity 57 | Password Length 58 | Password Age (Days) 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /Main/AdmPwd/Config.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Config.h" 3 | 4 | Config::Config() noexcept 5 | { 6 | DWORD data; 7 | HKEY hPolicyKey = 0; 8 | HKEY hGPExtKey = 0; 9 | 10 | //initialize default values 11 | _AccountManagementEnabled=false; 12 | _pwdComplexity = MAX_PWD_COMPLEXITY; 13 | _pwdLength=PWD_LENGTH; 14 | _pwdAge = PWD_AGE_DAYS; 15 | _pwdExpirationProtectionRequired=false; 16 | 17 | _logLevel=0; 18 | 19 | _adminName=nullptr; 20 | //end of init 21 | 22 | RegOpenKeyEx(HKEY_LOCAL_MACHINE, GPEXT_REG_PATH, 0, KEY_QUERY_VALUE, &hGPExtKey); 23 | RegOpenKeyEx(HKEY_LOCAL_MACHINE, GPEXT_REG_POLICY_PATH, 0, KEY_QUERY_VALUE, &hPolicyKey); 24 | 25 | if (hGPExtKey != 0) 26 | { 27 | GetRegistryDWORD(hGPExtKey, LOG_LEVEL_REG_VALUE, &_logLevel); 28 | if (_logLevel >= LOGLEVEL_INVALID) 29 | _logLevel = LOGLEVEL_ALL_EVENTS; 30 | 31 | RegCloseKey(hGPExtKey); 32 | } 33 | 34 | if (hPolicyKey != 0) 35 | { 36 | GetRegistryDWORD(hPolicyKey, PWD_LEN_REG_VALUE, &_pwdLength); 37 | if (_pwdLength > MAX_PWD_LENGTH || _pwdLength < MIN_PWD_LENGTH) 38 | _pwdLength = PWD_LENGTH; 39 | 40 | GetRegistryDWORD(hPolicyKey, PWD_AGE_REG_VALUE, &_pwdAge); 41 | if (_pwdAge > MAX_PWD_AGE_DAYS) 42 | _pwdAge = MAX_PWD_AGE_DAYS; 43 | 44 | GetRegistryDWORD(hPolicyKey, PWD_COMPLEXITY_REG_VALUE, &_pwdAge); 45 | if (_pwdComplexity < MIN_PWD_COMPLEXITY || _pwdComplexity > MAX_PWD_COMPLEXITY) 46 | _pwdComplexity = MAX_PWD_COMPLEXITY; 47 | 48 | data = 0; 49 | GetRegistryDWORD(hPolicyKey, ADMIN_ACCOUNT_MANAGEMENT_ENABLED, &data); 50 | _AccountManagementEnabled = (data != 0); 51 | 52 | data = 0; 53 | GetRegistryString(hPolicyKey, ADMIN_ACCOUNT_NAME, &_adminName, &data); 54 | 55 | data = 0; 56 | GetRegistryDWORD(hPolicyKey, PWD_EXPIRATION_PROTECTION_ENABLED_REG_VALUE, &data); 57 | _pwdExpirationProtectionRequired = (data != 0); 58 | 59 | RegCloseKey(hPolicyKey); 60 | } 61 | } 62 | 63 | Config::~Config() 64 | { 65 | if (_adminName != nullptr) 66 | { 67 | delete [] _adminName; 68 | } 69 | } 70 | 71 | _Use_decl_annotations_ 72 | HRESULT Config::GetRegistryDWORD(HKEY hReg, LPCTSTR regValueName, DWORD *retVal) noexcept { 73 | LONG lResult; 74 | DWORD dwBuffLen = sizeof(*retVal); 75 | 76 | if (!hReg) 77 | HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND); 78 | 79 | lResult = RegQueryValueEx(hReg, regValueName, NULL, NULL, (LPBYTE) retVal, &dwBuffLen); 80 | 81 | if (lResult == ERROR_MORE_DATA) 82 | { 83 | lResult = ERROR_BAD_ARGUMENTS; //value stored in registry is not REG_DWORD 84 | } 85 | 86 | return HRESULT_FROM_WIN32(lResult); 87 | } 88 | 89 | _Use_decl_annotations_ 90 | HRESULT Config::GetRegistryString(HKEY hReg, LPCTSTR regValueName, TCHAR **retVal, DWORD *dwStringLen) noexcept 91 | { 92 | LONG lResult; 93 | DWORD dwBuffLen = 0; 94 | 95 | lResult = RegQueryValueEx(hReg, regValueName, NULL, NULL, NULL, &dwBuffLen); 96 | 97 | if (lResult == ERROR_MORE_DATA || lResult == ERROR_SUCCESS) 98 | { 99 | //seems to return ERROR_SUCCESS instead of ERROR_MORE_DATA when trying to get buffer length (at least on W2K8R2) 100 | *dwStringLen = dwBuffLen / sizeof(TCHAR); 101 | *retVal = new(std::nothrow) TCHAR[*dwStringLen](); //allocate buffer; caller is responsible for releasing it 102 | if (*retVal == NULL) 103 | return HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); 104 | 105 | lResult = RegQueryValueEx(hReg, regValueName, NULL, NULL, (LPBYTE) *retVal, &dwBuffLen); 106 | } 107 | return HRESULT_FROM_WIN32(lResult); 108 | } 109 | 110 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwd.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | #include "..\Solution Items\Version.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // Neutral resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU) 20 | LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL 21 | #pragma code_page(1250) 22 | 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // String Table 26 | // 27 | 28 | STRINGTABLE 29 | BEGIN 30 | IDS_ATTR_PWD "ms-Mcs-AdmPwd" 31 | IDS_ATTR_PWD_TIMESTAMP "ms-Mcs-AdmPwdExpirationTime" 32 | END 33 | 34 | #endif // Neutral resources 35 | ///////////////////////////////////////////////////////////////////////////// 36 | 37 | 38 | ///////////////////////////////////////////////////////////////////////////// 39 | // Czech (Czech Republic) resources 40 | 41 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CSY) 42 | LANGUAGE LANG_CZECH, SUBLANG_DEFAULT 43 | #pragma code_page(1250) 44 | 45 | ///////////////////////////////////////////////////////////////////////////// 46 | // 47 | // Version 48 | // 49 | 50 | VS_VERSION_INFO VERSIONINFO 51 | FILEVERSION FILEVER 52 | PRODUCTVERSION PRODUCTVER 53 | FILEFLAGSMASK 0x17L 54 | #ifdef _DEBUG 55 | FILEFLAGS 0x1L 56 | #else 57 | FILEFLAGS 0x0L 58 | #endif 59 | FILEOS 0x4L 60 | FILETYPE 0x2L 61 | FILESUBTYPE 0x0L 62 | BEGIN 63 | BLOCK "StringFileInfo" 64 | BEGIN 65 | BLOCK "040904b0" 66 | BEGIN 67 | VALUE "CompanyName", COMPANYNAME 68 | VALUE "FileDescription", "AdmPwd GPO Extension: manage local admin account password" 69 | VALUE "FileVersion", FileVersion 70 | VALUE "InternalName", "AdmPwd" 71 | VALUE "LegalCopyright", COPYRIGHT 72 | VALUE "OriginalFilename", "AdmPwd.dll" 73 | VALUE "ProductName", PRODUCT 74 | VALUE "ProductVersion", ProductVersion 75 | END 76 | END 77 | BLOCK "VarFileInfo" 78 | BEGIN 79 | VALUE "Translation", 0x409, 1200 80 | END 81 | END 82 | 83 | #endif // Czech (Czech Republic) resources 84 | ///////////////////////////////////////////////////////////////////////////// 85 | 86 | 87 | ///////////////////////////////////////////////////////////////////////////// 88 | // English (United States) resources 89 | 90 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 91 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 92 | #pragma code_page(1252) 93 | 94 | #ifdef APSTUDIO_INVOKED 95 | ///////////////////////////////////////////////////////////////////////////// 96 | // 97 | // TEXTINCLUDE 98 | // 99 | 100 | 1 TEXTINCLUDE 101 | BEGIN 102 | "resource.h\0" 103 | END 104 | 105 | 2 TEXTINCLUDE 106 | BEGIN 107 | "#include ""winres.h""\r\n" 108 | "\0" 109 | END 110 | 111 | 3 TEXTINCLUDE 112 | BEGIN 113 | "\r\n" 114 | "\0" 115 | END 116 | 117 | #endif // APSTUDIO_INVOKED 118 | 119 | #endif // English (United States) resources 120 | ///////////////////////////////////////////////////////////////////////////// 121 | 122 | 123 | 124 | #ifndef APSTUDIO_INVOKED 125 | ///////////////////////////////////////////////////////////////////////////// 126 | // 127 | // Generated from the TEXTINCLUDE 3 resource. 128 | // 129 | 130 | 131 | ///////////////////////////////////////////////////////////////////////////// 132 | #endif // not APSTUDIO_INVOKED 133 | 134 | -------------------------------------------------------------------------------- /Main/AdmPwd/Config.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef ADMPWD_CONFIG 3 | #define ADMPWD_CONFIG 4 | 5 | //Logging levels 6 | enum { 7 | LOGLEVEL_ERRORS_ONLY = 0, 8 | LOGLEVEL_ERRORS_WARNINGS, 9 | LOGLEVEL_ALL_EVENTS, 10 | LOGLEVEL_INVALID //always at the end of enum 11 | }; 12 | 13 | // extension registration place 14 | #define GPEXT_REG_PATH L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions\\{D76B9641-3288-4f75-942D-087DE603E3EA}" 15 | // extension policy store 16 | #define GPEXT_REG_POLICY_PATH L"Software\\Policies\\Microsoft Services\\AdmPwd" 17 | 18 | //name of registry value storing flag that enables password management 19 | #define ADMIN_ACCOUNT_MANAGEMENT_ENABLED L"AdmPwdEnabled" 20 | //name of registry value storing the admin account name 21 | #define ADMIN_ACCOUNT_NAME L"AdminAccountName" 22 | //name of registry value storing desired password length 23 | #define PWD_LEN_REG_VALUE L"PasswordLength" 24 | //name of registry value storing desired password length 25 | #define PWD_COMPLEXITY_REG_VALUE L"PasswordComplexity" 26 | //name of registry value storing desired password age in days 27 | #define PWD_AGE_REG_VALUE L"PasswordAgeDays" 28 | //name of registry value storing the logging level 29 | #define LOG_LEVEL_REG_VALUE L"ExtensionDebugLevel" 30 | //name of registry value storing flag whether or not to enforce password age policy on expiration time 31 | #define PWD_EXPIRATION_PROTECTION_ENABLED_REG_VALUE L"PwdExpirationProtectionEnabled" 32 | 33 | //Password quality and duration parameters 34 | //default pwd complexity 35 | #define MAX_PWD_COMPLEXITY 4 36 | #define MIN_PWD_COMPLEXITY 1 37 | #define MIN_PWD_LENGTH 8 38 | //default pwd length 39 | #define PWD_LENGTH 12 40 | #define MAX_PWD_LENGTH 64 41 | //default pwd age 42 | #define PWD_AGE_DAYS 30 43 | #define MAX_PWD_AGE_DAYS 365 44 | #define MIN_PWD_AGE_DAYS 1 45 | 46 | class Config 47 | { 48 | public: 49 | Config() noexcept; 50 | ~Config(); 51 | 52 | //password complexity 53 | __declspec(property(get = GET_PasswordComplexity)) DWORD PasswordComplexity; 54 | //password length 55 | __declspec(property(get = GET_PasswordLength)) DWORD PasswordLength; 56 | //max password age 57 | __declspec(property(get = GET_PasswordAge)) DWORD PasswordAge; 58 | //logging level 59 | __declspec(property(get = GET_LogLevel)) DWORD LogLevel; 60 | //admin account name 61 | __declspec(property(get = GET_AdminAccountName)) TCHAR* AdminAccountName; 62 | //management enabled 63 | __declspec(property(get = GET_AccountManagementEnabled)) bool AccountManagementEnabled; 64 | //password expiration protection 65 | __declspec(property(get = GET_PasswordExpirationProtectionRequired)) bool PasswordExpirationProtectionRequired; 66 | 67 | //accessors 68 | DWORD GET_PasswordComplexity() noexcept { 69 | return _pwdComplexity; 70 | }; 71 | bool GET_AccountManagementEnabled() noexcept { 72 | return _AccountManagementEnabled; 73 | }; 74 | DWORD GET_PasswordLength() noexcept { 75 | return _pwdLength; 76 | }; 77 | DWORD GET_PasswordAge() noexcept { 78 | return _pwdAge; 79 | }; 80 | DWORD GET_LogLevel() noexcept { 81 | return _logLevel; 82 | }; 83 | TCHAR* GET_AdminAccountName() noexcept { 84 | return _adminName; 85 | }; 86 | bool GET_PasswordExpirationProtectionRequired() noexcept { 87 | return _pwdExpirationProtectionRequired; 88 | }; 89 | 90 | private: 91 | bool _AccountManagementEnabled; 92 | DWORD _pwdComplexity; 93 | DWORD _pwdLength; 94 | DWORD _pwdAge; 95 | 96 | DWORD _logLevel; 97 | 98 | TCHAR* _adminName; 99 | bool _pwdExpirationProtectionRequired; 100 | 101 | //methods 102 | HRESULT GetRegistryDWORD(_In_ HKEY hReg, _In_ LPCTSTR regValueName, _Out_ DWORD *retVal) noexcept; 103 | HRESULT GetRegistryString(_In_ HKEY hReg, _In_ LPCTSTR regValueName, _Out_ TCHAR **retVal, _Out_ DWORD *dwStringLen) noexcept; 104 | }; 105 | 106 | #endif // !ADMPWD_CONFIG 107 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdminAccount.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "AdminAccount.h" 3 | 4 | _Use_decl_annotations_ 5 | AdminAccount::AdminAccount(TCHAR* AccountName) 6 | { 7 | PSID pSID = NULL; 8 | BOOL bResult = false; 9 | TCHAR *RefDomain = nullptr; 10 | HRESULT hr=S_OK; 11 | 12 | //initialize members 13 | _AccountName = nullptr; 14 | _AccountNameLength = 0; 15 | //end of init 16 | 17 | if (AccountName != nullptr && _tcscmp(AccountName, _T(""))!=0) 18 | { 19 | //account name specified in GPO --> use it 20 | size_t dwNameLen = 0; 21 | hr = StringCchLength(AccountName, STRSAFE_MAX_CCH, &dwNameLen); 22 | if (FAILED(hr)) 23 | goto Cleanup; 24 | dwNameLen++; //to include trailing NULL 25 | _AccountName = new(std::nothrow)TCHAR[dwNameLen]; 26 | if (_AccountName == nullptr) 27 | { 28 | hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); 29 | goto Cleanup; //not enough memory, bad... 30 | } 31 | _tcscpy_s(_AccountName,dwNameLen,AccountName); 32 | _AccountNameLength = dwNameLen; 33 | } 34 | else 35 | { 36 | //account name from gpo null or empty --> use builtin admin account 37 | DWORD dwNameSize=0, dwRefDomainSize=0; 38 | SID_NAME_USE snu; 39 | 40 | bResult = ConvertStringSidToSid(L"LA", &pSID); 41 | bResult = LookupAccountSid(NULL, pSID, NULL, &dwNameSize, NULL, &dwRefDomainSize, &snu); 42 | if (!bResult) 43 | { 44 | DWORD dwErr = GetLastError(); 45 | if (dwErr != ERROR_INSUFFICIENT_BUFFER) 46 | { 47 | hr = HRESULT_FROM_WIN32(dwErr); 48 | goto Cleanup; 49 | } 50 | } 51 | 52 | _AccountName = new(std::nothrow) TCHAR[dwNameSize]; 53 | RefDomain = new(std::nothrow) TCHAR[dwRefDomainSize]; 54 | if (_AccountName == NULL || RefDomain == NULL) 55 | { 56 | hr = HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); 57 | goto Cleanup; //not enough memory, bad... 58 | } 59 | 60 | bResult = LookupAccountSid(NULL, pSID, _AccountName, &dwNameSize, RefDomain, &dwRefDomainSize, &snu); 61 | if (!bResult) 62 | { 63 | hr = HRESULT_FROM_WIN32(GetLastError()); 64 | goto Cleanup; //could not resolve the SID to account, bad... 65 | } 66 | _AccountNameLength = dwNameSize; 67 | } 68 | Cleanup: 69 | if (pSID) 70 | LocalFree(pSID); 71 | if (RefDomain != nullptr) 72 | delete [] RefDomain; 73 | 74 | if (FAILED(hr)) 75 | throw hr; 76 | } 77 | 78 | 79 | AdminAccount::~AdminAccount() 80 | { 81 | if (_AccountName != nullptr) 82 | delete [] _AccountName; 83 | } 84 | 85 | _Use_decl_annotations_ 86 | HRESULT AdminAccount::ResetPassword(LPCTSTR NewPasword) 87 | { 88 | HRESULT hr = S_OK; 89 | USER_INFO_1003 ui1003; 90 | DWORD dwErr = 0; 91 | NET_API_STATUS rslt = NERR_Success; 92 | 93 | ui1003.usri1003_password = const_cast(NewPasword); 94 | 95 | rslt=NetUserSetInfo(nullptr, _AccountName, 1003, (LPBYTE) &ui1003, &dwErr); 96 | if (rslt != NERR_Success) 97 | hr = HRESULT_FROM_WIN32(rslt); 98 | 99 | //flag password change with user account 100 | USER_INFO_1012 ui; 101 | 102 | ui.usri1012_usr_comment = _T("1"); 103 | rslt = NetUserSetInfo(nullptr, _AccountName, 1012, (LPBYTE)&ui, &dwErr); 104 | if (rslt != NERR_Success) 105 | hr = HRESULT_FROM_WIN32(rslt); 106 | 107 | return hr; 108 | } 109 | 110 | _Use_decl_annotations_ 111 | HRESULT AdminAccount::HasPasswordEverManaged(_Out_ bool *pResult) 112 | { 113 | HRESULT hr = S_OK; 114 | LPUSER_INFO_1012 pui = nullptr; 115 | NET_API_STATUS rslt = NERR_Success; 116 | 117 | //this is to prevent ever changing of password in case that NetUserGetInfo() fails 118 | *pResult = true; 119 | 120 | rslt = NetUserGetInfo(nullptr, _AccountName, 1012, (LPBYTE*)&pui); 121 | if (rslt == NERR_Success) 122 | { 123 | *pResult = _tcscmp(pui->usri1012_usr_comment,_T("1"))==0; 124 | } 125 | else 126 | { 127 | hr = HRESULT_FROM_WIN32(rslt); 128 | } 129 | 130 | if (pui != nullptr) 131 | NetApiBufferFree(pui); 132 | 133 | return hr; 134 | } -------------------------------------------------------------------------------- /Main/_Other/ADMX/AdmPwd.admx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /Main/AdmPwd.PS/AdmPwd.PS.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0} 8 | Library 9 | Properties 10 | AdmPwd.PS 11 | AdmPwd.PS 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | False 47 | ..\..\..\..\..\..\..\..\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35\System.Management.Automation.dll 48 | False 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Properties\GlobalAssemblyInfo.cs 58 | 59 | 60 | 61 | 62 | 63 | 64 | Always 65 | 66 | 67 | Always 68 | 69 | 70 | 71 | 72 | {6a55db40-baed-4d53-84a3-659dcaa7e38b} 73 | AdmPwd.Utils 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 91 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Form1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using AdmPwd.Utils; 4 | using AdmPwd.PSTypes; 5 | using AdmPwd.UI.Properties; 6 | 7 | namespace AdmPwd.UI 8 | { 9 | public partial class Form1 : Form 10 | { 11 | public Form1() 12 | { 13 | InitializeComponent(); 14 | } 15 | 16 | private string computerDN=null; 17 | 18 | private void btnSearch_Click(object sender, EventArgs e) 19 | { 20 | try 21 | { 22 | if (string.IsNullOrEmpty(txtComputerName.Text.Trim())) 23 | { 24 | lblStatus.Text = Resources.MustSpecifyComputerName; 25 | return; 26 | } 27 | lblStatus.Text = string.Empty; 28 | string compDN; 29 | 30 | if (txtComputerName.Text.StartsWith("CN=", StringComparison.OrdinalIgnoreCase)) 31 | { 32 | compDN = txtComputerName.Text; 33 | } 34 | else 35 | { 36 | var DNs=DirectoryUtils.GetComputerDN(txtComputerName.Text); 37 | if(DNs.Count==0) { 38 | lblStatus.Text = Resources.ComputerNotFound; 39 | return; 40 | } 41 | if(DNs.Count>1) { 42 | lblStatus.Text = Resources.ComputerNameAmbiguous; 43 | return; 44 | } 45 | compDN = DNs[0]; 46 | } 47 | PasswordInfo pi = DirectoryUtils.GetPasswordInfo(compDN); 48 | if (pi == null) 49 | { 50 | lblStatus.Text = Resources.ComputerNotFound; 51 | return; 52 | } 53 | this.txtPassword.Text = pi.Password; 54 | this.txtCurrentPwdExpiration.Text = pi.ExpirationTimestamp.ToString(); 55 | this.computerDN = pi.DistinguishedName; 56 | } 57 | catch (Exception ex) 58 | { 59 | lblStatus.Text = ex.Message; 60 | txtPassword.Text = string.Empty; 61 | txtCurrentPwdExpiration.Text = string.Empty; 62 | } 63 | } 64 | 65 | private void btnExit_Click(object sender, EventArgs e) 66 | { 67 | this.Close(); 68 | } 69 | 70 | private void btnForceExpiration_Click(object sender, EventArgs e) 71 | { 72 | lblStatus.Text = string.Empty; 73 | if (this.computerDN == null) 74 | { 75 | lblStatus.Text = Resources.NoComputerSelected; 76 | return; 77 | } 78 | DateTime newPwdExpiration = DateTime.Now; 79 | if (!string.IsNullOrEmpty(txtPwdExpiration.Text.Trim())) 80 | { 81 | try 82 | { 83 | newPwdExpiration = System.Convert.ToDateTime(txtPwdExpiration.Text.Trim(),System.Globalization.DateTimeFormatInfo.CurrentInfo); 84 | } 85 | catch (FormatException) 86 | { 87 | lblStatus.Text = Resources.InvalidDateFormat; 88 | return; 89 | } 90 | } 91 | try { 92 | DirectoryUtils.ResetPassword(this.computerDN,newPwdExpiration); 93 | //read back from AD 94 | PasswordInfo pi = DirectoryUtils.GetPasswordInfo(computerDN); 95 | if (pi == null) 96 | { 97 | lblStatus.Text = Resources.ComputerNotFound; 98 | return; 99 | } 100 | this.txtPassword.Text = pi.Password; 101 | this.txtCurrentPwdExpiration.Text = pi.ExpirationTimestamp.ToString(); 102 | this.computerDN = pi.DistinguishedName; 103 | } 104 | catch(Exception) { 105 | lblStatus.Text = Resources.PasswordResetFailed; 106 | return; 107 | } 108 | lblStatus.Text = Resources.PasswordResetSucceeded; 109 | } 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwdMsg.h: -------------------------------------------------------------------------------- 1 | //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2 | // 1 - 10 ... Error events 3 | //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4 | // 5 | // Values are 32 bit values laid out as follows: 6 | // 7 | // 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 8 | // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 | // +---+-+-+-----------------------+-------------------------------+ 10 | // |Sev|C|R| Facility | Code | 11 | // +---+-+-+-----------------------+-------------------------------+ 12 | // 13 | // where 14 | // 15 | // Sev - is the severity code 16 | // 17 | // 00 - Success 18 | // 01 - Informational 19 | // 10 - Warning 20 | // 11 - Error 21 | // 22 | // C - is the Customer code flag 23 | // 24 | // R - is a reserved bit 25 | // 26 | // Facility - is the facility code 27 | // 28 | // Code - is the facility's status code 29 | // 30 | // 31 | // Define the facility codes 32 | // 33 | 34 | 35 | // 36 | // Define the severity codes 37 | // 38 | #define STATUS_SEVERITY_SUCCESS 0x0 39 | #define STATUS_SEVERITY_INFORMATIONAL 0x1 40 | #define STATUS_SEVERITY_WARNING 0x2 41 | #define STATUS_SEVERITY_ERROR 0x3 42 | 43 | 44 | // 45 | // MessageId: S_GET_COMPUTER 46 | // 47 | // MessageText: 48 | // 49 | // Could not get computer object from AD. Error %1. 50 | // 51 | #define S_GET_COMPUTER 0xC0000002L 52 | 53 | // 54 | // MessageId: S_GET_ADMIN 55 | // 56 | // MessageText: 57 | // 58 | // Could not get local Administrator account. Error %1. 59 | // 60 | #define S_GET_ADMIN 0xC0000003L 61 | 62 | // 63 | // MessageId: S_GET_TIMESTAMP 64 | // 65 | // MessageText: 66 | // 67 | // Could not get password expiration timestamp from computer account in AD. Error %1. 68 | // 69 | #define S_GET_TIMESTAMP 0xC0000004L 70 | 71 | // 72 | // MessageId: S_CHANGE_PWD 73 | // 74 | // MessageText: 75 | // 76 | // Could not reset local Administrator's password. Error %1. 77 | // 78 | #define S_CHANGE_PWD 0xC0000006L 79 | 80 | // 81 | // MessageId: S_REPORT_PWD 82 | // 83 | // MessageText: 84 | // 85 | // Could not write changed password to AD. Error %1. 86 | // 87 | #define S_REPORT_PWD 0xC0000007L 88 | 89 | // 90 | // MessageId: S_EXPIRATION_TOO_LONG 91 | // 92 | // MessageText: 93 | // 94 | // Password expiration too long for computer (%1 days). Resetting password now. 95 | // 96 | #define S_EXPIRATION_TOO_LONG 0x8000000AL 97 | 98 | //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 99 | // 11 - 20 ... Informational events 100 | //;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 101 | // 102 | // MessageId: S_CHANGE_PWD_NOT_YET 103 | // 104 | // MessageText: 105 | // 106 | // It is not necessary to change password yet. Days to change: %1. 107 | // 108 | #define S_CHANGE_PWD_NOT_YET 0x4000000BL 109 | 110 | // 111 | // MessageId: S_CHANGE_PWD_SUCCESS 112 | // 113 | // MessageText: 114 | // 115 | // Local Administrator's password has been changed. 116 | // 117 | #define S_CHANGE_PWD_SUCCESS 0x4000000CL 118 | 119 | // 120 | // MessageId: S_REPORT_PWD_SUCCESS 121 | // 122 | // MessageText: 123 | // 124 | // Local Administrator's password has been reported to AD. 125 | // 126 | #define S_REPORT_PWD_SUCCESS 0x4000000DL 127 | 128 | // 129 | // MessageId: S_FINISHED 130 | // 131 | // MessageText: 132 | // 133 | // Finished successfully. 134 | // 135 | #define S_FINISHED 0x4000000EL 136 | 137 | // 138 | // MessageId: S_STARTED 139 | // 140 | // MessageText: 141 | // 142 | // Beginning processing. 143 | // 144 | #define S_STARTED 0x4000000FL 145 | 146 | // 147 | // MessageId: S_NOT_ENABLED 148 | // 149 | // MessageText: 150 | // 151 | // Admin account management not enabled, exiting. 152 | // 153 | #define S_NOT_ENABLED 0x40000010L 154 | 155 | // 156 | // MessageId: S_NEVER_MANAGED 157 | // 158 | // MessageText: 159 | // 160 | // Admin account was never managed. Changing the password now. 161 | // 162 | #define S_NEVER_MANAGED 0x40000011L 163 | 164 | -------------------------------------------------------------------------------- /Main/AdmPwd/PasswordGenerator.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | #include "stdafx.h" 4 | extern wchar_t* DICTIONARY[MAX_PWD_COMPLEXITY]; 5 | 6 | typedef struct _DictionaryItem { 7 | size_t Length; //length of charset 8 | wchar_t *Value; //charset 9 | unsigned int Boundary; //boundary for unbiased randoms 10 | } DictionaryItem; 11 | 12 | class PasswordGenerator 13 | { 14 | public: 15 | 16 | PasswordGenerator(_In_ unsigned int Complexity, _In_ unsigned int Length) 17 | { 18 | //complexity: 19 | // 1=large letters 20 | // 2=large_letters+small letters 21 | // 3=large_letters + small_letters + numbers 22 | // 4=large_letters + small_letters + numbers + spec_chars 23 | if (Complexity < 1 || Complexity > MAX_PWD_COMPLEXITY) 24 | _complexity = MAX_PWD_COMPLEXITY; 25 | else 26 | _complexity = Complexity; 27 | 28 | _complexityBoundary = (((unsigned int)(-1)) / _complexity)*_complexity; 29 | //length must be at least the same as complexity to fulfill complexity requirement 30 | _length = Length > _complexity ? Length : _complexity; 31 | 32 | _dictionary = new(std::nothrow) DictionaryItem[_complexity](); 33 | if (_dictionary == nullptr) 34 | throw HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); 35 | 36 | for (unsigned int i = 0; i < _complexity; i++) 37 | { 38 | _dictionary[i].Value = DICTIONARY[i]; 39 | //just be secure here, although we know which data we're processing 40 | HRESULT hr = StringCchLength(DICTIONARY[i], STRSAFE_MAX_CCH, &(_dictionary[i].Length)); 41 | if (FAILED(hr)) 42 | throw hr; 43 | //compute proper boundary for generated randoms that avoids bias when doing modulus 44 | _dictionary[i].Boundary = (unsigned int)((((unsigned int)-1) / _dictionary[i].Length)*_dictionary[i].Length); 45 | } 46 | 47 | _bUsed = new(std::nothrow) bool[_complexity](); 48 | if (_bUsed == nullptr) 49 | throw HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); 50 | 51 | NTSTATUS rslt = BCryptOpenAlgorithmProvider(&_hProv, BCRYPT_RNG_ALGORITHM, nullptr, 0); 52 | if (rslt != ERROR_SUCCESS) 53 | throw HRESULT_FROM_WIN32(rslt); 54 | } 55 | 56 | ~PasswordGenerator() 57 | { 58 | if (_dictionary != nullptr) 59 | delete[] _dictionary; 60 | if (_bUsed != nullptr) 61 | delete[] _bUsed; 62 | 63 | ReleasePassword(); 64 | 65 | if (_hProv != 0) 66 | BCryptCloseAlgorithmProvider(_hProv, 0); 67 | } 68 | 69 | void Generate() { 70 | 71 | unsigned int dict; 72 | unsigned int pos; 73 | 74 | ReleasePassword(); 75 | AllocatePassword(); 76 | 77 | for (unsigned int i = 0; i < _length; i++) { 78 | if (i >= _length - _complexity && _bUsed[_length - i - 1] == false) 79 | { 80 | //this ensures that all required dictionaries are used at least once with maximum amount of randomness 81 | dict = _length - i - 1; 82 | } 83 | else 84 | { 85 | dict = GetRandom(_complexity, _complexityBoundary); 86 | } 87 | _bUsed[dict] = true; 88 | pos = GetRandom((unsigned int)_dictionary[dict].Length, _dictionary[dict].Boundary); 89 | _pNewPwd[i] = _dictionary[dict].Value[pos]; 90 | } 91 | } 92 | 93 | //Current password complexity 94 | __declspec(property(get = GET_PasswordComplexity)) unsigned int PasswordComplexity; 95 | unsigned int GET_PasswordComplexity() { 96 | return _complexity; 97 | }; 98 | 99 | //Current password 100 | __declspec(property(get = GET_Password)) LPCTSTR Password; 101 | LPCTSTR GET_Password() { 102 | return _pNewPwd; 103 | }; 104 | 105 | private: 106 | DictionaryItem* _dictionary = nullptr; 107 | 108 | unsigned int _complexity; 109 | unsigned int _length; 110 | unsigned int _complexityBoundary; 111 | 112 | bool *_bUsed = nullptr; 113 | 114 | TCHAR *_pNewPwd = nullptr; 115 | 116 | BCRYPT_ALG_HANDLE _hProv = 0; 117 | 118 | void ReleasePassword() 119 | { 120 | if (_pNewPwd != nullptr) 121 | { 122 | SecureZeroMemory(_pNewPwd, _length * sizeof(_pNewPwd[0])); 123 | delete[] _pNewPwd; 124 | _pNewPwd = nullptr; 125 | } 126 | } 127 | 128 | void AllocatePassword() 129 | { 130 | _pNewPwd = new(std::nothrow) TCHAR[_length + 1](); 131 | if (_pNewPwd == nullptr) 132 | throw HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); 133 | ZeroMemory(_pNewPwd, _length * sizeof(_pNewPwd[0])); 134 | for (unsigned int i = 0; i < _complexity; i++) 135 | _bUsed[i] = false; 136 | } 137 | 138 | unsigned int GetRandom(unsigned int boundary, unsigned int rangeUpperExclusive) 139 | { 140 | unsigned int nRandom = INT_MAX; 141 | do { 142 | BCryptGenRandom(_hProv, (LPBYTE)&nRandom, sizeof(nRandom), 0); 143 | if (nRandom < rangeUpperExclusive) 144 | { 145 | return nRandom % boundary; 146 | } 147 | } while (true); 148 | } 149 | }; 150 | 151 | -------------------------------------------------------------------------------- /Main/AdmPwd/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // AdmPwd.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | #include "stdafx.h" 5 | #include "Constants.h" 6 | #include "Config.h" 7 | 8 | HINSTANCE hDll=(HINSTANCE)INVALID_HANDLE_VALUE; 9 | wchar_t* DICTIONARY [] = { L"ABCDEFGHIJKLMNOPQRSTUVWXYZ", L"abcdefghijklmnopqrstuvwxyz", L"0123456789", L",.-+;!#&@{}[]+$/()%|" }; 10 | 11 | //DllMain, Installation, Uninstallation 12 | BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason, LPVOID lpReserved) { 13 | if(ul_reason==DLL_PROCESS_ATTACH) { 14 | hDll=(HINSTANCE)hModule; 15 | } 16 | return TRUE; 17 | } 18 | 19 | //unregistration routine 20 | STDAPI DllUnregisterServer() { 21 | LSTATUS status=ERROR_SUCCESS; 22 | HRESULT hr=S_OK; 23 | 24 | status=SHDeleteKey(HKEY_LOCAL_MACHINE, GPEXT_REG_PATH); 25 | if(status!=ERROR_SUCCESS) { 26 | //CSE not registered and we run unregistration 27 | if(status==ERROR_FILE_NOT_FOUND) 28 | hr=S_OK; 29 | else 30 | hr=HRESULT_FROM_WIN32(status); 31 | } 32 | status=SHDeleteKey(HKEY_LOCAL_MACHINE, GPEXT_REG_PATH_EVT); 33 | if(status!=ERROR_SUCCESS) { 34 | //CSE not registered and we run unregistration 35 | if(status==ERROR_FILE_NOT_FOUND) 36 | hr=S_OK; 37 | else 38 | hr=HRESULT_FROM_WIN32(status); 39 | } 40 | return hr; 41 | } 42 | 43 | //registration routine 44 | //registers CSE with winlogon/gpsvc 45 | //registers DLL as event source for application event log 46 | STDAPI DllRegisterServer() 47 | { 48 | HKEY hKey=0; 49 | LONG lResult; 50 | size_t size; 51 | DWORD dwData; 52 | 53 | LPTSTR szPathBuff=NULL; 54 | 55 | __try { 56 | szPathBuff=new(std::nothrow) TCHAR[MAX_PATH]; 57 | lResult=::GetModuleFileName((HINSTANCE)hDll, szPathBuff, MAX_PATH); 58 | // Register extension. 59 | if( lResult == 0 ) __leave; 60 | 61 | //this is to handle the scenario when replacing existing dll 62 | //and registering the new version using code running within module with temporary name 63 | //installer might replaced extension ".new", so we're replacing here back to ".dll" 64 | PathRenameExtension(szPathBuff,FINAL_FILE_EXTENSION); 65 | 66 | lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, 67 | GPEXT_REG_PATH, 68 | 0, 69 | NULL, 70 | REG_OPTION_NON_VOLATILE, 71 | KEY_WRITE, 72 | NULL, 73 | &hKey, 74 | NULL); 75 | 76 | if( lResult != ERROR_SUCCESS ) __leave; 77 | 78 | //Name of entry point 79 | size=sizeof(ENTRY_POINT); 80 | lResult = RegSetValueEx( hKey, 81 | L"ProcessGroupPolicy", 82 | 0, 83 | REG_SZ, 84 | (BYTE*)ENTRY_POINT, 85 | size); 86 | if( lResult != ERROR_SUCCESS ) __leave; 87 | 88 | //Name of extension 89 | size=sizeof(EXTENSION_NAME); 90 | lResult = RegSetValueEx( hKey, 91 | NULL, 92 | 0, 93 | REG_SZ, 94 | (BYTE*)EXTENSION_NAME, 95 | size); 96 | if( lResult != ERROR_SUCCESS ) __leave; 97 | 98 | // Path to DLL 99 | ::StringCbLength(szPathBuff,MAX_PATH,&size); 100 | lResult = RegSetValueEx( hKey, 101 | L"DllName", 102 | 0, 103 | REG_EXPAND_SZ, 104 | (BYTE*)szPathBuff, 105 | size ); 106 | if( lResult != ERROR_SUCCESS ) __leave; 107 | 108 | //we don't want be called when refreshing user policy 109 | dwData=1; 110 | lResult = RegSetValueEx( hKey, 111 | L"NoUserPolicy", 112 | 0, 113 | REG_DWORD, 114 | (BYTE*)&dwData, 115 | sizeof(DWORD) ); 116 | if( lResult != ERROR_SUCCESS ) __leave; 117 | 118 | RegCloseKey(hKey); 119 | 120 | //Register event log message file 121 | lResult = RegCreateKeyEx( HKEY_LOCAL_MACHINE, 122 | GPEXT_REG_PATH_EVT, 123 | 0, 124 | NULL, 125 | REG_OPTION_NON_VOLATILE, 126 | KEY_WRITE, 127 | NULL, 128 | &hKey, 129 | NULL); 130 | 131 | if( lResult != ERROR_SUCCESS ) __leave; 132 | 133 | //Path to DLL 134 | ::StringCbLength(szPathBuff,MAX_PATH,&size); 135 | lResult = RegSetValueEx( hKey, 136 | L"EventMessageFile", 137 | 0, 138 | REG_EXPAND_SZ, 139 | (BYTE*)szPathBuff, 140 | size); 141 | if( lResult != ERROR_SUCCESS ) __leave; 142 | 143 | //we provide event log with errors and successes 144 | dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_INFORMATION_TYPE | EVENTLOG_WARNING_TYPE; 145 | lResult = RegSetValueEx( hKey, 146 | L"TypesSupported", 147 | 0, 148 | REG_DWORD, 149 | (BYTE*)&dwData, 150 | sizeof(DWORD) ); 151 | if( lResult != ERROR_SUCCESS ) __leave; 152 | 153 | } 154 | __finally { 155 | //Close the registry key if necessary 156 | if(hKey) RegCloseKey( hKey ); 157 | } 158 | 159 | return lResult; 160 | } 161 | 162 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/AdmPwd.UI.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68} 8 | WinExe 9 | Properties 10 | AdmPwd.UI 11 | AdmPwd.UI 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | ..\Solution Items\app.ico 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | Properties\GlobalAssemblyInfo.cs 57 | 58 | 59 | Form 60 | 61 | 62 | Form1.cs 63 | 64 | 65 | 66 | 67 | Form1.cs 68 | 69 | 70 | ResXFileCodeGenerator 71 | Resources.Designer.cs 72 | Designer 73 | 74 | 75 | True 76 | Resources.resx 77 | True 78 | 79 | 80 | 81 | SettingsSingleFileGenerator 82 | Settings.Designer.cs 83 | 84 | 85 | True 86 | Settings.settings 87 | True 88 | 89 | 90 | 91 | 92 | {6a55db40-baed-4d53-84a3-659dcaa7e38b} 93 | AdmPwd.Utils 94 | 95 | 96 | 97 | 98 | 99 | 100 | 107 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | *.VC.VC.opendb 85 | 86 | # Visual Studio profiler 87 | *.psess 88 | *.vsp 89 | *.vspx 90 | *.sap 91 | 92 | # TFS 2012 Local Workspace 93 | $tf/ 94 | 95 | # Guidance Automation Toolkit 96 | *.gpState 97 | 98 | # ReSharper is a .NET coding add-in 99 | _ReSharper*/ 100 | *.[Rr]e[Ss]harper 101 | *.DotSettings.user 102 | 103 | # JustCode is a .NET coding add-in 104 | .JustCode 105 | 106 | # TeamCity is a build add-in 107 | _TeamCity* 108 | 109 | # DotCover is a Code Coverage Tool 110 | *.dotCover 111 | 112 | # NCrunch 113 | _NCrunch_* 114 | .*crunch*.local.xml 115 | nCrunchTemp_* 116 | 117 | # MightyMoose 118 | *.mm.* 119 | AutoTest.Net/ 120 | 121 | # Web workbench (sass) 122 | .sass-cache/ 123 | 124 | # Installshield output folder 125 | [Ee]xpress/ 126 | 127 | # DocProject is a documentation generator add-in 128 | DocProject/buildhelp/ 129 | DocProject/Help/*.HxT 130 | DocProject/Help/*.HxC 131 | DocProject/Help/*.hhc 132 | DocProject/Help/*.hhk 133 | DocProject/Help/*.hhp 134 | DocProject/Help/Html2 135 | DocProject/Help/html 136 | 137 | # Click-Once directory 138 | publish/ 139 | 140 | # Publish Web Output 141 | *.[Pp]ublish.xml 142 | *.azurePubxml 143 | # TODO: Comment the next line if you want to checkin your web deploy settings 144 | # but database connection strings (with potential passwords) will be unencrypted 145 | *.pubxml 146 | *.publishproj 147 | 148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 149 | # checkin your Azure Web App publish settings, but sensitive information contained 150 | # in these scripts will be unencrypted 151 | PublishScripts/ 152 | 153 | # NuGet Packages 154 | *.nupkg 155 | # The packages folder can be ignored because of Package Restore 156 | **/packages/* 157 | # except build/, which is used as an MSBuild target. 158 | !**/packages/build/ 159 | # Uncomment if necessary however generally it will be regenerated when needed 160 | #!**/packages/repositories.config 161 | # NuGet v3's project.json files produces more ignoreable files 162 | *.nuget.props 163 | *.nuget.targets 164 | 165 | # Microsoft Azure Build Output 166 | csx/ 167 | *.build.csdef 168 | 169 | # Microsoft Azure Emulator 170 | ecf/ 171 | rcf/ 172 | 173 | # Windows Store app package directories and files 174 | AppPackages/ 175 | BundleArtifacts/ 176 | Package.StoreAssociation.xml 177 | _pkginfo.txt 178 | 179 | # Visual Studio cache files 180 | # files ending in .cache can be ignored 181 | *.[Cc]ache 182 | # but keep track of directories ending in .cache 183 | !*.[Cc]ache/ 184 | 185 | # Others 186 | ClientBin/ 187 | ~$* 188 | *~ 189 | *.dbmdl 190 | *.dbproj.schemaview 191 | *.pfx 192 | *.publishsettings 193 | node_modules/ 194 | orleans.codegen.cs 195 | 196 | # Since there are multiple workflows, uncomment next line to ignore bower_components 197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 198 | #bower_components/ 199 | 200 | # RIA/Silverlight projects 201 | Generated_Code/ 202 | 203 | # Backup & report files from converting an old project file 204 | # to a newer Visual Studio version. Backup files are not needed, 205 | # because we have git ;-) 206 | _UpgradeReport_Files/ 207 | Backup*/ 208 | UpgradeLog*.XML 209 | UpgradeLog*.htm 210 | 211 | # SQL Server files 212 | *.mdf 213 | *.ldf 214 | 215 | # Business Intelligence projects 216 | *.rdl.data 217 | *.bim.layout 218 | *.bim_*.settings 219 | 220 | # Microsoft Fakes 221 | FakesAssemblies/ 222 | 223 | # GhostDoc plugin setting file 224 | *.GhostDoc.xml 225 | 226 | # Node.js Tools for Visual Studio 227 | .ntvs_analysis.dat 228 | 229 | # Visual Studio 6 build log 230 | *.plg 231 | 232 | # Visual Studio 6 workspace options file 233 | *.opt 234 | 235 | # Visual Studio LightSwitch build output 236 | **/*.HTMLClient/GeneratedArtifacts 237 | **/*.DesktopClient/GeneratedArtifacts 238 | **/*.DesktopClient/ModelManifest.xml 239 | **/*.Server/GeneratedArtifacts 240 | **/*.Server/ModelManifest.xml 241 | _Pvt_Extensions 242 | 243 | # Paket dependency manager 244 | .paket/paket.exe 245 | paket-files/ 246 | 247 | # FAKE - F# Make 248 | .fake/ 249 | 250 | # JetBrains Rider 251 | .idea/ 252 | *.sln.iml 253 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace AdmPwd.UI.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AdmPwd.UI.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | 63 | /// 64 | /// Looks up a localized string similar to Computer name ambiguous, use DN instead of computer name. 65 | /// 66 | internal static string ComputerNameAmbiguous { 67 | get { 68 | return ResourceManager.GetString("ComputerNameAmbiguous", resourceCulture); 69 | } 70 | } 71 | 72 | /// 73 | /// Looks up a localized string similar to Computer not found. 74 | /// 75 | internal static string ComputerNotFound { 76 | get { 77 | return ResourceManager.GetString("ComputerNotFound", resourceCulture); 78 | } 79 | } 80 | 81 | /// 82 | /// Looks up a localized string similar to Invalid format of date/time. 83 | /// 84 | internal static string InvalidDateFormat { 85 | get { 86 | return ResourceManager.GetString("InvalidDateFormat", resourceCulture); 87 | } 88 | } 89 | 90 | /// 91 | /// Looks up a localized string similar to You must enter a computer name. 92 | /// 93 | internal static string MustSpecifyComputerName { 94 | get { 95 | return ResourceManager.GetString("MustSpecifyComputerName", resourceCulture); 96 | } 97 | } 98 | 99 | /// 100 | /// Looks up a localized string similar to No computer selected. 101 | /// 102 | internal static string NoComputerSelected { 103 | get { 104 | return ResourceManager.GetString("NoComputerSelected", resourceCulture); 105 | } 106 | } 107 | 108 | /// 109 | /// Looks up a localized string similar to Failed to request password reset. 110 | /// 111 | internal static string PasswordResetFailed { 112 | get { 113 | return ResourceManager.GetString("PasswordResetFailed", resourceCulture); 114 | } 115 | } 116 | 117 | /// 118 | /// Looks up a localized string similar to Password reset request was successful. 119 | /// 120 | internal static string PasswordResetSucceeded { 121 | get { 122 | return ResourceManager.GetString("PasswordResetSucceeded", resourceCulture); 123 | } 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /Main/AdmPwd/Computer.cpp: -------------------------------------------------------------------------------- 1 | #include "stdafx.h" 2 | #include "Computer.h" 3 | #include "Constants.h" 4 | #include "resource.h" 5 | 6 | 7 | Computer::Computer() 8 | { 9 | ULONG retVal=LDAP_SUCCESS; 10 | ULONG buffLen; 11 | 12 | //initialize members 13 | _pwdExpiration = 0; 14 | _conn=nullptr; 15 | _dn = nullptr; 16 | //end of init 17 | 18 | if (!GetComputerObjectName(NameFullyQualifiedDN, _dn, &buffLen)) 19 | throw HRESULT_FROM_WIN32(GetLastError()); 20 | _dn = new(std::nothrow) TCHAR[buffLen]; 21 | if (!GetComputerObjectName(NameFullyQualifiedDN, _dn, &buffLen)) 22 | throw HRESULT_FROM_WIN32(GetLastError()); 23 | 24 | //initialize connection 25 | _conn = ldap_init(nullptr, LDAP_PORT); 26 | if (_conn==nullptr) 27 | throw HRESULT_FROM_WIN32(LdapGetLastError()); 28 | //require encryption 29 | retVal = ldap_set_option(_conn, LDAP_OPT_ENCRYPT, LDAP_OPT_ON); 30 | if(retVal != LDAP_SUCCESS) 31 | throw HRESULT_FROM_WIN32(retVal); 32 | //require signing 33 | retVal = ldap_set_option(_conn, LDAP_OPT_SIGN, LDAP_OPT_ON); 34 | if (retVal != LDAP_SUCCESS) 35 | throw HRESULT_FROM_WIN32(retVal); 36 | //require writable DC 37 | ULONG flags = DS_WRITABLE_REQUIRED; 38 | retVal = ldap_set_option(_conn, LDAP_OPT_GETDSNAME_FLAGS, &flags); 39 | if (retVal != LDAP_SUCCESS) 40 | throw HRESULT_FROM_WIN32(retVal); 41 | 42 | //bind 43 | retVal = ldap_bind_s(_conn, nullptr, nullptr, LDAP_AUTH_NEGOTIATE); 44 | if (retVal != LDAP_SUCCESS) 45 | throw HRESULT_FROM_WIN32(retVal); 46 | } 47 | 48 | Computer::~Computer() 49 | { 50 | if (_dn != nullptr) 51 | delete [] _dn; 52 | if (_conn != nullptr) 53 | ldap_unbind_s(_conn); 54 | } 55 | 56 | 57 | HRESULT Computer::Load() 58 | { 59 | HRESULT hr = S_OK; 60 | BerElement *pBer = nullptr; 61 | LDAPMessage* rslt = nullptr; 62 | TCHAR* pAttribute = nullptr; 63 | TCHAR** ppValues = nullptr; 64 | 65 | TCHAR attrName[MAX_ATTR_NAME]; 66 | ZeroMemory(attrName, MAX_ATTR_NAME*sizeof(TCHAR)); 67 | 68 | int nChars = 0; 69 | 70 | extern HINSTANCE hDll; 71 | 72 | //retrieve timestamp 73 | nChars = ::LoadString(hDll, IDS_ATTR_PWD_TIMESTAMP, attrName, MAX_ATTR_NAME); 74 | if (nChars == 0) 75 | { 76 | hr = HRESULT_FROM_WIN32(GetLastError()); 77 | goto Cleanup; 78 | } 79 | TCHAR *attrs[2]; 80 | attrs[0] = attrName; 81 | attrs[1] = nullptr; 82 | //load the computer object 83 | if (LDAP_SUCCESS != ldap_search_s(_conn, _dn, LDAP_SCOPE_BASE, _T("(objectClass=*)"), attrs, 0, &rslt)) 84 | { 85 | hr = HRESULT_FROM_WIN32(GetLastError()); 86 | goto Cleanup; 87 | } 88 | //should be always one entry 89 | ULONG numEntries = ldap_count_entries(_conn, rslt); 90 | if (numEntries < 1) 91 | { 92 | if (_conn->ld_errno!=0) 93 | hr = HRESULT_FROM_WIN32(_conn->ld_errno); 94 | else 95 | hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 96 | goto Cleanup; 97 | } 98 | 99 | //get the entry. Does not to be explicitly freed as it's freed with rslt 100 | LDAPMessage *entry = ldap_first_entry(_conn, rslt); 101 | 102 | //get attribute name 103 | pAttribute = ldap_first_attribute(_conn, entry, &pBer); 104 | if (pAttribute == NULL) 105 | { 106 | if (_conn->ld_errno != 0) 107 | //error in processing 108 | hr = HRESULT_FROM_WIN32(_conn->ld_errno); 109 | else 110 | //processing OK but attribute not found 111 | hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); 112 | goto Cleanup; 113 | } 114 | 115 | ppValues = ldap_get_values(_conn, entry, pAttribute); 116 | if (_conn->ld_errno != 0) 117 | { 118 | hr = HRESULT_FROM_WIN32(_conn->ld_errno); 119 | goto Cleanup; 120 | } 121 | ULONG numValues = ldap_count_values(ppValues); 122 | 123 | if (numValues > 0) 124 | _stscanf_s(*ppValues, _T("%I64u"), &_pwdExpiration); 125 | 126 | Cleanup: 127 | if (rslt!=nullptr) 128 | ldap_msgfree(rslt); 129 | if (pBer != nullptr) 130 | ber_free(pBer,0); 131 | if (ppValues != nullptr) 132 | ldap_value_free(ppValues); 133 | if (pAttribute != nullptr) 134 | ldap_memfree(pAttribute); 135 | 136 | return hr; 137 | } 138 | 139 | 140 | _Use_decl_annotations_ 141 | HRESULT Computer::ReportPassword(LPCTSTR password, FILETIME* timestamp, DWORD dwPasswordAge) 142 | { 143 | LDAPMod ts, pwd; 144 | ULARGE_INTEGER uli; 145 | HRESULT hr = S_OK; 146 | int nChars = 0; 147 | 148 | TCHAR attrTSName[MAX_ATTR_NAME]; 149 | ZeroMemory(attrTSName, MAX_ATTR_NAME*sizeof(TCHAR)); 150 | 151 | TCHAR attrPwdName[MAX_ATTR_NAME]; 152 | ZeroMemory(attrPwdName, MAX_ATTR_NAME*sizeof(TCHAR)); 153 | 154 | extern HINSTANCE hDll; 155 | 156 | //timestamp 157 | //get attribute name from string table 158 | nChars = ::LoadString(hDll, IDS_ATTR_PWD_TIMESTAMP, attrTSName, MAX_ATTR_NAME); 159 | if (nChars == 0) 160 | { 161 | hr = HRESULT_FROM_WIN32(GetLastError()); 162 | goto Cleanup; 163 | } 164 | TCHAR tsBuff[32]; 165 | uli.LowPart = timestamp->dwLowDateTime; 166 | uli.HighPart = timestamp->dwHighDateTime; 167 | uli.QuadPart += (ULONGLONG) dwPasswordAge*TICKS_IN_DAY; 168 | _stprintf_s(tsBuff, 31, _T("%I64u"), uli.QuadPart); 169 | TCHAR* pTimestamp [] = { tsBuff, nullptr }; 170 | ts.mod_op = LDAP_MOD_REPLACE; 171 | ts.mod_type = attrTSName; 172 | ts.mod_values = pTimestamp; 173 | 174 | //password 175 | nChars = ::LoadString(hDll, IDS_ATTR_PWD, attrPwdName, MAX_ATTR_NAME); 176 | if (nChars == 0) 177 | { 178 | hr = HRESULT_FROM_WIN32(GetLastError()); 179 | goto Cleanup; 180 | } 181 | TCHAR* pPassword[2] = { const_cast(password), nullptr }; 182 | pwd.mod_op = LDAP_MOD_REPLACE; 183 | pwd.mod_type = attrPwdName; 184 | pwd.mod_values = pPassword; 185 | 186 | LDAPMod *mods [] = { &ts, &pwd, nullptr}; 187 | 188 | ULONG rslt=ldap_modify_s(_conn, _dn, mods); 189 | if (rslt != LDAP_SUCCESS) 190 | hr= HRESULT_FROM_WIN32(rslt); 191 | 192 | Cleanup: 193 | 194 | return hr; 195 | } 196 | 197 | -------------------------------------------------------------------------------- /Main/AdmPwd.PS/AdmPwd.PS.format.ps1xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ExtendedRightsInfo 6 | 7 | AdmPwd.PSTypes.ExtendedRightsInfo 8 | 9 | 10 | 11 | 12 | 45 13 | 14 | 15 | 60 16 | 17 | 18 | 19 | 20 | 21 | 22 | ObjectDN 23 | 24 | 25 | ExtendedRightHolders 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | PasswordInfo 34 | 35 | AdmPwd.PSTypes.PasswordInfo 36 | 37 | 38 | 39 | 40 | 20 41 | 42 | 43 | 45 44 | 45 | 46 | 18 47 | 48 | 49 | 20 50 | 51 | 52 | 53 | 54 | 55 | 56 | ComputerName 57 | 58 | 59 | DistinguishedName 60 | 61 | 62 | Password 63 | 64 | 65 | ExpirationTimestamp 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | OrgUnitInfo 74 | 75 | AdmPwd.PSTypes.ObjectInfo 76 | 77 | 78 | 79 | 80 | 20 81 | 82 | 83 | 65 84 | 85 | 86 | 20 87 | 88 | 89 | 90 | 91 | 92 | 93 | Name 94 | 95 | 96 | DistinguishedName 97 | 98 | 99 | Status 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | OperationStatus 108 | 109 | AdmPwd.PSTypes.DirectoryOperationStatus 110 | 111 | 112 | 113 | 114 | 20 115 | 116 | 117 | 65 118 | 119 | 120 | 25 121 | 122 | 123 | 124 | 125 | 126 | 127 | Operation 128 | 129 | 130 | DistinguishedName 131 | 132 | 133 | Status 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | PasswordResetStatus 142 | 143 | AdmPwd.PSTypes.PasswordResetStatus 144 | 145 | 146 | 147 | 148 | 65 149 | 150 | 151 | 25 152 | 153 | 154 | 155 | 156 | 157 | 158 | DistinguishedName 159 | 160 | 161 | Status 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | -------------------------------------------------------------------------------- /Main/AdmPwd.Utils/PSTypes.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Text; 5 | using System.DirectoryServices.Protocols; 6 | using System.Security.Principal; 7 | using System.Xml.Linq; 8 | using System.Linq; 9 | 10 | namespace AdmPwd.PSTypes 11 | { 12 | #region Enums 13 | 14 | public enum SchemaObjectType 15 | { 16 | Attribute = 0, 17 | Class 18 | } 19 | 20 | public enum PasswordResetState 21 | { 22 | PasswordReset = 0 23 | } 24 | 25 | public enum PermissionDelegationState 26 | { 27 | Unknown = 0, 28 | Delegated 29 | } 30 | 31 | public enum DirectoryOperationType 32 | { 33 | AddSchemaAttribute = 0, 34 | ModifySchemaClass 35 | } 36 | 37 | #endregion 38 | 39 | #region Output data 40 | public class ExtendedRightsInfo 41 | { 42 | public string ObjectDN { get { return DN; } } 43 | public ReadOnlyCollection ExtendedRightHolders 44 | { 45 | get 46 | { 47 | return new ReadOnlyCollection(erh); 48 | } 49 | } 50 | public ExtendedRightsInfo(string dn,List holders) 51 | { 52 | DN = dn; 53 | erh = holders; 54 | } 55 | string DN; 56 | List erh; 57 | } 58 | 59 | public class PasswordInfo 60 | { 61 | private string _computerName; 62 | private string _distinguishedName; 63 | private string _password; 64 | private DateTime _expirationTimestamp; 65 | 66 | public string ComputerName 67 | { 68 | get { return _computerName; } 69 | set { _computerName = value; } 70 | } 71 | 72 | public string DistinguishedName 73 | { 74 | get { return _distinguishedName; } 75 | set { _distinguishedName = value; } 76 | } 77 | 78 | public string Password 79 | { 80 | get { return _password; } 81 | set { _password = value; } 82 | } 83 | 84 | public DateTime ExpirationTimestamp 85 | { 86 | get { return _expirationTimestamp; } 87 | set { _expirationTimestamp = value; } 88 | } 89 | public PasswordInfo(string DistinguishedName) 90 | { 91 | this._distinguishedName = DistinguishedName; 92 | } 93 | } 94 | 95 | public class ObjectInfo 96 | { 97 | public string Name { get { return N; } } 98 | public string DistinguishedName { get { return DN; } } 99 | public PermissionDelegationState Status { get { return PDS; } } 100 | 101 | public ObjectInfo(string name, string dn, PermissionDelegationState status) 102 | { 103 | N = name; 104 | DN = dn; 105 | PDS = status; 106 | } 107 | 108 | string N; 109 | string DN; 110 | PermissionDelegationState PDS; 111 | } 112 | 113 | public class ForestInfo 114 | { 115 | private DomainInfo _rootDomain; 116 | private string _configurationNamingContext; 117 | private string _schemaNamingContext; 118 | 119 | public DomainInfo RootDomain 120 | { 121 | get { return _rootDomain; } 122 | set { _rootDomain = value; } 123 | } 124 | 125 | public string ConfigurationNamingContext 126 | { 127 | get { return _configurationNamingContext; } 128 | set { _configurationNamingContext = value; } 129 | } 130 | 131 | public string SchemaNamingContext 132 | { 133 | get { return _schemaNamingContext; } 134 | set { _schemaNamingContext = value; } 135 | } 136 | public ForestInfo() 137 | { 138 | _rootDomain = new DomainInfo(); 139 | } 140 | } 141 | 142 | public class DomainInfo 143 | { 144 | private string _dnsName; 145 | private string _connectedHost; 146 | private SecurityIdentifier _sid; 147 | private string _dn; 148 | 149 | public string DnsName 150 | { 151 | get { return _dnsName; } 152 | set { _dnsName = value; } 153 | } 154 | 155 | public string Dn 156 | { 157 | get { return _dn; } 158 | set { _dn = value; } 159 | } 160 | 161 | public string ConnectedHost 162 | { 163 | get { return _connectedHost; } 164 | set { _connectedHost = value; } 165 | } 166 | 167 | public SecurityIdentifier Sid 168 | { 169 | get { return _sid; } 170 | set { _sid = value; } 171 | } 172 | } 173 | 174 | public class PasswordResetStatus 175 | { 176 | public string DistinguishedName { get { return DN; } } 177 | public PasswordResetState Status { get { return PRS; } } 178 | 179 | public PasswordResetStatus(string dn, PasswordResetState state) 180 | { 181 | DN = dn; 182 | PRS = state; 183 | } 184 | 185 | string DN; 186 | PasswordResetState PRS; 187 | } 188 | 189 | public class DirectoryOperationStatus 190 | { 191 | public DirectoryOperationType Operation 192 | { 193 | get 194 | { 195 | return DOT; 196 | } 197 | } 198 | public string DistinguishedName 199 | { 200 | get 201 | { 202 | return DN; 203 | } 204 | } 205 | public ResultCode Status 206 | { 207 | get 208 | { 209 | return RC; 210 | } 211 | } 212 | 213 | public DirectoryOperationStatus(DirectoryOperationType op, string distinguishedName, ResultCode state) 214 | { 215 | DOT = op; 216 | DN = distinguishedName; 217 | RC = state; 218 | } 219 | 220 | DirectoryOperationType DOT; 221 | string DN; 222 | ResultCode RC; 223 | } 224 | #endregion 225 | 226 | #region Exceptions 227 | [Serializable] 228 | public class AmbiguousResultException : Exception 229 | { 230 | public AmbiguousResultException(string message) 231 | : base(message) 232 | { 233 | 234 | } 235 | } 236 | 237 | [Serializable] 238 | public class NotFoundException : Exception 239 | { 240 | public NotFoundException(string message) 241 | : base(message) 242 | { 243 | 244 | } 245 | } 246 | #endregion 247 | } -------------------------------------------------------------------------------- /Main/AdmPwd.Setup/AdmPwd.Setup.wixproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 3.11 7 | a7243abf-20dc-46d4-be20-c023a27838ef 8 | 2.0 9 | AdmPwd.Setup 10 | Package 11 | $(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets 12 | $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets 13 | AdmPwd.Setup 14 | 15 | 16 | bin\$(Platform)\$(Configuration)\ 17 | obj\$(Platform)\$(Configuration)\ 18 | Debug 19 | 20 | 21 | bin\$(Platform)\$(Configuration)\ 22 | obj\$(Platform)\$(Configuration)\ 23 | 24 | 25 | 26 | 27 | bin\$(Platform)\$(Configuration)\ 28 | obj\$(Platform)\$(Configuration)\ 29 | Debug 30 | 31 | 32 | bin\$(Platform)\$(Configuration)\ 33 | obj\$(Platform)\$(Configuration)\ 34 | 35 | 36 | 37 | 38 | Debug 39 | bin\$(Platform)\$(Configuration)\ 40 | obj\$(Platform)\$(Configuration)\ 41 | 42 | 43 | bin\$(Platform)\$(Configuration)\ 44 | obj\$(Platform)\$(Configuration)\ 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | AdmPwd.PS 56 | {43685adc-30fe-4e90-98eb-443ba58d9ea0} 57 | True 58 | True 59 | Binaries;Content;Satellites 60 | INSTALLFOLDER 61 | 62 | 63 | AdmPwd.Setup.CustomActions 64 | {ee229589-d6f5-49c0-917c-52fdb7ffd3d1} 65 | True 66 | True 67 | Binaries;Content;Satellites 68 | INSTALLFOLDER 69 | 70 | 71 | AdmPwd.UI 72 | {edb0c01e-8dd3-4d72-b445-01d11184ae68} 73 | True 74 | True 75 | Binaries;Content;Satellites 76 | INSTALLFOLDER 77 | 78 | 79 | AdmPwd.Utils 80 | {6a55db40-baed-4d53-84a3-659dcaa7e38b} 81 | True 82 | True 83 | Binaries;Content;Satellites 84 | INSTALLFOLDER 85 | 86 | 87 | AdmPwd 88 | {c738ce8e-0b5e-4f1e-bddf-d7a9c602ca64} 89 | True 90 | True 91 | Binaries;Content;Satellites 92 | INSTALLFOLDER 93 | 94 | 95 | 96 | 97 | $(WixExtDir)\WixUtilExtension.dll 98 | WixUtilExtension 99 | 100 | 101 | $(WixExtDir)\WixUIExtension.dll 102 | WixUIExtension 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 138 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | Computer name ambiguous, use DN instead of computer name 122 | 123 | 124 | Computer not found 125 | 126 | 127 | Invalid format of date/time 128 | 129 | 130 | You must enter a computer name 131 | 132 | 133 | No computer selected 134 | 135 | 136 | Failed to request password reset 137 | 138 | 139 | Password reset request was successful 140 | 141 | 142 | -------------------------------------------------------------------------------- /Main/AdmPwd/AdmPwd.cpp: -------------------------------------------------------------------------------- 1 | // AdmPwd.cpp : Defines the entry point for the DLL application. 2 | // 3 | #include "stdafx.h" 4 | #include "Constants.h" 5 | #include "Config.h" 6 | #include "PasswordGenerator.h" 7 | #include "Computer.h" 8 | #include "AdminAccount.h" 9 | #include "AdmPwd.h" 10 | #include "AdmPwdMsg.h" 11 | #include "resource.h" 12 | 13 | extern HINSTANCE hDll; 14 | //#pragma warning( disable : 4267 ) 15 | //#pragma warning( disable : 4995 ) 16 | 17 | 18 | _Use_decl_annotations_ 19 | ADMPWD_API DWORD APIENTRY ProcessGroupPolicy( 20 | DWORD dwFlags, 21 | HANDLE hToken, 22 | HKEY hKeyRoot, 23 | PGROUP_POLICY_OBJECT pDeletedGPOList, 24 | PGROUP_POLICY_OBJECT pChangedGPOList, 25 | ASYNCCOMPLETIONHANDLE pHandle, 26 | BOOL* pAbort, 27 | PFNSTATUSMESSAGECALLBACK pStatusCallback) 28 | { 29 | 30 | if(*pAbort) 31 | return ERROR_SUCCESS; 32 | 33 | // We only work if refreshing machine policy 34 | if(!(dwFlags & GPO_INFO_FLAG_MACHINE)) 35 | return (ERROR_SUCCESS); 36 | 37 | Config config; 38 | 39 | LOGDATA LogData; 40 | ::ZeroMemory(&LogData, sizeof(LogData)); 41 | 42 | ULONGLONG llTimestamp=0; 43 | 44 | FILETIME currentTime; 45 | 46 | try { 47 | LogData.dwLogLevel = config.LogLevel; 48 | 49 | if(!config.AccountManagementEnabled) 50 | { 51 | LogData.dwID=S_NOT_ENABLED; 52 | LogData.hr=ERROR_SUCCESS; 53 | LogAppEvent(&LogData); 54 | return ERROR_SUCCESS; 55 | } 56 | //begin processing 57 | LogData.dwID=S_STARTED; 58 | LogData.hr=ERROR_SUCCESS; 59 | LogAppEvent(&LogData); 60 | 61 | //Get computer account in AD 62 | LogData.dwID=S_GET_COMPUTER; 63 | Computer comp; 64 | 65 | //Get timestamp of expected password expiration 66 | LogData.dwID=S_GET_TIMESTAMP; 67 | LogData.hr=comp.Load(); 68 | if (FAILED(LogData.hr)) 69 | { 70 | if (LogData.hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND)) //NOT_FOUND --> empty attribute, which is OK 71 | throw LogData.hr; 72 | } 73 | ULONGLONG lDaysToChange=CompareTimestamp(comp.PasswordExpirationTimestamp); 74 | //if timestampExpire is empty or timestampExpire < Now - we will change the password 75 | if (lDaysToChange > config.PasswordAge && config.PasswordExpirationProtectionRequired) 76 | { 77 | LogData.dwID = S_EXPIRATION_TOO_LONG; 78 | LogData.info1 = (DWORD) lDaysToChange; 79 | LogAppEvent(&LogData); 80 | 81 | lDaysToChange = 0; 82 | } 83 | 84 | //get local Administrator account we're managing password for 85 | LogData.dwID = S_GET_ADMIN; 86 | AdminAccount admin(config.AdminAccountName); 87 | if(lDaysToChange) 88 | { 89 | bool wasPasswordEverManaged = false; 90 | LogData.hr = admin.HasPasswordEverManaged(&wasPasswordEverManaged); 91 | if (!wasPasswordEverManaged) 92 | { 93 | //force password change 94 | lDaysToChange = 0; 95 | LogData.dwID = S_NEVER_MANAGED; 96 | LogAppEvent(&LogData); 97 | 98 | } 99 | else 100 | { 101 | LogData.dwID = S_CHANGE_PWD_NOT_YET; 102 | LogData.info1 = (DWORD)lDaysToChange; 103 | LogAppEvent(&LogData); 104 | } 105 | } 106 | else 107 | { 108 | //it's time to change the password 109 | 110 | PasswordGenerator gen(config.PasswordComplexity, config.PasswordLength); 111 | gen.Generate(); 112 | LPCTSTR newPwd = gen.Password; 113 | 114 | //report new password and timestamp to AD 115 | GetSystemTimeAsFileTime(¤tTime); 116 | LogData.dwID = S_REPORT_PWD; 117 | LogData.hr = comp.ReportPassword(newPwd, ¤tTime, config.PasswordAge); 118 | if (FAILED(LogData.hr)) 119 | throw LogData.hr; 120 | else 121 | { 122 | LogData.dwID = S_REPORT_PWD_SUCCESS; 123 | LogAppEvent(&LogData); 124 | } 125 | 126 | //RESET password 127 | // Note: we reset password AFTER we successfully report it to AD 128 | // so in case we fail to report password for any reason, we do no reset the password 129 | // we may still fail reset the password, in this case, AD password and real password do not match, 130 | // but in this case we know that there must be previous password set on admin account 131 | LogData.dwID = S_CHANGE_PWD; 132 | 133 | LogData.hr=admin.ResetPassword(newPwd); 134 | if (FAILED(LogData.hr)) 135 | throw LogData.hr; 136 | else 137 | { 138 | LogData.dwID = S_CHANGE_PWD_SUCCESS; 139 | LogAppEvent(&LogData); 140 | } 141 | } 142 | //everything succeeded 143 | LogData.dwID=S_FINISHED; 144 | LogAppEvent(&LogData); 145 | } 146 | catch (HRESULT hr) 147 | { 148 | LogData.hr = hr; 149 | LogAppEvent(&LogData); 150 | } 151 | 152 | //In my opinion returning non-success in case of our error disturbs winlogon/gpsvc too much... 153 | //so we're simply returning success every time and just reporting our errors into event log 154 | return ERROR_SUCCESS; 155 | } 156 | 157 | 158 | //compares timestamps of expected password expiration with current time and returns number of days to change the password 159 | _Use_decl_annotations_ 160 | ULONGLONG CompareTimestamp(ULONGLONG pTimestampExpire) 161 | { 162 | FILETIME ftNow; 163 | ULONGLONG daysToChange=0; 164 | 165 | //Get local time 166 | //compare with expiration time and return result 167 | ::GetSystemTimeAsFileTime(&ftNow); 168 | 169 | ULARGE_INTEGER uli; 170 | uli.HighPart=ftNow.dwHighDateTime; 171 | uli.LowPart=ftNow.dwLowDateTime; 172 | 173 | if(uli.QuadPartdwLogLevel) { 201 | case LOGLEVEL_ERRORS_ONLY: 202 | if(!FAILED(pLogData->hr)) return; //success or warning in errors_only level -> do not log 203 | break; 204 | case LOGLEVEL_ERRORS_WARNINGS: 205 | if(pLogData->hr==ERROR_SUCCESS) return; //success in errors_warnings level -> do not log 206 | break; 207 | } 208 | 209 | HANDLE h=NULL; 210 | BSTR szBuff=NULL; 211 | 212 | szBuff=SysAllocStringLen(NULL, MAX_MSG_LEN); 213 | if(szBuff==NULL) 214 | goto Cleanup; 215 | 216 | h = RegisterEventSource(NULL, EXTENSION_NAME); 217 | if (h == NULL) 218 | goto Cleanup; 219 | 220 | switch(pLogData->dwID) 221 | { 222 | case S_GET_COMPUTER: 223 | case S_GET_ADMIN: 224 | case S_GET_TIMESTAMP: 225 | case S_CHANGE_PWD: 226 | case S_REPORT_PWD: 227 | if(FAILED(StringCbPrintf(szBuff, MAX_MSG_LEN*sizeof(OLECHAR), TEXT("0x%x"), pLogData->hr))) 228 | goto Cleanup; 229 | if (!ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, pLogData->dwID, NULL, 1, 0, (LPCTSTR*)&szBuff, NULL)) 230 | goto Cleanup; 231 | break; 232 | case S_FINISHED: 233 | case S_STARTED: 234 | case S_NOT_ENABLED: 235 | case S_CHANGE_PWD_SUCCESS: 236 | case S_REPORT_PWD_SUCCESS: 237 | case S_NEVER_MANAGED: 238 | BOOL bRslt; 239 | bRslt=ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, pLogData->dwID, NULL, 0, 0, NULL, NULL); 240 | if (!bRslt) 241 | goto Cleanup; 242 | break; 243 | case S_CHANGE_PWD_NOT_YET: 244 | if(FAILED(StringCbPrintf(szBuff, MAX_MSG_LEN*sizeof(OLECHAR), TEXT("%u"), pLogData->info1))) 245 | goto Cleanup; 246 | if (!ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, pLogData->dwID, NULL, 1, 0, (LPCTSTR*)&szBuff, NULL)) 247 | goto Cleanup; 248 | break; 249 | case S_EXPIRATION_TOO_LONG: 250 | if(FAILED(StringCbPrintf(szBuff, MAX_MSG_LEN*sizeof(OLECHAR), TEXT("%u"), pLogData->info1))) 251 | goto Cleanup; 252 | if (!ReportEvent(h, EVENTLOG_WARNING_TYPE, 0, pLogData->dwID, NULL, 1, 0, (LPCTSTR*)&szBuff, NULL)) 253 | goto Cleanup; 254 | } 255 | 256 | Cleanup: 257 | if(h != NULL) DeregisterEventSource(h); 258 | if(szBuff != NULL) SysFreeString(szBuff); 259 | } 260 | 261 | 262 | -------------------------------------------------------------------------------- /Main/AdmPwd.UI/Form1.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace AdmPwd.UI 2 | { 3 | partial class Form1 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.components = new System.ComponentModel.Container(); 32 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1)); 33 | this.txtPwdExpiration = new System.Windows.Forms.TextBox(); 34 | this.panel1 = new System.Windows.Forms.Panel(); 35 | this.label1 = new System.Windows.Forms.Label(); 36 | this.btnSearch = new System.Windows.Forms.Button(); 37 | this.txtComputerName = new System.Windows.Forms.TextBox(); 38 | this.panel2 = new System.Windows.Forms.Panel(); 39 | this.txtCurrentPwdExpiration = new System.Windows.Forms.TextBox(); 40 | this.lblCurrentPwdExpiration = new System.Windows.Forms.Label(); 41 | this.btnForceExpiration = new System.Windows.Forms.Button(); 42 | this.label3 = new System.Windows.Forms.Label(); 43 | this.label2 = new System.Windows.Forms.Label(); 44 | this.txtPassword = new System.Windows.Forms.TextBox(); 45 | this.errorProvider1 = new System.Windows.Forms.ErrorProvider(this.components); 46 | this.btnExit = new System.Windows.Forms.Button(); 47 | this.statusStrip = new System.Windows.Forms.StatusStrip(); 48 | this.lblStatus = new System.Windows.Forms.ToolStripStatusLabel(); 49 | this.panel1.SuspendLayout(); 50 | this.panel2.SuspendLayout(); 51 | ((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).BeginInit(); 52 | this.statusStrip.SuspendLayout(); 53 | this.SuspendLayout(); 54 | // 55 | // txtPwdExpiration 56 | // 57 | resources.ApplyResources(this.txtPwdExpiration, "txtPwdExpiration"); 58 | this.txtPwdExpiration.Name = "txtPwdExpiration"; 59 | // 60 | // panel1 61 | // 62 | this.panel1.Controls.Add(this.label1); 63 | this.panel1.Controls.Add(this.btnSearch); 64 | this.panel1.Controls.Add(this.txtComputerName); 65 | resources.ApplyResources(this.panel1, "panel1"); 66 | this.panel1.Name = "panel1"; 67 | // 68 | // label1 69 | // 70 | resources.ApplyResources(this.label1, "label1"); 71 | this.label1.Name = "label1"; 72 | // 73 | // btnSearch 74 | // 75 | resources.ApplyResources(this.btnSearch, "btnSearch"); 76 | this.btnSearch.Name = "btnSearch"; 77 | this.btnSearch.UseVisualStyleBackColor = true; 78 | this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click); 79 | // 80 | // txtComputerName 81 | // 82 | resources.ApplyResources(this.txtComputerName, "txtComputerName"); 83 | this.txtComputerName.Name = "txtComputerName"; 84 | // 85 | // panel2 86 | // 87 | this.panel2.Controls.Add(this.txtCurrentPwdExpiration); 88 | this.panel2.Controls.Add(this.lblCurrentPwdExpiration); 89 | this.panel2.Controls.Add(this.btnForceExpiration); 90 | this.panel2.Controls.Add(this.label3); 91 | this.panel2.Controls.Add(this.label2); 92 | this.panel2.Controls.Add(this.txtPassword); 93 | this.panel2.Controls.Add(this.txtPwdExpiration); 94 | resources.ApplyResources(this.panel2, "panel2"); 95 | this.panel2.Name = "panel2"; 96 | // 97 | // txtCurrentPwdExpiration 98 | // 99 | resources.ApplyResources(this.txtCurrentPwdExpiration, "txtCurrentPwdExpiration"); 100 | this.txtCurrentPwdExpiration.Name = "txtCurrentPwdExpiration"; 101 | this.txtCurrentPwdExpiration.ReadOnly = true; 102 | // 103 | // lblCurrentPwdExpiration 104 | // 105 | resources.ApplyResources(this.lblCurrentPwdExpiration, "lblCurrentPwdExpiration"); 106 | this.lblCurrentPwdExpiration.Name = "lblCurrentPwdExpiration"; 107 | // 108 | // btnForceExpiration 109 | // 110 | resources.ApplyResources(this.btnForceExpiration, "btnForceExpiration"); 111 | this.btnForceExpiration.Name = "btnForceExpiration"; 112 | this.btnForceExpiration.UseVisualStyleBackColor = true; 113 | this.btnForceExpiration.Click += new System.EventHandler(this.btnForceExpiration_Click); 114 | // 115 | // label3 116 | // 117 | resources.ApplyResources(this.label3, "label3"); 118 | this.label3.Name = "label3"; 119 | // 120 | // label2 121 | // 122 | resources.ApplyResources(this.label2, "label2"); 123 | this.label2.Name = "label2"; 124 | // 125 | // txtPassword 126 | // 127 | resources.ApplyResources(this.txtPassword, "txtPassword"); 128 | this.txtPassword.Name = "txtPassword"; 129 | this.txtPassword.ReadOnly = true; 130 | this.txtPassword.TabStop = false; 131 | // 132 | // errorProvider1 133 | // 134 | this.errorProvider1.ContainerControl = this; 135 | // 136 | // btnExit 137 | // 138 | resources.ApplyResources(this.btnExit, "btnExit"); 139 | this.btnExit.Name = "btnExit"; 140 | this.btnExit.UseVisualStyleBackColor = true; 141 | this.btnExit.Click += new System.EventHandler(this.btnExit_Click); 142 | // 143 | // statusStrip 144 | // 145 | this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { 146 | this.lblStatus}); 147 | resources.ApplyResources(this.statusStrip, "statusStrip"); 148 | this.statusStrip.Name = "statusStrip"; 149 | // 150 | // lblStatus 151 | // 152 | this.lblStatus.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text; 153 | this.lblStatus.Name = "lblStatus"; 154 | resources.ApplyResources(this.lblStatus, "lblStatus"); 155 | // 156 | // Form1 157 | // 158 | this.AcceptButton = this.btnSearch; 159 | resources.ApplyResources(this, "$this"); 160 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 161 | this.Controls.Add(this.statusStrip); 162 | this.Controls.Add(this.btnExit); 163 | this.Controls.Add(this.panel2); 164 | this.Controls.Add(this.panel1); 165 | this.Name = "Form1"; 166 | this.panel1.ResumeLayout(false); 167 | this.panel1.PerformLayout(); 168 | this.panel2.ResumeLayout(false); 169 | this.panel2.PerformLayout(); 170 | ((System.ComponentModel.ISupportInitialize)(this.errorProvider1)).EndInit(); 171 | this.statusStrip.ResumeLayout(false); 172 | this.statusStrip.PerformLayout(); 173 | this.ResumeLayout(false); 174 | this.PerformLayout(); 175 | 176 | } 177 | 178 | #endregion 179 | 180 | private System.Windows.Forms.TextBox txtPwdExpiration; 181 | private System.Windows.Forms.Panel panel1; 182 | private System.Windows.Forms.Label label1; 183 | private System.Windows.Forms.Button btnSearch; 184 | private System.Windows.Forms.TextBox txtComputerName; 185 | private System.Windows.Forms.Panel panel2; 186 | private System.Windows.Forms.Label label3; 187 | private System.Windows.Forms.Label label2; 188 | private System.Windows.Forms.TextBox txtPassword; 189 | private System.Windows.Forms.ErrorProvider errorProvider1; 190 | private System.Windows.Forms.Button btnExit; 191 | private System.Windows.Forms.Button btnForceExpiration; 192 | private System.Windows.Forms.StatusStrip statusStrip; 193 | private System.Windows.Forms.ToolStripStatusLabel lblStatus; 194 | private System.Windows.Forms.TextBox txtCurrentPwdExpiration; 195 | private System.Windows.Forms.Label lblCurrentPwdExpiration; 196 | } 197 | } 198 | 199 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup/AdmPwd.Setup.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 1 105 | 106 | NOT Installed AND NOT PATCH 107 | Installed AND PATCH 108 | 109 | 1 110 | 1 111 | 1 112 | 1 113 | 114 | WixUI_InstallMode = "Change" 115 | WixUI_InstallMode = "InstallCustom" 116 | 1 117 | 118 | WixUI_InstallMode = "InstallCustom" 119 | WixUI_InstallMode = "Change" 120 | WixUI_InstallMode = "Repair" OR WixUI_InstallMode = "Remove" 121 | WixUI_InstallMode = "Update" 122 | 123 | 1 124 | 125 | 1 126 | 1 127 | 1 128 | 1 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | "__null__"]]> 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /Main/AdmPwd.sln: -------------------------------------------------------------------------------- 1 | Microsoft Visual Studio Solution File, Format Version 12.00 2 | # Visual Studio 15 3 | VisualStudioVersion = 15.0.28010.2003 4 | MinimumVisualStudioVersion = 10.0.40219.1 5 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdmPwd", "AdmPwd\AdmPwd.vcxproj", "{C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}" 6 | EndProject 7 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdmPwd.PS", "AdmPwd.PS\AdmPwd.PS.csproj", "{43685ADC-30FE-4E90-98EB-443BA58D9EA0}" 8 | EndProject 9 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdmPwd.UI", "AdmPwd.UI\AdmPwd.UI.csproj", "{EDB0C01E-8DD3-4D72-B445-01D11184AE68}" 10 | EndProject 11 | Project("{930C7802-8A8C-48F9-8165-68863BCCD9DD}") = "AdmPwd.Setup", "AdmPwd.Setup\AdmPwd.Setup.wixproj", "{A7243ABF-20DC-46D4-BE20-C023A27838EF}" 12 | EndProject 13 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdmPwd.Utils", "AdmPwd.Utils\AdmPwd.Utils.csproj", "{6A55DB40-BAED-4D53-84A3-659DCAA7E38B}" 14 | EndProject 15 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_Other", "_Other", "{FE352340-DE74-452C-8E0D-01450E9EDBC7}" 16 | EndProject 17 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ADMX", "ADMX", "{0F4C0D17-40CC-4ADE-B95A-6931CA181522}" 18 | ProjectSection(SolutionItems) = preProject 19 | _Other\ADMX\AdmPwd.admx = _Other\ADMX\AdmPwd.admx 20 | EndProjectSection 21 | EndProject 22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AD_Schema", "AD_Schema", "{2FD3B70E-EE82-4A1C-A54B-A1F07849C3E5}" 23 | ProjectSection(SolutionItems) = preProject 24 | _Other\AD_Schema\AdmPwd_SchemaUpdate.ldf = _Other\AD_Schema\AdmPwd_SchemaUpdate.ldf 25 | EndProjectSection 26 | EndProject 27 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "en-us", "en-us", "{90ACEE66-385F-4492-ADA4-2926994326ED}" 28 | ProjectSection(SolutionItems) = preProject 29 | _Other\ADMX\en-US\AdmPwd.adml = _Other\ADMX\en-US\AdmPwd.adml 30 | EndProjectSection 31 | EndProject 32 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0783463C-8469-4C3A-8A78-7E5A931DE4AC}" 33 | ProjectSection(SolutionItems) = preProject 34 | Solution Items\app.ico = Solution Items\app.ico 35 | Solution Items\GlobalAssemblyInfo.cs = Solution Items\GlobalAssemblyInfo.cs 36 | Solution Items\Version.h = Solution Items\Version.h 37 | EndProjectSection 38 | EndProject 39 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdmPwd.Setup.CustomActions", "AdmPwd.Setup.CustomActions\AdmPwd.Setup.CustomActions.vcxproj", "{EE229589-D6F5-49C0-917C-52FDB7FFD3D1}" 40 | EndProject 41 | Global 42 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 43 | Debug|Any CPU = Debug|Any CPU 44 | Debug|ARM64 = Debug|ARM64 45 | Debug|Mixed Platforms = Debug|Mixed Platforms 46 | Debug|Win32 = Debug|Win32 47 | Debug|x64 = Debug|x64 48 | Debug|x86 = Debug|x86 49 | Release|Any CPU = Release|Any CPU 50 | Release|ARM64 = Release|ARM64 51 | Release|Mixed Platforms = Release|Mixed Platforms 52 | Release|Win32 = Release|Win32 53 | Release|x64 = Release|x64 54 | Release|x86 = Release|x86 55 | EndGlobalSection 56 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 57 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|Any CPU.ActiveCfg = Debug|x64 58 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|ARM64.ActiveCfg = Debug|ARM64 59 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|ARM64.Build.0 = Debug|ARM64 60 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|Mixed Platforms.ActiveCfg = Debug|x64 61 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|Mixed Platforms.Build.0 = Debug|x64 62 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|Win32.ActiveCfg = Debug|Win32 63 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|Win32.Build.0 = Debug|Win32 64 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|x64.ActiveCfg = Debug|x64 65 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|x64.Build.0 = Debug|x64 66 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|x86.ActiveCfg = Debug|Win32 67 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Debug|x86.Build.0 = Debug|Win32 68 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|Any CPU.ActiveCfg = Release|x64 69 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|ARM64.ActiveCfg = Release|ARM64 70 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|ARM64.Build.0 = Release|ARM64 71 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|Mixed Platforms.ActiveCfg = Release|x64 72 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|Mixed Platforms.Build.0 = Release|x64 73 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|Win32.ActiveCfg = Release|Win32 74 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|Win32.Build.0 = Release|Win32 75 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|x64.ActiveCfg = Release|x64 76 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|x64.Build.0 = Release|x64 77 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|x86.ActiveCfg = Release|Win32 78 | {C738CE8E-0B5E-4F1E-BDDF-D7A9C602CA64}.Release|x86.Build.0 = Release|Win32 79 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 80 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|Any CPU.Build.0 = Debug|Any CPU 81 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|ARM64.ActiveCfg = Debug|Any CPU 82 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|ARM64.Build.0 = Debug|Any CPU 83 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 84 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 85 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|Win32.ActiveCfg = Debug|Any CPU 86 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|Win32.Build.0 = Debug|Any CPU 87 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|x64.ActiveCfg = Debug|Any CPU 88 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|x64.Build.0 = Debug|Any CPU 89 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|x86.ActiveCfg = Debug|Any CPU 90 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Debug|x86.Build.0 = Debug|Any CPU 91 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|Any CPU.ActiveCfg = Release|Any CPU 92 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|Any CPU.Build.0 = Release|Any CPU 93 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|ARM64.ActiveCfg = Release|Any CPU 94 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|ARM64.Build.0 = Release|Any CPU 95 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 96 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|Mixed Platforms.Build.0 = Release|Any CPU 97 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|Win32.ActiveCfg = Release|Any CPU 98 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|Win32.Build.0 = Release|Any CPU 99 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|x64.ActiveCfg = Release|Any CPU 100 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|x64.Build.0 = Release|Any CPU 101 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|x86.ActiveCfg = Release|Any CPU 102 | {43685ADC-30FE-4E90-98EB-443BA58D9EA0}.Release|x86.Build.0 = Release|Any CPU 103 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 104 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|Any CPU.Build.0 = Debug|Any CPU 105 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|ARM64.ActiveCfg = Debug|Any CPU 106 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|ARM64.Build.0 = Debug|Any CPU 107 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 108 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 109 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|Win32.ActiveCfg = Debug|Any CPU 110 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|Win32.Build.0 = Debug|Any CPU 111 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|x64.ActiveCfg = Debug|Any CPU 112 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|x64.Build.0 = Debug|Any CPU 113 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|x86.ActiveCfg = Debug|Any CPU 114 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Debug|x86.Build.0 = Debug|Any CPU 115 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|Any CPU.ActiveCfg = Release|Any CPU 116 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|Any CPU.Build.0 = Release|Any CPU 117 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|ARM64.ActiveCfg = Release|Any CPU 118 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|ARM64.Build.0 = Release|Any CPU 119 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 120 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|Mixed Platforms.Build.0 = Release|Any CPU 121 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|Win32.ActiveCfg = Release|Any CPU 122 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|Win32.Build.0 = Release|Any CPU 123 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|x64.ActiveCfg = Release|Any CPU 124 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|x64.Build.0 = Release|Any CPU 125 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|x86.ActiveCfg = Release|Any CPU 126 | {EDB0C01E-8DD3-4D72-B445-01D11184AE68}.Release|x86.Build.0 = Release|Any CPU 127 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|Any CPU.ActiveCfg = Debug|x86 128 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|ARM64.ActiveCfg = Debug|ARM64 129 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|ARM64.Build.0 = Debug|ARM64 130 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|Mixed Platforms.ActiveCfg = Debug|x86 131 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|Mixed Platforms.Build.0 = Debug|x86 132 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|Win32.ActiveCfg = Debug|x86 133 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|Win32.Build.0 = Debug|x86 134 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|x64.ActiveCfg = Debug|x64 135 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|x64.Build.0 = Debug|x64 136 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|x86.ActiveCfg = Debug|x86 137 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Debug|x86.Build.0 = Debug|x86 138 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|Any CPU.ActiveCfg = Release|x86 139 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|ARM64.ActiveCfg = Release|ARM64 140 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|ARM64.Build.0 = Release|ARM64 141 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|Mixed Platforms.ActiveCfg = Release|x86 142 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|Mixed Platforms.Build.0 = Release|x86 143 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|Win32.ActiveCfg = Release|x86 144 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|Win32.Build.0 = Release|x86 145 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|x64.ActiveCfg = Release|x64 146 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|x64.Build.0 = Release|x64 147 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|x86.ActiveCfg = Release|x86 148 | {A7243ABF-20DC-46D4-BE20-C023A27838EF}.Release|x86.Build.0 = Release|x86 149 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 150 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|Any CPU.Build.0 = Debug|Any CPU 151 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|ARM64.ActiveCfg = Debug|Any CPU 152 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|ARM64.Build.0 = Debug|Any CPU 153 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 154 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 155 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|Win32.ActiveCfg = Debug|Any CPU 156 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|Win32.Build.0 = Debug|Any CPU 157 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|x64.ActiveCfg = Debug|Any CPU 158 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|x64.Build.0 = Debug|Any CPU 159 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|x86.ActiveCfg = Debug|Any CPU 160 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Debug|x86.Build.0 = Debug|Any CPU 161 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|Any CPU.ActiveCfg = Release|Any CPU 162 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|Any CPU.Build.0 = Release|Any CPU 163 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|ARM64.ActiveCfg = Release|Any CPU 164 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|ARM64.Build.0 = Release|Any CPU 165 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 166 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|Mixed Platforms.Build.0 = Release|Any CPU 167 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|Win32.ActiveCfg = Release|Any CPU 168 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|Win32.Build.0 = Release|Any CPU 169 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|x64.ActiveCfg = Release|Any CPU 170 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|x64.Build.0 = Release|Any CPU 171 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|x86.ActiveCfg = Release|Any CPU 172 | {6A55DB40-BAED-4D53-84A3-659DCAA7E38B}.Release|x86.Build.0 = Release|Any CPU 173 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|Any CPU.ActiveCfg = Debug|Win32 174 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|ARM64.ActiveCfg = Debug|ARM64 175 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|ARM64.Build.0 = Debug|ARM64 176 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 177 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|Mixed Platforms.Build.0 = Debug|Win32 178 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|Win32.ActiveCfg = Debug|Win32 179 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|Win32.Build.0 = Debug|Win32 180 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|x64.ActiveCfg = Debug|x64 181 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|x64.Build.0 = Debug|x64 182 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|x86.ActiveCfg = Debug|Win32 183 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Debug|x86.Build.0 = Debug|Win32 184 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|Any CPU.ActiveCfg = Release|Win32 185 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|ARM64.ActiveCfg = Release|ARM64 186 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|ARM64.Build.0 = Release|ARM64 187 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|Mixed Platforms.ActiveCfg = Release|Win32 188 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|Mixed Platforms.Build.0 = Release|Win32 189 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|Win32.ActiveCfg = Release|Win32 190 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|Win32.Build.0 = Release|Win32 191 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|x64.ActiveCfg = Release|x64 192 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|x64.Build.0 = Release|x64 193 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|x86.ActiveCfg = Release|Win32 194 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1}.Release|x86.Build.0 = Release|Win32 195 | EndGlobalSection 196 | GlobalSection(SolutionProperties) = preSolution 197 | HideSolutionNode = FALSE 198 | EndGlobalSection 199 | GlobalSection(NestedProjects) = preSolution 200 | {0F4C0D17-40CC-4ADE-B95A-6931CA181522} = {FE352340-DE74-452C-8E0D-01450E9EDBC7} 201 | {2FD3B70E-EE82-4A1C-A54B-A1F07849C3E5} = {FE352340-DE74-452C-8E0D-01450E9EDBC7} 202 | {90ACEE66-385F-4492-ADA4-2926994326ED} = {0F4C0D17-40CC-4ADE-B95A-6931CA181522} 203 | EndGlobalSection 204 | GlobalSection(ExtensibilityGlobals) = postSolution 205 | SolutionGuid = {5517DBCB-B8F9-4063-9012-A412C5F917BA} 206 | EndGlobalSection 207 | EndGlobal 208 | -------------------------------------------------------------------------------- /Main/AdmPwd.Setup.CustomActions/AdmPwd.Setup.CustomActions.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | ARM64 7 | 8 | 9 | Debug 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | ARM64 19 | 20 | 21 | Release 22 | Win32 23 | 24 | 25 | Release 26 | x64 27 | 28 | 29 | 30 | {EE229589-D6F5-49C0-917C-52FDB7FFD3D1} 31 | AdmPwd.Setup.CustomActions 32 | Win32Proj 33 | AdmPwd.Setup.CustomActions 34 | 10.0 35 | true 36 | 37 | 38 | 39 | DynamicLibrary 40 | v143 41 | Unicode 42 | true 43 | 44 | 45 | DynamicLibrary 46 | v143 47 | Unicode 48 | true 49 | 50 | 51 | DynamicLibrary 52 | v143 53 | Unicode 54 | true 55 | 56 | 57 | DynamicLibrary 58 | v143 59 | Unicode 60 | 61 | 62 | DynamicLibrary 63 | v143 64 | Unicode 65 | 66 | 67 | DynamicLibrary 68 | v143 69 | Unicode 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | <_ProjectFileVersion>12.0.30501.0 95 | 96 | 97 | $(ProjectDir)$(Platform)\$(Configuration)\ 98 | $(ProjectDir)$(Platform)\$(Configuration)\ 99 | true 100 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(Wix)SDK\VS2017\inc 101 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(Wix)SDK\VS2017\lib\$(PlatformTarget) 102 | 103 | 104 | true 105 | $(ProjectDir)$(Platform)\$(Configuration)\ 106 | $(ProjectDir)$(Platform)\$(Configuration)\ 107 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(Wix)SDK\VS2017\lib\$(PlatformTarget) 108 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(Wix)SDK\VS2017\inc 109 | 110 | 111 | true 112 | $(ProjectDir)$(Platform)\$(Configuration)\ 113 | $(ProjectDir)$(Platform)\$(Configuration)\ 114 | $(VC_LibraryPath_arm64);$(WindowsSDK_LibraryPath_arm64);$(Wix)SDK\VS2017\lib\$(PlatformTarget) 115 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(Wix)SDK\VS2017\inc 116 | 117 | 118 | $(ProjectDir)$(Platform)\$(Configuration)\ 119 | $(ProjectDir)$(Platform)\$(Configuration)\ 120 | false 121 | $(VC_LibraryPath_x86);$(WindowsSDK_LibraryPath_x86);$(Wix)SDK\VS2017\lib\$(PlatformTarget) 122 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(Wix)SDK\VS2017\inc 123 | 124 | 125 | false 126 | $(ProjectDir)$(Platform)\$(Configuration)\ 127 | $(ProjectDir)$(Platform)\$(Configuration)\ 128 | $(VC_LibraryPath_x64);$(WindowsSDK_LibraryPath_x64);$(Wix)SDK\VS2017\lib\$(PlatformTarget) 129 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(Wix)SDK\VS2017\inc 130 | 131 | 132 | false 133 | $(ProjectDir)$(Platform)\$(Configuration)\ 134 | $(ProjectDir)$(Platform)\$(Configuration)\ 135 | $(VC_LibraryPath_arm64);$(WindowsSDK_LibraryPath_arm64);$(Wix)SDK\VS2017\lib\$(PlatformTarget) 136 | $(VC_IncludePath);$(WindowsSDK_IncludePath);$(Wix)SDK\VS2017\inc 137 | 138 | 139 | 140 | Disabled 141 | %(AdditionalIncludeDirectories) 142 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions) 143 | true 144 | EnableFastChecks 145 | MultiThreadedDebug 146 | Use 147 | Level3 148 | EditAndContinue 149 | 150 | 151 | msi.lib;dutil.lib;wcautil.lib;Version.lib;Netapi32.lib;Advapi32.lib;legacy_stdio_definitions.lib;Bcrypt.lib;Shell32.lib;%(AdditionalDependencies) 152 | %(AdditionalLibraryDirectories) 153 | CustomAction.def 154 | true 155 | Windows 156 | MachineX86 157 | 158 | 159 | 160 | 161 | Disabled 162 | %(AdditionalIncludeDirectories) 163 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions) 164 | EnableFastChecks 165 | MultiThreadedDebug 166 | Use 167 | Level3 168 | ProgramDatabase 169 | 170 | 171 | msi.lib;dutil.lib;wcautil.lib;Version.lib;Netapi32.lib;Advapi32.lib;legacy_stdio_definitions.lib;Bcrypt.lib;Shell32.lib;%(AdditionalDependencies) 172 | %(AdditionalLibraryDirectories) 173 | CustomAction.def 174 | true 175 | Windows 176 | 177 | 178 | 179 | 180 | Disabled 181 | %(AdditionalIncludeDirectories) 182 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions) 183 | EnableFastChecks 184 | MultiThreadedDebug 185 | Use 186 | Level3 187 | ProgramDatabase 188 | 189 | 190 | msi.lib;dutil.lib;wcautil.lib;Version.lib;Netapi32.lib;Advapi32.lib;legacy_stdio_definitions.lib;Bcrypt.lib;Shell32.lib;%(AdditionalDependencies) 191 | %(AdditionalLibraryDirectories) 192 | CustomAction.def 193 | true 194 | Windows 195 | 196 | 197 | 198 | 199 | MaxSpeed 200 | true 201 | %(AdditionalIncludeDirectories) 202 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions) 203 | MultiThreaded 204 | true 205 | Use 206 | Level3 207 | ProgramDatabase 208 | 209 | 210 | msi.lib;dutil.lib;wcautil.lib;Version.lib;Netapi32.lib;Advapi32.lib;legacy_stdio_definitions.lib;Bcrypt.lib;Shell32.lib;%(AdditionalDependencies) 211 | %(AdditionalLibraryDirectories) 212 | CustomAction.def 213 | true 214 | Windows 215 | true 216 | true 217 | MachineX86 218 | $(OutDir)$(TargetName)$(TargetExt) 219 | 220 | 221 | 222 | 223 | MaxSpeed 224 | true 225 | %(AdditionalIncludeDirectories) 226 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions) 227 | MultiThreaded 228 | true 229 | Use 230 | Level3 231 | ProgramDatabase 232 | 233 | 234 | msi.lib;dutil.lib;wcautil.lib;Version.lib;Netapi32.lib;Advapi32.lib;legacy_stdio_definitions.lib;Bcrypt.lib;Shell32.lib;%(AdditionalDependencies) 235 | %(AdditionalLibraryDirectories) 236 | CustomAction.def 237 | true 238 | Windows 239 | true 240 | true 241 | 242 | 243 | 244 | 245 | MaxSpeed 246 | true 247 | %(AdditionalIncludeDirectories) 248 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CUSTOMACTIONTEST_EXPORTS;%(PreprocessorDefinitions) 249 | MultiThreaded 250 | true 251 | Use 252 | Level3 253 | ProgramDatabase 254 | 255 | 256 | msi.lib;dutil.lib;wcautil.lib;Version.lib;Netapi32.lib;Advapi32.lib;legacy_stdio_definitions.lib;Bcrypt.lib;Shell32.lib;%(AdditionalDependencies) 257 | %(AdditionalLibraryDirectories) 258 | CustomAction.def 259 | true 260 | Windows 261 | true 262 | true 263 | 264 | 265 | 266 | 267 | 268 | 269 | Create 270 | Create 271 | Create 272 | Create 273 | Create 274 | Create 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | --------------------------------------------------------------------------------