使用 Objective C 更新根 Crontab
Update Root Crontab with Objective C
考虑一个带有命令行应用程序的第三方 SDK,需要 运行 在 OSX 上作为 root。您在 Objective C 中构建了一个 Cocoa 应用程序,并将其安装在 "root:wheel"(用户:root,组:wheel)所有权下的 /Applications 中。我已经拥有 folder/file 所有权,因为我的安装程序应用程序使用 AppleScript 提示输入 root,然后为此执行 chown 和 chmod。
那么,Cocoa 应用程序更新 root 的 crontab 以便第三方命令行应用程序 运行s 在 root 上下文下的首选编程方式是什么?我的意思是,当我 运行 Cocoa 应用程序时,它是否在 root 下 运行 因为这是我在安装程序中设置文件所有权的方式?或者,Apple 是否以登录用户的身份启动它?如果应用程序 运行s 在根上下文下,那么我想普通文件 I/O 可以工作。如果,即使我安装了具有 root 所有权的 Cocoa 应用程序,它 运行s 作为登录笔记本电脑的用户,那么我需要以某种方式提升权限来执行该文件 I/O 作为根。而且我希望不必每次都提示访问钥匙串。
我创建了一个示例 OSX Cocoa 应用程序 (MyApp.app),它在 applicationDidFinishLaunching
class 方法中包含以下内容:
std::ofstream outfile;
outfile.open("/tmp/test.txt");
NSString *sUser = NSUserName();
outfile << "\n" << [sUser UTF8String] << "\n";
std::ofstream outfile2;
outfile2.open("/var/at/tabs/root");
outfile2 << "\n#DEMO";
然后我将它复制到 /Applications 并做了 chown -R root:wheel /Applications/MyApp.app
。
当我 运行 它时,/tmp/test.txt 说 "mike"(不是我希望的 root),并且 /var/at/tabs/root 文件没有附加“#DEMO ".
我想它没有权限,正如我所希望的那样。那么有什么诀窍可以让我的应用程序能够更新 /var/at/tabs/root 而无需每次都提示这样做,除非在安装期间可能有一次,或者,如果不可能的话,在应用程序的第一个 运行 之后安装?
Apple 推荐的使用您的代码执行此操作的方法是:
http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/
SMJobBless + XPC
它非常精致。你必须制作一个 XPC 服务,以你需要的权限安装它,以特殊的方式安装它,然后向它发送 XPC 消息,让它执行特权任务。它还涉及代码签名,以确保您 运行 与 XPC 服务通信的应用程序得到正确授权。
因此,XPC 服务将成为更新 /var/at/tabs/root 的服务。也就是说,除非您以另一种方式进行——XPC 服务会自行检查时钟以查看何时需要执行某些操作。
另一种方法是使用 SUID,尽管 Apple 不支持。
考虑一个带有命令行应用程序的第三方 SDK,需要 运行 在 OSX 上作为 root。您在 Objective C 中构建了一个 Cocoa 应用程序,并将其安装在 "root:wheel"(用户:root,组:wheel)所有权下的 /Applications 中。我已经拥有 folder/file 所有权,因为我的安装程序应用程序使用 AppleScript 提示输入 root,然后为此执行 chown 和 chmod。
那么,Cocoa 应用程序更新 root 的 crontab 以便第三方命令行应用程序 运行s 在 root 上下文下的首选编程方式是什么?我的意思是,当我 运行 Cocoa 应用程序时,它是否在 root 下 运行 因为这是我在安装程序中设置文件所有权的方式?或者,Apple 是否以登录用户的身份启动它?如果应用程序 运行s 在根上下文下,那么我想普通文件 I/O 可以工作。如果,即使我安装了具有 root 所有权的 Cocoa 应用程序,它 运行s 作为登录笔记本电脑的用户,那么我需要以某种方式提升权限来执行该文件 I/O 作为根。而且我希望不必每次都提示访问钥匙串。
我创建了一个示例 OSX Cocoa 应用程序 (MyApp.app),它在 applicationDidFinishLaunching
class 方法中包含以下内容:
std::ofstream outfile;
outfile.open("/tmp/test.txt");
NSString *sUser = NSUserName();
outfile << "\n" << [sUser UTF8String] << "\n";
std::ofstream outfile2;
outfile2.open("/var/at/tabs/root");
outfile2 << "\n#DEMO";
然后我将它复制到 /Applications 并做了 chown -R root:wheel /Applications/MyApp.app
。
当我 运行 它时,/tmp/test.txt 说 "mike"(不是我希望的 root),并且 /var/at/tabs/root 文件没有附加“#DEMO ".
我想它没有权限,正如我所希望的那样。那么有什么诀窍可以让我的应用程序能够更新 /var/at/tabs/root 而无需每次都提示这样做,除非在安装期间可能有一次,或者,如果不可能的话,在应用程序的第一个 运行 之后安装?
Apple 推荐的使用您的代码执行此操作的方法是:
http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/
SMJobBless + XPC
它非常精致。你必须制作一个 XPC 服务,以你需要的权限安装它,以特殊的方式安装它,然后向它发送 XPC 消息,让它执行特权任务。它还涉及代码签名,以确保您 运行 与 XPC 服务通信的应用程序得到正确授权。
因此,XPC 服务将成为更新 /var/at/tabs/root 的服务。也就是说,除非您以另一种方式进行——XPC 服务会自行检查时钟以查看何时需要执行某些操作。
另一种方法是使用 SUID,尽管 Apple 不支持。