prevent using an Access database on other computers - ms-access

I have an Access database and I want make it work for one computer only. If someone takes a copy of my database they shouldn't be able to open it on another machine.
I was thinking that the database could check the properties of the computer to see if they match those of the machine on which it should run. If not, the database would show a MsgBox that says "You can't open this database because you copied to other computer please call the programmer."

You can use VBA in a start-up routine to check if the following properties match some predetermined values:
VBA.Environ("ComputerName")
VBA.Environ("UserDomain")
VBA.Environ("UserName")
To prevent users bypassing your start-up routine by holding down the Shift key, you can use the following code as a one-off to add a property to the database preventing this (works in Access 2007, not sure about earlier versions):
Dim AllowBypassKey As Property
Set AllowBypassKey = CurrentDb.CreateProperty("AllowBypassKey", dbBoolean, vbFalse)
CurrentDb.Properties.Append AllowBypassKey

In access you can encrypt the database with a password. This will only allow the users who have the password to open the database.
http://office.microsoft.com/en-001/access-help/encrypt-a-database-by-using-a-database-password-HA010096299.aspx#BM2

Been looking for an answer to this myself...and came across this.
This link shows a couple of ways that might be a bit more unique.
You can check for hard drive serial number or motherboard serial number.
Computer name and usernames can be moved to other PCs...it would be a lot harder to move hard drives or motherboards around.
http://www.mrexcel.com/forum/excel-questions/457262-visual-basic-applications-code-do-check-valid-use-computer.html

Related

Cannot Connect Access DB to ODBC DSN Using MySQL Connector/ODBC

I am trying to connect MS Access to a MySQL database backend - using the windows "Set up data sources (ODBC)" command allows me to connect to my database fine, but will not save the DSN file for some reason.
I've tried to get around it by manually creating a DSN file which looks like (with the actual data instead of the ***):
[ODBC]
DRIVER=MySQL ODBC 5.1 Driver
USER=****
PASSWORD=****
SERVER=**.***.**.**
DATABASE=cl39-beech
However Access throws up the message
ODBC--call failed.
[microsoft][odbc driver manager] data source name not found and no default driver specified.
Any thoughts on how to get around the problem(s)? I'm not too worried about the first one if I can manually create the DSN file, but need to work out where the second is going wrong!
Simply create the working link from Access like you did in your first step. When the ODBC manager from Access launches then simply create a file data source.
Check that the linked table works by opening the linked table in Access to ensure the connection works and you see data.
Now, simply grab/pull out the connection string saved for that table like this in the debug window (hit ctrl+g to launch VBA IDE and jump to command line).
? currentdb.TableDefs("dbo_customers2").Connect
The debug window will then out put the correct connection string. (so in above, replace what I have with the name of the WORKING linked table).
It is the above connection string result that you can use to re-link a table.
A suggested code example for the above string to re-link tables can be found here.
So don’t bother with trying to use a DSN, as there is often a zillion issues such as where you have to place the file to work etc. The above approach means no DSN is required.
edit:
Edit:
In most cases, you likely don’t need any code. Remember, once you linked the Access tables, then the DSN is in general NOT required. Access linked tables “remember” their settings.
So you really only need such code if you not going to “manually” use the ODBC manager from access to link the tables.
Thus, the code ONLY need to run “one time”. So you on your development machine simply place the code in a standard code module and while in the VBA editor hit F5. As noted, if you ALREADY linked the tables, then you don’t need the DSN anymore anyway (it is only used “during” the re-link process and the settings in that DSN are transferred to each linked tables.
So you don’t need to run the code in some form – it is a “one time” thing you do much like designing a form. You don’t re-design forms on application startup, nor do you need to run some re-link code ONCE the tables have been linked.
In most cases such re-link code is ONLY required if you going to CHANGE the back end database (say from developer back end to the actual production back end database). And thus I suppose you could make a form with a button on it to re-link, but as a general rule you don’t need that code to run each time the application runs.
Once tables are linked then your forms and reports etc. should work as if such tables were regular “local” access tables. So this re-link code is really a “substitute” for you doing the manual linking to the SQL server tables. However ONCE you done a “manual” link, then the original DSN is not required. The re-link code thus in “most” cases is to allow you to re-link the front end database to a back end database of your choice, or in those cases in which you are supporting a client “far away”.
If you are developing “off site” then your linked tables are to your local copy of MySQL. When you send a updated “next great” version of your application to the customer site, then your table links are wrong, and on startup you need to run that re-link code to correctly link the tables to their back end. A “great” way to do this is to ALWAYS have a text file in the same directory as the application. Your application on startup can read that text file, and if the connection string is DIFFERENT then the existing connection, then you call + run your re-link code with this new connection string. Thus you don’t have to be on the customer’s site to roll out updated software. Next time the application runs, the connection strings will match and thus a re-link will NOT be required on startup. So re-linking is a “one time” type of deal here.
There are a BILLION different use cases here. What works for me may well not work for you. It not clear if you are working “on site” (so re-linking of tables is likely NOT required), or you developing off site with your own copy of MySql running (and thus you linked tables point to the wrong server). Or you are developing on site, but DURING development, your front end tables are linked to a “test” copy of the database as to not accidently “mess” with the production data.
So the code belong in a standard (non class) code module. As to when you need to run such code will depending on the billion different possibility’s (so it kind of like asking me to tell you where your shoes are in the morning – I have no idea and never could have an idea). But I can tell you that you should put shoes on when you go outside!
So if your linked tables are now working, then your application should be compiled to a accDE, and then that accDE should be distributed to each computer that requires this application. If they are on the same network etc., then no code or re-linking of the tables is required. On the other hand, if you are developing off site, or the application has to be distributed to several different companies then likely EACH company will have a different server location as to where MySQL is running and thus you need to re-link in each of those cases.
So it is possible that you may well not need ANY re-linking code. If you are “on-site”, then once you linked those tables, then your application should run on ANY computer without needing any re-linking code or having to run this re-link code.
So once tables are “linked”, access remembers that setting and it is permanent.

Access database won't share

We have an access database on a file share that has permissions for everyone in the department to access. The problem i am having is that when multiple users try accessing the database at the same time they are unable to do this. One user can open the database fine but when another user tries to simultaneously, they double click the file icon, get an hour glass for a split second and nothing happens after. We are using Server 2003 as our domain controller. All permissions have been verified on both a domain level and in the access database under tools-options-advanced and setting relevent permissions to shared and no locks. Do you know what could be causing this issue with a "dead link" when user try to open the file simulateneously?
Any help is greatly appreciated.
Thanks.
Ignore the naysayers - Access is perfectly fine for a small number of users. Either you have the default Access settings to open dbs exclusive which will lock out other users or there is some weird network problem.
EDIT
- noticed you already have default shared access
- is record-level locking on?
- also try giving user full control of the shared network folder (Access needs read/write/create/delete to be able to create and delete the ldb file)
This issue occasionally happens to Access databases for almost no apparent reason. Of the suggested responses by Microsoft, you are already doing the second (opening from within Access) but I believe the first provides somewhat of the answer you are looking for.
In the target of the shortcut, include
the path of MSAccess.exe
According to Microsoft Help and Support
When you say share permissions, do the users have full permissions? Full permissions are needed because the share file (.ldb) must be created and deleted.
I am just recently experiencing the same issues, only one person can open the database. We only have 3 people accessing the same database through shorcuts on our desktop.
Now according to Microsoft we need to include the database path in our shortcut, I will tried that. They acknowledge this problem.
MS Access is not worth the trouble in a multi-user setup.
Your time is better spent converting the database over to a server-based RDBMS such as SQL server while you still have hair.
Believe me, you will have to do it sooner or later anyway! Sorry for the bad news.

How to control user rights to an Access database?

What is the simplest way to allow one user write access and everyone else read-only access to a MS Access database on a local network?
I trust my users, but unfortunately Access saves changes to data as soon as the row of a table is deselected. Accidental keystrokes are saved without the user asking for the changes to be saved.
Some thoughts on controlling user rights to a Jet data store:
if you really want to lock things down, you'll never manage it with Jet, as it's inherently vulnerable because the user has to have WRITE access to the MDB file.
if you are content with controlling rights to the data in your front-end application, you could provide different front ends (one for WRITE users and one for READ-ONLY).
if you're not using ACCDB format, you can use Jet user-level security. It's a surprisingly complicated technology if you really want to lock down access to the data -- you have to follow all the instructions in the Jet Security White Paper to the letter, or your data will be open to anyone with the standard Jet workgroup file. And even once you're done, it is crackable (though not without spending $$$ to buy cracking software). BTW, database passwords before Access 2007 were completely useless and easily cracked. Access 2007 enhances the security by raising the level of data encryption, but a database password causes lots of issues and doesn't allow you to have more than one level of access (unless you provide two different front ends with different passwords -- cf. #2).
if you just want to use Jet ULS to control access in your front end, you can add your users to groups and then check the group membership in your front-end UI objects (i.e., forms), and give WRITE permission to the users who are in the user group that provides that level of access. The easiest way to do this, assuming you have more READ-ONLY users than those with WRITE permission is to have the READ-ONLY users log on as the default admin user (i.e., you do nothing for their setup), and have the WRITE users log on as a user in the group with WRITE permission. In other words, if they aren't logged on as user "admin", they have full WRITE access.
another alternative is to use NTFS security groups. API code for that is found on the Access Web, but it does require a Windows administrator to implement for you. Again, you would be limiting access in your front end application, rather than actually restricting user rights in the back-end MDB.
Only Jet ULS actually allows you to prevent a READ-ONLY user (who hasn't cracked your workgroup file) from editing your data. All users have to have network access to your back-end MDB, but you can make it hard for them to get to the data even without jumping through the hoops in implementing Jet ULS. Here are some steps to do that (and yes, all of these are a form of "security by obscurity" and will only slow down a READ-ONLY user determined to hack your back end):
Right click each table in your back end and turn on the HIDDEN attribute. This can also be done in code (see SetHiddenAttribute in Help). Naturally, if the end user sets their Access options to display hidden tables, this won't do anything. But most end users don't know about that, and if your users are running your app in the runtime, they won't have the option.
Change the back-end database's Startup Properties to not display the database window and to not use special keys. You can find code for setting the startup properties in the Help topic for "AllowBypassKey".
In your back-end, create a macro named AutoExec with one command, Quit. With special keys disabled, there is no way to prevent the execution of this macro, and as soon as the user attempts to open the back end (even if they hold down the SHIFT key, i.e., the standard keystroke for bypassing all startup routines), the database (and the instance of Access) will close.
Now, all of these things can be undone by someone who knows what they are doing. If you gave me a back end with these things implemented, I'd be in it in about 5 minutes, simply by running code in another Access database to change all these startup properties to give me access.
But your end users likely don't have that level of expertise. Any such user who does probably ought to be a WRITE user, no? :)
Yes, of course -- all of these things are easily hackable by anyone who knows how. But it's also easy to break into your house in seconds for the person with the right tools. That doesn't mean you don't lock the doors, even though it's not bulletproof protection from burglary.
Another consideration is that if you provide your users only the Access runtime instead of full Access, they won't be able to undo any of these settings in your back-end MDB.
Last of all:
Security is not solely a technical issue -- most of it is, in fact, a people problem. In order for people to do their work, you have to trust them to a certain extent in giving them access to your data. There is no technical solution to the problem of the untrustworthy system administrator, for instance, and the only way to fully protect your data is to not give them any access to it at all.
The easiest way would be to use share permissions. Grant write access to a group and put the users who must write to the database in that group. Put everyone else in a read group. This assumes you have a Windows domain, of course.
Here is a site that has some information on securing Access databases. It deals with Access 2000, there may be more options for newer versions.
This is the cheeky answer, but if you need better security, seriously consider upgrading to a more robust RDBMS.
I think it is possible using an ODBC connection to use Access as an interface to almost any database. For example, I have successfully configured a SQL Server 2008 Express Edition database with 2 users, one read/write and one read-only. I have been able to connect to the database from Access by opening an ODBC data source. So a user can have the Office-based report-generating and mail-merging functionality they are familiar with. But with any database server you wish.
This conversation may be a little old, but for some reasons I got the same problem recently. It will not suit to everyone, cause it relies not on M$ SQL Server but on MySQL. Use the MySQL ODBC connector (available here: http://dev.mysql.com/downloads/connector/odbc/), and store your tables on a MySQL server. The Access user's rights on tables will inherit from the MySQL user's rights. Pretty easy to customize...
Fact is, there is NO functional security for an access database.
The link below sells software that will 'recover' your access database Even if it has a a password.
It is a good thing they exist. Their program saved one of my customer's butts once when their previous programmer died and no one else had the password. Thanks to this program we could not get in and no data was lost.
http://www.stellarinfo.com/access-recovery.htm
And before you even think it, No, I do not work for them.

Access Caching ODBC connection settings

My company uses SAI heavily and in order to create reports from this system we use ODBC to connect to the DB. Our setup at the moment is regional and thus we have separate environments for each region. When trying to access these environments using MS ACCESS I am finding that I cannot link to tables in different environments and retrieve accurate data.
I can create the links to various environments using the specific DSN's. I then can access the data, however the first table that I open, no matter the region it belongs to, works fine. After that, however, all of the tables, regardless to the region they belong to, all use the DSN settings from the first table that was opened. If I shut Access down and restart I can then start with data from another environment which will then work, however the rest of the data will then reflect those DSN settings. Additionally, when I look at the property sheet the DSN settings are as they should be.
Let me also add that the tables for each region all have the same name. IE the sales table is sales in all environments, the production table is the production table in all regions. As a result as I link to the sales table from multiple environments the need to be renamed in MS ACCESS.
I would have a look at this SO Question answered a last month.
It describes a couple of methods for forcing Access to re-link ODBC tables and, if all fails, provides you with a way to restart the database programmatically using a small function that you'll find on my blog.
I suspect you leaving out a few details that we need.
When you open that first table, are you prompted for a logon? (this is critical info). If you using “different” links and saving the userid/password in those links, then you should not get any ODBC prompts and you can thus easily work with more than one region.
However, it sounds like you have one set of links, and want to re-point/re-link to a different server. This can work - but NOT if you seeing/allowing ODBC prompts.
If you ARE including the userid/password in the links then you should be able to re-link (switch) to either system. However when you do this, then BOTH uid/password combos ARE and WILL be active at that same given time.
Where things go VERY wrong is that if you re-link with an incorrect logon then the previous uid/password WILL be used! And in fact if you TEST for a logon (even a bad one!), then the first legal logon will be used! At the end of the day, this means the weak point here is WHEN/if you ask for a logon, it WILL return “yes” for a legal logon EVEN if the logon is bad! (because Access will revent to the previous legal logon used) You MUST deal with this issue.
So likely things point to your code that does a logon “test” before re-link. What I would suggest is that your “test” logon code returns OK, you THEN execute a pass-through query to return the database name – if that database name/server is wrong, then you reject that logon and do NOT re-link.
So critical here is how you are testing for the new logon/server? And you most certainly NEVER want the ODBC logon prompt to appear – since if a user cancel, or enters the wrong logon, then your re-link code will use the previous cached logon.
You should be able to re-link the same given set of tables and point them to another server – but you need to ensure that the logon you used did in fact work.
Last but not least:
Access ALWAYS uses a DSN less connection. The ONLY exception is if you are using a system DSN. So when you create a file DSN, and re-link then the DSN FROM THAT point on is ignored, and not used. (this allows you to say distribute the application to other desktops without having to copy/include a DSN). So in effect you near always using a DSN-less connection and if you are not, then I suggest you dump the SYSTEM DSN’s, since Access cannot use the USER/password from such system DSN’s – even if you include the USER/password in that DSN it is STILL ignored.
Also when you re-link, are you using the dbAttachSavePWD – you should not have to, but I would for testing include it.
If you are using/allowing the ODBC driver to prompt the user for a logon – then you have to eliminate this and ensure your code does the logon.
One option you may have (though a bit long winded) would be to create an access database for each region which links to one regions tables. eg have the sales table and production table for region Europe in one access database, and put those from ASIA into another database.
Once you have this set up, you might find it much easier to then use a third access database to link to the two other access databases.
Hope this is useful.

How can I open an Access DB via ADO so that I can write, but others can only read?

From the documentation, I would expect adModeShareDenyWrite to be the way, but it's not working right.
I'm using an Access database via ADO. My connection string says Mode=8, which is adModeShareDenyWrite. But when I try to delete a row from a table, I get:
Unspecified error, Description:Could not delete from specified tables., Source:Microsoft JET Database Engine
In other words, the setting is preventing ME from updating the database using my OWN connection.
I found a couple other posts on the web reporting the same thing, the adModeShareDenyWrite setting used with Access not working as documented.
I am looking for a solution that doesn't involve an administrator changing permissions. It needs to be something that my program can control.
My motivation here is to minimize the chances of database corruption. One of the causes of mdb file corruption documented by Microsoft is two apps writing to the same db. So, I want to make sure that only one app can have a write connection to the db. Others can read, but should fail when they try to write. Whoever makes a connection first wins.
Cory Trager wrote:
My motivation here is to minimize the
chances of database corruption. One of
the causes of mdb file corruption
documented by Microsoft is two apps
writing to the same db. So, I want to
make sure that only one app can have a
write connection to the db. Others can
read, but should fail when they try to
write. Whoever makes a connection
first wins.
Why are you worrying about it? Jet is by default a multi-user database engine. If somebody else is updating a table, the data pages involved will be locked as read-only (in the state they were before the write began).
There is no realistic reason to fear corruption from mere multi-user interaction. Corruption of Jet databases usually happens because of dropped connections or an interruption of the connection during a write (such as users who force quit an app that is not responding as fast as they want).
I think your fear of corruption is misplaced.
On the other hand, you should still be able to open with an exclusive lock, and I'm not sure why it's not working. Have you considered using DAO instead of ADO to manipulate Jet data? Given that it's the native data interface (instead of a generic interface layer), it ought to be easier.
One solution is to give them access to a copy of the database. They can change whatever they want, but it won't keep past your copying it over with the master.
I suppose you access here an MDB file from a client interface, whatever it is, and others can also connect to the same file at the same time. When you use adModeShareDenyWrite in your connection mode, it means that you can still share the data with others (no locks of any kind on tables or records in the MDB file) but it can't be modified (this is why you get an error).
One solution would be to manage your connection parameters, with something like that:
(where you have a user object with a '.role' property, or anything equivalent ...)
if activeUser.role = "admin" then
m_connectionMode = adModeWrite
else
m_connectionMode = adModeShareDenyWrite
endif
Then you can open your ADO connection with the parameter m_connectionMode. Administrators will be given the right to insert/update/delete while other users will ony be able to view the data. This means you have somewhere in your program, or ideally in a table, some data saying who is what in your application.
EDIT: Following multiples comments with Corey:
You won't be able to do what you want to do in a straight way. My proposal: when the app accesses the database, it checks for a special file in the .mdb folder (whatever the file is).
If this file exists, the app opens a "read-only" connection.
If this file does not exist, the app creates the file (you can create one for example with "transferDatabase") and open a read-write connection. Once you quit the app, destroy the file.
If you have multiple users connecting to an access database across a network you might want to consider upgrading to SqlServer instead of using Access.
Corey Trager wrote:
I am looking for a solution that
doesn't involve an administrator
changing permissions. It needs to be
something that my program can control.
Well, if the problem is due to NTFS permissions being read-only for the user, there isn't a thing you can do to make the MDB writable. You don't specify where the MDB is stored, on a server or on a local hard drive, but in either case, for a user to have WRITE permissions on the MDB, NTFS permissions have to be set to allow it (for a share on a server, it has to be allowed both on the SHARE and on the underlying file). If it's a local file, the best solution is to make sure that you're storing the file in a location in which user-level logons have full WRITE permission. This would be anywhere in the user profile, and just about nowhere else.
That said, I'm not really suggesting that this is the source of your problem (I really can't say one way or the other), just pointing out that if it is the cause, then there's not a damned thing you can do programmatically to work around it.