Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Logon to database using windows logins 2

Status
Not open for further replies.

RGoldthorpe

Technical User
Aug 10, 2001
83
0
0
GB
Hi

I have a problem I am hoping all you gurus out there can help me with.

What I want to do is use the windows logon to allow access to my data base. But I dont nessecarly need the same user that has logged on the machine to log into the data base.

What I have at the minute works providing the same username and password are used for loging in to the machine as the database.

The code for that is

LPARAMETERS tcUserid, tcDomain, tcPassword

#define LOGON32_LOGON_INTERACTIVE 2
#define LOGON32_LOGON_NETWORK 3
#define LOGON32_LOGON_BATCH 4
#define LOGON32_LOGON_SERVICE 5
#define LOGON32_PROVIDER_DEFAULT 0

lnFlags = LOGON32_LOGON_INTERACTIVE

DECLARE INTEGER LogonUser in WIN32API ;
String lcUser,;
String lcServer,;
String lcPassword,;
INTEGER dwLogonType,;
Integer dwProvider,;
Integer @dwToken

lnToken = 0
lcUser = ALLTRIM(tcUserID)
lcServer = ALLTRIM(tcDomain)
lcPassword = ALLTRIM(tcPassword)


lnResult = LogonUser(lcuser,lcServer,lcPassword,;
lnFlags,LOGON32_PROVIDER_DEFAULT,@lnToken)

DECLARE INTEGER CloseHandle IN WIN32API INTEGER
CloseHandle(lnToken)
IF lnResult=1
RETURN .T.
ELSE
RETURN .F.
ENDIF

Any of you have anyidea how I can minipulate this so it looks at the 2000 server to verify the logon.

All help is greatly appreciated

Thankyou

Rach
 
Well, why do you need a user to login to the
win 2000 server?

Normally you share some directory and grant
access to the Useraccounts of those windows
users, that use the application and should
have access to it's data.

Now, you don't share this directory to all
those user, but only to one user. Only your
application logs in as this user.
(LOGON32_PROVIDER_DEFAULT should do that).

Then you only need to access your database
with \\servername\directory\database.dbc
instead of a mapped drive and as this special
user has access to that directory this should
be sufficient.

Bye, Olaf.
 
Rach,

Let me see if I understand what you're looking for. User Tom has logged onto the network with his logon and password. Tom has certain rights/privileges to your application and you can detect them. But Tom walks away from the workstation and Dick wants to use the application also, but his rights/privileges are more restrictive than Toms. You want to have your application validate the user rights/privileges from the W2K logon for Dick (and all users really) from their network settings (i.e. Active Directory) even though Tom is the current user. Right?

Steve
 
I dont need the user to log in to the windows 2000 server what I want to do is verify the passwords there so I do not have 183 different places holding passwords everywhere because when it comes to changing the password time it becomes a pain to change for example :-

Windows login
groupwise login
database login
etc..

I thought maybe there would be some windows service I could call to authenticate the user through the windows.

So that when the windows password changes so do the database one by default.

Security wise this is better to as users can assign there own passwords.

The above code does this at the minute but only seems to work if you use same username and password as you logged on to the PC with.

E.G logged in to windows on a local pc with
"user: rgoldthorpe password: muppet Domain: thingy"
you can log on to the database as that and it is fine.
but if you log on to windows with the above username and password but then want to log on to the data base as
"User: Kermit Password:piggy Domain : thingy"
Although is a valid windows 2000 account will not grant access to the data base and I want it to.

PLease any more help very much appreciated.

Rach



 
I think you may be misunderstanding or underestimating the functionality of the LogonUser() function.
All it does is check for a valid username/password, and returns a token or handle.
That token must be then used by several other API calls to create new processes or be 'impersonate'-able to use other services.

Here is an example on how to do it using VB:

And:
Has an excellent example of how to do what you need using VFP. But you will need to subscribe to obtain the code.
(It is probably worth your time and money to do so.)

Sorry, that's the best I can come up with right now.


-Dave Summers-
[cheers]
Even more Fox stuff at:
 
Now what's the problem? In the example of Steve,
Tom has not locked his workstation? If Dick really does the windows login Toms session/applications would be shutdown, won't they?

Well, if Dick finds the open workstation and logs in to your application again and you internally do the
LogonUser, then your app will work with the privi-
liges of Dick only, you'd only still have the desktop and everything from Tom, but you even can't access Tom's own files within the app now. You've changed user for the process of your application. Isn't that what you wanted?

You are talking about a database logon. Do you have SQL-Server in mind or a foxpro database? I'd say after LogonUser, if you connect to SQL-Server your app will authenticate with Dicks Username/password and if you try to open a foxpro database or table Dick must have at least read access to these files.

Hmm, let's see, you throw away the token you got from LogonUser with CloseHandle before you return, so won't this code be quite useless? I think you shouldn't close that handle unless you want to go back to the original logged in user. May that be the problem? This code is just good for chekcing if a user logon is correct or fails, you don't change to that user permanently.

Also, if you do LOGON32_LOGON_NETWORK MSDN help states, you only get an impersonation token, not a primary token. That is you can't use that token with CreateProcessAsUser, you first have to call DuplicateTokenEx.

Bye, Olaf.
 
If I understand what you're looking to do, it isn't really that hard.

Code:
lcMachine=LEFT(SYS(0),ATC([#],SYS(0))-2)
lcUser=RIGHT(SYS(0),LEN(SYS(0))-ATC([#],SYS(0))-1)

objUser = GetObject([WinNT://]+lcMachine+[/]+lcUser)
llPasswordVerified=.t.

lcPassword=INPUTBOX([Please verify windows password])

ON ERROR llPasswordVerified=.f.

objUser.ChangePassword (lcPassword, lcPassword)

ON ERROR

IF llPasswordVerified
 messagebox([Please continue])
ELSE
 messagebox([Please try again])
ENDIF
[code]
 
HI thanks for all your responses. I tried them all.

it turns out the the reason my code doesn't work is the security on the network. Users are only physically allowed to log on to one specific machine if you log on to the database as a user that has privilledges to log on to all machines it works.

I tried to reason with the person incharge that then they should only be using the machine they log on to in that case, but he doesn't want it done like that any more .

So after a week of trying to get code working that already worked guess how I feel. What a bummer.
 
Star for you baltman... simple and very useful. I've taken the liberty of expanding on it a bit to allow for username and password to be specified. Works like a charm and should not only address the issue of this thread, but might actually be something I would incorporate into my applicaitons. Cut-n-paste the code below into a prg and run it from within VFP
Code:
PUBLIC oform1
_screen.addproperty("successfullogin",.F.)
oform1=createobject("form1",5) && 5 is the maximum tries
oform1.Show(1)

IF _screen.successfullogin
	MESSAGEBOX("Welcome to my application!",64,"LOGIN WAS SUCCESSFUL")
ELSE
	MESSAGEBOX("You are not allowed access to this application!",16,"LOGIN FAILED")
ENDIF
	
RETURN

DEFINE CLASS form1 AS form

	Height = 142
	Width = 299
	DoCreate = .T.
	AutoCenter = .T.
	Caption = "Application Login"
	Name = "Form1"
	MaxTries = 3 && Default to 3
	NumberOfTries = 0
	
	ADD OBJECT label1 AS label WITH ;
		AutoSize = .F., ;
		FontName = "Tahoma", ;
		Alignment = 1, ;
		BackStyle = 0, ;
		Caption = "Username", ;
		Height = 16, ;
		Left = 12, ;
		Top = 24, ;
		Width = 56, ;
		Name = "Label1"


	ADD OBJECT label2 AS label WITH ;
		AutoSize = .F., ;
		FontName = "Tahoma", ;
		Alignment = 1, ;
		BackStyle = 0, ;
		Caption = "Password", ;
		Height = 16, ;
		Left = 15, ;
		Top = 60, ;
		Width = 53, ;
		Name = "Label2"


	ADD OBJECT text1 AS textbox WITH ;
		FontName = "Tahoma", ;
		Height = 23, ;
		Left = 84, ;
		Top = 24, ;
		Width = 204, ;
		Name = "Text1"


	ADD OBJECT text2 AS textbox WITH ;
		FontBold = .T., ;
		FontName = "Tahoma", ;
		Height = 23, ;
		Left = 84, ;
		Top = 60, ;
		Width = 204, ;
		PasswordChar = "*", ;
		Name = "Text2"


	ADD OBJECT command1 AS commandbutton WITH ;
		Top = 101, ;
		Left = 120, ;
		Height = 27, ;
		Width = 84, ;
		FontName = "Tahoma", ;
		Caption = "OK", ;
		Enabled = .F., ;
		Name = "Command1"


	ADD OBJECT command2 AS commandbutton WITH ;
		Top = 101, ;
		Left = 204, ;
		Height = 27, ;
		Width = 84, ;
		FontName = "Tahoma", ;
		Caption = "Cancel", ;
		Name = "Command2"


	PROCEDURE Init
		LPARAMETERS tnMaxTries
		IF PCOUNT() > 0 AND TYPE("tnMaxTries") = "N"
			this.maxtries = tnMaxTries
		ENDIF
	ENDPROC


	PROCEDURE checklogin
		LOCAL lcMachine, lcUser, loUser, llPasswordVerified, lcErrorHandlerWas
		lcMachine=LEFT(SYS(0),ATC([#],SYS(0))-2)

		lcUser = ALLTRIM(thisform.text1.value)     && if we want the current user then: RIGHT(SYS(0),LEN(SYS(0))-ATC([#],SYS(0))-1)

		lcErrorHandlerWas = ON("Error")

		llPasswordVerified = .T.

		ON ERROR llPasswordVerified = .F.

		loUser = GetObject([WinNT://]+lcMachine+[/]+lcUser)

		loUser.ChangePassword (ALLTRIM(thisform.text2.value), ALLTRIM(thisform.text2.value))

		ON ERROR &lcErrorHandlerWas

		RETURN llPasswordVerified

		*!* Additional useful information at: [URL unfurl="true"]http://www.4guysfromrolla.com/webtech/061202-1.shtml#postadlink[/URL]
		*!* One possibility is to use the Domain that this computer is a part of so
		*!* validation is done at that level rather than on just the computer at hand
		*!* more information is needed on this subject to handle complex situations,
		*!* but the basics for it are here and it appears to be a quick and easy way
		*!* to use window's authentication with an application
		*!* Next step would be to check user's permissions and see if they should
		*!* be allowed access even if they have a windows user account
	ENDPROC


	PROCEDURE validateentries
		thisform.command1.Enabled = !EMPTY(this.text1.Value) AND !EMPTY(this.text2.Value)
	ENDPROC


	PROCEDURE QueryUnload
		thisform.command2.Click() && Call cancel button code
	ENDPROC


	PROCEDURE text1.InteractiveChange
		thisform.validateentries()
	ENDPROC
	

	PROCEDURE text1.KeyPress
		LPARAMETERS nKeyCode, nShiftAltCtrl
		IF nKeycode = 13 AND thisform.command1.Enabled
			thisform.command1.Click()
		ENDIF
	ENDPROC


	PROCEDURE text2.InteractiveChange
		thisform.validateentries()
	ENDPROC


	PROCEDURE text2.KeyPress
		LPARAMETERS nKeyCode, nShiftAltCtrl
		IF nKeycode = 13 AND thisform.command1.Enabled
			thisform.command1.Click()
		ENDIF
	ENDPROC


	PROCEDURE command1.Click
		thisform.Visible = .F.
		_screen.successfullogin = thisform.checklogin()
		IF !_screen.successfullogin
			thisform.numberoftries = thisform.numberoftries + 1
			IF thisform.numberoftries < thisform.maxtries
				IF MESSAGEBOX("The Username or Password you have enter is incorrect." + CHR(13) + ;
					"Would you like to try again?",36,"INVALID LOGIN INFORMATION") = 6
					thisform.text2.SetFocus()
					thisform.Visible = .t.
					RETURN .F.
				ENDIF
			ELSE
				MESSAGEBOX("Please check with your Systems Administrator to obtain correct login information.",64,"UNABLE TO LOGIN")
			ENDIF
		ENDIF
		thisform.Release()
	ENDPROC


	PROCEDURE command2.Click
		_screen.successfullogin = .F. && Just in case - future changes may need this
		thisform.release
	ENDPROC


ENDDEFINE

boyd.gif

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top