FILE SECURITY: PROTECTION IN A HIGH-RISK ENVIRONMENT by Eugene Volokh, VESOFT MPE file security is an interesting sort of thing. It is powerful enough to cause a lot of confusion -- what's the difference between :ALTSEC, :RELEASE, and :SECURE? What do R, A, W, L, X, ANY, AC, AL, GU, GL, and CR mean? How do file, group, and account security work? Unfortunately, it's not powerful enough to do a lot of things that you'd very much like to do (such as grant a particular access to a particular user id). If it were only a little bit less fancy or a little bit more fancy, life would be a lot easier... IN WHAT WAYS CAN YOU ACCESS A FILE? First, a little general discussion. From the file system's point of view, there are five types of access you can have to a file: * READ -- if you have READ access to a file, you can open the file and read data from it. Simple. * APPEND -- if you have APPEND access to a file, you can open the file and add records to it. You can't read records (unless you also have READ access) or overwrite them or purge the file (unless you also have WRITE access). * WRITE -- if you have WRITE access to a file, you can open the file, append records to it, overwriting existing records, or purge the file; you can't read records unless you also have READ access. Note that if you have WRITE access, you will always be allowed to :PURGE the file -- you can't grant a user write access and deny him purge access. * LOCK -- if you have LOCK access to a file, you can open it EXCLUSIVELY and/or open it shared but then call the FLOCK intrinsic. Lock access doesn't explicitly imply read or write (though it would be pretty useless if you didn't also have read or write access to a file); note, however, that APPEND and WRITE access DO imply LOCK access -- if you have append/write access to a file, you can always open it exclusively or FLOCK it even if you don't have lock access to it. * EXECUTE -- if you have EXECUTE access to a program file, you can run it; if you have EXECUTE access to a job stream file, you can :STREAM it. You don't need any other access to do these things -- thus, you may deny a user READ access to a program or job stream and still let him run it or :STREAM it. You should remember these "access types" because they control what you may or may not do with file security. For instance, as I mentioned, the fact that there is no special "PURGE" access mode means that you can't allow writes but forbids :PURGEs; however, since there IS a special "APPEND" mode you can allow appending to a file (e.g. some sort of log file) but not allow overwriting. WHO CAN ACCESS A FILE? Now that we've discussed HOW a file may be accessed, we must ask WHO it can be accessed by. Say that you've built a file and want to grant READ and APPEND access to certain people -- how do you do this? Well, for every type of access (Read, Append, Write, Lock, and Execute, abbreviated R, A, W, L, and X), you may specify a set of "user class specifiers". You may say that the particular access involved is allowed to: * ANY, meaning any user in the system; * AC, meaning any user in the account in which the file resides; * GU, meaning any user who signs on to the group in which the file resides; * CR, meaning only the user who created the file; * AL, meaning any user with AL ("Account Librarian") capability in the account in which the file resides; * GL, meaning any user with GL ("Group Librarian") capability who signs on to the group in which the file resides; * Any combination of the above; * None of the above, in which case access is allowed only to a user with SM (System Manager) capability or a user with AM (Account Manager) capability in the file's account. An SM or AM user can ALWAYS do ANYTHING to a file. Thus, when you say :ALTSEC F;(R,A:ANY;W,L,X:CR) you mean "anybody can Read or Append to the file F, but only the file's creator can Write to it, Lock it, or Execute it". Similarly, when you say: :ALTSEC F;(X:AC;R,L:AL;W,A:GU) you mean "anybody in the account can Execute the file, only users with AL capability can Read it or Lock it, and only users in the file's group can Write to it or Append to it". FILE, GROUP, AND ACCOUNT SECURITY -- THE TRIPLE WALL So, thus far we've discussed HOW a file may be accessed and WHO you can allow to access it. Note that one thing conspicuously missing from our discussion is the ability to say "user JOE can read the file and user JOHN can write to it". This is because MPE provides no such ability. Unless you can arrange the right capabilities (SM, AM, AL, or GL) for the right users, you can't really control access by individual user id. One other important fact, however (which substantially changes the implications of what we've talked about), has to do with GROUP and ACCOUNT security. Just as you can restrict R, A, W, L, and X access on an individual file, you can also restrict it on a group (which means that the restriction applies to all the files in the group) or on an account (which means that the restriction applies to all the files in the account). In order to access a file, a user must satisfy the file restrictions AND the group restrictions AND the account restrictions. For instance, say that we say: :ALTACCT PROD;ACCESS= (R,X:ANY; W,A,L:AC) :ALTGROUP DATA.PROD;ACCESS= (R:ANY; X:AC; A:GU,AL; W:GU; L:CR) :ALTSEC F.DATA.PROD;ACCESS= (R:CR; X:ANY; A:AC; W:CR,GU; L:AL) What are the true access restrictions on F.DATA.PROD? We must COMBINE -- "AND" together -- all three sets of restrictions: Access Account Group File Total R ANY ANY CR CR A AC GU or AL AC GU or AL W AC GU CR or GU GU L AC CR AL CR X ANY AC ANY AC As you see, the resultant access rights are as restrictive as the account, group, and file access rights put together. Even though account and group security allows anybody to read the file, file security allows only the CReator to read it -- therefore, only the creator may read it; even though account and file security let anybody execute the file, group security allows only ACcount users to execute it -- therefore, only users in the PROD account can execute it. Now, we have the theory down; let's have a look at the practice. By default, all accounts (except the SYS) account have access restrictions of (R, A, W, X, L: AC) In other words, by default NOBODY outside an account can access a file in the account, EVEN IF FILE AND GROUP SECURITY ALLOW IT! Similarly, all groups (except PUB groups in any account) by default have access restrictions of (R, A, W, X, L: GU) Thus, NOBODY outside a group can access a file in the group, EVEN IF FILE AND ACCOUNT SECURITY ALLOW IT! On the other hand, default file security is (R, A, W, X, L: ANY) Access is allowed to anybody in the system who can pass the group and account restrictions, but as we just saw, with default restrictions this means that only a user in the file's group can access the file in any way! You can see the serious problems that this causes. Say that I am JOHN.PROD and I want to let MARY.DEV read my file. First of all, I can't just allow MARY.DEV read it (since access rights can only be given to classes of users, such as ANY, not to individual user ids). However, say that I'm willing to let everybody read the file -- I still can't do this! For MARY.DEV to read my file, she must be able to pass file security (which is easy, since by default it is R:ANY), but also group and account security, which by default prohibit any access! To let MARY.DEV read my file, I have to: * Go to my account manager and ask him to grant Read access to ANY on the group in which the file resides; * Go to my system manager and ask him to grant Read access to ANY on the account in which the file resides; Now, after I've gotten two other people involved in this, ALL files in the group in question are readable by ANYBODY (unless I explicitly :ALTSEC all those files to lower their file security, which [even with MPEX] may be a cumbersome task). I've had to spend a lot of effort, and in the bargain have waived security on a lot more than what I wanted to waive it on. Thus, we see several problems with file security: * You can't grant access to an individual user id, only to an entire class of users. * Default group and account security is such that a normal user must intervene with his Account Manager AND his System Manager to let people access one of his files. * In the process of granting access to a file, the AM and SM must lower security on the account and the group, THUS WAIVING SECURITY ON ALL THE FILES IN THE GROUP. * Finally (one thing we hadn't mentioned before), file-level security (implemented using :ALTSEC) is very hard to maintain since whenever you /KEEP the file in EDITOR, the file security is RESET to (R,A,W,L,X:ANY)! Thus, if you leave your group and account security open and rely on :ALTSEC to protect your files, you must make sure that EVERY TIME YOU DO AN EDITOR /KEEP (or re-build the file in any other way), YOU REPEAT THE :ALTSEC COMMAND. If you don't, you'll leave the file wide open. :RELEASEing FILES -- WHY IT'S BAD, WHY PEOPLE DO IT, WHEN IT'S OK Therefore, on the one hand we have far too much security -- group and account security gets in the way. On the other hand, we don't have enough security, since once we waive group and account security, we leave ourselves wide open. To avoid these problems, HP invented the :RELEASE and :SECURE commands, but these have very substantial problems all their own. Simply put, :RELEASEing a file allows ANYBODY to do ANYTHING to the file. ANY USER ON THE SYSTEM can READ the file, WRITE to it, APPEND to it, LOCK it, EXECUTE it, PURGE it, do whatever he pleases to it. The advantage of this is you can let MARY.DEV read your file without having to change group/account security (since :RELEASE waives ALL security, file, group, and account); the disadvantage is that not only can MARY.DEV read it, but she can also modify it or purge it, AS CAN EVERYBODY ELSE IN THE SYSTEM. Again, you either have too much security (nobody can do anything) or far too much (everybody can do everything). Unfortunately, the dangers of :RELEASE go way beyond the danger to the now-unsecured file. In particular, if you have A GROUP WITH PM CAPABILITY and you :RELEASE a PROGRAM FILE that resides in that group, then an ordinary, plain vanilla user can OBTAIN SM OR AM CAPABILITY. Naturally, I won't explain exactly how he'll do this, but trust me -- :RELEASEing program files in groups with PM capability (the program itself need not necessarily have PM) is A VERY BAD IDEA. We suggest to our MPEX users that every night they execute the command :RUN MPEX.PUB.VESOFT %SECURE @.@.@ (CODE="PROG" and ISRELEASED and GPMCAP=ON) which will find all the program files (CODE="PROG") that are :RELEASEd (SECURITY=OFF) and reside in privileged groups (GPMCAP=ON) and :SECURE them. If you don't do this -- if you let such files to stay on your system -- you can be extremely vulnerable to break-ins. I personally think that virtually every :RELEASE is a bad idea, since it's very rare that you really want to let ANYBODY do ANYTHING to a file. What you ought to do instead is organize your file security in such a way that it's easy for people to selectively grant appropriate access to other people -- this isn't very simple to do, but I'll give a fairly straightforward recipe shortly. The only other thing that ought to be said about :RELEASE is that IT'S OK TO RELEASE DATABASES (using DBUTIL or MPEX). Since databases are protected from normal file system access by their PRIV file code, and since IMAGE security implements an additional layer of security on top of normal file system security, you can afford to release them. That way, file security will be entirely bypassed and the user will only have to specify the right IMAGE password to be able to access the database. STRUCTURING YOUR SYSTEM SECURITY TO AVOID :RELEASEs We've established that :RELEASEing files is generally not a good thing to do. Unfortunately, with a default security set-up, :RELEASEs are often necessary (the only other alternative being to get BOTH your account manager AND your system manager involved, and then risk the security of other files by changing group and account security). The only way you can really avoid :RELEASEs is by making easier the legitimate things that people may want to do -- allow other people to read and/or write their files. The first step is to :ALTACCT ALL YOUR ACCOUNTS TO HAVE (R,A,W,L,X:ANY). Is this a safe thing to do? Yes, because group security (by default (R,A,W,L,X:GU)) can protect your files perfectly well. The only thing you might be concerned about is that default security for PUB groups is (R,X:ANY;A,W,L,S:AL,GU); thus, the above :ALTACCT read and execute files in your PUB groups. This is probably not a problem (that's usually what PUB groups are for), but if it is, you can just :ALTGROUP your PUB group to deny R or X access (or BOTH) to non-AC users. Now that your account security is waived, you can control file security by groups. I recommend that you build a group in each account called READANY: :NEWGROUP READANY;(R,X:ANY;W,A,L:CR) As you see, anybody can Read or Execute files in this group, but only the file's creator can modify them. Say that I want to let MARY.DEV read that file of mine -- all I need to do is say: :RENAME MYFILE.EUGENE, MYFILE.READANY Now Mary can read MYFILE but she can't modify it (since the file has W access allowed only to me, the file's creator). Alternatively, I might decide that anybody should be able to read all of my files -- I can then just go to my account manager and ask him to change my group security, without having to get the system manager involved. Then I could, if I want to, further control my file security by using :ALTSECs, but it's unlikely that I will, since file security gets so easily lost every time a file is re-built (e.g. in an EDITOR /KEEP or a re-:PREP of a program file). Further, if you care about security within accounts, you might well have a group called READAC: :NEWGROUP READAC;(R,X:AC;W,A,L:CR) Any file that I want to "show" to some other user in my account can just be moved to the READAC group -- it will then be readable to all account users, but to no users (except those with SM) in other accounts.