Ignore:
Timestamp:
Jan 8, 2004, 5:43:29 PM (22 years ago)
Author:
umoeller
Message:

Fixes that have piled up in the last three months.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/xwpsecty.h

    r241 r257  
    7070 *      real ACLs which are unlimited in size per resource.
    7171 *
    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.
     72 *      To implement this efficiently, XWPSec uses "subject handles",
     73 *      which is a concept borrowed from SES. However, XWPSec does not
     74 *      use the SES APIs for creating and managing those, but implements
     75 *      this functionality itself.
    7676 *
    7777 *      For authorizing events, XWPSec uses the XWPSUBJECTINFO and
    7878 *      XWPSECURITYCONTEXT structures, plus an array of RESOURCEACL
    79  *      structs which forms the global system ACL table shared with
     79 *      structs that forms the global system ACL table shared with
    8080 *      the ring-0 device driver.
    8181 *
     
    8787 *      users. However, one user logon is special and is called
    8888 *      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.
     89 *      importantly PM and the Workplace Shell, and processes
     90 *      started via the shell run on behalf of that user.
    9191 *
    9292 *      When a user logs on, XWPShell authenticates the credentials
     
    222222    typedef unsigned long HXSUBJECT;
    223223
    224     typedef unsigned long XWPSECID;
     224    typedef long XWPSECID;
    225225
    226226    /*
     
    303303
    304304    /*
    305      *@@ XWPSECURITYCONTEXT:
     305     *@@ XWPSECURITYCONTEXTCORE:
    306306     *      describes the security context for a process.
    307307     *
     
    345345     *          there would be one subject handle representing the
    346346     *          ACLs for that in addition to those of the user running
    347      *          it.
     347     *          it (if any).
    348348     *
    349349     *      --  For processes that were started during system startup,
     
    352352     *          PIDs to the driver with the "initialization" ring-0 API.
    353353     *          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
     354     *          are presently considered trusted processes.
     355     */
     356
     357    typedef struct _XWPSECURITYCONTEXTCORE
     358    {
     359        USHORT      pidParent;      // ID of process parent
     360
     361        USHORT      cSubjects;      // no. of subject handles in this context
    363362
    364363        HXSUBJECT   aSubjects[1];   // array of cSubjects subject handles,
    365                                         // determining the permissions of this
    366                                         // process
    367 
    368     } XWPSECURITYCONTEXT, *PXWPSECURITYCONTEXT;
     364                                    // determining the permissions of this
     365                                    // process
     366
     367    } XWPSECURITYCONTEXTCORE, *PXWPSECURITYCONTEXTCORE;
    369368
    370369    /* ******************************************************************
     
    426425                    // is required for that).
    427426                    // Should be used together with "Read", because
    428                     // "Write" alone doesn't make much sense.
     427                    // "Write" alone is not terribly useful.
    429428                    // Besides, "Attrib" permission will also be
    430429                    // required.
     
    460459    /*
    461460     *@@ XWPSECSTATUS:
     461     *      structure representing the current status of XWPSec.
     462     *      Used with QUECMD_QUERYSTATUS.
    462463     *
    463464     *@@added V1.0.1 (2003-01-10) [umoeller]
     
    470471        // the following fields are only set if fLocalSecurity is TRUE
    471472
    472         ULONG       cbAllocated;        // fixed memory currently allocated in ring 0
     473        ULONG       cbAllocated;        // total fixed memory currently allocated in ring 0
    473474        ULONG       cAllocations,       // no. of allocations made since startup
    474475                    cFrees;             // no. of frees made since startup
     
    478479        ULONG       cGranted,           // no. of syscalls where access was granted
    479480                    cDenied;            // ... and denied
     481        LONG        cContexts;          // no. of currently allocated security contexts
     482                                        // (always >= the no. of running processes)
     483        ULONG       cbACLs;             // of cbAllocated, no. of bytes in use for ACLs
    480484    } XWPSECSTATUS, *PXWPSECSTATUS;
    481 
    482485
    483486    /* ******************************************************************
     
    507510    typedef struct _XWPUSERINFO
    508511    {
    509         XWPSECID    uid;                // user's ID (unique); 0 for root
     512        XWPSECID    uid;                    // user's ID (unique); 0 for root
    510513        CHAR        szUserName[XWPSEC_NAMELEN];
    511514        CHAR        szFullName[XWPSEC_FULLNAMELEN];       // user's clear name
     515        CHAR        szUserShell[CCHMAXPATH];    // user shell (normally "X:\OS2\PMSHELL.EXE")
    512516    } XWPUSERINFO, *PXWPUSERINFO;
    513517
     
    557561        XWPSECID    uid;            // user's ID
    558562        CHAR        szUserName[XWPSEC_NAMELEN];
    559         ULONG       cSubjects;      // no. of entries in aSubjects array
     563        USHORT      cSubjects;      // no. of entries in aSubjects array
    560564        HXSUBJECT   aSubjects[1];   // array of subject handles of this user; one "0" entry if root
    561565    } XWPLOGGEDON, *PXWPLOGGEDON;
     
    601605
    602606    #define XWPSEC_DB_ACL_SYNTAX        (ERROR_XWPSEC_FIRST + 40)
    603     #define XWPSEC_DB_ACL_DUPRES        (ERROR_XWPSEC_FIRST + 41)
     607    #define XWPSEC_DB_ACL_INTEGRITY     (ERROR_XWPSEC_FIRST + 41)
     608    #define XWPSEC_DB_ACL_DUPRES        (ERROR_XWPSEC_FIRST + 42)
    604609                // more than one line for the same resource in ACL DB
    605610
     
    745750        } QueryGroups;
    746751
    747         #define QUECMD_QUERYPROCESSOWNER            5
     752        #define QUECMD_QUERYUSERNAME                5
     753
     754        struct
     755        {
     756            XWPSECID    uid;                            // in: user ID
     757            CHAR        szUserName[XWPSEC_NAMELEN];     // out: user name
     758        } QueryUserName;
     759
     760        #define QUECMD_QUERYPROCESSOWNER            6
    748761            // return the uid of the user who owns
    749762            // the given process.
    750             // Required authority: administrator.
     763            // Required authority: XWPPERM_QUERYUSERINFO,
     764            // unless the given process is owned by the
     765            // same user who runs the query.
    751766        struct
    752767        {
    753             ULONG               ulPID;      // in: PID to query
     768            USHORT              pid;        // in: PID to query (or 0 for calling process)
     769            HXSUBJECT           hsubj0;     // out: hSubject of user (or privileged process)
    754770            XWPSECID            uid;        // out: uid of owner, if NO_ERROR is returned
    755771        } QueryProcessOwner;
    756772
    757         #define QUECMD_CREATEUSER                   6
     773        #define QUECMD_CREATEUSER                   7
    758774
    759775        struct
     
    765781        } CreateUser;
    766782
    767         #define QUECMD_SETUSERDATA                  7
     783        #define QUECMD_SETUSERDATA                  8
    768784
    769785        XWPUSERINFO     SetUserData;
    770786
    771         #define QUECMD_DELETEUSER                   8
     787        #define QUECMD_DELETEUSER                   9
    772788
    773789        XWPSECID        uidDelete;
    774790
    775         #define QUECMD_QUERYPERMISSIONS             9
     791        #define QUECMD_QUERYPERMISSIONS             10
    776792
    777793        struct
     
    781797        } QueryPermissions;
    782798
     799        #define QUECMD_SWITCHUSER                   11
     800            // change the credentials of the current process. This
     801            // allows a process to run on behalf of a different user
     802            // and can be used to implement a "su" command, since
     803            // processes started by the current process will inherit
     804            // those credentials.
     805
     806        struct
     807        {
     808            CHAR        szUserName[XWPSEC_NAMELEN];
     809            CHAR        szPassword[XWPSEC_NAMELEN];
     810            XWPSECID    uid;                        // out: user id if NO_ERROR
     811        } SwitchUser;
     812
    783813    } QUEUEUNION, *PQUEUEUNION;
    784814
     
    836866    /* ******************************************************************
    837867     *
    838      *   Ring-0 (driver) APIs
     868     *   APIs for interfacing XWPShell
    839869     *
    840870     ********************************************************************/
    841871
    842     /*
    843      *      Ring 0 interfaces required to be called from XWPShell:
    844      *
    845      *      --  Initialization: to be called exactly once when
    846      *          XWPShell starts up. This call enables local security
    847      *          and switches the driver into authorization mode:
    848      *          from then on, all system events are authenticated
    849      *          via the KPI callouts.
    850      *
    851      *          With this call, XWPShell must pass down an array of
    852      *          PIDs that were already running when XWPShell was
    853      *          started, including XWPShell itself. For these
    854      *          processes, the driver will create security contexts
    855      *          as trusted processes.
    856      *
    857      *          In addition, XWPShell sends down an array with all
    858      *          definitions of trusted processes so that the driver
    859      *          can create special security contexts for those.
    860      *
    861      *      --  Query security context: XWPShell needs to be able
    862      *          to retrieve the security context of a given PID
    863      *          from the driver to be able to authorize ring-3 API
    864      *          calls such as "create user" or changing permissions.
    865      *
    866      *      --  Set security context: changes the security context
    867      *          of an existing process. This is used by XWPShell
    868      *          to change its own context when the local user logs
    869      *          on. In addition, XWPShell will call this when a
    870      *          third party process has requested to change its
    871      *          context and this request was authenticated.
    872      *
    873      *      --  ACL table: Whenever subject handles are created or
    874      *          deleted, XWPShell needs to rebuild the system ACL
    875      *          table to contain the fresh subject handles and
    876      *          pass them all down to the driver.
    877      *
    878      *      --  Refresh process list: XWPShell needs to periodically
    879      *          call into the driver to pass it a list of processes
    880      *          that are currently running. Since there is no callout
    881      *          for when a process has terminated, the driver will
    882      *          end up with plenty of zombie PIDs after a while. This
    883      *          call will also be necessary before a user logs off
    884      *          after his processes have been terminated to make
    885      *          sure that subject handles are no longer in use.
    886      */
    887 
    888     /*
    889      *@@ ACCESS:
    890      *
    891      *@@added V1.0.1 (2003-01-05) [umoeller]
    892      */
    893 
    894     typedef struct _ACCESS
    895     {
    896         HXSUBJECT   hSubject;           // subject handle; this is -1 if an entry
    897                                         // exists for this resource but the user or
    898                                         // group is not currently in use (because no
    899                                         // such user is logged on)
    900         BYTE        fbAccess;           // XWPACCESS_* flags
    901     } ACCESS, *PACCESS;
    902 
    903     /*
    904      *@@ RESOURCEACL:
    905      *      definition of a resource entry in the system access control
    906      *      list (ACL).
    907      *
    908      *      At ring 0, the driver has a list of all RESOURCEACL entries
    909      *      defined for the system. Each entry in turn has an array of
    910      *      ACCESS structs listing the subject handles for the resource,
    911      *      for example, defining that subject handle 1 (which could be
    912      *      representing a user) may read and write this resource, subject
    913      *      handle 2 (representing one of the groups the user belongs to)
    914      *      may execute, and so on.
    915      *
    916      *      There will only be one entry for any resource per subject.
    917      *      As a result, if the permissions for a resource are changed,
    918      *      the existing entry must be found and refreshed to avoid
    919      *      duplicates.
    920      *
    921      *      The global ACL table is build by XWPShell whenever it needs
    922      *      updating and passed down to the driver for future use. It
    923      *      will need rebuilding whenever a subject handle gets created
    924      *      or when access permissions are changed by an administrator.
    925      *
    926      *      The table will be build as follows by XWPShell:
    927      *
    928      *      1)  XWPShell loads the file defining the ACLs for the entire
    929      *          system.
    930      *
    931      *          For each definition in the file, it builds a RESOURCEACL
    932      *          entry. It checks the permissions defined for the resource
    933      *          in the file and sets up the array of ACCESS structures for
    934      *          the resource. If a permission was defined for a user for
    935      *          which a subject handle already exists (because the user
    936      *          is already logged on), that subject handle is stored.
    937      *          If a definition exists but none of the permissions apply
    938      *          to any of the current users (because those users are not
    939      *          logged on, or the groups are not in use yet), a dummy
    940      *          entry with a -1 subject handle is created to block access
    941      *          to the resource (see the algorithm description below).
    942      *
    943      *      2)  XWPShell then sends the system ACL list down to the driver.
    944      *
    945      *      During authorization, for any event, the driver first checks
    946      *      if a null ("root") subject handle exists in the process's
    947      *      security context. If so, access is granted unconditionally.
    948      *
    949      *      Otherwise, ACLs apply to all subdirectories too, unless a more
    950      *      specific ACL entry is encountered. In other words,
    951      *      the driver authorizes events bottom-up in the following order:
    952      *
    953      *      1)  It checks for whether an ACL entry for the given resource
    954      *          exists in the ACL table.
    955      *
    956      *          If any ACL entry was found for the resource, access is
    957      *          granted if any ACL entry allowed access for one of the
    958      *          subjects in the process's security context. Access is denied
    959      *          if ACL entries existed for the resource but none allowed access,
    960      *          which includes the "blocker" -1 entry described above.
    961      *
    962      *          In any case, the search stops if an ACL entry was found
    963      *          in the table, and access is either granted or denied.
    964      *
    965      *      2)  Only if no entry was found for the resource in any of the
    966      *          subject infos, we climb up to the parent directory and
    967      *          search all subject infos again. Go back to (1).
    968      *
    969      *      3)  After the root directory has been processed and still no
    970      *          entry exists, access is denied.
    971      *
    972      *      Examples:
    973      *
    974      *      User "dumbo" belongs to the groups "users" and "admins".
    975      *      The following ACLs are defined:
    976      *
    977      *      --  "users" may read "C:\DIR",
    978      *
    979      *      --  "admins" may read and write "C:\",
    980      *
    981      *      --  "admins" may create directories in "C:\DIR",
    982      *
    983      *      --  "otheruser" may read "C:\OTHERDIR".
    984      *
    985      *      Assuming that only "dumbo" is logged on presently and the following
    986      *      subject handles have thus been created:
    987      *
    988      *      --  1 for user "dumbo",
    989      *
    990      *      --  2 for group "users",
    991      *
    992      *      --  3 for group "admins",
    993      *
    994      *      the system ACL table will contain the following entries:
    995      *
    996      *      --  "C:\": 3 (group "admins") may read and write;
    997      *
    998      *      --  "C:\DIR": 2 (group "users") may read, 3 (group "admins) may
    999      *          create directories;
    1000      *
    1001      *      --  "C:\OTHERDIR": this will have a dummy -1 entry with no permissions
    1002      *          because the only ACL defined is that user "otheruser" may read, and
    1003      *          that user is not logged on.
    1004      *
    1005      *      1)  Assume a process running on behalf of "dumbo" wants to open
    1006      *          C:\DIR\SUBDIR\TEXT.DOC for reading.
    1007      *          Since the security context of "dumbo" has the three subject
    1008      *          handles for user "dumbo" (1) and the groups "users" (2) and
    1009      *          "admins" (3), the following happens:
    1010      *
    1011      *          a)  We check the system ACL table for "C:\DIR\SUBDIR\TEXT.DOC"
    1012      *              and find no ACL entry.
    1013      *
    1014      *          b)  So we take the parent directory, "C:\DIR\SUBDIR",
    1015      *              and again we find nothing.
    1016      *
    1017      *          c)  Taking the next parent, "C:\DIR\", we find the above two
    1018      *              subject handles: since "users" (2) may read, and that is
    1019      *              part of the security context, we grant access.
    1020      *
    1021      *      2)  Now assume that the same process wants to write the file back:
    1022      *
    1023      *          a)  Again, we find no ACL entries for "C:\DIR\SUBDIR\TEXT.DOC"
    1024      *              or "C:\DIR\SUBDIR".
    1025      *
    1026      *          b)  Searching for "C:\DIR", we find that "users" (2) may only read,
    1027      +              but not write. Also, "admins" (3) may create directories under
    1028      *              "C:\DIR", which is not sufficient either. Since no other entries
    1029      *              exist for "C:\DIR"  that would permit write, we deny access.
    1030      *              That "admins" may write to "C:\" does not help since more
    1031      *              specific entries exist for "C:\DIR".
    1032      *
    1033      *      3)  Now assume that the same process wants to create a new directory
    1034      *          under "C:\DIR\SUBDIR".
    1035      *
    1036      *          a)  Again, we find no ACL entries for "C:\DIR\SUBDIR".
    1037      *
    1038      *          b)  Searching for "C:\DIR", we find that "users" may only read,
    1039      *              which does not help. However, "admins" may create directories,
    1040      *              so we grant access.
    1041      *
    1042      *      4)  Assume now that the process wants to create a new directory under
    1043      *          "C:\OTHERDIR".
    1044      *
    1045      *          We find the ACL entry for "C:\OTHERDIR" and see only the -1
    1046      *          subject handle (for user "otheruser", who's not logged on),
    1047      *          and since no other permissions are set for us, we deny access.
    1048      *
    1049      *@@added V1.0.1 (2003-01-05) [umoeller]
    1050      */
    1051 
    1052     typedef struct _RESOURCEACL
    1053     {
    1054         ULONG       cbStruct;           // size of entire structure; this is
    1055                                         //   sizeof(RESOURCEACL)
    1056                                         // + cbName - 1
    1057                                         // + cAccesses * sizeof(ACCESS)
    1058         USHORT      cAccesses;          // no. of entries in array of ACCESS structs;
    1059                                         // this comes right after szName, so its address
    1060                                         // is szName + cbName
    1061         USHORT      cbName;             // offset of array of ACCESS structs after szName
    1062                                         // (includes null terminator and DWORD alignment
    1063                                         // filler bytes)
    1064         CHAR        szName[1];          // fully qualified filename of this resource
    1065                                         // (zero-terminated)
    1066     } RESOURCEACL, *PRESOURCEACL;
    1067 
    1068     /*
    1069      *@@ RING0BUF:
    1070      *
    1071      *@@added V1.0.1 (2003-01-05) [umoeller]
    1072      */
    1073 
    1074     typedef struct _RING0BUF
    1075     {
    1076         ULONG       cbTotal;
    1077         ULONG       cSubjectInfos;      // no. of subject infos (directly after this struct)
    1078         ULONG       cACLs;              // no. of RESOURCEACL structs (after subject infos)
    1079         ULONG       ofsACLs;            // ofs of first RESOURCEACL struct from beginning of
    1080                                         // RING0BUF
    1081     } RING0BUF, *PRING0BUF;
     872    APIRET xsecQueryStatus(PXWPSECSTATUS pStatus);
     873
     874    APIRET xsecQueryLocalUser(PXWPUSERDBENTRY *ppLocalUser);
     875
     876    APIRET xsecQueryAllUsers(PULONG pcUsers,
     877                             PXWPUSERDBENTRY *ppaUsers);
     878
     879    APIRET xsecQueryGroups(PULONG pcGroups,
     880                           PXWPGROUPDBENTRY *ppaGroups);
     881
     882    APIRET xsecQueryUserName(XWPSECID uid,
     883                             PSZ pszUserName);
     884
     885    APIRET xsecQueryProcessOwner(USHORT pid,
     886                                 XWPSECID *puid);
     887
     888    APIRET xsecCreateUser(PCSZ pcszUserName,
     889                          PCSZ pcszFullName,
     890                          PCSZ pcszPassword,
     891                          XWPSECID gid,
     892                          XWPSECID *puid);
     893
     894    APIRET xsecSetUserData(XWPSECID uid,
     895                           PCSZ pcszUserName,
     896                           PCSZ pcszFullName);
     897
     898    APIRET xsecDeleteUser(XWPSECID uid);
     899
     900    APIRET xsecQueryPermissions(PCSZ pcszFilename,
     901                                PULONG pflAccess);
    1082902
    1083903#endif
Note: See TracChangeset for help on using the changeset viewer.