Microsoft Access Security
Last Updated:  09/15/93

Purpose
The purpose of this document is to explain the Microsoft Access security 
model.  The hope is that if the user understands the intricacies of 
security, and is conscientious, he will be able to safely and 
successfully use Microsoft Access security in his databases.

Examples of scenarios that have caused difficulty for people in the past 
have been set apart under the heading of Gotcha.  These are intended to 
give practical examples of common misunderstandings, and to explain why 
Microsoft Access security works the way it does.

This document is applicable to Microsoft Access versions 1.0 and 1.1, as 
well as to the Microsoft Access Distribution Kit (ADK).  Features new to 
Microsoft Access 1.1 and the ADK are called out with New for 1.1.

Disclaimer:  There are several places in this document where the 
Microsoft Access sytem tables (those MSys*) are referred to.  In spite 
of this, these tables are officially "undocumented", and are subject to 
change in future versions.  Any attempts to read from or especially to 
write to these tables will most almost certainly fail future versions of 
Microsoft Access.
Overview
Microsoft Access security consists of 2 parts which are stored in 
different places.  Information regarding the permissions that users and 
groups have on the objects in a database is stored in the database 
itself.  This way the permission information travels with the .mdb file 
in which the objects exist.  All other security information is stored in 
the SystemDB specified in msaccess.ini.  The default SystemDB is 
system.mda.  Information stored in the SystemDB includes:  which Users & 
Groups exist;  which Groups each User belongs to;  and User logon 
passwords.  In Microsoft Access parlance, a SystemDB defines a 
"Workgroup".

Note:  Retail Microsoft Access looks for the file msaccess.ini to find 
it's settings, including SystemDB.  Applications created with the ADK 
can specify any file for these settings (e.g. myapp.ini.)  For the 
purposes of this document, msaccess.ini and myapp.ini are 
interchangeable.
Logging On
Each User and Group has associated with it a Security ID (SID).  The SID 
is a binary string that uniquely identifies the User or Group.  When a 
user logs on, Microsoft Access looks in the MSysAccounts table of the 
SystemDB for a user of the same name (case-insensitive).  If a user with 
the same name is found, it then validates the password (case-sensitive).  
If the password matches, the SID of the user is retrieved and saved in 
an internal structure.  The password is only used to validate the user 
when he logs on.  Other than validating the identity of the user when he 
logs on, it has no effect on security.

By default, Microsoft Access first attempts to logon as the user Admin, 
with a blank password.  If this logon fails, the user is presented with 
the Logon dialog.  If a user name and password were specified on the 
command line (using the /USER and /PWD flags), Microsoft Access first 
tries to logon using that user name and password.  If this logon fails, 
the user is presented with the Logon dialog.  Once logged on, the user's 
SID is retrieved.  This SID is used for all subsequent security 
operations within Microsoft Access.
Users and Groups
Each user can be a member of 1 or more groups.  Users & Groups share the 
same namespace.  This means that you can't have both a group and user 
with the same name.

Microsoft Access defines 3 default groups:  Admins, Users, and Guests.  
Whenever a user is added to the SystemDB, they are automatically given 
membership in the group Users, and they cannot be removed from the Users 
group.  There is one exception to this rule---the user Guest CAN be 
removed from the Users group.  The Admins group must always have at 
least one member.

Microsoft Access defines 2 users:  Admin and Guest.  The user Admin is a 
member of the Admins and Users groups.  The user Guest is a member of 
the Guests group (only).

The pre-defined groups (Admins, Users, and Guests) cannot be deleted.  
The user Guest cannot be deleted, though the user Admin CAN if there is 
at least one other member of the Admins group.  Chapter 25 of the Access 
Users Guide recommends deleting the Admin account.  The only reason for 
this recommendation is so that you don't accidentally create any objects 
using this account.  Objects created by Admin cannot be secured.

Each user and group has a SID associated with it.  The SIDs of the Users 
and Guests groups, and of the Admin and Guest users, are the same in all 
Microsoft Access installations.  The SID of the Admins group, however, 
is unique across all Microsoft Access installations.  This prevents 
someone who is in the Admins group of one SystemDB from being able to 
have the permissions of the Admins group of any other SystemDB.

Gotcha:  If you delete the user Admin, and then create 
another user named Admin, the SID of the new Admin will NOT 
be the same as the SID of the Admin that exists in an 
unsecure system.  This is because the Admin user that you 
create will have a different PIN that the Admin user that 
exists in a freshly-installed SystemDB.

If you setup from the Microsoft Access disks, the SID of the Admins 
group is a function of the serial number of the Setup disk and the User 
and Company names given (case-insensitive).  Therefore, it is critical 
that the disks used to install Microsoft Access be kept in a safe place, 
and that the User and Company names be recorded.  

New for 1.1:  You can also create a SystemDB by running the Change 
Workgroup utility.  Using Change Workgroup, you are able specify a 
Personal Identification Number (PIN) in place of the disk serial number, 
as well as any User and Company names.  This PIN can be any alphanumeric 
string, up to 20 characters long.  The the SID of the Admins group will 
be determined by these values (also case-insensitive).

In the event that the SystemDB has to be recreated, you must either have 
the same installation disks, or have recorded the PIN, User name, and 
Company name used to create it.  Because the Change Workgroup 
functionality removes the connection between the original disks and 
Access security, this is the recommended method of creating a SystemDB.

The SIDs of users and groups that you create are a function of the user 
or group name (case-sensitive) and Personal Identification Number (PIN) 
that you specify.  For this reason it is critical that the user and 
group names and their PINs be recorded.  If there is ever a need to 
recreate the SystemDB, you will need the name and PIN of each user and 
group that was in the SystemDB.  Note that by using different PINs, it 
possible for users and groups in different SystemDB's to have the same 
name, but they will actually be different accounts as far as Microsoft 
Access security is concerned because they have different SIDs.

Gotcha:  When you setup Microsoft Access, the User and 
Company names are written to Disk #1.  If you then give 
anyone else your disks to setup from, Microsoft Access 
doesn't prompt for the User and Company name.  The Admins 
group in the SystemDB that is created will have the same SID 
as the Admins group in your SystemDB.  This means that 
anyone who uses that new SystemDB will have all the 
permissions that you do, in any databases that you have 
permissions.  While this functionality wasn't intended as a 
form of copy protection, it is a good incentive to abide by 
the License Agreement.  It is also a good reason to create 
your SystemDB using the Change Workgroup utility in 
Microsoft Access 1.1
Permissions
There are 2 types of permissions:  Explicit and Implicit.  Explicit 
permissions are those given directly to a user.  When they are granted, 
no other users are affected.  Implicit permissions are those granted to 
a group.  When they are granted, all users who are members of the group 
get the permissions of the group.  Implicit permissions belong to the 
group, not the users.  If a user is removed from the group, he no longer 
has the permissions of the group.  If a user is added to the group, he 
gets all the permissions assigned to the group.  If the permissions of 
the group are changed, all users in the group are affected.

When a user attempts to do something, he will get the least restrictive 
permissions of:  1) all the groups in which he is a member (his Implicit 
permissions), and 2) those given directly to him (his Explicit 
permissions.)

In the Microsoft Access Permissions dialog, only the Explicit 
permissions are displayed.  This is a limitation of v.1.x.  To view the 
Implicit permissions, view the permissions of each group that the user 
is a member of.

The Admins group of the SystemDB in use when the database was created 
will always have permission to change permissions on all objects in the 
database.  This permission cannot be taken away by anyone!!!  This 
permission remains even when all permissions have been revoked from the 
Admins group, and isn't displayed in the Permissions dialog.  It should 
therefore be obvious that it is very important to know and keep track of 
which SystemDB was in use when the database was created.  To stress this 
point, italics will be used throughout this document where it comes up.

The Users group initially has Full permissions on all objects created in 
the database.  The Guests group has Read Definition and/or Read Data 
permissions on them, as appropriate for the object type.  Basically, 
Guests can read all objects and data, but can't change anything.

Permissions on an object can be changed by anyone having permissions to 
do so.  By default, the following users have this permission:  members 
of the Admins group of the SystemDB in use when the database was 
created;  the creator of the database (it's owner);  the creator of the 
object (it's owner); and anyone who has Full permissions on the object, 
either explicitly or implicitly.

Gotcha:  Jane gives Joe a database that she created.  Joe is 
a member of the Users group, and no other groups.  He is 
using a different SystemDB (the SID of the Admins group of 
his SystemDB is different from the SID of the Admins group 
in Jane's SystemDB).  Jane's database is "unsecure", meaning 
that the Users group has Full permission on all objects.  
Joe revokes Full permissions from the Users group on a 
Table1.  From that point forward, Joe can no longer change 
permissions on that Table1.  If he also revoked Read Data 
permissions, he has prevented himself from being able to 
read Table1, because he no longer has permission to do so.  
For both these cases, he just revoked his own permissions on 
the Table1.  Because Joe isn't a member of the Admins group 
of the SystemDB in use when the database was created, and 
because he didn't create Table1, he's completely locked out 
of Table1 until Jane (using her own SystemDB) gives him 
permissions again.

All users always have permission to open any database and create objects 
in it.  Microsoft Access relies on operating system security to prevent 
a user from being able to open a database.

Gotcha:  Even if a user doesn't have an account in your 
SystemDB, he can use any other SystemDB in which he has an 
account to logon to Microsoft Access.  Then he can open any 
database that he can get to through the operating system.  
Once the database is open, he can see which objects exist, 
and create new objects.  There is no method to prevent 
creation of objects.

It is possible for a user to have permissions on an object in a 
database, and not be able to see those permissions in the Permissions 
dialog.  This will happen if the user was assigned permissions in the 
database and then was deleted from the SystemDB.  The permissions given 
to the user are stored in the .mdb, and aren't removed when the user is 
removed from the SystemDB.  The following steps will show these 
permissions:
1. Set the Show System Objects option to Yes
2. Give yourself Read Data permissions on the MSysACEs table
If you don't have permissions to do this, you're not a member of 
the Admins group of the SystemDB in use when the database was 
created, and you didn't create the database.
3. Attach to or import the MSysAccounts table from the SystemDB 
currently in use
If you don't have permissions to do this, you're not a member of 
the Admins group of the SystemDB currently in use.
4. Run this query:
SELECT DISTINCTROW MSysObjects.Name AS Object, MSysAccounts.Name 
As UserOrGroup FROM MSysACEs, MSysAccounts, MSysObjects, MSysACEs 
LEFT JOIN MSysAccounts ON MSysACEs.SID = MSysAccounts.SID, 
MSysACEs INNER JOIN MSysObjects ON MSysACEs.ObjectId = 
MSysObjects.Id;

This will show the names of all users and groups who have permissions on 
all objects in the database.  If the UserGroup field is blank, it means 
that the user or group doesn't exist in your SystemDB, yet still has 
some kind of permissions on that object.  Again:  The query above works 
fine in Microsoft Access 1.x.  However, the Microsoft Access system 
tables (MSys*) are officially "undocumented", and are subject to change 
in future versions.
Ownership
Ownership is a very important part of Microsoft Access' security model.  
The SID of the user who creates a database is considered the "owner" of 
the database.  He will always have permission to change permissions on 
any object in the database, regardless of who creates the object, or 
what permissions are on the object.

The SID of the user who creates an object is considered the "owner" of 
the object.  He will always have permission to change permissions on the 
object, even if the database owner has revoked his permissions on the 
object.

The Admins group of the SystemDB in use when the database was created 
will always have permissions to change permissions on any object in that 
database.

The only way to transfer ownership of a database or object is to 
recreate it.  For databases, this means doing a File New Database and 
importing all the objects from the old database.  Table relationships 
will have to be recreated after importing, as they're not preserved when 
importing or exporting.

For objects, ownership can be transferred by importing or exporting the 
object, or by copying and pasting it.  These operations essentially 
create a brand new object, one that is completely unsecured.  Note that 
for both of these situations, the person doing the importing/exporting 
or copy/pasting must have permission to read the object in the first 
place.

Gotcha:  As mentioned above, the Admin and Guest users have 
the same SID in all SystemDB's.  It is therefore critical to 
security that the Admin and Guest users NOT create (are the 
owner of) any objects or databases.  If they do, anyone who 
has Microsoft Access and can get to the database .mdb file 
can open it and have Full permission on the objects created 
by Admin or Guest, and all objects in the database if either 
of these users created the database.
The "Hole"
By default, the Users and Guests groups have Read Data permissions on 
the MSysObjects table.  For various technical reasons, this is necessary 
to allow the user to do File Load From Query in the Filter window.

The astute reader will see that MSysObjects contains a field named 
"Owner", and he will figure out that it contains the SID of the owner of 
each object.  The astute reader will also realize that the SID field in 
the MSysAccounts table of system.mda contains his own SID.  Because 
everyone has Read Data permissions on MSysObjects, it would be possible 
to read the SID of the owner of any given object, and replace his SID in 
MSysAccounts with it.  The next time he logged on, he would have the SID 
of the owner of the object, and all rights associated with it.  He could 
change permissions on the objects, and therefore do anything he wanted 
to with it.

SIDs are binary fields.  When MSysObjects is browsed, the binary fields 
are truncated at the first null terminator (ASCII 0).  Additionally, any 
characters whose ASCII values are below 32 will display as garbage.  All 
of this essentially prevents someone from being able to edit or copy and 
paste this value directly.  However, it would be a relatively simple 
matter to change your own SID using Microsoft Access Basic code or a 
query.

Fortunately, the Security Wizard will patch this hole.  See the section 
on the Security Wizard, below.

Needless to say, this hole will be plugged in a future version of 
Microsoft Access.  Disclaimer:  Again, the Microsoft Access system 
tables (MSys*) are officially "undocumented", and are subject to change 
in future versions.  Don't count on any information regarding them to be 
applicable to anything but Access version 1.x.
The "Run with Owner's Permissions" Query Property
Microsoft Access queries have an property called "Run with Owner's 
Permissions" (RWOP).  This is in the Query Properties dialog.  If this 
property is checked, the permissions of the owner of the query are the 
only permissions that are considered when attempting to access tables or 
queries that the query is dependent on.

Gotcha:  Joe has Read Definition permissions on the Salary 
table, but not Read Data.  Joe creates Query1, which is 
based on the Salary table.  Joe has left RWOP turned on.  
Joe is unable to execute the query, because he doesn't have 
Read Data permissions on the Salary table.  This much is 
intuitive.  Jane created the Salary table, and has Full 
permission on it.  Jane tries to execute Query1.  She 
cannot, because the RWOP option of Query1 is turned on, and 
the owner of the query (Joe) doesn't have Read Data 
permissions on the Salary table.  While this may not be 
entirely intuitive, it is correct functionality.

Only the owner (creator) of a query may save it if the RWOP property is 
turned on.  Even the database owner or members of the Admins group of 
the SystemDB in use when the database was created can't save a query 
created by another user if the RWOP property is turned on.  It would be 
a security breach to allow them to.  Note though, that anyone with 
Modify Definition permissions on the query can uncheck RWOP and 
successfully save the query.  This may lead to other complications if 
other people were using the query and depending on RWOP being there.

Gotcha:  Joe has Read Definition permissions (only) on the 
Salary table.  Jane creates Query1, which is based on the 
Salary table, which Jane has Read Data permissions on.  The 
query is defined as "Select LastName from Salary WITH 
OWNERACCESS OPTION;".  Joe has Read Data and Read Definition 
permissions (only) on Query1.  Joe can execute Query1 and 
see the LastName field.  He can also open Query1 in design 
mode and add any field (like the EmployeeSalary field!) to 
the query output, then execute the query.  He cannot save 
the query, however.  This is arguably a bug.  The workaround 
is that if you're using RWOP queries to enforce security, 
you need to ensure that Joe doesn't have Read Definition 
permissions on ANY tables or queries in Query1.

If the owner of a RWOP query has been removed from the system (by using 
the Users dialog to delete the user), nobody will be able to execute 
RWOP query.  This is because Access first checks to see if the owner 
exists before executing the query.  The solution to this is for someone 
who has Read Definition permission on the query (and all tables/queries 
in the query) to do a Save As, then delete the original query and rename 
the new query to the same name as the original one.  You could also add 
the original user (with the same PIN) back to the system.

This functionality extends to the QueryDef object as well.  Only the 
owner of a query can change the query using the "Set Qry.SQL = 
MySQLString$" syntax if MySQLString$ contains "WITH OWNER ACCESS 
OPTION".
Encryption
Database encryption has nothing to do with security.  It is only used to 
prevent someone from using a file or disk editor (such as Norton 
Utilities) from being able to read and write data in an .mdb file.  
Access reads and writes all data a page at a time.  Pages are 2Kb in 
size.  Encryption is done at the page level, not at the data level.  
That is, at the level that encryption is being done, there is no notion 
of what is on the page, only that there's 2Kb of data that needs to be 
encrypted and written, or read and decrypted.  This implies that 
everything in an Access .mdb file is encrypted, including tables, 
queries, forms, indexes, etc.  Access uses the RSA algorithm for 
database encryption.

Given a database that isn't encrypted, it would be possible for a (very) 
knowledgable person to use a disk editor to read the SID of the database 
owner or the SID of the Admins group in use when the .mdb was created.  
Given that SID, they could assume ownership of the database using the 
methods outlined above, and do anything they wanted with the database.  
For this reason, it is recommended that if you want to protect against 
such a person, you should encrypt your database.  Because of this, 
databases secured by the Security Wizard are encrypted.

Only the creator (owner) of a database, or a member of the Admins group 
in use when the database was created, can encrypt or decrypt it.

Due to the overhead of encrypting and decryption, there is a performance 
degradation of approximately 10-15% in encrypted databases.  Encrypted 
files are also essentially uncompressible (via PKZip, Stacker, DOS 6 
DoubleSpace, etc.)
The Security Wizard
The Access Security Wizard is used to secure databases.  It allows you 
to choose which object types to secure (Tables, Queries, Forms, Reports, 
Macros, Modules.)  The selected object types are secured by revoking all 
permissions from the Users and Guests groups.

To install the Security Wizard, copy wzsecure.mda into your Microsoft 
Access 1.1 program directory.  Add the following line to the [Libraries] 
section of your msaccess.ini file:

    wzsecure.mda=ro

If it doesn't already exist, add a [Menu Add-Ins] section in your 
msaccess.ini file, and add the following line to it:

    Security &Wizard==swz_SecureDB()

The next time you start Microsoft Access, the Security Wizard command 
will appear on the Help menu.  To secure a database, open it and invoke 
the Security Wizard by selecting this command.

The Security Wizard will only run on Microsoft Access 1.1, but will work 
with databases in 1.0 or 1.1 format.  Attempting to use the Security 
Wizard with Microsoft Access 1.0 will result in "Out-of-date database 
format", followed by "Some library modules could not be loaded" when you 
start Microsoft Access.  Databases created by the Security Wizard are 
always in 1.1 format.

The Security Wizard can take quite a while to run.  For instance, 
securing nwind.mdb on a 486/50 takes approximately 13 minutes.  The 
About dialog gives more detailed information about what the Security 
Wizard does.

Gotcha:  One of the steps that the Security Wizard takes is 
to update several internal database security structures to 
patch "The Hole" (documented above).  The only negative side 
effect of patching "The Hole" is that when people who aren't 
in the Admins group of the system.mda in use when the 
database was created attempt to use the "Load Filter From 
Query" or "Save Filter as Query" functionality while in 
MyApp.mdb, they will get an error that says "No permission 
for 'MSysObjects'".  This problem will be fixed in a future 
release of Microsoft Access.

Because of the updates to the internal database security structures that 
the Security Wizard makes, it is the only supported method of securing a 
database.  Any other steps will result in a database that is not fully 
secured.
Common Scenarios
Securing an Existing Database
You've written an application using Microsoft Access---call it 
MyApp.mdb.  You've created all the objects while you were logged on as 
Admin (the default.)  Now you want to "secure" the database.  Here are 
the steps to follow to do so:
1.  Install the Security Wizard using the steps above.
2.  Choose Change Password from the security menu and give a password 
to the user Admin.
3.  Create a new user and add him to the Admins group.  For this 
example, the user is Joe.
4.  Exit Microsoft Access and restart it, giving Joe as the user when 
the Logon dialog is given.
5.  Open MyApp.mdb
6.  Invoke the Security Wizard by selecting the Security Wizard 
command from the Help menu.
7.  Select the object types to be secured.
The Security Wizard creates a new, encrypted, database, exports 
all the objects from the current database, and properly secures 
the selected object types by revoking permissions from the Users 
and Guests groups.  It doesn't change the current database in any 
way.  It recreates attached tables and table relationships in the 
new db as well.
8.  If desired, create any of your own groups and users, and give 
them appropriate permissions on all the objects in the new 
database.

The new database is now secure.  The only people who can get into the 
objects in MyApp.mdb are those you gave permissions to in step 8, and 
anyone who is a member of the Admins group of the current SystemDB.
Unsecuring a Secured Database
You've followed the steps under Securing an Existing Database, above.  
Joe is the owner of the database and all objects in it.  The Admins 
group of Joe's system.mda has permissions to change permissions on any 
object in the database.  The goal here is to make the user Admin the 
owner of the database and all objects in it, and to give the Users group 
Full permissions on all objects.  Remember, the SIDs of the user Admin 
and the Users group are constant in all system.mda's, so this will 
effectively give everyone Full permissions on all objects in the 
database, and make them the database owner as well.
1.  Make a backup of MyApp.mdb!!!
2.  Boot Microsoft Access, logging on as someone who has Read Data 
and Read Definition permissions on all the objects in 
MyApp.mdb.
3.  Open MyApp.mdb.
4.  Give the Users group Full permissions on all objects in the 
database.
5.  Edit your msaccess.ini file so that SystemDB points to a 
system.mda in which the original user Admin exists.  If you've 
deleted the Admin account, you cannot recreate it, because you 
don't know the PIN.  You can recreate a clean SystemDB using 
the Microsoft Access 1.1 Change Workgroup utility.  This 
SystemDB will have an Admin user with the correct SID.
6.  Exit Microsoft Access and restart it logging on as the user 
Admin.
7.  Create a new database (call it MyApp2.mdb).
8.  Import all the objects from MyApp.mdb into MyApp2.mdb.

Your database is now completely unsecured.  Anyone who can get to the 
MyApp2.mdb file has Full permissions on all the objects in it.
Protecting Your Code
You've written Microsoft Access Basic code that you want to distribute, 
perhaps as an application or a Library database, but you don't want 
anyone to be able to read your code.  The modules are in MyApp.mdb, and 
were all created while you were logged on as Admin.  Assuming that 
you're starting from a completely unsecure configuration, simply follow 
the steps under "Securing an Existing Database", above, choosing the 
Modules checkbox in step #7.

Your modules are now secured so that nobody except Joe and members of 
the Admins group of the current SystemDB can read the modules.  All 
users will still be able to execute the code---there's no way to prevent 
someone from being able to execute code.
Moving a Database to Another System.mda
You are Joe, and have written MyApp.mdb and want to give it to Jane who 
is using a different system.mda.  You want Jane to have complete 
administrative authority over your database.  The problem is this:  The 
Admins group of Jane's system.mda doesn't have any permissions on 
anything in MyApp.mdb.

There are 2 variations of this scenario:

Variation #1:  MyApp.mdb is completely unsecured (the Users group has 
Full permissions on everything).
The situation here is as follows...  The user Admin created 
MyApp.mdb and all the objects in it, and is therefore the owner of 
everything.  The Admins group of Joe's system.mda has permissions 
to change permissions on all the objects in MyApp.mdb.  The Users 
group (which has the same SID in all Microsoft Access 
installations) has Full permissions on all objects in MyApp.mdb.  
Jane's system.mda is unsecure (the Admin password is blank, and 
there are no user accounts or groups.)

To give MyApp.mdb to Jane, and have her get complete 
administrative authority over it, follow these steps:
1.  Make a backup of MyApp.mdb!!!
2.  Boot Microsoft Access using Jane's system.mda.
3.  Create a new database---call it MyApp2.mdb
This will establish Admin as the database owner.
4.  Import all the objects from MyApp.mdb into MyApp2.mdb
This will establish the user Admin as owner of all the objects, 
and give the Admins group of Jane's system.mda permission to 
change permissions on all objects created in MyApp2.mdb.
5.  If you had any table relationships or attached tables, 
recreate them in MyApp2.mdb
6.  Rename MyApp.mdb to MyApp.old and rename MyApp2.mdb to 
MyApp.mdb.

Variation #2:  MyApp.mdb is secured using the steps under Securing an 
Existing Database.

To give MyApp.mdb to Jane, and have the Admins group of her 
system.mda get complete administrative authority over it, follow 
these steps:
1.  Follow the instructions under Unsecuring a Secured Database, 
above
2.  Follow the instructions under Variation #1, above.

For all intents and purposes, Jane is now the "owner" of MyApp.mdb and 
all objects in it, and Joe is just another user.  Under both these 
scenarios, you can include the steps under Securing an Existing 
Database, above, as necessary to make the database secured under Jane's 
system.mda.
Additional Guidelines for Shipping a Secure Application
There is an intimate connection between each .mdb file and the SystemDB 
in use when the database is created.  Members of the Admins group of 
that SystemDB will always have permissions to change permissions on any 
objects in the .mdb file.  Thus it is impossible to protect your code 
from anyone who is in the Admins group of  the SystemDB in use when the 
.mdb was created, and has a copy of the SystemDB.  For this reason, you 
should NEVER release that SystemDB to anyone who you don't want to be 
able to read your tables, forms, modules, etc.  Use the Change Workgroup 
utility to create a new SystemDB.
Miscellaneous Tidbits
The User() function in Microsoft Access Basic returns the name of the 
current user.  This is not the same as the SID.  As mentioned under 
Users and Groups, above, it is possible for 2 users in different 
SystemDB's to have the same name but different SIDs.

Gotcha:  This can cause a problem if 2 people that are using 
different SystemDB's have the same name but different PINs 
(and therefore different SIDs).  For example, if you are 
using the User() function to log activity, and both are 
using your database, the activity logging could be 
inaccurate.  These are actually 2 different accounts, even 
though their user names are the same.  This is another 
reason that applications that attempt to implement their own 
security cannot be truly secure.
Changes in Access 1.1 and the ADK
Change Workgroup
The Change Workgroup tool now allows you to create a SystemDB.  When 
creating the SystemDB, it allows you to specify the User and Company 
names, as well as a Personal Identification Number (PIN).  This 
completely removed the connection between the disks from which Access 
was installed and the SID of the Admins group.  The PIN can contain any 
characters, and can be up to 20 characters long.  To ensure that your 
SystemDB (and therefore the SID of the Admins group) couldn't be 
recreated by someone who has your original Microsoft Access setup disks, 
it is recommended that you create a new SystemDB before creating any 
secure databases.
Upgrade Setup
When using the Microsoft Access 1.1 Upgrade disks to upgrade an existing 
1.0 installation to 1.1, the SID of the Admins group is not changed.  In 
fact, the SystemDB is not touched in any way.  This means that the SID 
of the Admins group is still tied to your original Microsoft Access 1.0 
setup disks.  You can use the Change Workgroup utility to change this, 
if desired.

Microsoft Access Security

	Page 2 of 10

	Page 1 of 10


