5 // Created by Claudio on 28/06/07.
11 #include <Security/Authorization.h>
12 #include <Security/AuthorizationTags.h>
13 #include <sys/param.h>
16 #include <sys/types.h>
17 #include <sys/fcntl.h>
18 #include <sys/errno.h>
23 #include <sys/event.h>
24 #include <mach-o/dyld.h>
27 #import "PListManager.h"
29 #define AFS_DAEMON_STARTUPSCRIPT "/Library/OpenAFS/Tools/root.client/usr/vice/etc/afs.rc"
30 #define AFS_DAEMON_PATH "/Library/LaunchDaemons/org.openafs.filesystems.afs.plist"
32 void stopAfs(int argc, char *argv[]);
33 void getPath(char **selfPathPtr);
34 void selfRepair(char *selfPath);
35 void runWithSelfRepair(char *selfPath,int argc, char *argv[]);
36 void runCommand(int argc, char *argv[]);
38 int main(int argc, char *argv[])
40 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
43 NSLog(@"num of arguments %d", argc);
44 int status = [[AuthUtil shared] autorize];
45 if(status != noErr) exit(-1);
47 // Get the path to the tool's executable
50 //selfRepair(selfPath);
51 // All done with the executable path
52 if(selfPath) free(selfPath);
54 // Now do the real work of running the command.
55 runCommand(argc, argv);
56 [[AuthUtil shared] deautorize];
63 void runCommand(int argc, char *argv[])
66 NSString *cmdString = [NSString stringWithCString:(const char *)argv[1] encoding:NSUTF8StringEncoding];
68 if(argc == 2 && [cmdString rangeOfString:@"stop_afs"].location!=NSNotFound ){
69 NSLog(@"Stop afs from helper");
70 const char *stopArgs[] = {"stop", 0L};
71 [[AuthUtil shared] execUnixCommand:AFS_DAEMON_STARTUPSCRIPT
75 } else if(argc == 2 && [cmdString rangeOfString:@"start_afs"].location!=NSNotFound){
76 NSLog(@"Start afs from helper");
77 const char *startArgs[] = {"start", 0L};
78 [[AuthUtil shared] execUnixCommand:AFS_DAEMON_STARTUPSCRIPT
82 } else if(argc == 4 && [cmdString rangeOfString:@"enable_krb5_startup"].location!=NSNotFound) {
83 NSLog(@"Manage KRB5 at login time with option %s from helper", argv[2]);
84 int arg2 = atoi(argv[2]);
85 [PListManager krb5TiketAtLoginTime:[[NSNumber numberWithInt:arg2] boolValue]];
86 } else if(argc == 3 && [cmdString rangeOfString:@"start_afs_at_startup"].location!=NSNotFound){
87 BOOL enable = strcmp("enable", argv[2])==0;
88 NSLog(@"Manage start_afs_at_startup with option %s from helper", argv[2]);
89 [PListManager launchctlStringCommand:enable?@"load":@"unload"
90 option:[NSArray arrayWithObjects:@"-w", nil]
91 plistName:@AFS_DAEMON_PATH];
95 void stopAfs(int argc, char *argv[])
100 const char *umountArgs[] = {"-f", "/afs", 0L};
101 [[AuthUtil shared] execUnixCommand:"/sbin/umount"
105 const char *afsdArgs[] = {"-shutdown", 0L};
106 [[AuthUtil shared] execUnixCommand:argv[3]
110 const char *kernelExtArgs[] = {argv[2], 0L};
111 [[AuthUtil shared] execUnixCommand:"/sbin/kextunload"
115 [[AuthUtil shared] deautorize];
119 // Code to get the path to the executable using _NSGetExecutablePath.
120 void getPath(char **selfPathPtr)
122 uint32_t selfPathSize = MAXPATHLEN;
123 if(!(*selfPathPtr = malloc(selfPathSize)))
127 if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) == -1)
129 // Try reallocating selfPath with the size returned by the function.
130 if(!(*selfPathPtr = realloc(*selfPathPtr, selfPathSize + 1)))
132 NSLog(@"Could not allocate memory to hold executable path.");
135 if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) != 0)
137 NSLog(@"Could not get executable path.");
143 // Self-repair code. Found somehwere in internet
144 void selfRepair(char *selfPath)
148 printf("selfRepair");
150 // [[AuthUtil shared] autorize];
152 // Open tool exclusively, noone can touch it when we work on it, this idea i kepped somewhere in internet
153 fdTool = open(selfPath, O_NONBLOCK | O_RDONLY | O_EXLOCK, 0);
157 NSLog(@"Open Filed: %d.", errno);
161 if(fstat(fdTool, &st))
163 NSLog(@"fstat failed.");
169 fchown(fdTool, 0, st.st_gid);
170 } else NSLog(@"st_uid = 0");
172 // Disable group and world writability and make setuid root.
173 fchmod(fdTool, (st.st_mode & (~(S_IWGRP | S_IWOTH))) | S_ISUID);
177 NSLog(@"Self-repair done.");
181 // Code to execute the tool in self-repair mode.
182 void runWithSelfRepair(char *selfPath, int argc, char *argv[])
188 // Make the qargs array for passing to child the same args of father
189 const char *arguments[] = {argv[1], argv[2], argv[3], "--self-repair", 0L};
191 // Get the privileged AuthorizationRef
192 [[AuthUtil shared] autorize];
193 [[AuthUtil shared] execUnixCommand:selfPath
198 if(pid == -1 || !WIFEXITED(status))
200 NSLog(@"Error returned from wait().");
204 // Exit with the same exit code as the self-repair child
205 exit(WEXITSTATUS(status));