0
# Privilege Elevation
1
2
Cross-platform privilege elevation functionality supporting UAC on Windows and sudo on Unix systems. Compatible with various Python packaging formats including CPython, Nuitka, PyInstaller, and frozen executables.
3
4
## Capabilities
5
6
### Main Elevation Function
7
8
Automatically elevates privileges and executes functions with administrative rights, handling platform detection and execution environment detection transparently.
9
10
```python { .api }
11
def elevate(callable_function, *args, **kwargs):
12
"""
13
Elevate privileges and execute function with administrative rights.
14
15
Automatically detects the current platform and execution environment (CPython,
16
Nuitka, PyInstaller, etc.) and uses the appropriate elevation method. On Windows,
17
triggers UAC prompt and re-executes with administrative privileges. On Unix systems,
18
uses sudo to gain root privileges. Exits the current process after elevation.
19
20
Args:
21
callable_function: Function to execute with elevated privileges
22
*args: Positional arguments to pass to the function
23
**kwargs: Keyword arguments to pass to the function
24
25
Returns:
26
Does not return - calls sys.exit() with child process exit code
27
28
Raises:
29
SystemExit: Always exits after elevation attempt
30
EnvironmentError: If platform is unsupported or elevation unavailable
31
32
Examples:
33
Simple elevation:
34
>>> def admin_task():
35
... print("Running with admin privileges")
36
... # Perform administrative operations
37
>>>
38
>>> if __name__ == '__main__':
39
... elevate(admin_task)
40
41
Elevation with arguments:
42
>>> def install_service(service_name, service_path):
43
... # Install system service with admin rights
44
... pass
45
>>>
46
>>> if __name__ == '__main__':
47
... elevate(install_service, "MyService", "/opt/myapp/service")
48
49
Conditional elevation:
50
>>> def main():
51
... if not is_admin():
52
... print("Requesting administrator privileges...")
53
... elevate(main)
54
... else:
55
... print("Running with admin privileges")
56
... # Perform administrative tasks
57
>>>
58
>>> if __name__ == '__main__':
59
... main()
60
61
Platform Behavior:
62
Windows: Triggers UAC elevation dialog, re-executes script with elevated token
63
Unix/Linux: Uses sudo to re-execute script with root privileges
64
macOS: Uses sudo with appropriate path handling
65
66
Execution Environment Support:
67
CPython: Re-executes Python interpreter with script
68
Nuitka: Re-executes compiled binary
69
PyInstaller: Re-executes frozen executable
70
cx_freeze: Re-executes frozen executable
71
py2exe: Re-executes frozen executable
72
73
Security Notes:
74
- Always validates elevation success before performing privileged operations
75
- Preserves command-line arguments across elevation
76
- Handles quoted arguments correctly to prevent injection attacks
77
- Uses absolute paths to prevent PATH-based attacks
78
"""
79
```
80
81
### Privilege Detection
82
83
Check current privilege level to determine if elevation is needed.
84
85
```python { .api }
86
def is_admin():
87
"""
88
Check if current process has administrative privileges.
89
90
Tests whether the current process is running with administrative/root privileges
91
using platform-appropriate methods. Does not require external dependencies.
92
93
Returns:
94
bool: True if process has administrative privileges, False otherwise
95
96
Raises:
97
EnvironmentError: If platform is unsupported for privilege detection
98
99
Examples:
100
Check before privileged operations:
101
>>> if is_admin():
102
... print("Already running as administrator")
103
... perform_admin_tasks()
104
... else:
105
... print("Need to elevate privileges")
106
... elevate(perform_admin_tasks)
107
108
Conditional feature availability:
109
>>> def get_available_features():
110
... features = ['basic_features']
111
... if is_admin():
112
... features.extend(['admin_features', 'system_config'])
113
... return features
114
115
Platform Implementation:
116
Windows: Uses IsUserAnAdmin() from win32com.shell.shell
117
Unix/Linux: Checks if os.getuid() == 0 (root user)
118
macOS: Uses Unix method (root user check)
119
120
Performance Notes:
121
- Fast check using native platform APIs
122
- No network or file system access required
123
- Safe to call frequently without performance impact
124
"""
125
```
126
127
### Utility Functions
128
129
Helper functions for elevation system implementation and debugging.
130
131
```python { .api }
132
def get_absolute_path(executable):
133
"""
134
Find absolute path of executable in system PATH.
135
136
Searches for the specified executable in system PATH directories and returns
137
the absolute path. Used internally for finding sudo on Unix systems and
138
available as a public utility function.
139
140
Args:
141
executable (str): Name of executable to find (e.g., "sudo", "python")
142
143
Returns:
144
str: Absolute path to executable, or None if not found
145
146
Examples:
147
Find sudo executable:
148
>>> from command_runner.elevate import get_absolute_path
149
>>> sudo_path = get_absolute_path("sudo")
150
>>> if sudo_path:
151
... print(f"sudo found at: {sudo_path}")
152
... else:
153
... print("sudo not found in PATH")
154
155
Find Python interpreter:
156
>>> python_path = get_absolute_path("python3")
157
>>> print(f"Python 3 location: {python_path}")
158
159
Verify tool availability:
160
>>> if get_absolute_path("docker"):
161
... print("Docker is available")
162
... else:
163
... print("Docker not found in PATH")
164
165
Implementation:
166
Uses command_runner to execute 'type -p' command for reliable path detection
167
Falls back to PATH environment variable parsing on failure
168
Validates file existence before returning path
169
Cross-platform compatible (Windows uses semicolon, Unix uses colon PATH separator)
170
"""
171
```
172
173
## Platform-Specific Implementation Details
174
175
### Windows UAC Elevation
176
177
Windows elevation uses the ShellExecuteEx API with the "runas" verb to trigger UAC:
178
179
```python
180
# Internal Windows elevation process
181
def _windows_runner(runner, arguments):
182
"""
183
Execute elevated process on Windows using UAC.
184
185
Uses ShellExecuteEx with runas verb to trigger User Account Control
186
elevation dialog. Waits for child process completion and returns exit code.
187
"""
188
```
189
190
**Windows Dependencies:**
191
- `win32event`: Process monitoring
192
- `win32process`: Process management
193
- `win32com.shell.shell`: UAC elevation APIs
194
195
**Windows Behavior:**
196
- Displays UAC elevation prompt to user
197
- Re-executes current script/executable with elevated token
198
- Preserves command-line arguments with proper quoting
199
- Waits for elevated process completion
200
- Returns child process exit code
201
202
### Unix Sudo Elevation
203
204
Unix elevation uses sudo to re-execute the current script with root privileges:
205
206
```python
207
# Internal Unix elevation process
208
def _check_environment():
209
"""
210
Determine current execution environment and build re-execution command.
211
212
Detects whether running under CPython, Nuitka, PyInstaller, or other
213
packaging system and constructs appropriate sudo command.
214
"""
215
```
216
217
**Unix Dependencies:**
218
- `sudo`: Must be available in system PATH
219
- Standard Unix process APIs
220
221
**Unix Behavior:**
222
- Locates sudo executable in PATH
223
- Prompts for password if required
224
- Re-executes current script/binary with root privileges
225
- Passes through all command-line arguments
226
- Returns child process exit code
227
228
## Execution Environment Detection
229
230
The elevation system automatically detects various Python execution environments:
231
232
### CPython Detection
233
- Standard Python interpreter execution
234
- Re-executes: `python script.py args...`
235
236
### Nuitka Detection
237
- Detects `__compiled__` global variable
238
- Re-executes compiled binary directly
239
- Handles both standalone and non-standalone modes
240
241
### Frozen Executable Detection
242
- Detects `sys.frozen` attribute (PyInstaller, cx_freeze, py2exe)
243
- Re-executes frozen executable directly
244
- Preserves executable path and arguments
245
246
### Environment Detection Matrix
247
248
| Environment | Detection Method | Re-execution Command |
249
|-------------|------------------|---------------------|
250
| CPython | Default case | `python script.py args` |
251
| Nuitka | `__compiled__` in globals | `./compiled_binary args` |
252
| PyInstaller | `sys.frozen == True` | `./frozen_exe args` |
253
| cx_freeze | `sys.frozen == True` | `./frozen_exe args` |
254
| py2exe | `sys.frozen == True` | `./frozen_exe args` |
255
256
## Security Considerations
257
258
### Input Validation
259
- All arguments are properly quoted to prevent injection attacks
260
- Absolute paths used to prevent PATH manipulation
261
- Command construction uses safe string joining methods
262
263
### Privilege Validation
264
- Always check elevation success with `is_admin()` after elevation
265
- Don't assume elevation succeeded without verification
266
- Implement appropriate error handling for elevation failures
267
268
### Best Practices
269
270
```python
271
def secure_admin_operation():
272
"""Example of secure privilege elevation pattern."""
273
274
# Check if already elevated
275
if is_admin():
276
perform_privileged_operation()
277
return
278
279
# Request elevation
280
print("This operation requires administrator privileges.")
281
try:
282
elevate(secure_admin_operation)
283
except Exception as e:
284
print(f"Elevation failed: {e}")
285
return
286
287
def perform_privileged_operation():
288
"""Perform operation that requires admin rights."""
289
290
# Verify elevation succeeded
291
if not is_admin():
292
raise PermissionError("Operation requires administrator privileges")
293
294
# Proceed with privileged operations
295
print("Performing administrative task...")
296
```
297
298
## Error Handling
299
300
### Common Elevation Scenarios
301
302
**User Cancels UAC (Windows):**
303
- UAC dialog cancelled by user
304
- Returns exit code 1223 (ERROR_CANCELLED)
305
- Handle gracefully in calling code
306
307
**Sudo Password Cancelled (Unix):**
308
- User cancels sudo password prompt
309
- Returns non-zero exit code
310
- May indicate authentication failure
311
312
**Missing Dependencies:**
313
- Windows: Missing win32 modules
314
- Unix: sudo not installed or in PATH
315
- Graceful degradation with informative error messages
316
317
### Exception Handling Pattern
318
319
```python
320
import sys
321
from command_runner.elevate import elevate, is_admin
322
323
def main():
324
try:
325
if not is_admin():
326
print("Requesting elevation...")
327
elevate(main)
328
else:
329
print("Running with privileges")
330
# Perform administrative operations
331
except EnvironmentError as e:
332
print(f"Platform not supported: {e}")
333
sys.exit(1)
334
except Exception as e:
335
print(f"Elevation failed: {e}")
336
sys.exit(1)
337
338
if __name__ == '__main__':
339
main()
340
```