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

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