как использовать polkit с python для запуска команд systemd d-bus от пользователя без полномочий root?

Я очень новичок в услугах d-bus. У меня есть скрипт, который останавливает указанную службу. Но его нужно запускать от имени root.

У меня есть пользователь, у которого есть права запускать любую команду без пароля с помощью sudoers. Мой вопрос: как я могу использовать свои привилегии sudoers для расширения возможностей пользователя, не запуская этот скрипт с помощью sudo? Полкит может быть полезен?

edit: Теперь я могу запустить скрипт с помощью polkit. Но все равно просит пароль.

import dbus
import subprocess
import os
import sys
import time

SYSTEMD_BUSNAME = 'org.freedesktop.systemd1'
SYSTEMD_PATH = '/org/freedesktop/systemd1'
SYSTEMD_MANAGER_INTERFACE = 'org.freedesktop.systemd1.Manager'
SYSTEMD_UNIT_INTERFACE = 'org.freedesktop.systemd1.Unit'

bus = dbus.SystemBus()

proxy = bus.get_object('org.freedesktop.PolicyKit1', '/org/freedesktop/PolicyKit1/Authority')
authority = dbus.Interface(proxy, dbus_interface='org.freedesktop.PolicyKit1.Authority')
system_bus_name = bus.get_unique_name()

subject = ('system-bus-name', {'name' : system_bus_name})
action_id = 'org.freedesktop.systemd1.manage-units'
details = {}
flags = 1            # AllowUserInteraction flag
cancellation_id = '' # No cancellation id

result = authority.CheckAuthorization(subject, action_id, details, flags, cancellation_id)

print result

systemd_object = bus.get_object(SYSTEMD_BUSNAME, SYSTEMD_PATH)
systemd_manager = dbus.Interface(systemd_object, SYSTEMD_MANAGER_INTERFACE)

unit = systemd_manager.GetUnit('cups.service')
unit_object = bus.get_object(SYSTEMD_BUSNAME, unit)
#unit_interface = dbus.Interface(unit_object, SYSTEMD_UNIT_INTERFACE)

#unit_interface.Stop('replace')
systemd_manager.StopUnit('cups.service', 'replace')

while list(systemd_manager.ListJobs()):
    time.sleep(2)
    print 'there are pending jobs, lets wait for them to finish.'

prop_unit = dbus.Interface(unit_object, 'org.freedesktop.DBus.Properties')

active_state = prop_unit.Get('org.freedesktop.systemd1.Unit', 'ActiveState')

sub_state = prop_unit.Get('org.freedesktop.systemd1.Unit', 'SubState')

print active_state, sub_state

person Arindam Choudhury    schedule 01.09.2015    source источник


Ответы (1)


Добавление правила в /etc/polkit-1/rules.d/ решило проблему:

cat 60-wheel.rules 

polkit.addRule(function(action, subject) {
    if (action.id == "org.freedesktop.systemd1.manage-units" &&
        subject.isInGroup("wheel")) {
        return polkit.Result.YES;
    } });
person Arindam Choudhury    schedule 02.09.2015