tags:

views:

1210

answers:

4

I have an installation package that installs a service process that I create. I'd like to prompt the user for the username/password of the account that the service process should run under. I'd like to verify the the username/password combination are valid before continuing with the installation. I have a C DLL that I am using for special installation behavior, but I can't figure out how to use the Windows API to verify an account's credentials. I'd like to be able to support the same account name syntax used by the service control manager.

+5  A: 

The function you want to use is LogonUser. You can even be extra-cool and specify the LOGON32_LOGON_SERVICE flag which checks to make sure the user has the appropriate permissions to run a service.

Nick
Just be aware that on older OS versions (Win2K and before) the LogonUser() API requires a high privilige ("Act as part of the operating system").
Michael Burr
+1  A: 

I suggest reading http://support.microsoft.com/kb/180548 which I think will help you. It's a walk through from Microsoft on how to use WIN32 API to authenticate user credentials.

Loscas
+1  A: 

LogonUser is the canonical way to do this, though Microsoft somewhat discourages it.

Mark Brackett
A: 

I've implemented this using the LogonUser function as you guys have mentioned (by the way, this service requires WinXP SP2 or later so I'm not worried about the privilege issue). However, this isn't quite working as I had hoped. If I call QueryServiceConfig, lpServiceStartName is in the format ".\accountname". If I pass this string as is to LogonUser, it fails. I assume the portion before the '\' represents the machine on which the user belongs?

Also, if I call ChangeServiceConfig specifying "LocalSystem" and "" for the lpServiceStartName and lpPassword parameters respectively, this works fine. However, calling LogonUser with these parameters does not work.

I'd really like to use the same syntax that the SCM uses for the account names.

Jason
You need to split the domain from the username. The '.' will work as the domain for LogonUser (it maps to the local system namespace), but you need to split the fully qualified username.
Nick
Also, you can't explicitly logon as LocalSystem using the API (as far as I know). You'll have to special-case this account, and the couple of other built-in accounts (which are in the NT_AUTHORITY namespace).
Nick