For learning purposes I am writing my own Active Directory client. In order to execute commands like unlocking accounts and resetting passwords, I have to put in my admin account and password and use and WindowsIdentity.Impersonate
run the code as my admin account. I am wondering about my options for securing my password, as it has to be used many times across my program.
From what I understand, I can use SecureString
to store the password. But to run code as my admin account, I have use WindowsIdentity.Impersonate
, and to use that I have to get a token from LogonUser
which requires a regular string
and not SecureString
.
So I would have to:
Login at start up
Convert input to a SecureString
Clear the input
Then later when I want to preform a function that requires elevation:
Convert previously created SecureString
to string
Pass the converted string to LogonUser
Clear the convert string to null
Execute command
Clear the LogonUser
object
Is this the correct way to approach this? It seems weird to have to have to convert the SecureString
to string
to use it... seems like it would defeat the purpose and leave the password more vulnerable while I am converting it.
EDIT: Fixed the name for LogonUser
In your UserImpersonation
class, change how you declare LogonUser
to use IntPtr
instead of string
for password.
The code sample for Marshal.SecureStringToGlobalAllocUnicode has exactly what you need. Here's the relevant snippet:
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
internal static extern bool LogonUser(String username, String domain,
IntPtr password, int logonType,
int logonProvider, ref IntPtr token);
...
IntPtr tokenHandle = IntPtr.Zero;
IntPtr passwordPtr = IntPtr.Zero;
try
{
// Marshal the SecureString to unmanaged memory.
passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);
returnValue = LogonUser(userName, domainName, passwordPtr,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, ref tokenHandle);
}
finally
{
// Zero-out and free the unmanaged string reference.
Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr);
// Close the token handle.
CloseHandle(tokenHandle);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With