1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
# vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=python:textwidth=0:
# License: GPL2 or later see COPYING
# Written by Michael Brown
# Copyright (C) 2007 Michael E Brown <mebrown@michaels-house.net>
# python library imports
import logging
import os
# our imports
from mock.trace_decorator import traceLog
# set up logging
log = logging.getLogger("mock.uid")
# class
class uidManager(object):
@traceLog(log)
def __init__(self, unprivUid=-1, unprivGid=-1):
self.privStack = []
self.unprivUid = unprivUid
self.unprivGid = unprivGid
@traceLog(log)
def becomeUser(self, uid, gid=-1):
# save current ruid, euid, rgid, egid
self._push()
self._becomeUser(uid, gid)
@traceLog(log)
def dropPrivsTemp(self):
# save current ruid, euid, rgid, egid
self._push()
self._becomeUser(self.unprivUid, self.unprivGid)
@traceLog(log)
def restorePrivs(self):
# back to root first
self._elevatePrivs()
# then set saved
privs = self.privStack.pop()
os.setregid(privs['rgid'], privs['egid'])
setresuid(privs['ruid'], privs['euid'])
@traceLog(log)
def dropPrivsForever(self):
self._elevatePrivs()
os.setregid(self.unprivGid, self.unprivGid)
os.setreuid(self.unprivUid, self.unprivUid)
@traceLog(log)
def _push(self):
# save current ruid, euid, rgid, egid
self.privStack.append({
"ruid": os.getuid(),
"euid": os.geteuid(),
"rgid": os.getgid(),
"egid": os.getegid(),
})
@traceLog(log)
def _elevatePrivs(self):
setresuid(0, 0, 0)
os.setregid(0, 0)
@traceLog(log)
def _becomeUser(self, uid, gid=None):
self._elevatePrivs()
if gid is not None:
os.setregid(gid, gid)
setresuid(uid, uid, 0)
# python doesnt have native versions of these. :(
import ctypes
import errno
_libc = ctypes.cdll.LoadLibrary("libc.so.6")
_errno = ctypes.c_int.in_dll(_libc, "errno")
def getresuid():
ruid = ctypes.c_long()
euid = ctypes.c_long()
suid = ctypes.c_long()
res = _libc.getresuid(ctypes.byref(ruid), ctypes.byref(euid), ctypes.byref(suid))
if res:
raise OSError(_errno.value, os.strerror(_errno.value))
return (ruid.value, euid.value, suid.value)
def setresuid(ruid=-1, euid=-1, suid=-1):
ruid = ctypes.c_long(ruid)
euid = ctypes.c_long(euid)
suid = ctypes.c_long(suid)
res = _libc.setresuid(ruid, euid, suid)
if res:
raise OSError(_errno.value, os.strerror(_errno.value))
def getresgid():
rgid = ctypes.c_long()
egid = ctypes.c_long()
sgid = ctypes.c_long()
res = _libc.getresgid(ctypes.byref(rgid), ctypes.byref(egid), ctypes.byref(sgid))
if res:
raise OSError(_errno.value, os.strerror(_errno.value))
return (rgid.value, egid.value, sgid.value)
def setresgid(rgid=-1, egid=-1, sgid=-1):
rgid = ctypes.c_long(rgid)
egid = ctypes.c_long(egid)
sgid = ctypes.c_long(sgid)
res = _libc.setresgid(rgid, egid, sgid)
if res:
raise OSError(_errno.value, os.strerror(_errno.value))
|