mirror of
https://github.com/ksherlock/ample.git
synced 2024-06-01 01:41:31 +00:00
add button to set owner and +s permissions on the vmnet_helper app.
this relies on deprecated functionality yet it's the easiest way to do it. At some point, should try to move vmnet_helper to be a launchd service which is the preferred way to do rooty things.
This commit is contained in:
parent
0befba12a5
commit
e1a3d39021
|
@ -8,6 +8,7 @@
|
|||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="PreferencesWindowController">
|
||||
<connections>
|
||||
<outlet property="fixButton" destination="kt8-xs-My0" id="GeF-Kj-q2l"/>
|
||||
<outlet property="pathField" destination="Oz5-Xb-btk" id="EnV-kr-0XI"/>
|
||||
<outlet property="window" destination="QvC-M9-y7g" id="xJa-tx-X62"/>
|
||||
</connections>
|
||||
|
@ -33,8 +34,8 @@
|
|||
</textFieldCell>
|
||||
<connections>
|
||||
<action selector="pathChanged:" target="-2" id="RRj-dC-q2y"/>
|
||||
<binding destination="yvB-HG-64y" name="enabled" keyPath="values.UseCustomMame" id="iex-A9-Db6"/>
|
||||
<binding destination="yvB-HG-64y" name="value" keyPath="values.MamePath" id="H3O-1l-peo"/>
|
||||
<binding destination="yvB-HG-64y" name="enabled" keyPath="values.UseCustomMame" id="iex-A9-Db6"/>
|
||||
</connections>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Qmb-Ag-Xyr">
|
||||
|
@ -68,6 +69,17 @@
|
|||
<binding destination="yvB-HG-64y" name="value" keyPath="values.UseCustomMame" id="lH4-dm-kQC"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kt8-xs-My0">
|
||||
<rect key="frame" x="287" y="13" width="179" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Fix VMNet Permissions" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ifc-ID-wbu">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="fixPerms:" target="-2" id="0e2-yf-UgY"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="140" y="147"/>
|
||||
|
|
|
@ -9,8 +9,12 @@
|
|||
#import "Ample.h"
|
||||
#import "PreferencesWindowController.h"
|
||||
|
||||
#import <Security/Security.h>
|
||||
|
||||
|
||||
@interface PreferencesWindowController ()
|
||||
@property (weak) IBOutlet NSTextField *pathField;
|
||||
@property (weak) IBOutlet NSButton *fixButton;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -28,6 +32,10 @@
|
|||
|
||||
[self validateMamePath: [defaults stringForKey: kMamePath]];
|
||||
|
||||
/* check vmnet_helper permissions */
|
||||
|
||||
int needs_fixin = [self checkHelperPermissions: nil];
|
||||
[_fixButton setEnabled: needs_fixin > 0];
|
||||
}
|
||||
|
||||
-(void)validateMamePath: (NSString *)path {
|
||||
|
@ -48,5 +56,106 @@
|
|||
|
||||
}
|
||||
|
||||
// -1 - error
|
||||
// 1 - needs help
|
||||
// 0 - a-ok
|
||||
-(int)checkHelperPermissions: (NSString *)path {
|
||||
|
||||
static const unsigned Mask = S_ISUID | S_ISGID;
|
||||
if (!path) {
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
path = [bundle pathForAuxiliaryExecutable: @"vmnet_helper"];
|
||||
}
|
||||
if (!path) return -1;
|
||||
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
NSError *error = nil;
|
||||
NSDictionary *attr = [fm attributesOfItemAtPath: path error: &error];
|
||||
|
||||
if (error) return -1;
|
||||
|
||||
NSNumber *owner = [attr objectForKey: NSFileOwnerAccountID];
|
||||
NSNumber *perm = [attr objectForKey: NSFilePosixPermissions];
|
||||
if ([owner longValue] == 0 && ([perm unsignedIntValue] & Mask) == Mask) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (IBAction)fixPerms:(id)sender {
|
||||
|
||||
NSBundle *bundle = [NSBundle mainBundle];
|
||||
NSString *path = [bundle pathForAuxiliaryExecutable: @"vmnet_helper"];
|
||||
if (!path) return;
|
||||
|
||||
|
||||
#if 0
|
||||
// this requires an entitlement and sanboxing and Apple's permission.
|
||||
NSWorkspace *ws = [NSWorkspace sharedWorkspace];
|
||||
|
||||
[ws requestAuthorizationOfType:NSWorkspaceAuthorizationTypeSetAttributes
|
||||
completionHandler: ^(NSWorkspaceAuthorization *a, NSError *e){
|
||||
if (e || !a) return;
|
||||
|
||||
NSError *error = nil;
|
||||
NSDictionary *attr = @{
|
||||
NSFileOwnerAccountID: @0, /* root */
|
||||
NSFileGroupOwnerAccountID: @20, /* staff */
|
||||
// NSFilePosixPermissions: @0106755 /* 755 + setuid + setgid */
|
||||
};
|
||||
|
||||
|
||||
|
||||
NSFileManager *fm = [NSFileManager fileManagerWithAuthorization: a];
|
||||
[fm setAttributes: attr ofItemAtPath: path error: &error];
|
||||
if (error) {
|
||||
NSLog(@"%@", error);
|
||||
// NSAlert *a = [NSAlert alertWithError: error];
|
||||
// [a runModal];
|
||||
}
|
||||
else {
|
||||
[self->_fixButton setEnabled: NO];
|
||||
}
|
||||
|
||||
}];
|
||||
#endif
|
||||
|
||||
// AuthorizationExecuteWithPrivileges - deprecated in 10.7
|
||||
// https://github.com/sveinbjornt/STPrivilegedTask
|
||||
// XMJobBless + launchd stuff - the preferred way to do it...
|
||||
// https://developer.apple.com/library/archive/samplecode/BetterAuthorizationSample/Introduction/Intro.html
|
||||
// https://developer.apple.com/library/archive/samplecode/SMJobBless/Listings/ReadMe_txt.html#//apple_ref/doc/uid/DTS40010071-ReadMe_txt-DontLinkElementID_3
|
||||
//
|
||||
// really should be a launchd service but that's for another time...
|
||||
|
||||
AuthorizationRef myAuthorizationRef = 0;
|
||||
OSStatus myStatus = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &myAuthorizationRef);
|
||||
if (myStatus) return;
|
||||
|
||||
AuthorizationItem myItems[1] = {{0}};
|
||||
myItems[0].name = kAuthorizationRightExecute;
|
||||
myItems[0].valueLength = 0;
|
||||
myItems[0].value = NULL;
|
||||
myItems[0].flags = 0;
|
||||
AuthorizationRights myRights = {0};
|
||||
myRights.count = sizeof(myItems) / sizeof(myItems[0]);
|
||||
myRights.items = myItems;
|
||||
AuthorizationFlags myFlags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed |
|
||||
kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize;
|
||||
myStatus = AuthorizationCopyRights(myAuthorizationRef, &myRights,
|
||||
kAuthorizationEmptyEnvironment, myFlags, NULL);
|
||||
|
||||
if (!myStatus) {
|
||||
const char *cp = [path fileSystemRepresentation];
|
||||
const char* args_chown[] = {"root", cp , NULL};
|
||||
const char* args_chmod[] = {"+s", cp, NULL};
|
||||
myStatus = AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/usr/sbin/chown", kAuthorizationFlagDefaults, (char**)args_chown, NULL);
|
||||
myStatus = AuthorizationExecuteWithPrivileges(myAuthorizationRef, "/bin/chmod", kAuthorizationFlagDefaults, (char**)args_chmod, NULL);
|
||||
|
||||
}
|
||||
AuthorizationFree(myAuthorizationRef, kAuthorizationFlagDestroyRights);
|
||||
|
||||
int needs_fixin = [self checkHelperPermissions: path];
|
||||
[_fixButton setEnabled: needs_fixin > 0];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in New Issue
Block a user