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 27static const struct { 28 enum sec_privilege privilege; 29 const char *name; 30 const char *display_name; 31} privilege_names[] = { 32 {SEC_PRIV_SECURITY, 33 "SeSecurityPrivilege", 34 "System security"}, 35 36 {SEC_PRIV_BACKUP, 37 "SeBackupPrivilege", 38 "Backup files and directories"}, 39 40 {SEC_PRIV_RESTORE, 41 "SeRestorePrivilege", 42 "Restore files and directories"}, 43 44 {SEC_PRIV_SYSTEMTIME, 45 "SeSystemtimePrivilege", 46 "Set the system clock"}, 47 48 {SEC_PRIV_SHUTDOWN, 49 "SeShutdownPrivilege", 50 "Shutdown the system"}, 51 52 {SEC_PRIV_REMOTE_SHUTDOWN, 53 "SeRemoteShutdownPrivilege", 54 "Shutdown the system remotely"}, 55 56 {SEC_PRIV_TAKE_OWNERSHIP, 57 "SeTakeOwnershipPrivilege", 58 "Take ownership of files and directories"}, 59 60 {SEC_PRIV_DEBUG, 61 "SeDebugPrivilege", 62 "Debug processes"}, 63 64 {SEC_PRIV_SYSTEM_ENVIRONMENT, 65 "SeSystemEnvironmentPrivilege", 66 "Modify system environment"}, 67 68 {SEC_PRIV_SYSTEM_PROFILE, 69 "SeSystemProfilePrivilege", 70 "Profile the system"}, 71 72 {SEC_PRIV_PROFILE_SINGLE_PROCESS, 73 "SeProfileSingleProcessPrivilege", 74 "Profile one process"}, 75 76 {SEC_PRIV_INCREASE_BASE_PRIORITY, 77 "SeIncreaseBasePriorityPrivilege", 78 "Increase base priority"}, 79 80 {SEC_PRIV_LOAD_DRIVER, 81 "SeLoadDriverPrivilege", 82 "Load drivers"}, 83 84 {SEC_PRIV_CREATE_PAGEFILE, 85 "SeCreatePagefilePrivilege", 86 "Create page files"}, 87 88 {SEC_PRIV_INCREASE_QUOTA, 89 "SeIncreaseQuotaPrivilege", 90 "Increase quota"}, 91 92 {SEC_PRIV_CHANGE_NOTIFY, 93 "SeChangeNotifyPrivilege", 94 "Register for change notify"}, 95 96 {SEC_PRIV_UNDOCK, 97 "SeUndockPrivilege", 98 "Undock devices"}, 99 100 {SEC_PRIV_MANAGE_VOLUME, 101 "SeManageVolumePrivilege", 102 "Manage system volumes"}, 103 104 {SEC_PRIV_IMPERSONATE, 105 "SeImpersonatePrivilege", 106 "Impersonate users"}, 107 108 {SEC_PRIV_CREATE_GLOBAL, 109 "SeCreateGlobalPrivilege", 110 "Create global"}, 111 112 {SEC_PRIV_ENABLE_DELEGATION, 113 "SeEnableDelegationPrivilege", 114 "Enable Delegation"}, 115 116 {SEC_PRIV_INTERACTIVE_LOGON, 117 "SeInteractiveLogonRight", 118 "Interactive logon"}, 119 120 {SEC_PRIV_NETWORK_LOGON, 121 "SeNetworkLogonRight", 122 "Network logon"}, 123 124 {SEC_PRIV_REMOTE_INTERACTIVE_LOGON, 125 "SeRemoteInteractiveLogonRight", 126 "Remote Interactive logon"}, 127 128 {SEC_PRIV_MACHINE_ACCOUNT, 129 "SeMachineAccountPrivilege", 130 "Add workstations to domain"} 131}; 132 133 134/* 135 map a privilege id to the wire string constant 136*/ 137const char *sec_privilege_name(enum sec_privilege privilege) 138{ 139 int i; 140 for (i=0;i<ARRAY_SIZE(privilege_names);i++) { 141 if (privilege_names[i].privilege == privilege) { 142 return privilege_names[i].name; 143 } 144 } 145 return NULL; 146} 147 148/* 149 map a privilege id to a privilege display name. Return NULL if not found 150 151 TODO: this should use language mappings 152*/ 153const char *sec_privilege_display_name(enum sec_privilege privilege, uint16_t *language) 154{ 155 int i; 156 if (privilege < 1 || privilege > 64) { 157 return NULL; 158 } 159 for (i=0;i<ARRAY_SIZE(privilege_names);i++) { 160 if (privilege_names[i].privilege == privilege) { 161 return privilege_names[i].display_name; 162 } 163 } 164 return NULL; 165} 166 167/* 168 map a privilege name to a privilege id. Return -1 if not found 169*/ 170enum sec_privilege sec_privilege_id(const char *name) 171{ 172 int i; 173 for (i=0;i<ARRAY_SIZE(privilege_names);i++) { 174 if (strcasecmp(privilege_names[i].name, name) == 0) { 175 return privilege_names[i].privilege; 176 } 177 } 178 return -1; 179} 180 181 182/* 183 return a privilege mask given a privilege id 184*/ 185static uint64_t sec_privilege_mask(enum sec_privilege privilege) 186{ 187 uint64_t mask = 1; 188 189 if (privilege < 1 || privilege > 64) { 190 return 0; 191 } 192 193 mask <<= (privilege-1); 194 return mask; 195} 196 197 198/* 199 return true if a security_token has a particular privilege bit set 200*/ 201bool security_token_has_privilege(const struct security_token *token, enum sec_privilege privilege) 202{ 203 uint64_t mask; 204 205 if (privilege < 1 || privilege > 64) { 206 return false; 207 } 208 209 mask = sec_privilege_mask(privilege); 210 if (token->privilege_mask & mask) { 211 return true; 212 } 213 return false; 214} 215 216/* 217 set a bit in the privilege mask 218*/ 219void security_token_set_privilege(struct security_token *token, enum sec_privilege privilege) 220{ 221 if (privilege < 1 || privilege > 64) { 222 return; 223 } 224 token->privilege_mask |= sec_privilege_mask(privilege); 225} 226 227void security_token_debug_privileges(int dbg_lev, const struct security_token *token) 228{ 229 DEBUGADD(dbg_lev, (" Privileges (0x%16llX):\n", 230 (unsigned long long) token->privilege_mask)); 231 232 if (token->privilege_mask) { 233 int i = 0; 234 uint_t privilege; 235 236 for (privilege = 1; privilege <= 64; privilege++) { 237 uint64_t mask = sec_privilege_mask(privilege); 238 239 if (token->privilege_mask & mask) { 240 DEBUGADD(dbg_lev, (" Privilege[%3lu]: %s\n", (unsigned long)i++, 241 sec_privilege_name(privilege))); 242 } 243 } 244 } 245} 246