Hugo wrote: > Hi, > > I am in the process of designing a program which performs a form of > task scheduling. Briefly, the system will execute tasks based on > system events (I'm thinking dial-up networking, here) rather than at a > given time (as cron does). Things can arrive asynchronously, i.e. many all at once, or in a short space of time. Watch out for resource locking, etc. > > However, I have come up with a problem about the best (most secure) > way of managing user permissions for this program. Basically, what > I'm after is something which behaves rather like crontab: There is a > "system" repository of tasks (like /etc/crontab), and "per-user" tasks > (like /var/spool/cron/<user>, or whatever). The system repository is essentially the file for user "root". I think. > The "per-user" tasks are executed (under the users own identity) > when the scheduler is triggered. These tasks are placed in an > otherwise write-protected area by a suid program, in a similar manner > to crontab. Race conditions, can I get your file replaced by mine. What do these tasks do? How bad could it be if you (or root) executed an arbitrary set of tasks placed there by me? > This is fine, and (I think) I could do this without too much > difficulty. However, there is one additional twist: there are two > types of task -- transient and permanent. The transient tasks are > executed once (on the next trigger event) and then deleted; the > permanent tasks are executed at every trigger event. I think that > there should be a directory structure looking something like this: Can I make a transient task permanent by having the last instruction in the transient task set a transient task to be executed next run? > /var/spool/taskscheduler/ > permanent/ > user1/<files...> > user2/<files...> > ... > transient/ > user1/<files...> > ... > > What I'd like is to have a nested set of permissions: > > Set (A): Some subset of all users -- able to set transient events > > Set (B): Some subset of (A) -- able to set permanent events I think A can become B fairly easily. How critical is this? > I can see a couple of ways of achieving this: > > 1) Have two groups (say, tsperm and tstemp) which grant access to the > appropriate configuration directory (the dirs are root.ts(perm|temp) > drwxrwx--t). -- This allows the user to edit directly their > configuration files. You run the risk here I mention above. Since I can write anything I want into the transient task, then I can crash the perms barrier, or do anything else I want to, here. Can I create a transient file under the name of a tsperm group user, which will then get picked up as theirs? If I can, can I pick up the privileges of the other user (I assume so). > 2) Have two groups granting access, and check users' membership of the > appropriate group before allowing them access to the spool dirs (which > are root.root drwx------). -- This requires a suid-root program. What would the suid-root program do? Could you use another way of storing tasks, e.g. in some kind of database, that would have validation and monitor routines as part of task filing and also task execution? It might be possible to split out the suid-root program into a very simple executor that simply switches to the correct uid, cleans up the environment, and launches the task. > 3) Have two lists of users in a configuration file, allowing access to > the spool dirs (root.root drwx------ as above). -- This also requires > a suid-root program. I think there is a limitation in using the unix directory structure here, in that you must manage your locking yourself, and protect against rogue processes and users wandering through your tree doing random things. There is also apparently nothing protecting the tasks from executing anything they are told to. This troubles me. > I *think* that option 2 is the one to go for, but I'm not sure. > > So... my questions are: > > Which of the above options is the best in terms of secure design? Secure design requires more information about what you are trying to do, the environment you are trying to do it in, and the safeguards and controls you place in the system against stupidity, incompetence, arrogance, laziness, tiredness, and failing hard disks. And evil. The canonical definition of secure design talks about "Integrity, Availability, and Confidentiality." If a task file got changed without a users permission, how bad would that be? If a task file was unavailable at time of run, how bad would that be? If everyone on the Internet could see the task files at will, how bad would that be? Make sure that your controls address the answers to the questions above. > Are there any other sensible options I've missed? Probably :) This is not meant to be flip. Implement your solution. Release it as v0.1(alpha). Work out how to break it. Fix those holes. Release a Beta. Fix more holes. Release a v1.0. Have a beer. Then throw it all away and write it again from scratch, incorporating what you have learnt so far. > What pitfalls should I try to avoid in implementing this design? Suid root programs executing code that should be executed as user. Random processes scribbling random things into the task files. Nasty people scribbling random things into task files. Lots of things all trying to write to the same task file at once. > I'd appreciate comments on this. Thanks, > Hugo. With kind regards, Jonathan Care Tel/Fax: +44 7092 016192 (Please note new number)
This archive was generated by hypermail 2b30 : Tue May 29 2001 - 10:45:14 PDT