Usermode/ld-acess - Added two more ARM relocation types
[tpg/acess2.git] / Kernel / vfs / acls.c
1 /* 
2  * Acess Micro VFS
3  */
4 #include <acess.h>
5 #include "vfs.h"
6 #include "vfs_int.h"
7
8 // === GLOBALS ===
9 tVFS_ACL        gVFS_ACL_EveryoneRWX = { {1,-1}, {0,VFS_PERM_ALL} };
10 tVFS_ACL        gVFS_ACL_EveryoneRW = { {1,-1}, {0,VFS_PERM_ALL^VFS_PERM_EXECUTE} };
11 tVFS_ACL        gVFS_ACL_EveryoneRX = { {1,-1}, {0,VFS_PERM_READ|VFS_PERM_EXECUTE} };
12 tVFS_ACL        gVFS_ACL_EveryoneRO = { {1,-1}, {0,VFS_PERM_READ} };
13
14 // === CODE ===
15 /**
16  * \fn int VFS_CheckACL(tVFS_Node *Node, Uint Permissions)
17  * \brief Checks the permissions on a file
18  */
19 int VFS_CheckACL(tVFS_Node *Node, Uint Permissions)
20 {
21          int    i;
22          int    uid = Threads_GetUID();
23          int    gid = Threads_GetGID();
24         
25         // Root can do anything
26         if(uid == 0)    return 1;
27         
28         // Root only file?, fast return
29         if( Node->NumACLs == 0 ) {
30                 Log("VFS_CheckACL - %p inaccesable, NumACLs = 0, uid=%i", Node, uid);
31                 return 0;
32         }
33         
34         // Check Deny Permissions
35         for(i=0;i<Node->NumACLs;i++)
36         {
37                 if(!Node->ACLs[i].Inv)  continue;       // Ignore ALLOWs
38                 if(Node->ACLs[i].ID != 0x7FFFFFFF)
39                 {
40                         if(!Node->ACLs[i].Group && Node->ACLs[i].ID != uid)     continue;
41                         if(Node->ACLs[i].Group && Node->ACLs[i].ID != gid)      continue;
42                 }
43                 
44                 //Log("Deny %x", Node->ACLs[i].Perms);
45                 
46                 if(Node->ACLs[i].Perms & Permissions) {
47                         Log("VFS_CheckACL - %p inaccesable, %x denied",
48                                 Node, Node->ACLs[i].Perms & Permissions);
49                         return 0;
50                 }
51         }
52         
53         // Check for allow permissions
54         for(i=0;i<Node->NumACLs;i++)
55         {
56                 if(Node->ACLs[i].Inv)   continue;       // Ignore DENYs
57                 if(Node->ACLs[i].ID != 0x7FFFFFFF)
58                 {
59                         if(!Node->ACLs[i].Group && Node->ACLs[i].ID != uid)     continue;
60                         if(Node->ACLs[i].Group && Node->ACLs[i].ID != gid)      continue;
61                 }
62                 
63                 //Log("Allow %x", Node->ACLs[i].Perms);
64                 
65                 if((Node->ACLs[i].Perms & Permissions) == Permissions)  return 1;
66         }
67         
68         Log("VFS_CheckACL - %p inaccesable, %x not allowed", Node, Permissions);
69         return 0;
70 }
71 /**
72  * \fn int VFS_GetACL(int FD, tVFS_ACL *Dest)
73  */
74 int VFS_GetACL(int FD, tVFS_ACL *Dest)
75 {
76          int    i;
77         tVFS_Handle     *h = VFS_GetHandle(FD);
78         
79         // Error check
80         if(!h) {
81                 return -1;
82         }
83         
84         // Root can do anything
85         if(Dest->Group == 0 && Dest->ID == 0) {
86                 Dest->Inv = 0;
87                 Dest->Perms = -1;
88                 return 1;
89         }
90         
91         // Root only file?, fast return
92         if( h->Node->NumACLs == 0 ) {
93                 Dest->Inv = 0;
94                 Dest->Perms = 0;
95                 return 0;
96         }
97         
98         // Check Deny Permissions
99         for(i=0;i<h->Node->NumACLs;i++)
100         {
101                 if(h->Node->ACLs[i].Group != Dest->Group)       continue;
102                 if(h->Node->ACLs[i].ID != Dest->ID)     continue;
103                 
104                 Dest->Inv = h->Node->ACLs[i].Inv;
105                 Dest->Perms = h->Node->ACLs[i].Perms;
106                 return 1;
107         }
108         
109         
110         Dest->Inv = 0;
111         Dest->Perms = 0;
112         return 0;
113 }
114
115 /**
116  * \fn tVFS_ACL *VFS_UnixToAcessACL(Uint Mode, Uint Owner, Uint Group)
117  * \brief Converts UNIX permissions to three Acess ACL entries
118  */
119 tVFS_ACL *VFS_UnixToAcessACL(Uint Mode, Uint Owner, Uint Group)
120 {
121         tVFS_ACL        *ret = malloc(sizeof(tVFS_ACL)*3);
122         
123         // Error Check
124         if(!ret)        return NULL;
125         
126         // Owner
127         ret[0].Group = 0;       ret[0].ID = Owner;
128         ret[0].Inv = 0;         ret[0].Perms = 0;
129         if(Mode & 0400) ret[0].Perms |= VFS_PERM_READ;
130         if(Mode & 0200) ret[0].Perms |= VFS_PERM_WRITE;
131         if(Mode & 0100) ret[0].Perms |= VFS_PERM_EXECUTE;
132         
133         // Group
134         ret[1].Group = 1;       ret[1].ID = Group;
135         ret[1].Inv = 0;         ret[1].Perms = 0;
136         if(Mode & 0040) ret[1].Perms |= VFS_PERM_READ;
137         if(Mode & 0020) ret[1].Perms |= VFS_PERM_WRITE;
138         if(Mode & 0010) ret[1].Perms |= VFS_PERM_EXECUTE;
139         
140         // Global
141         ret[2].Group = 1;       ret[2].ID = -1;
142         ret[2].Inv = 0;         ret[2].Perms = 0;
143         if(Mode & 0004) ret[2].Perms |= VFS_PERM_READ;
144         if(Mode & 0002) ret[2].Perms |= VFS_PERM_WRITE;
145         if(Mode & 0001) ret[2].Perms |= VFS_PERM_EXECUTE;
146         
147         // Return buffer
148         return ret;
149 }
150
151 // === EXPORTS ===
152 // --- Variables ---
153 EXPORTV(gVFS_ACL_EveryoneRWX);
154 EXPORTV(gVFS_ACL_EveryoneRW);
155 EXPORTV(gVFS_ACL_EveryoneRX);
156 // --- Functions ---
157 EXPORT(VFS_UnixToAcessACL);

UCC git Repository :: git.ucc.asn.au