213:ユーザID・グループIDを切り替える
スーパーユーザから一般ユーザに切り替える
スーパーユーザが一時的に一般ユーザとなって作業を行うには os.seteuid を用います。 元の値を保持しておいて、再度設定することでスーパーユーザに戻ることができます。 永続的に一般ユーザになるには os.setuid を用います。 引数にはユーザ ID を与えます。 ID の確認方法は 212:ユーザやグループに関する情報を得る を参照してください。
>>> import os >>> ruid = os.geteuid() >>> os.seteuid(1000) >>> >>> os.setuid(ruid)
グループ ID を切り替える
一時的にグループを変更し os.setegid を、永続的に行うには os.setgid を用います。
>>> import os >>> rgid = os.getegid() >>> os.setegid(1000) >>> >>> os.setegid(rgid)
一時的にユーザー・グループに切り替えて、確実に元に戻すには
try, finally を用います。
ruid = os.geteuid()
os.seteuid(1000)
try:
print os.geteuid() # 一般ユーザー権限で行う処理
finally:
os.seteuid(ruid)
次の SwitchEuid? のようなコンテキストマネージャを用いる方法もあります (Python 2.5 以降限定。 Python 2.5 の場合、さらに from future import with_statement が必要)。
import os
class SwitchEuid():
def __init__(self, id):
self.id = id
def __enter__(self):
self.ruid = os.geteuid()
os.seteuid(self.id)
def __exit__(self, exc_type, exc_value, traceback):
os.seteuid(self.ruid)
if exc_type:
return False
return True
これは with 文にて次のように用います。
print os.geteuid()
with SwitchEuid(1000):
print os.geteuid()
print os.geteuid()
関数単位の処理ならば次の switch_euid のようなデコレータを用いるという方法もあります(Python 2.4 以降限定)。
import os
import functools
def switch_euid(euid):
def wrapper(func):
@functools.wraps(func)
def _(*args, **kwargs):
ruid = os.geteuid()
os.seteuid(euid)
try:
return func(*args, **kwargs)
finally:
os.seteuid(ruid)
return _
return wrapper
デコレータは次のように使います。
@switch_euid(1000)
def test():
print os.geteuid()
def main():
print os.geteuid()
test()
print os.geteuid()
if __name__ == '__main__':
main()