Проблема с Popen, запущенным от имени другого пользователя (macOS) - PullRequest
0 голосов
/ 17 сентября 2018

У меня есть скрипт на python, который запускается на некоторых компьютерах Mac моим инструментом MDM. Это означает, что скрипт запускается от имени пользователя root. Есть часть скрипта, которую мне нужно запустить как зарегистрированный в данный момент локальный пользователь в учетной записи. Я нашел эту статью ниже для использования Popen, чтобы сделать это:

Запуск дочерних процессов от имени другого пользователя из продолжительного процесса

Тем не менее, я получаю сообщение об ошибке при попытке использовать этот метод на любых компьютерах с пред Mac OS 10.13. Это все еще современные версии ОС, такие как 10.12 и 10.11. Я не смог отследить эту ошибку. Пожалуйста, смотрите код ниже.

Примечание. Скорее всего, существуют некоторые дополнительные операторы импорта, так как они взяты из более крупного скрипта. Этот фрагмент должен работать как есть.

#!/usr/bin/python

import subprocess
import platform
import os
import pwd
import sys
import hashlib
import plistlib
import time
from SystemConfiguration import SCDynamicStoreCopyConsoleUser
from distutils.version import StrictVersion as SV

def getLoggedInUserUID():
    userUID = SCDynamicStoreCopyConsoleUser(None, None, None)[1]
    return userUID

def getLoggedInUsername():
    username = (SCDynamicStoreCopyConsoleUser(None, None, None) or [None])[0]; username = [username,""][username in [u"loginwindow", None, u""]]
    return username

def getLoggedInUserGID():
    username = getLoggedInUsername()
    pwRecord = pwd.getpwnam(username)
    userGID = pwRecord.pw_gid
    return userGID

def getLoggedInUserHomeDir():
    username = getLoggedInUsername()
    pwRecord = pwd.getpwnam(username)
    homeDir = pwRecord.pw_dir
    return homeDir

def demote():
    def result():
        os.setgid(getLoggedInUserGID())
        os.setuid(getLoggedInUserUID())
    return result

def setupEnvironment():
    environment = os.environ.copy()
    environment['HOME'] = str(getLoggedInUserHomeDir())
    environment['LOGNAME'] = str(getLoggedInUsername())
    environment['PWD'] = str(getLoggedInUserHomeDir())
    environment['USER'] = str(getLoggedInUsername())
    return environment

def launchCommand():
    command = ['echo', 'whoami']
    process = subprocess.Popen(command,
                               stdout=subprocess.PIPE,
                               preexec_fn=demote(),
                               cwd=str(getLoggedInUserHomeDir()),
                               env=setupEnvironment())

def main():
    launchCommand()

if __name__== "__main__":
    main()

Я получаю ошибку:

Traceback (most recent call last):
  File "testScript.py", line 60, in <module>
    main()
  File "testScript.py", line 57, in main
    launchCommand()
  File "testScript.py", line 54, in launchCommand
    env=setupEnvironment())
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 710, in __init__
    errread, errwrite)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1335, in _execute_child
    raise child_exception
KeyError: 'getpwnam(): name not found: '

Похоже, ему не хватает некоторого ключевого значения, но я не могу понять, что это такое. Любая помощь в отслеживании этого, чтобы я мог выполнить команду как зарегистрированный пользователь, очень помог бы.

Заранее спасибо, Ed

1 Ответ

0 голосов
/ 04 октября 2018

То, что я делал в своей небольшой управляемой среде mdm, выглядит следующим образом:

Я разработал маленькое окно без окон LoginItem helperApp, которое запускается при каждом открытом сеансе пользователя на Mac и прослушивает пользовательские уведомления распределенной системы.Он также имеет функцию для выполнения команд терминала без отображения окна терминала (Вы можете найти примеры для этого в stackowerflow).Я передаю всем приложениям, в настоящее время работающим в системе, два параметра в уведомлении: имя пользователя и строку команды терминала.Все пользователи, выполняющие экземпляры, получают уведомление, после чего они проверяют имя пользователя, если они запускаются от имени этого пользователя, а тот, который выполняет - выполняет команду с таким именем пользователя.

Попробуйте, если это соответствует вашим требованиям.

...