Is it possible to run pluginkit from a process running as root?

99封情书 提交于 2019-12-08 03:55:02

问题


I'm trying to run pluginkit (The executable that manages extensions on OS X) from a launch daemon running as root.

/usr/bin/pluginkit -m -i "<identifier>" fails with an output of match: Connection invalid. This is not terribly unexpected, since extension settings are handled on a per-user basis.

However, I've tried to use su to run pluginkit as a normal user, and it still doesn't work.

su <username> -l -c "/usr/bin/pluginkit -m -i "<identifier>" also fails with an output of match: Connection invalid.

Somehow the environment that pluginkit is running in is still different enough from a normal user that it doesn't work properly. Is there anyway to run pluginkit as root? Or is there any other way to launch a process as another user that might provide a more complete environment?

I'm testing this with a command line tool written in Swift:

main.swift

import Foundation

let task = NSTask()

// Option 1: Run pluginkit directly
task.launchPath="/usr/bin/pluginkit"
task.arguments = ["-m", "-i", "com.example.findersyncext"]

// Option 2: Run pluginkit as <username> using 'su'
//task.launchPath="/usr/bin/su"
//task.arguments = ["<username>", "-l", "-c", "/usr/bin/pluginkit -m -i \"com.example.findersyncext\""]

// Option 3: Run pluginkit as <username> using 'sudo'
//task.launchPath="/usr/bin/sudo"
//task.arguments = ["-u", "<username>", "/usr/bin/pluginkit", "-m", "-i", "com.example.findersyncext"]

task.standardOutput = NSPipe()
task.standardError = NSPipe()
task.launch()
task.waitUntilExit()

NSLog("Exit code: \(task.terminationStatus)")
let output = NSString(data: (task.standardOutput!.fileHandleForReading.readDataToEndOfFile()), encoding: NSUTF8StringEncoding)
NSLog("Output: \(output)")

let error = NSString(data: (task.standardError!.fileHandleForReading.readDataToEndOfFile()), encoding: NSUTF8StringEncoding)
NSLog("Error: \(error)")

/Library/LaunchDaemons/com.example.PluginKitTest.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>com.example.PluginKitTest</string>
    <key>Program</key>
    <string>/path/to/PluginKitTest</string>
    <key>RunAtLoad</key>
    <true/>
    <key>StandardErrorPath</key>
    <string>/Users/<username>/Desktop/pluginkit-error.log</string>
    <key>StandardOutPath</key>
    <string>/Users/<username>/Desktop/pluginkit-out.log</string>
</dict>
</plist>

回答1:


It turns out that there is additional user context that is not set by the su command, that needs to be set by using the command launchctl asuser. So, I was able to solve my problem by updating my command to invoke both launchctl asuser and su to update all aspects of the context:

launchctl asuser $USER_UID su $USER_UID -c "<command>"

According to the documentation of launchctl asuser:

Adopted attributes include the Mach bootstrap namespace, exception server and security audit session.

I'm not familiar enough with these concepts to tell you exactly what these do, but it was enough to get pluginkit working.



来源:https://stackoverflow.com/questions/38706735/is-it-possible-to-run-pluginkit-from-a-process-running-as-root

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!