Solved

97 Runtime problems in XP limited user account

Posted on 2004-10-20
7
530 Views
Last Modified: 2008-01-13
We are having several problems with a 97 runtime application running in various XP environments when the user is a limited account. We are using Wise and the SageKey scripts to build the install, and everything works fine as long as the account used to install the program is the same account used to run it. But we have some clients who understandably want to do the install from one account and have the user run it from another account.

Our errors have included:

1. on startup, "can't be started - was unable to initialize the Windows registry" error (this occurs when Access XP is also installed)
2. on exit from app, "you do not have access to make the required system configuration modifications" (this occurs on limited user accounts in a client-server setup)
3. within app, 3027 error when reattaching to back end tables unless we are running from the same account that did the runtime install - even another admin account gets this error.

I think all of these issues probably have to do with the user not being able to update the registry. My questions are:

1. Are there people out there successfully running 97 runtime fe/be apps in XP limited user accounts? or is that too much to ask?
2. Is there a "run as" option or other workaround that consistently works? Our testing with "run as" has had problems, too.

I have not been successful at finding anything on the web which specifically addresses 97 runtime in a limited XP user environment.

Thank you.

0
Comment
Question by:ssskw
  • 3
  • 2
  • 2
7 Comments
 
LVL 36

Assisted Solution

by:SidFishes
SidFishes earned 50 total points
Comment Utility
try these... we are using A2002 RT with Win2k standard users (not power users group so should be similar to XP limited) so these may not be very helpful

first time start up as admin (i know that this is not very practical but it's necessary to allow for the registry modification)
make sure user has full read/write permissions to the RT folder...think this takes care of the 3027

not sure about the exit error not seen that...perhaps the folder permissions will help that

and as always...make sure the client machines have the latest os and office SP's...our RT would not run until we applied Office SP3 to all clients...however I don;t know the level of SP support for A97 so you may be sol



0
 
LVL 39

Accepted Solution

by:
stevbe earned 450 total points
Comment Utility
I have vb code that allows you to "run as" using win32 api very reliably, you could wrap it up as a vb exe and have users launch that (hopefully the same account as was used to install due to sage key settings etc creating Access user profiles in the registry)
and that would use automation to launch your app. The only problem, or inconvenince is that you will need to have code that will terminate the VB app when you close your application because the vb app is waht crates the "Power User" context thread for your app to use, not really a big deal becasue it don't need to have a UI for the VB app but it is a bit more code.

I will post the api and hopefully you can modify to suit your needs, certainly post back if I can help with the bits and pieces.

Now that I think about it, you don't really need VB as the code would work just as well in any VBA host, be it Access, Excel, Word or AutoCAD.

Steve

ok ... next section of code goes into a new standard module ...

'-------------------------------------------------------------------------------
'   Environment
    Option Explicit
    Option Base 0
'-------------------------------------------------------------------------------
'
'
'-------------------------------------------------------------------------------
'   Win32 API declarations
    Public Declare Function GetComputerNameEx Lib "kernel32.dll" Alias "GetComputerNameExA" (ByVal NameFormat As Long, ByVal Buffer As String, Size As Long) As Long
    Public Declare Function GetUserNameAPI Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
    Public Declare Function LogonUser Lib "advapi32.dll" Alias "LogonUserA" (ByVal UserName As String, ByVal Domain As String, ByVal Password As String, ByVal LogonType As Long, ByVal LogonProvider As Long, Token As Any) As Long
    Public Declare Function ImpersonateLoggedOnUser Lib "advapi32.dll" (ByVal Token As Long) As Long
    Public Declare Function RevertToSelf Lib "advapi32.dll" () As Boolean
    Public Declare Function RegSaveKey Lib "advapi32.dll" Alias "RegSaveKeyA" (ByVal hKey As Long, ByVal lpFile As String, lpSecurityAttributes As SECURITY_ATTRIBUTES) As Long
'-------------------------------------------------------------------------------
    'Computer Name Format
    Public Const ComputerNameDnsDomain = 2
   
    'LogonUser enumerations
    Public Const LOGON32_LOGON_INTERACTIVE = 2
    'Public Const LOGON32_LOGON_NETWORK = 3
    Public Const LOGON32_LOGON_BATCH = 4
    'Public Const LOGON32_LOGON_SERVICE = 5
   
    Public Const LOGON32_PROVIDER_DEFAULT = 0
    Public Const LOGON32_PROVIDER_WINNT35 = 1
    Public Const LOGON32_PROVIDER_WINNT40 = 2
    Public Const LOGON32_PROVIDER_WINNT50 = 3
'-------------------------------------------------------------------------------
    'SECURITY_ATTRIBUTES data structure used by RegSaveKey api
    Public Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Variant
        bInheritHandle As Boolean
    End Type
'-------------------------------------------------------------------------------

Public Function GetDomainName() As String
    Dim lLength As Long
    Dim lRet As Long
   
    GetDomainName = String$(255, vbNullChar)
    lLength = 255
    lRet = GetComputerNameEx(ComputerNameDnsDomain, GetDomainName, lLength)
    If lRet = 0 Then
        'return 0 indicates failure
        GetDomainName = ""
    Else
        'return <> 0 indicates success, strip trailing null characters
        GetDomainName = Left$(GetDomainName, lLength)
    End If
   
End Function
'-------------------------------------------------------------------------------
Public Function LogonAsUser(ByVal UserAlias As String, _
                            ByVal Domain As String, _
                            ByVal Password As String, _
                            ByVal LogonType As Long, _
                            ByVal LogonProvider As Long, _
                            Token As Long) _
                    As Long

Dim lngToken As Long

    lngToken = LogonUser(UserAlias, "", Password, LogonType, LogonProvider, Token)

    'assign return value
    LogonAsUser = Token

End Function
'-------------------------------------------------------------------------------
Public Function ImpersonateUser(ByVal Token As Long) As Boolean

    If ImpersonateLoggedOnUser(Token) = 0 Then
        ImpersonateUser = False
        MsgBox "impersonation error=" & vbCrLf & Err.LastDllError
    Else
        ImpersonateUser = True
    End If

End Function
'-------------------------------------------------------------------------------
Public Function RevertUser()
    RevertToSelf
End Function
'-------------------------------------------------------------------------------
Public Function GetUserName() As String
    Dim lRet As Long
    Dim lLength As Long
   
    GetUserName = String$(255, vbNullChar)
    lLength = 255
    lRet = GetUserNameAPI(GetUserName, lLength)
   
    If lRet = 0 Then
        'return of 0 indicates failure
        GetUserName = ""
    Else
        'non-zero return indicates success
        GetUserName = Left$(GetUserName, lLength - 1)
    End If
   
End Function
'-------------------------------------------------------------------------------


and to use the impersonation you can pout this code anywhere you need to ...

Public Function KeySave()
Dim strDomain
Dim lngToken As Long

    'get domain
    strDomain = GetDomainName

    'logon as local admin
    lngToken = LogonAsUser(UserAlias:="admin", _
                           Domain:=strDomain, _
                           Password:="nimda", _
                           LogonType:=LOGON32_LOGON_INTERACTIVE, _
                           LogonProvider:=LOGON32_PROVIDER_WINNT50, _
                           Token:=lngToken)
    If lngToken = 0 Then
        MsgBox "unable to logon as admin"
    End If

    'impersonate admin
    If ImpersonateUser(lngToken) = False Then
        MsgBox "unable to impersonate admin"
    End If

    'this is where you would create a new instance of an Access.Application
    Set accApp = New Access.Application
                ..... do you thing here to open it.....


and for the final piece ... you could skip but I like to keep things clean ... in Unload event, close event

...
    'revert to logged on user's context
    Call RevertToSelf
0
 
LVL 36

Expert Comment

by:SidFishes
Comment Utility
nice one Steve ;)...that sucker's bookmarked
0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 39

Expert Comment

by:stevbe
Comment Utility
Thanks Sid,

The way I have this set now you need to set the user name and password in code, if you use VB and copile it is fairly well hidden, and you could also make it in an Access.mde which would also be OK. If you use something that deos not remove conanical text you have a potential security hole. I do have some more code that uses simple text encryption and reads the username and password from a file so you do not have to redistribute the entire app when these change, as the should on a regular basis. I am in the process of putting together the same concept using windows crypto api but it is not ready for prime time quite yet.

You could drop this part from the standard module as it was part of the specifc utility I wrote this for to read/write to the registry.
'-------------------------------------------------------------------------------
    'SECURITY_ATTRIBUTES data structure used by RegSaveKey api
    Public Type SECURITY_ATTRIBUTES
        nLength As Long
        lpSecurityDescriptor As Variant
        bInheritHandle As Boolean
    End Type
'-------------------------------------------------------------------------------

Steve
0
 

Author Comment

by:ssskw
Comment Utility
Wow, Steve. It looks like you've been down this road before. :-)

This app is distributed to numerous sites, so the admin userid/password will vary. Am I following correctly that I would need the other part you refer to for them to store their username and password in a specific file?

Sid, to follow up on your comments:

We had also noticed that if ran as admin the first time, that got us around the startup problem. But we were hoping for a more elegant solution, which it looks like Steve has provided. Also, our runtime gets updated fairly often, and the rerun-as-admin seemed to be necessary after every update, which was a pain.

We are getting the 3027 error despite full folder permissions (in a 2003 server environment). The user can actually create a new database (using CompactDatabase from an old mdb to the new mdb), then the attach to the new db still gets an error. It is too weird.

Thanks to you both for the prompt responses!

Kory

0
 
LVL 39

Expert Comment

by:stevbe
Comment Utility
I will post the username / password code tomorrow, it is at work :-)

Steve
0
 

Author Comment

by:ssskw
Comment Utility
The code Steve sent is great, but we still had some issues due to some other things we were doing at startup to do version control checking for automatic updates. With SageKey's help we have identified registry changes to make. The startup problem requires a registry fix which every limited user must run once...SageKey is still working on this so I won't post the details yet, but it has to do with the CurrentUser/Software keys for Access. The ending problem uses a SageKey dll to modify some security permissions.

The 3027 (and also a 3051 error in some cases) were caused by limited users not have full permissions to the LOCAL folder where the FE code was running. We kept thinking it was a network folder permission problem.

Thanks to you both.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

In the article entitled Working with Objects – Part 1 (http://www.experts-exchange.com/Microsoft/Development/MS_Access/A_4942-Working-with-Objects-Part-1.html), you learned the basics of working with objects, properties, methods, and events. In Work…
Regardless of which version on MS Access you are using, one of the harder data-entry forms to create is one where most data from previous entries needs to be appended to new records, especially when there are numerous fields and records involved.  W…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
In Microsoft Access, when working with VBA, learn some techniques for writing readable and easily maintained code.

771 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now