source: trunk/include/helpers/xwpsecty.h@ 240

Last change on this file since 240 was 240, checked in by umoeller, 23 years ago

Misc fixes.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 45.7 KB
Line 
1
2/*
3 *@@sourcefile xwpsecty.h:
4 * public declarations which are shared between the various ring-3
5 * parts of XWorkplace Security (XWPSec).
6 *
7 * XWPSec consists of the following modules:
8 *
9 * 1) XWPSHELL.EXE, which is to be installed through RUNWORKPLACE
10 * in CONFIG.SYS and functions as both a WPS starter and a
11 * daemon for managing the security driver;
12 *
13 * 2) XWPSEC32.SYS, which is a ring-0 driver performing
14 * authentification for OS/2 APIs like DosOpen, DosMove etc.
15 * through SES callouts.
16 *
17 * Note that Security Enabling Services (SES) is NOT used
18 * for user logon and authentication. In other words, this
19 * program serves neither as an SES System Logon Authority
20 * (SLA) nor a User Identification Authority (UIA). I have
21 * found SES Logon Shell Services (LSS) too buggy to be useful,
22 * but maybe I was too dumb to find out how to use them. But
23 * then again, these APIs are too complicated and error-prone
24 * to be used by ordinary humans.
25 *
26 * So instead, I have rewritten the LSS functionality for
27 * XWPShell. SES is only used for kernel interfaces (KPIs)
28 * in XWPSEC32.SYS. As a result, the SECURE.SYS text file
29 * in \OS2\SECURITY\SESDB is not used either.
30 *
31 *
32 * <B>Concepts:</B>
33 *
34 * To implement XWPSec, I have reviewed the concepts of Linux,
35 * SES, and OS/2 LAN Server (Warp Server for e-Business).
36 * See subjects.c, users.c, and userdb.c for a discussion of
37 * security concepts which came out of this review.
38 *
39 * As a summary, XWPSec follows the SES security models, with a
40 * few simplifications. To make processing more efficient, user
41 * IDs and group IDs have been added (like Linux uid and gid) to
42 * allow looking up data based on numbers instead of names.
43 *
44 * <B>Recommended reading:</B>
45 *
46 * -- "SES Developer's Guide" (IBM SG244668 redbook). This
47 * sucks, but it's the only source for SES information.
48 *
49 * -- "Network Administrator Tasks" (BOOKS\A3AA3MST.INF
50 * on a WSeB installation). A very good book.
51 *
52 * -- Linux manpages for group(5) and passwd(5); Linux info
53 * page for chmod (follow the "File permissions" node).
54 *
55 *
56 * <b>XWPSec Authentication Model</b>
57 *
58 * Basically, there are two competing models of access permissions
59 * in the computing world, the POSIX model and the Windows/OS/2
60 * model. Since the POSIX model can be implemented as a subset of
61 * the OS/2 model, XWPSec follows the OS/2 model, with very
62 * fine-grained access permissions and different ACLs per resource.
63 *
64 * XWPSec implements the usual stuff like users, groups, and
65 * privileged processes with increased access rights. As opposed
66 * to the POSIX model, group membership is an M:N relation, meaning
67 * that any user can be a member of an infinite number of groups.
68 * Also, while the POSIX model only allows controlling permissions
69 * for the owner, group, and "world" (rwxrwxrwx model), XWPSec has
70 * real ACLs which are unlimited in size per resource.
71 *
72 * To implement this efficiently, XWPSec uses "subject handles", which
73 * is a concept borrowed from SES. However, XWPSec does not use the
74 * SES APIs for creating and managing those, but implements this
75 * functionality itself.
76 *
77 * For authorizing events, XWPSec uses the XWPSUBJECTINFO and
78 * XWPSECURITYCONTEXT structures, plus an array of RESOURCEACL
79 * structs which forms the global system ACL table shared with
80 * the ring-0 device driver.
81 *
82 *
83 * <b>Logon</b>
84 *
85 * XWPShell maintains a list of users that are currently
86 * logged on. There can be an infinite number of logged-on
87 * users. However, one user logon is special and is called
88 * the "local" logon: that user owns the shell, most
89 * importantly the Workplace Shell, and processes started
90 * via the shell run on behalf of that user.
91 *
92 * When a user logs on, XWPShell authenticates the credentials
93 * (normally, via user name and password), and creates one
94 * subject handle for that user plus one subject handle for
95 * every group that the user belongs to. XWPShell then rebuilds
96 * the system ACL table and sends it to the driver so it can
97 * perform authentication.
98 *
99 * Logon can thus happen in two situations. Most frequently,
100 * the local user logs on via the logon dialog when XWPShell
101 * starts up together with the system. However, XWPShell also
102 * allows any application to change its own security context
103 * be re-logging on with different credentials.
104 *
105 * This is the typical sequence of events when XWPShell is running:
106 *
107 * 1) When XWPShell starts up, it scans the process list to figure
108 * out all processes that are already running because of system
109 * startup. It then contacts the ring-0 driver, passing it an
110 * array of these PIDs, and thus enables local security. The
111 * driver then creates root security contexts for those processes.
112 *
113 * From that point on, all system events are authenticated until
114 * the system is shut down.
115 *
116 * (Before that, the driver does not deny access in order not to
117 * hickup the startup sequence.)
118 *
119 * 2) XWPShell displays the logon dialog.
120 *
121 * 3) After the user has entered his user name and password,
122 * XWPShell authenticates the user against the user database.
123 *
124 * 4) If the user was authenticated, XWPSec creates subjects
125 * for the user and his groups. With each subject creation,
126 * XWPShell rebuilds the system ACL list with the subject
127 * handles and sends them down to ring 0 so that the driver
128 * can perform authorization (see RESOURCEACL for details).
129 *
130 * 5) XWPShell sets the security context of itself (XWPSHELL.EXE)
131 * to contain these subject handles by calling a ring-0 driver
132 * API. Whoever owns XWPSHELL.EXE is, by definition, the "local"
133 * user.
134 *
135 * 6) XWPShell then changes the user profile (OS2.INI) via PrfReset,
136 * builds an environment for the Workplace Shell, and starts
137 * PMSHELL.EXE so that the WPS starts up with the user's Desktop.
138 * The WPS is started as a child of XWPSHELL.EXE and thus
139 * inherits its security context. Since the WPS uses WinStartApp
140 * to start applications, those will inherit the local user's
141 * security context as well.
142 *
143 * The following environment variables are set:
144 *
145 * -- USER is set to the user name;
146 * -- USERID is set to the user ID (uid);
147 * -- HOME is set to the user's home directory;
148 * -- OS2_INI is set to the user's OS2.INI file. This
149 * does not affect the profile (which has been
150 * changed using PrfReset before), but is still
151 * changed in case any program references this
152 * variable.
153 *
154 * All processes started by the WPS will inherit this
155 * environment since the WPS always copies its environment
156 * to child processes.
157 *
158 * 7) From then on, all system events will be authorized against
159 * the local user's security context, which contains the subject
160 * handles of the local user and his groups. For example, when
161 * an application opens a file, the driver will authorize this
162 * event against the ACLs stored in the user's subject infos
163 * and permit the operation or deny access.
164 *
165 * 8) When the user logs off via the new menu item in the Desktop's
166 * context menu (implemented by XWorkplace), XWorkplace will then
167 * terminate all processes running on behalf of this user and
168 * terminate the WPS process via DosExit. It sets a special flag
169 * in shared memory to indicate to XWPShell that this was not
170 * just a WPS restart (or trap), but a logoff event to prevent
171 * XWPShell from restarting the WPS immediately.
172 *
173 * 9) When XWPShell then realizes that the WPS has terminated and
174 * finds this flag, it logs off the user. Logging off implies
175 * again checking that no processes are running on behalf of
176 * the local user any more, changing the security context of
177 * XWPSHELL.EXE back to "noone", and deleting the subject
178 * handles that were created in (4.). Go back to (2.).
179 *
180 * Note: Version numbering in this file relates to XWorkplace version
181 * numbering.
182 *
183 *@@include #define INCL_DOSSEMAPHORES
184 *@@include #include <os2.h>
185 *@@include #include "helpers\xwpsecty.h"
186 */
187
188/*
189 * Copyright (C) 2000-2002 Ulrich M”ller.
190 * This program is free software; you can redistribute it and/or modify
191 * it under the terms of the GNU General Public License as published by
192 * the Free Software Foundation, in version 2 as it comes in the COPYING
193 * file of the XWorkplace main distribution.
194 * This program is distributed in the hope that it will be useful,
195 * but WITHOUT ANY WARRANTY; without even the implied warranty of
196 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
197 * GNU General Public License for more details.
198 */
199
200#if __cplusplus
201extern "C" {
202#endif
203
204#ifndef XWPSECTY_HEADER_INCLUDED
205 #define XWPSECTY_HEADER_INCLUDED
206
207 /* ******************************************************************
208 *
209 * Global constants
210 *
211 ********************************************************************/
212
213 #define XWPSEC_NAMELEN 32
214 #define XWPSEC_FULLNAMELEN 80
215
216 /* ******************************************************************
217 *
218 * Subjects and security contexts
219 *
220 ********************************************************************/
221
222 typedef unsigned long HXSUBJECT;
223
224 typedef unsigned long XWPSECID;
225
226 /*
227 *@@ XWPSUBJECTINFO:
228 * describes a subject.
229 *
230 * A subject represents either a user, a group, or a
231 * trusted process associated with an access control
232 * list.
233 *
234 * Subject handles allow for reusing ACLs efficiently
235 * when multiple users are logged on and also isolate
236 * the ring-0 driver from user and group management.
237 *
238 * Subject handle 0 is special and means "no restrictions".
239 * Only the superuser ("root") will have a subject handle
240 * of 0, regardless of the groups he's a member of. All
241 * other users will have nonzero subject handles.
242 *
243 * When a user logs on, subject handles get created
244 * that represent the access permissions of that user.
245 * Every running process has a list of subject handles
246 * associated with it (the security context), the sum
247 * of which allow for authorizing events. The driver
248 * only sees subject handles, not users or groups.
249 * However, the user and group IDs are listed in the
250 * subject info structure to allow the driver to audit
251 * events.
252 *
253 * Subject handles are created by XWPShell (ring 3)
254 * when users log on and then sent down to the ring-0
255 * driver together with a new system ACL list for future
256 * use.
257 *
258 * Comparison with other concepts:
259 *
260 * -- The concept of a "subject" has been taken from
261 * SES. However, with SES, a subject is much more
262 * complicated and not really well explained. The
263 * SES documentation sucks anyway.
264 *
265 * -- Warp (LAN) Server bases ACL entries on users and
266 * groups also, however without calling them "subjects".
267 * However, if I understood that right, LAN server can
268 * define an infinite number of ACL entries for each
269 * resource.
270 *
271 * -- Linux does not have the notion of a subject.
272 * Instead, all access rights are determined from
273 * the user id (uid) and group id (gid), apparently.
274 *
275 * -- Java seems to have something similar; it bases
276 * ACL entries on "principals", where a principal
277 * can either be a user or a group. See the API
278 * docs for java.security.acl.Acl.
279 *
280 *@@added V0.9.5 (2000-09-23) [umoeller]
281 */
282
283 typedef struct _XWPSUBJECTINFO
284 {
285 HXSUBJECT hSubject;
286 // handle of this subject (unique),
287 // simply raised with each subject creation
288 XWPSECID id;
289 // ID related to this subject;
290 // -- for a user subject: the user id (uid); 0 if root
291 // -- for a group subject: the group id (gid)
292 // -- for a process subject: the process id (pid)
293 BYTE bType;
294 // one of:
295 #define SUBJ_USER 1
296 #define SUBJ_GROUP 2
297 #define SUBJ_PROCESS 3
298
299 ULONG cUsage;
300 // usage count (to allow for reuse)
301
302 } XWPSUBJECTINFO, *PXWPSUBJECTINFO;
303
304 /*
305 *@@ XWPSECURITYCONTEXT:
306 * describes the security context for a process.
307 *
308 * For each process on the system, one security context
309 * defines its permissions via subject handles. Security
310 * contexts are created in ring 0 in the following
311 * situations:
312 *
313 * -- Via the DosExecPgm callout, when a new process is
314 * started. The driver then creates a security context
315 * with the same subject handles as the new process's
316 * parent process. This way process permissions inherit
317 * from each other.
318 *
319 * -- Via a ring-0 API that gets called by XWPShell to
320 * create security contexts for processes that are
321 * already running at startup, including XWPShell
322 * itself.
323 *
324 * Each subject handle in the context represents either a user,
325 * a group, or a trusted process. A subject handle of "0" is
326 * special and indicates root access. If such a subject handle
327 * is found, the driver grants full access and does not reject
328 * anything.
329 *
330 * As a result, the following are typical security contexts:
331 *
332 * -- A process running on behalf of a certain user will
333 * usually contain at least two subject handles, one
334 * for the user (if any ACLs were defined for that user
335 * at all), and one for each group that the user belongs
336 * to.
337 *
338 * -- Processes running on behalf of the superuser (root)
339 * will only have a single "0" subject handle.
340 *
341 * -- A trusted process that was defined by an adnimistrator
342 * will contain an additional subject handle with the access
343 * permissions defined for it. For example, if the program
344 * "C:\MASTER\MASTER.EXE" is given specific permissions,
345 * there would be one subject handle representing the
346 * ACLs for that in addition to those of the user running
347 * it.
348 *
349 * -- For processes that were started during system startup,
350 * the driver creates security contexts with a single "0"
351 * (root) subject handle when XWPShell passes a list of
352 * PIDs to the driver with the "initialization" ring-0 API.
353 * As a result, all processes started through CONFIG.SYS
354 * are considered trusted processes.
355 */
356
357 typedef struct _XWPSECURITYCONTEXT
358 {
359 ULONG cbStruct;
360 ULONG ulPID; // process ID
361
362 ULONG cSubjects; // no. of subject handles in this context
363
364 HXSUBJECT aSubjects[1]; // array of cSubjects subject handles,
365 // determining the permissions of this
366 // process
367
368 } XWPSECURITYCONTEXT, *PXWPSECURITYCONTEXT;
369
370 /* ******************************************************************
371 *
372 * Access control
373 *
374 ********************************************************************/
375
376 /*
377 * The following global permissions exist:
378 *
379 */
380
381 #define XWPPERM_CREATEUSER 0x00000100
382 // permission to create new users
383
384 #define XWPPERM_CHANGEUSER 0x00000200
385 // permission to change user information
386
387 #define XWPPERM_CHANGEUSERPERM 0x00000400
388 // permission to change permissions for a
389 // given user
390
391 #define XWPPERM_DELETEUSER 0x00000800
392 // permission to delete existing users
393
394 #define XWPPERM_CREATEGROUP 0x00001000
395 // permission to create new groups
396
397 #define XWPPERM_CHANGEGROUP 0x00002000
398 // permission to change group information
399
400 #define XWPPERM_CHANGEGROUPERM 0x00000400
401 // permission to change permissions for a
402 // given group
403
404 #define XWPPERM_DELETEGROUP 0x00008000
405 // permission to delete existing groups
406
407 #define XWPPERM_QUERYUSERINFO 0x00010000
408 // permission to retrieve global user, group, and membership info
409
410 /*
411 * The following permissions are defined per resource:
412 *
413 */
414
415 #define XWPACCESS_READ 0x01 // "R"
416 // For files: Permission to read data from a file and
417 // copy the file.
418 // For directories: Permission to view the directory's
419 // contents.
420 // For copying a file, both the file and its directory
421 // need "Read" permission.
422 #define XWPACCESS_WRITE 0x02 // "W"
423 // For files: Permission to write data to a file.
424 // For directories: Permission to write to files
425 // in the directory, but not create files ("Create"
426 // is required for that).
427 // Should be used together with "Read", because
428 // "Write" alone doesn't make much sense.
429 // Besides, "Attrib" permission will also be
430 // required.
431 #define XWPACCESS_CREATE 0x04 // "C"
432 // Permission to create subdirectories and files
433 // in a directory. "Create" alone allows creation
434 // of the file only, but once it's closed, it
435 // cannot be changed any more.
436 #define XWPACCESS_EXEC 0x08 // "X"
437 // Permission to run (not copy) an executable
438 // or command file.
439 // Note: For .CMD and .BAT files, "Read" permission
440 // is also required.
441 // -- for directories: XWPSec defines this as
442 // with Unix, to change to a directory.
443 #define XWPACCESS_DELETE 0x10 // "D"
444 // Permission to delete subdirectories and files.
445 #define XWPACCESS_ATRIB 0x20 // "A"
446 // Permission to modify the attributes of a
447 // resource (read-only, hidden, system, and
448 // the date and time a file was last modified).
449 #define XWPACCESS_PERM 0x40
450 // Permission to modify the permissions (read,
451 // write, create, execute, and delete) assigned
452 // to a resource for a user or application.
453 // This gives the user limited administration
454 // authority for a given resource.
455 #define XWPACCESS_ALL 0x7F
456 // Permission to read, write, create, execute,
457 // or delete a resource, or to modify attributes
458 // or permissions.
459
460 /*
461 *@@ RING0STATUS:
462 *
463 *@@added V1.0.1 (2003-01-10) [umoeller]
464 */
465
466 typedef struct _RING0STATUS
467 {
468 BOOL fLocalSecurity; // TRUE if XWPSEC32.SYS is active
469 ULONG cGranted, // if so, no. of syscalls where access was granted
470 cDenied; // ... and denied
471 } RING0STATUS, *PRING0STATUS;
472
473 /* ******************************************************************
474 *
475 * User Database
476 *
477 ********************************************************************/
478
479 /*
480 *@@ XWPGROUPDBENTRY:
481 * group entry in the user database.
482 * See userdb.c for details.
483 */
484
485 typedef struct _XWPGROUPDBENTRY
486 {
487 XWPSECID gid; // group ID
488 CHAR szGroupName[XWPSEC_NAMELEN]; // group name
489 } XWPGROUPDBENTRY, *PXWPGROUPDBENTRY;
490
491 /*
492 *@@ XWPUSERINFO:
493 * description of a user in the user database.
494 * See userdb.c for details.
495 */
496
497 typedef struct _XWPUSERINFO
498 {
499 XWPSECID uid; // user's ID (unique); 0 for root
500 CHAR szUserName[XWPSEC_NAMELEN];
501 CHAR szFullName[XWPSEC_FULLNAMELEN]; // user's clear name
502 } XWPUSERINFO, *PXWPUSERINFO;
503
504 /*
505 *@@ XWPMEMBERSHIP:
506 *
507 *@@added V1.0.1 (2003-01-05) [umoeller]
508 */
509
510 typedef struct _XWPMEMBERSHIP
511 {
512 ULONG cGroups;
513 XWPSECID aGIDs[1];
514 } XWPMEMBERSHIP, *PXWPMEMBERSHIP;
515
516 /*
517 *@@ XWPUSERDBENTRY:
518 *
519 *@@added V1.0.1 (2003-01-05) [umoeller]
520 */
521
522 typedef struct _XWPUSERDBENTRY
523 {
524 ULONG cbStruct;
525 XWPUSERINFO User;
526 CHAR szPassword[XWPSEC_NAMELEN];
527 XWPMEMBERSHIP Membership;
528 } XWPUSERDBENTRY, *PXWPUSERDBENTRY;
529
530 /* ******************************************************************
531 *
532 * Logons
533 *
534 ********************************************************************/
535
536 /*
537 *@@ XWPLOGGEDON:
538 * describes a current user (i.e. a user
539 * which is in the user database and is
540 * currently logged on, either locally
541 * or via network).
542 */
543
544 typedef struct _XWPLOGGEDON
545 {
546 ULONG cbStruct; // size of entire structure
547 XWPSECID uid; // user's ID
548 CHAR szUserName[XWPSEC_NAMELEN];
549 ULONG cSubjects; // no. of entries in aSubjects array
550 HXSUBJECT aSubjects[1]; // array of subject handles of this user; one "0" entry if root
551 } XWPLOGGEDON, *PXWPLOGGEDON;
552
553 /* ******************************************************************
554 *
555 * Errors
556 *
557 ********************************************************************/
558
559 #define ERROR_XWPSEC_FIRST 31000
560
561 #define XWPSEC_INTEGRITY (ERROR_XWPSEC_FIRST)
562 #define XWPSEC_STRUCT_MISMATCH (ERROR_XWPSEC_FIRST + 1) // V1.0.1 (2003-01-05) [umoeller]
563 // sizeof XWPSHELLQUEUEDATA does not match (different versions?)
564 #define XWPSEC_INVALID_DATA (ERROR_XWPSEC_FIRST + 2)
565 #define XWPSEC_CANNOT_GET_MUTEX (ERROR_XWPSEC_FIRST + 3)
566 #define XWPSEC_CANNOT_START_DAEMON (ERROR_XWPSEC_FIRST + 4)
567
568 #define XWPSEC_INSUFFICIENT_AUTHORITY (ERROR_XWPSEC_FIRST + 5)
569
570 #define XWPSEC_HSUBJECT_EXISTS (ERROR_XWPSEC_FIRST + 6)
571 #define XWPSEC_INVALID_HSUBJECT (ERROR_XWPSEC_FIRST + 7)
572
573 #define XWPSEC_INVALID_PID (ERROR_XWPSEC_FIRST + 10)
574 #define XWPSEC_NO_CONTEXTS (ERROR_XWPSEC_FIRST + 11)
575
576 #define XWPSEC_USER_EXISTS (ERROR_XWPSEC_FIRST + 20)
577 #define XWPSEC_NO_USERS (ERROR_XWPSEC_FIRST + 21)
578 #define XWPSEC_NO_GROUPS (ERROR_XWPSEC_FIRST + 22)
579 #define XWPSEC_INVALID_ID (ERROR_XWPSEC_FIRST + 23)
580 // invalid user or group ID
581
582 #define XWPSEC_NOT_AUTHENTICATED (ERROR_XWPSEC_FIRST + 30)
583 #define XWPSEC_NO_USER_PROFILE (ERROR_XWPSEC_FIRST + 31) // V0.9.19 (2002-04-02) [umoeller]
584 #define XWPSEC_CANNOT_START_SHELL (ERROR_XWPSEC_FIRST + 32)
585 #define XWPSEC_INVALID_PROFILE (ERROR_XWPSEC_FIRST + 33)
586 #define XWPSEC_NO_LOGON (ERROR_XWPSEC_FIRST + 34)
587
588 #define XWPSEC_DB_GROUP_SYNTAX (ERROR_XWPSEC_FIRST + 35)
589 #define XWPSEC_DB_USER_SYNTAX (ERROR_XWPSEC_FIRST + 36)
590 #define XWPSEC_DB_INVALID_GROUPID (ERROR_XWPSEC_FIRST + 37)
591
592 #define XWPSEC_DB_ACL_SYNTAX (ERROR_XWPSEC_FIRST + 40)
593 #define XWPSEC_DB_ACL_DUPRES (ERROR_XWPSEC_FIRST + 41)
594 // more than one line for the same resource in ACL DB
595
596 #define XWPSEC_RING0_NOT_FOUND (ERROR_XWPSEC_FIRST + 50)
597
598 #define XWPSEC_QUEUE_INVALID_CMD (ERROR_XWPSEC_FIRST + 51)
599
600 #define ERROR_XWPSEC_LAST (ERROR_XWPSEC_FIRST + 51)
601
602 /* ******************************************************************
603 *
604 * XWPShell Shared Memory
605 *
606 ********************************************************************/
607
608 #define SHMEM_XWPSHELL "\\SHAREMEM\\XWORKPLC\\XWPSHELL.DAT"
609 // shared memory name of XWPSHELLSHARED structure
610
611 /*
612 *@@ XWPSHELLSHARED:
613 * shared memory structure allocated by XWPShell
614 * when it starts up. This can be requested by
615 * any process to receive more information and
616 * is also checked by XWorkplace at WPS startup
617 * to determine whether XWPShell is running or
618 * the WPS should be running in single-user
619 * mode.
620 */
621
622 typedef struct _XWPSHELLSHARED
623 {
624 BOOL fNoLogonButRestart;
625 // when the shell process terminates, it
626 // can set this flag to TRUE to prevent
627 // the logon prompt from appearing; instead,
628 // the shell should be restarted with the
629 // same user
630 } XWPSHELLSHARED, *PXWPSHELLSHARED;
631
632 /* ******************************************************************
633 *
634 * XWPShell Queue (Ring 3 API)
635 *
636 ********************************************************************/
637
638 /*
639 * Ring-3 APIs are implemented via a regular OS/2 Control
640 * Program queue. Programs can call these APIs by allocating
641 * a chunk of shared memory, writing the pointer to that
642 * with a command code into this queue, and blocking on an
643 * event semaphore, which gets posted by XWPShell when the
644 * command has been processed. XWPShell then writes a
645 * result code (NO_ERROR or an error code) and possibly
646 * result data back into that shared memory.
647 *
648 * Since OS/2 reports the PID of the queue writer with the
649 * queue APIs, XWPShell can validate whether the writing
650 * process is authorized to perform a certain event. For
651 * example, when a process issues the "create new user"
652 * command, the queue thread in XWPShell will check the
653 * writer's PID and validate the security context of that
654 * process for whether the subjects of that process include
655 * sufficient permission for that command.
656 *
657 * The following commands are necessary:
658 *
659 * -- Query security context for a PID (no permissions required)
660 *
661 * -- Create user (admin permission required)
662 *
663 * -- Create group (admin permission required)
664 *
665 * -- Set User membership in groups
666 *
667 * -- Query user info
668 *
669 * -- Query group info
670 *
671 * -- Query permissions for a resource
672 *
673 * -- Set permissions for a resource
674 *
675 */
676
677 #define QUEUE_XWPSHELL "\\QUEUES\\XWORKPLC\\XWPSHELL.QUE"
678 // queue name of the master XWPShell queue
679
680 /*
681 *@@ QUEUEUNION:
682 *
683 *@@added V0.9.11 (2001-04-22) [umoeller]
684 */
685
686 typedef union _QUEUEUNION
687 {
688 #define QUECMD_QUERYSTATUS 1
689
690 RING0STATUS Status;
691
692 #define QUECMD_QUERYLOCALUSER 2
693 // return data for user that is
694 // currently logged on locally.
695 // Required authority: None.
696 // If NO_ERROR is returned, pLocalUser has been
697 // set to single XWPUSERDBENTRY structure
698 // in shared memory given to the caller.
699 // The caller must issue DosFreeMem.
700 // Note that the szPassword field is always
701 // nulled out.
702 // Possible error codes: see slogQueryLocalUser.
703 PXWPUSERDBENTRY pLocalUser;
704
705 #define QUECMD_QUERYUSERS 3
706 // return info for all users that
707 // are defined in the userdb.
708 // Required authority: administrator.
709 // Possible error codes: see sudbQueryUsers.
710 // If NO_ERROR is returned, paUsers has been
711 // set to an array of cUsers XWPUSERDBENTRY
712 // structures as shared memory given to the
713 // caller. The caller must issue DosFreeMem.
714 // Note that the szPassword field for each
715 // user is always nulled out.
716 struct
717 {
718 ULONG cUsers;
719 PXWPUSERDBENTRY paUsers;
720 } QueryUsers;
721
722 #define QUECMD_QUERYGROUPS 4
723 // return info for all groups that
724 // are defined in the userdb.
725 // Required authority: administrator.
726 // Possible error codes: see sudbQueryGroups.
727 // If NO_ERROR is returned, paGroups has been
728 // set to an array of cGroups XWPGROUPDBENTRY
729 // structures as shared memory given to the
730 // caller. The caller must issue DosFreeMem.
731 struct
732 {
733 ULONG cGroups;
734 PXWPGROUPDBENTRY paGroups;
735 } QueryGroups;
736
737 #define QUECMD_QUERYPROCESSOWNER 5
738 // return the uid of the user who owns
739 // the given process.
740 // Required authority: administrator.
741 struct
742 {
743 ULONG ulPID; // in: PID to query
744 XWPSECID uid; // out: uid of owner, if NO_ERROR is returned
745 } QueryProcessOwner;
746
747 #define QUECMD_CREATEUSER 6
748
749 struct
750 {
751 CHAR szUserName[XWPSEC_NAMELEN]; // user name
752 CHAR szFullName[XWPSEC_FULLNAMELEN]; // user's clear name
753 CHAR szPassword[XWPSEC_NAMELEN]; // password
754 XWPSECID uidCreated; // out: uid of new user
755 } CreateUser;
756
757 #define QUECMD_SETUSERDATA 7
758
759 struct
760 {
761 XWPSECID uid;
762 CHAR szUserName[XWPSEC_NAMELEN]; // user name
763 CHAR szFullName[XWPSEC_FULLNAMELEN]; // user's clear name
764 } SetUserData;
765
766 #define QUECMD_DELETEUSER 8
767
768 XWPSECID uidDelete;
769
770 #define QUECMD_QUERYPERMISSIONS 9
771
772 struct
773 {
774 CHAR szResource[CCHMAXPATH]; // in: resource to query
775 ULONG flAccess; // out: XWPACCESS_* flags
776 } QueryPermissions;
777
778 } QUEUEUNION, *PQUEUEUNION;
779
780 /*
781 *@@ XWPSHELLQUEUEDATA:
782 * structure used in shared memory to communicate
783 * with XWPShell.
784 *
785 * A client process must use the following procedure
786 * to communicate with XWPShell:
787 *
788 * 1) Open the public XWPShell queue.
789 *
790 * 2) Allocate a giveable shared XWPSHELLQUEUEDATA
791 * and give it to XWPShell as read/write.
792 *
793 * 3) Create a shared event semaphore in
794 * XWPSHELLQUEUEDATA.hev.
795 *
796 * 4) Set XWPSHELLQUEUEDATA.ulCommand to one of the
797 * QUECMD_* flags, specifying the data to be queried.
798 *
799 * 5) Write the XWPSHELLQUEUEDATA pointer to the
800 * queue.
801 *
802 * 6) Block on XWPSHELLQUEUEDATA.hevData, which gets
803 * posted by XWPShell when the data has been filled.
804 *
805 * 7) Check XWPSHELLQUEUEDATA.arc. If NO_ERROR,
806 * XWPSHELLQUEUEDATA.Data union has been filled
807 * with data according to ulCommand.
808 *
809 * 8) Close the event sem and free the shared memory.
810 *
811 *@@added V0.9.11 (2001-04-22) [umoeller]
812 */
813
814 typedef struct _XWPSHELLQUEUEDATA
815 {
816 ULONG cbStruct; // size of XWPSHELLQUEUEDATA struct (for safety)
817
818 ULONG ulCommand; // in: one of the QUECMD_* values
819
820 HEV hevData; // in: event semaphore posted
821 // when XWPShell has produced
822 // the data
823
824 APIRET arc; // out: error code set by XWPShell;
825 // if NO_ERROR, the following is valid
826
827 QUEUEUNION Data; // out: data, format depends on ulCommand
828
829 } XWPSHELLQUEUEDATA, *PXWPSHELLQUEUEDATA;
830
831 /* ******************************************************************
832 *
833 * Ring-0 (driver) APIs
834 *
835 ********************************************************************/
836
837 /*
838 * Ring 0 interfaces required to be called from XWPShell:
839 *
840 * -- Initialization: to be called exactly once when
841 * XWPShell starts up. This call enables local security
842 * and switches the driver into authorization mode:
843 * from then on, all system events are authenticated
844 * via the KPI callouts.
845 *
846 * With this call, XWPShell must pass down an array of
847 * PIDs that were already running when XWPShell was
848 * started, including XWPShell itself. For these
849 * processes, the driver will create security contexts
850 * as trusted processes.
851 *
852 * In addition, XWPShell sends down an array with all
853 * definitions of trusted processes so that the driver
854 * can create special security contexts for those.
855 *
856 * -- Query security context: XWPShell needs to be able
857 * to retrieve the security context of a given PID
858 * from the driver to be able to authorize ring-3 API
859 * calls such as "create user" or changing permissions.
860 *
861 * -- Set security context: changes the security context
862 * of an existing process. This is used by XWPShell
863 * to change its own context when the local user logs
864 * on. In addition, XWPShell will call this when a
865 * third party process has requested to change its
866 * context and this request was authenticated.
867 *
868 * -- ACL table: Whenever subject handles are created or
869 * deleted, XWPShell needs to rebuild the system ACL
870 * table to contain the fresh subject handles and
871 * pass them all down to the driver.
872 *
873 * -- Refresh process list: XWPShell needs to periodically
874 * call into the driver to pass it a list of processes
875 * that are currently running. Since there is no callout
876 * for when a process has terminated, the driver will
877 * end up with plenty of zombie PIDs after a while. This
878 * call will also be necessary before a user logs off
879 * after his processes have been terminated to make
880 * sure that subject handles are no longer in use.
881 */
882
883 /*
884 *@@ ACCESS:
885 *
886 *@@added V1.0.1 (2003-01-05) [umoeller]
887 */
888
889 typedef struct _ACCESS
890 {
891 HXSUBJECT hSubject; // subject handle; this is -1 if an entry
892 // exists for this resource but the user or
893 // group is not currently in use (because no
894 // such user is logged on)
895 BYTE fbAccess; // XWPACCESS_* flags
896 } ACCESS, *PACCESS;
897
898 /*
899 *@@ RESOURCEACL:
900 * definition of a resource entry in the system access control
901 * list (ACL).
902 *
903 * At ring 0, the driver has a list of all RESOURCEACL entries
904 * defined for the system. Each entry in turn has an array of
905 * ACCESS structs listing the subject handles for the resource,
906 * for example, defining that subject handle 1 (which could be
907 * representing a user) may read and write this resource, subject
908 * handle 2 (representing one of the groups the user belongs to)
909 * may execute, and so on.
910 *
911 * There will only be one entry for any resource per subject.
912 * As a result, if the permissions for a resource are changed,
913 * the existing entry must be found and refreshed to avoid
914 * duplicates.
915 *
916 * The global ACL table is build by XWPShell whenever it needs
917 * updating and passed down to the driver for future use. It
918 * will need rebuilding whenever a subject handle gets created
919 * or when access permissions are changed by an administrator.
920 *
921 * The table will be build as follows by XWPShell:
922 *
923 * 1) XWPShell loads the file defining the ACLs for the entire
924 * system.
925 *
926 * For each definition in the file, it builds a RESOURCEACL
927 * entry. It checks the permissions defined for the resource
928 * in the file and sets up the array of ACCESS structures for
929 * the resource. If a permission was defined for a user for
930 * which a subject handle already exists (because the user
931 * is already logged on), that subject handle is stored.
932 * If a definition exists but none of the permissions apply
933 * to any of the current users (because those users are not
934 * logged on, or the groups are not in use yet), a dummy
935 * entry with a -1 subject handle is created to block access
936 * to the resource (see the algorithm description below).
937 *
938 * 2) XWPShell then sends the system ACL list down to the driver.
939 *
940 * During authorization, for any event, the driver first checks
941 * if a null ("root") subject handle exists in the process's
942 * security context. If so, access is granted unconditionally.
943 *
944 * Otherwise, ACLs apply to all subdirectories too, unless a more
945 * specific ACL entry is encountered. In other words,
946 * the driver authorizes events bottom-up in the following order:
947 *
948 * 1) It checks for whether an ACL entry for the given resource
949 * exists in the ACL table.
950 *
951 * If any ACL entry was found for the resource, access is
952 * granted if any ACL entry allowed access for one of the
953 * subjects in the process's security context. Access is denied
954 * if ACL entries existed for the resource but none allowed access,
955 * which includes the "blocker" -1 entry described above.
956 *
957 * In any case, the search stops if an ACL entry was found
958 * in the table, and access is either granted or denied.
959 *
960 * 2) Only if no entry was found for the resource in any of the
961 * subject infos, we climb up to the parent directory and
962 * search all subject infos again. Go back to (1).
963 *
964 * 3) After the root directory has been processed and still no
965 * entry exists, access is denied.
966 *
967 * Examples:
968 *
969 * User "dumbo" belongs to the groups "users" and "admins".
970 * The following ACLs are defined:
971 *
972 * -- "users" may read "C:\DIR",
973 *
974 * -- "admins" may read and write "C:\",
975 *
976 * -- "admins" may create directories in "C:\DIR",
977 *
978 * -- "otheruser" may read "C:\OTHERDIR".
979 *
980 * Assuming that only "dumbo" is logged on presently and the following
981 * subject handles have thus been created:
982 *
983 * -- 1 for user "dumbo",
984 *
985 * -- 2 for group "users",
986 *
987 * -- 3 for group "admins",
988 *
989 * the system ACL table will contain the following entries:
990 *
991 * -- "C:\": 3 (group "admins") may read and write;
992 *
993 * -- "C:\DIR": 2 (group "users") may read, 3 (group "admins) may
994 * create directories;
995 *
996 * -- "C:\OTHERDIR": this will have a dummy -1 entry with no permissions
997 * because the only ACL defined is that user "otheruser" may read, and
998 * that user is not logged on.
999 *
1000 * 1) Assume a process running on behalf of "dumbo" wants to open
1001 * C:\DIR\SUBDIR\TEXT.DOC for reading.
1002 * Since the security context of "dumbo" has the three subject
1003 * handles for user "dumbo" (1) and the groups "users" (2) and
1004 * "admins" (3), the following happens:
1005 *
1006 * a) We check the system ACL table for "C:\DIR\SUBDIR\TEXT.DOC"
1007 * and find no ACL entry.
1008 *
1009 * b) So we take the parent directory, "C:\DIR\SUBDIR",
1010 * and again we find nothing.
1011 *
1012 * c) Taking the next parent, "C:\DIR\", we find the above two
1013 * subject handles: since "users" (2) may read, and that is
1014 * part of the security context, we grant access.
1015 *
1016 * 2) Now assume that the same process wants to write the file back:
1017 *
1018 * a) Again, we find no ACL entries for "C:\DIR\SUBDIR\TEXT.DOC"
1019 * or "C:\DIR\SUBDIR".
1020 *
1021 * b) Searching for "C:\DIR", we find that "users" (2) may only read,
1022 + but not write. Also, "admins" (3) may create directories under
1023 * "C:\DIR", which is not sufficient either. Since no other entries
1024 * exist for "C:\DIR" that would permit write, we deny access.
1025 * That "admins" may write to "C:\" does not help since more
1026 * specific entries exist for "C:\DIR".
1027 *
1028 * 3) Now assume that the same process wants to create a new directory
1029 * under "C:\DIR\SUBDIR".
1030 *
1031 * a) Again, we find no ACL entries for "C:\DIR\SUBDIR".
1032 *
1033 * b) Searching for "C:\DIR", we find that "users" may only read,
1034 * which does not help. However, "admins" may create directories,
1035 * so we grant access.
1036 *
1037 * 4) Assume now that the process wants to create a new directory under
1038 * "C:\OTHERDIR".
1039 *
1040 * We find the ACL entry for "C:\OTHERDIR" and see only the -1
1041 * subject handle (for user "otheruser", who's not logged on),
1042 * and since no other permissions are set for us, we deny access.
1043 *
1044 *@@added V1.0.1 (2003-01-05) [umoeller]
1045 */
1046
1047 typedef struct _RESOURCEACL
1048 {
1049 ULONG cbStruct; // size of entire structure; this is
1050 // sizeof(RESOURCEACL)
1051 // + cbName - 1
1052 // + cAccesses * sizeof(ACCESS)
1053 USHORT cAccesses; // no. of entries in array of ACCESS structs;
1054 // this comes right after szName, so its address
1055 // is szName + cbName
1056 USHORT cbName; // offset of array of ACCESS structs after szName
1057 // (includes null terminator and DWORD alignment
1058 // filler bytes)
1059 CHAR szName[1]; // fully qualified filename of this resource
1060 // (zero-terminated)
1061 } RESOURCEACL, *PRESOURCEACL;
1062
1063 /*
1064 *@@ RING0BUF:
1065 *
1066 *@@added V1.0.1 (2003-01-05) [umoeller]
1067 */
1068
1069 typedef struct _RING0BUF
1070 {
1071 ULONG cbTotal;
1072 ULONG cSubjectInfos; // no. of subject infos (directly after this struct)
1073 ULONG cACLs; // no. of RESOURCEACL structs (after subject infos)
1074 ULONG ofsACLs; // ofs of first RESOURCEACL struct from beginning of
1075 // RING0BUF
1076 } RING0BUF, *PRING0BUF;
1077
1078#endif
1079
1080#if __cplusplus
1081}
1082#endif
1083
Note: See TracBrowser for help on using the repository browser.