s4-privs Remove link between enum sec_privilege and the privilege bitmap
[samba.git] / source4 / libcli / security / privilege.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    manipulate privileges
5
6    Copyright (C) Andrew Tridgell 2004
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "librpc/gen_ndr/security.h" 
24 #include "libcli/security/security.h" 
25
26
27 static const struct {
28         enum sec_privilege privilege;
29         uint64_t privilege_mask;
30         const char *name;
31         const char *display_name;
32 } privilege_names[] = {
33         {SEC_PRIV_SECURITY,                   
34          SE_SECURITY,
35          "SeSecurityPrivilege",
36         "System security"},
37
38         {SEC_PRIV_BACKUP,                     
39          SE_BACKUP,
40          "SeBackupPrivilege",
41          "Backup files and directories"},
42
43         {SEC_PRIV_RESTORE,                    
44          SE_RESTORE,
45          "SeRestorePrivilege",
46         "Restore files and directories"},
47
48         {SEC_PRIV_SYSTEMTIME,                 
49          SE_SYSTEMTIME,
50          "SeSystemtimePrivilege",
51         "Set the system clock"},
52
53         {SEC_PRIV_SHUTDOWN,                   
54          SE_SHUTDOWN,
55          "SeShutdownPrivilege",
56         "Shutdown the system"},
57
58         {SEC_PRIV_REMOTE_SHUTDOWN,            
59          SE_REMOTE_SHUTDOWN,
60          "SeRemoteShutdownPrivilege",
61         "Shutdown the system remotely"},
62
63         {SEC_PRIV_TAKE_OWNERSHIP,             
64          SE_TAKE_OWNERSHIP,
65          "SeTakeOwnershipPrivilege",
66         "Take ownership of files and directories"},
67
68         {SEC_PRIV_DEBUG,                      
69          SE_DEBUG,
70          "SeDebugPrivilege",
71         "Debug processes"},
72
73         {SEC_PRIV_SYSTEM_ENVIRONMENT,         
74          SE_SYSTEM_ENVIRONMENT,
75          "SeSystemEnvironmentPrivilege",
76         "Modify system environment"},
77
78         {SEC_PRIV_SYSTEM_PROFILE,             
79          SE_SYSTEM_PROFILE,
80          "SeSystemProfilePrivilege",
81         "Profile the system"},
82
83         {SEC_PRIV_PROFILE_SINGLE_PROCESS,     
84          SE_PROFILE_SINGLE_PROCESS,
85          "SeProfileSingleProcessPrivilege",
86         "Profile one process"},
87
88         {SEC_PRIV_INCREASE_BASE_PRIORITY,     
89          SE_INCREASE_BASE_PRIORITY,
90          "SeIncreaseBasePriorityPrivilege",
91          "Increase base priority"},
92
93         {SEC_PRIV_LOAD_DRIVER,
94          SE_LOAD_DRIVER,
95          "SeLoadDriverPrivilege",
96         "Load drivers"},
97
98         {SEC_PRIV_CREATE_PAGEFILE,            
99          SE_CREATE_PAGEFILE,
100          "SeCreatePagefilePrivilege",
101         "Create page files"},
102
103         {SEC_PRIV_INCREASE_QUOTA,
104          SE_INCREASE_QUOTA,
105          "SeIncreaseQuotaPrivilege",
106         "Increase quota"},
107
108         {SEC_PRIV_CHANGE_NOTIFY,              
109          SE_CHANGE_NOTIFY,
110          "SeChangeNotifyPrivilege",
111         "Register for change notify"},
112
113         {SEC_PRIV_UNDOCK,                     
114          SE_UNDOCK,
115          "SeUndockPrivilege",
116         "Undock devices"},
117
118         {SEC_PRIV_MANAGE_VOLUME,              
119          SE_MANAGE_VOLUME,
120          "SeManageVolumePrivilege",
121         "Manage system volumes"},
122
123         {SEC_PRIV_IMPERSONATE,                
124          SE_IMPERSONATE,
125          "SeImpersonatePrivilege",
126         "Impersonate users"},
127
128         {SEC_PRIV_CREATE_GLOBAL,              
129          SE_CREATE_GLOBAL,
130          "SeCreateGlobalPrivilege",
131         "Create global"},
132
133         {SEC_PRIV_ENABLE_DELEGATION,          
134          SE_ENABLE_DELEGATION,
135          "SeEnableDelegationPrivilege",
136         "Enable Delegation"},
137
138         {SEC_PRIV_INTERACTIVE_LOGON,          
139          SE_INTERACTIVE_LOGON,
140          "SeInteractiveLogonRight",
141         "Interactive logon"},
142
143         {SEC_PRIV_NETWORK_LOGON,
144          SE_NETWORK_LOGON,
145          "SeNetworkLogonRight",
146         "Network logon"},
147
148         {SEC_PRIV_REMOTE_INTERACTIVE_LOGON,   
149          SE_REMOTE_INTERACTIVE_LOGON,
150          "SeRemoteInteractiveLogonRight",
151         "Remote Interactive logon"},
152
153         {SEC_PRIV_MACHINE_ACCOUNT,
154          SE_MACHINE_ACCOUNT,
155          "SeMachineAccountPrivilege",
156          "Add workstations to domain"},
157
158         /* These last 3 are Samba only */
159         {SEC_PRIV_PRINT_OPERATOR,
160          SE_PRINT_OPERATOR,
161          "SePrintOperatorPrivilege",
162          "Manage printers"},
163
164         {SEC_PRIV_ADD_USERS,
165          SE_ADD_USERS,
166          "SeAddUsersPrivilege",
167          "Add users and groups to the domain"},
168
169         {SEC_PRIV_DISK_OPERATOR,
170          SE_DISK_OPERATOR,
171          "SeDiskOperatorPrivilege",
172          "Manage disk shares"},
173 };
174
175
176 /*
177   map a privilege id to the wire string constant
178 */
179 const char *sec_privilege_name(enum sec_privilege privilege)
180 {
181         int i;
182         for (i=0;i<ARRAY_SIZE(privilege_names);i++) {
183                 if (privilege_names[i].privilege == privilege) {
184                         return privilege_names[i].name;
185                 }
186         }
187         return NULL;
188 }
189
190 /*
191   map a privilege id to a privilege display name. Return NULL if not found
192   
193   TODO: this should use language mappings
194 */
195 const char *sec_privilege_display_name(enum sec_privilege privilege, uint16_t *language)
196 {
197         int i;
198         if (privilege < 1 || privilege > 64) {
199                 return NULL;
200         }
201         for (i=0;i<ARRAY_SIZE(privilege_names);i++) {
202                 if (privilege_names[i].privilege == privilege) {
203                         return privilege_names[i].display_name;
204                 }
205         }
206         return NULL;
207 }
208
209 /*
210   map a privilege name to a privilege id. Return -1 if not found
211 */
212 enum sec_privilege sec_privilege_id(const char *name)
213 {
214         int i;
215         for (i=0;i<ARRAY_SIZE(privilege_names);i++) {
216                 if (strcasecmp(privilege_names[i].name, name) == 0) {
217                         return privilege_names[i].privilege;
218                 }
219         }
220         return -1;
221 }
222
223 /*
224   map a privilege name to a privilege id. Return -1 if not found
225 */
226 enum sec_privilege sec_privilege_from_mask(uint64_t mask)
227 {
228         int i;
229         for (i=0;i<ARRAY_SIZE(privilege_names);i++) {
230                 if (privilege_names[i].privilege_mask == mask) {
231                         return privilege_names[i].privilege;
232                 }
233         }
234         return -1;
235 }
236
237
238 /*
239   return a privilege mask given a privilege id
240 */
241 static uint64_t sec_privilege_mask(enum sec_privilege privilege)
242 {
243         int i;
244         for (i=0;i<ARRAY_SIZE(privilege_names);i++) {
245                 if (privilege_names[i].privilege == privilege) {
246                         return privilege_names[i].privilege_mask;
247                 }
248         }
249
250         return 0;
251 }
252
253
254 /*
255   return true if a security_token has a particular privilege bit set
256 */
257 bool security_token_has_privilege(const struct security_token *token, enum sec_privilege privilege)
258 {
259         uint64_t mask;
260
261         mask = sec_privilege_mask(privilege);
262         if (mask == 0) {
263                 return false;
264         }
265
266         if (token->privilege_mask & mask) {
267                 return true;
268         }
269         return false;
270 }
271
272 /*
273   set a bit in the privilege mask
274 */
275 void security_token_set_privilege(struct security_token *token, enum sec_privilege privilege)
276 {
277         /* Relies on the fact that an invalid privilage will return 0, so won't change this */
278         token->privilege_mask |= sec_privilege_mask(privilege);
279 }
280
281 void security_token_debug_privileges(int dbg_lev, const struct security_token *token)
282 {
283         DEBUGADD(dbg_lev, (" Privileges (0x%16llX):\n",
284                             (unsigned long long) token->privilege_mask));
285
286         if (token->privilege_mask) {
287                 int i = 0;
288                 uint64_t mask;
289                 for (mask = 1; mask != 0; mask = mask << 1) {
290                         if (token->privilege_mask & mask) {
291                                 enum sec_privilege privilege = sec_privilege_from_mask(mask);
292                                 DEBUGADD(dbg_lev, ("  Privilege[%3lu]: %s\n", (unsigned long)i++, 
293                                         sec_privilege_name(privilege)));
294                         }
295                 }
296         }
297 }