Post by Dan FreemanOne option is to always use RUNAS when launching your app, and run it as the
Besides RUNAS you could also use some API functions
to change the user account programmatic.
Here is some sample code:
*
* Impersonate.prg
*
#Define LOGON32_LOGON_INTERACTIVE 2
#Define LOGON32_LOGON_NETWORK 3
#Define LOGON32_LOGON_BATCH 4
#Define LOGON32_LOGON_SERVICE 5
#Define LOGON32_LOGON_UNLOCK 7
#Define LOGON32_LOGON_NETWORK_CLEARTEXT 8
#Define LOGON32_LOGON_NEW_CREDENTIALS 9
#Define LOGON32_PROVIDER_DEFAULT 0
#Define LOGON32_PROVIDER_WINNT35 1
#Define LOGON32_PROVIDER_WINNT40 2
#Define LOGON32_PROVIDER_WINNT50 3
Clear && Screen
someDeclarations()
Local lcNewUser, lcDomain, lcPassword, loLoginForm, loUserinfo
loUserinfo = CREATEOBJECT("custom")
Addproperty(loUserinfo,"cDomain","")
Addproperty(loUserinfo,"cNewUser","")
Addproperty(loUserinfo,"cPassword","")
loLoginForm = CREATEOBJECT("loginform",loUserinfo)
loLoginForm.show(1)
loLoginForm = .null.
RELEASE loLoginForm
lcDomain = loUserinfo.cDomain
lcNewUser = loUserinfo.cNewUser
lcPassword = loUserinfo.cPassword
RELEASE loUserinfo
Local lnSuccess, lnUserHandle, llTotalsuccess
* try Logon
* local Login (Domain = Computername):
lnSuccess = LogonUser( lcNewUser, lcDomain, lcPassword, ;
LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, @lnUserHandle)
* See MSDN help on LogonUser for the meaning of the constants LOGON32,
* you may need to pass other values depending on Client and Server OS.
If lnSuccess>0
* impersonate user
lnSuccess = ImpersonateLoggedOnUser(lnUserHandle)
If lnSuccess>0
Local lcUserLoggedOn, lcName, lnBuffersize
lcName = Chr(0)
lnBuffersize = 64
lcUserLoggedOn = Replicate(lcName,lnBuffersize)
* this should be sufficient, to check if login succeeded:
? sys(0)
* alternative:
lnSuccess = WNetGetUser(@lcName, @lcUserLoggedOn, @lnBuffersize)
If lnSuccess = 0
lcUserLoggedOn = Chrtran(lcUserLoggedOn, Chr(0),"")
llTotalsuccess = (Upper(lcUserLoggedOn) == Upper(lcNewUser))
? "Login tried as " + lcNewUser
? "Logged in as: " + lcUserLoggedOn
If llTotalsuccess
DoSomethingAsLoggedInUser()
EndIf
Else
? "WNetGetUser failed with result:"+Transform(lnSuccess)
lastError()
Endif
Else
? "ImpersonateLoggedOnUser failed with result:"+Transform(lnSuccess)
lastError()
Endif
CloseHandle(lnUserHandle)
Else
? "LogonUser failed with result:"+Transform(lnSuccess)
lastError()
Endif
? Iif(llTotalsuccess,"Yessir!!","no luck this time")
RevertToSelf()
RETURN 0
Procedure someDeclarations()
Declare Short LogonUser In Win32API ;
String lcNewUserName, ;
String lcDomainName, ;
String lcPassword, ;
Integer lnLogonType, ;
Integer lnLogonProvider, ;
Integer @lnUserHandle
Declare Short ImpersonateLoggedOnUser In Win32API ;
Integer lnUserHanlde
Declare Integer WNetGetUser In Win32API ;
String @lcName, ;
String @lcUSer, ;
Integer @lnBuffersize
Declare Short RevertToSelf In Win32API
Declare Short CloseHandle In Win32API;
Integer lnHandle
Declare Long GetLastError In kernel32
Declare Integer FormatMessage In Win32API;
Integer dwFlags ,;
Integer lpvSource,;
Integer dwMsgId,;
Integer dwLangId,;
String @lpBuffer,;
Integer nSize,;
Integer Arguments
Declare Integer CreateProcessWithLogonW IN Advapi32;
String lpUsername,;
String lpDomain,;
String lpPassword,;
Integer dwLogonFlags,;
String lpAppName,;
String lpCmdLine,;
Integer dwCreationFlags,;
Integer lpEnvir,;
String lpCurDir,;
String @lpStartupInfo,;
String @lpProcessInfo
Endproc
Procedure lastError()
#Define FORMAT_MESSAGE_FROM_SYSTEM 8
#Define LANG_NEUTRAL 0
Local lnLastError
lnLastError = GetLastError()
Local lnSize, lcMessage
lcMessage = Replicate(Chr(0),2048)
lnSize = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,0,lnLastError,LANG_NEUTRAL,@lcMessage,Len(lcMessage)-1,0)
If lnSize > 2
lcMessage = Left(lcMessage,lnSize-2)
Else
lcMessage = ""
Endif
? "Error:" +Transform(lnLastError)+ " Message: "+lcMessage
Endproc
**************************************************
*-- Class: loginform (...\impersonate\libs\forms.vcx)
*-- ParentClass: form
*-- BaseClass: form
*-- Timestamp: 08/09/04 12:24:03 PM
*
DEFINE CLASS loginform AS form
AutoCenter = .t.
Top = 0
Left = 0
Height = 144
Width = 282
DoCreate = .T.
Caption = "Form"
Name = "loginform"
ADD OBJECT label1 AS label WITH ;
FontBold = .T., ;
Alignment = 1, ;
Caption = "User:", ;
Height = 17, ;
Left = 8, ;
Top = 12, ;
Width = 48, ;
Name = "Label1"
ADD OBJECT label2 AS label WITH ;
FontBold = .T., ;
Alignment = 1, ;
Caption = "Pass:", ;
Height = 17, ;
Left = 8, ;
Top = 44, ;
Width = 48, ;
Name = "Label2"
ADD OBJECT label3 AS label WITH ;
FontBold = .T., ;
Alignment = 1, ;
Caption = "Domain:", ;
Height = 17, ;
Left = 8, ;
Top = 76, ;
Width = 48, ;
Name = "Label3"
ADD OBJECT text1 AS textbox WITH ;
Height = 24, ;
Left = 61, ;
Top = 8, ;
Width = 211, ;
Name = "Text1"
ADD OBJECT text2 AS textbox WITH ;
Height = 23, ;
Left = 61, ;
Top = 40, ;
Width = 211, ;
PasswordChar = "*", ;
Name = "Text2"
ADD OBJECT text3 AS textbox WITH ;
Height = 23, ;
Left = 61, ;
Top = 72, ;
Width = 211, ;
Name = "Text3"
ADD OBJECT command1 AS commandbutton WITH ;
Default = .T., ;
Top = 104, ;
Left = 61, ;
Height = 27, ;
Width = 211, ;
Caption = "Login", ;
Name = "Command1"
PROCEDURE Init()
LPARAMETERS toUserinfo
This.AddProperty("oUserinfo",null)
This.oUserinfo = toUserinfo
ENDPROC
PROCEDURE command1.click()
thisform.oUserinfo.cNewUser = ALLTRIM(Thisform.text1.Value)
thisform.oUserinfo.cPassword = ALLTRIM(Thisform.text2.Value)
thisform.oUserinfo.cDomain = ALLTRIM(Thisform.text3.Value)
thisform.Release()
ENDPROC
ENDDEFINE
*
*-- EndDefine: loginform
**************************************************
Procedure DoSomethingAsLoggedInUser()
If lower(SUBSTR(SYS(0),AT(" # ",SYS(0))+3)) = "administrator"
? "You are administrator!"
Endif
Return
EndProc
But:
Try a SET STEP ON in the DoSomethingAsLoggedInUser() procedure
and type in some command. If foxcode.dbf is at default location you
won't be able to access it, and Intellisense will make problems. So you
should reconfigure at least the location of foxcode.dbf and perhaps some
more like foxuser.dbf, bacause these are normally configured for each
user within their own folders, and for switching user these should be
configured to public folders...
In principle now you can define an user account for the application
and give the appropriate rights only to this user. Of course then you
wouldn't diplay a login form for that user but the application would know
this username and password. Maybe store it encrypted within the exe.
Bye, Olaf.