Reputation: 13
everyone, I am facing an issue with LogonUser
function.
I just want to know if I can import the LogonUser
function into C# by this signature:
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern int LogonUser(string username, string domain, IntPtr password, int logonType, int logonProvider, ref IntPtr token);
Because I want to secure my password not using a string, but a SecureString
class. Then later the function is used like below:
var passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);
var result = LogonUser(userName, domain, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);
I always get result = 0 and the message shows that the user name and password is incorrect. But when I change the signature to use string password, then everything works well.
Please help me as to secure the password with SecureString
is important to me.
Upvotes: 1
Views: 1713
Reputation: 239704
As pointed out by Alex K, there's an example of using LogonUser
in the SecureStringToGlobalAllocUnicode
. Note that the P/Invoke declaration there is:
[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);
And that CharSet = CharSet.Unicode
has been specified. Unfortunately, for historical reasons, the default CharSet
value is Ansi
and so that's what your P/Invoke attempt is going to use.
This will be fine for the username
parameter since the P/Invoke infrastructure will ensure that it converts the string
appropriately. But it's not appropriate for the password
parameter since you've already performed the string conversion and you've done it as Unicode - and all that P/Invoke is seeing is an IntPtr
now.
I'd suggest updating your P/Invoke signature to match that given in the sample.
Another alternative would be to switch to using SecureStringToGlobalAllocAnsi
and leaving your P/Invoke signature alone. But this is a seriously second-rate solution. Writing non-Unicode aware code in 2015 is seriously not to be recommended.
Just get in the habit of always specifying CharSet.Unicode
in any P/Invoke signatures you write.
Upvotes: 3