What are the access restrictions on accessing a DSN - c++

We are running part of our app as a windows service and it needs to b able to access DSNs in order to import through ODBC. However there seem to be a lot of restrictions found through trial and error on what DSNs it can access. For example it seems that it cannot
1. access a system DSN unless the account that is running the service has admin privileges. (I get an Access Denied error, when trying to connect)
2. access a user DSN that was created by a different user (this one is understandable).
3. access a file DSN across the network
I've read that the purpose of a file DSN is to allow other computers to use it to connect, however i can't seem to make that work.
So does any know, or know where i can find out what all the rules and restrictions on accessing a DSN are when using a windows service.
thanks

This is somewhere between your #1 and #2: sometimes correct file permissions are also necessary. I once had troubles on a Vista machine connecting to a DB2 DSN because, for whatever reason (maybe to write out temp files; although I don't know why it would do such a thing in this location instead of a user-specific one), the driver needed write access to the directory where IBM had installed the client binaries and libs, which had been done by an Administrator and was in the root of the C drive.

I think you've already discovered the three main rules yourself. :-)
Except that you probably don't need admin privileges for your service account. IANANA (I am not a network administrator), but your service account probably just needs read access to one of the ODBC files or directories.

You cannot connect to mapped drives with a service. A mapped drive has to interact with memory called the desktop heap which tracks the icons on the desktop. Services do not have access to that memory. If you have to use a dsn create a systemdsn. better would be to use a connection string and store that in the app.config and use the encryption api to encrypt the user name and password.

Related

Qt cross platform safe way of storing data in an SQLite database?

I'm trying to figure out the safest way of storing chat history for my application on the clients computer. By "safe" I mean so that my application is allowed to actually read/write to the SQLite database. Clients will range from Windows, OS X and Linux users. So i need to find a way on each platform of determining where I'm allowed to create a SQLite database for storing the message history.
Problems I've run into in the past were for example when people used terminal clients for example Citrix where the users is not allowed to write to almost any directory. The drive is often a shared network drive.
Some ideas:
Include an empty database.db within my installer that contains prebuilt tables. And store the database next to my executable. However I'm almost certain that not all clients will be allowed to read/write here, for example Windows users who do not have admin rights.
Use QStandardPaths::writableLocation and create the database at the first run time
Locate the users home dir and create the database at the first run time
Any ideas if there is a really good solution to this problem?

Create file that can be opened only by a Windows Service

Is it possible to select such a security descriptor using a DACL string such that the file can only be opened by a Windows Service, but not by an ordinary process, even if the process is run by the local Administrator account?
To clarify, I just need to make it reasonably hard for a non-technical user to open it in NotePad and tamper with it. It doesn't need to work against a programmer willing to dedicate a month of his life to reverse engineering and cracking it.
I prefer to achieve this using DACL instead of locking the file because then my windows service doesn't need to run all the time for the file to be protected.
Local administrator account = God (at least on the box). There's no way to do this.
You can define a special privileged account for your service to run under, and make the ACLs on the protected file only allow access by that user (and all machine admins). You can disallow interactive login using that service account.
If your primary concern is tampering by interactive users, you may need a policy whereby the local user does not run by default with local admin rights. Unfortunately you cannot allow 'partial' local admin rights - it's all or nothing.
I don't know enough about DACLs to say whether or how you can accomplish what you want with those. I can think of a couple things you can do to make it harder for someone to tamper with the file, in addition to restricting it to the local administrator account:
Have your service start automatically, and open the file immediately with no sharing options. As long as your service has it open, another process won't be able to open it.
Compute a hash of the file contents plus a salt hardcoded into your service and store it somewhere else, e.g., in another file, in the registry, or even online. Next time you open the file, verify the hash, which will tell you if someone tampered with the file since the last time you opened it.
These are not foolproof by any stretch, but it sounds like your goal is simply to make it harder. There's no foolproof method to stop a user with administrator privileges.

Release writing permission in Windows 7

I am trying to release a C++ .Net application and am getting very frustrated with Windows UAC. I have not much experience with this as have always been writing for XP.
The program needs to update some properties that are stored in two XML files and every time it tries it gets access denied if it is not running with an Administrator account.
I have followed the recommendations from Microsoft and am writing all the files that need to be modified to the CSIDL_COMMON_APPDATA folder. The installer has an action that creates the [Organization}[Program] structure within the later and adds the security group Every One with full control privilege because by default, that directory is read only.
I have verified that the cretated directory [Organization}[Program] does actually contains the group and the privilege assigned after installing.
Also, the application has a manifest with a requestedExecutionLevel, which I have tried asinvoker and Highestavailable.
The application is still not being capable of writing to the directory unless the user is not logged as Administrator...
The machines are in a domain controled by a server 2003 but the clients are a mix of XP, vista and 7.
Please, could someone with more experience in this than I enlight me?
Should I use some other folder? The problem is that Different users might log into the computer and those settings are common, therefore the obvious User folder is not an option.
I cannot either add the user to the security of the folders with the installer because I don't know which user from the domain will use the program and I cannot do it from the program when starting because if the user does not have adminstrator rights the program will just be blocked.
Please, any advise or indication about what am I missing here?
This may discuss your problem. See especially
Your application's installer needs to set ACLs on your subdirectory of CSIDL_COMMON_APPDATA to allow users to access that directory as required by your application

Is there any way to read password policies via the WMI RSOP_XXX classes?

Those all reside in the root\RSOP\Computer namespace. The only class from which I got non-empty results is RSOP_RegistryPolicySetting, and that one only gave me settings for Windows Update and System Restore configuration.
I do know there are password policies in our network (age, length etc), but queries on the following classes only gave empty resilts:
RSOP_ScriptPolicySetting
RSOP_SecuritySettingNumeric
RSOP_SecuritySettingBoolean
RSOP_SecuritySettingString
Does it have to be via WMI?
If you're running a domain, Microsoft's Scripting Guys have an article How Long Until My Password Expires?... but it uses ADSI to read policies from Active Directory, rather than policies on the local machine.

Installing Root CA Cert via code on Win32

We've just set up a new remote access solution using Microsoft's TS Gateway, which requires a couple of somewhat fiddly steps on the end users behalf in order to get it working (installing our root ca cert, requirement of RDP 6.1 client etc).
In order to make this setup process as easy as possible (a lot of these users aren't technically minded), I'm looking to create a program to perform all these tasks automatically. I have most of it working, however I'm not entirely sure how to go about importing the Root CA cert into the Windows certificate store.
Because this can potentially be run on a wide range of computers with varying levels of patches and updates, I'm steering well clear of .NET and anything that isn't native - the tool should 'just run' without the user having to install anything extra (well, I will say windows XP, no service packs, is the bare minimum required version of windows). In saying that, I don't mind using something third party if it can be bundled in with the tool, as long as it's not huge, and doesn't introduce any interactive steps. Ideally something in the windows API would be best, however I can't seem to track down anything relevant.
Currently the tool is a C++ application, so I don't mind if it's quite low level stuff.
First you need to open the root certificate store...
HCERTSTORE hRootCertStore = CertOpenSystemStore(NULL,"ROOT");
Then add the certificate using one of the CertAdd functions, such as CertAddEncodedCertificateToStore.
CertAddEncodedCertificateToStore(hRootCertStore,X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,pCertData,cbCertData,CERT_STORE_ADD_USE_EXISTING,NULL);
pCertData and cbCertData would likely point to the certificate data that you read from a file (not sure if the certificate will be in a file, or how you will include it in your application).
Then close the store with...
CertCloseStore(hRootCertStore,0);
NOTE: This code if run as the user, installs the certificate to the user's root store, not the computer's. It also results in a warning dialog that the user must understand and select "Yes" to authorize the import. If your setup program can run this code in a system account, the import will affect the computer's root store and not warning dialog will be shown.
Have you looked at CertAddEncodedCertificateToStore ?
you could also check out CertAddEncodedCertificateToSystemStore