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[]);
37 void main(int argc, char *argv[])
40 return; // nothing to do
41 NSString *cmdString = [NSString stringWithCString:(const char *)argv[1] encoding:NSUTF8StringEncoding];
43 if(argc == 2 && [cmdString rangeOfString:@"stop_afs"].location!=NSNotFound ){
46 const char *stopArgs[] = {"stop", 0L};
47 [[AuthUtil shared] execUnixCommand:AFS_DAEMON_STARTUPSCRIPT
50 } else if(argc == 2 && [cmdString rangeOfString:@"start_afs"].location!=NSNotFound){
53 const char *startArgs[] = {"start", 0L};
54 [[AuthUtil shared] execUnixCommand:AFS_DAEMON_STARTUPSCRIPT
57 } else if(argc == 4 && [cmdString rangeOfString:@"enable_krb5_startup"].location!=NSNotFound) {
58 int olduid = getuid();
60 int arg2 = atoi(argv[2]);
61 [PListManager krb5TiketAtLoginTime:[[NSNumber numberWithInt:arg2] boolValue]];
62 } else if(argc == 3 && [cmdString rangeOfString:@"start_afs_at_startup"].location!=NSNotFound){
65 BOOL enable = strcmp("enable", argv[2])==0;
66 NSLog(@"Manage start_afs_at_startup with option %s from helper", argv[2]);
67 [PListManager launchctlStringCommand:enable?@"load":@"unload"
68 option:[NSArray arrayWithObjects:@"-w", nil]
69 plistName:@AFS_DAEMON_PATH];
71 } else if(argc == 2 && [cmdString rangeOfString:@"check_afs_daemon"].location!=NSNotFound) {
72 NSString *fsResult = [TaskUtil executeTaskSearchingPath:@"launchctl" args:[NSArray arrayWithObjects: @"list", nil]];
73 BOOL checkAfsDaemon = (fsResult?([fsResult rangeOfString:@"org.openafs.filesystems.afs"].location != NSNotFound):NO);
74 printf("afshlp:afs daemon registration result:%d",checkAfsDaemon);
80 void stopAfs(int argc, char *argv[])
82 const char *umountArgs[] = {"-f", "/afs", 0L};
83 [[AuthUtil shared] execUnixCommand:"/sbin/umount"
87 const char *afsdArgs[] = {"-shutdown", 0L};
88 [[AuthUtil shared] execUnixCommand:argv[3]
92 const char *kernelExtArgs[] = {argv[2], 0L};
93 [[AuthUtil shared] execUnixCommand:"/sbin/kextunload"
97 [[AuthUtil shared] deautorize];
100 // Code to get the path to the executable using _NSGetExecutablePath.
101 void getPath(char **selfPathPtr)
103 uint32_t selfPathSize = MAXPATHLEN;
104 if(!(*selfPathPtr = malloc(selfPathSize)))
108 if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) == -1)
110 // Try reallocating selfPath with the size returned by the function.
111 if(!(*selfPathPtr = realloc(*selfPathPtr, selfPathSize + 1)))
113 NSLog(@"Could not allocate memory to hold executable path.");
116 if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) != 0)
118 NSLog(@"Could not get executable path.");
124 int main(int argc, char *argv[])
126 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
129 NSLog(@"num of arguments %d", argc);
130 int status = [[AuthUtil shared] autorize];
131 if(status != noErr) exit(-1);
133 // Get the path to the tool's executable
136 //selfRepair(selfPath);
137 // All done with the executable path
138 if(selfPath) free(selfPath);
140 // Now do the real work of running the command.
141 runCommand(argc, argv);
142 [[AuthUtil shared] deautorize];
148 // Self-repair code. Found somehwere in internet
149 void selfRepair(char *selfPath)
153 printf("selfRepair");
155 // [[AuthUtil shared] autorize];
157 // Open tool exclusively, noone can touch it when we work on it, this idea i kepped somewhere in internet
158 fdTool = open(selfPath, O_NONBLOCK | O_RDONLY | O_EXLOCK, 0);
162 NSLog(@"Open Filed: %d.", errno);
166 if(fstat(fdTool, &st))
168 NSLog(@"fstat failed.");
172 // Disable group and world writability and make setuid root.
173 if ((st.st_uid != 0) || (st.st_mode & S_IWGRP) || (st.st_mode & S_IWOTH) ||
174 !(st.st_mode & S_ISUID))
176 fchown(fdTool, 0, st.st_gid);
177 fchmod(fdTool, (st.st_mode & (~(S_IWGRP | S_IWOTH))) | S_ISUID);
178 } else NSLog(@"st_uid = 0");
182 NSLog(@"Self-repair done.");
186 // Code to execute the tool in self-repair mode.
187 void runWithSelfRepair(char *selfPath, int argc, char *argv[])
193 // Make the qargs array for passing to child the same args of father
194 const char *arguments[] = {argv[1], argv[2], argv[3], "--self-repair", 0L};
196 // Get the privileged AuthorizationRef
197 [[AuthUtil shared] autorize];
198 [[AuthUtil shared] execUnixCommand:selfPath
203 if(pid == -1 || !WIFEXITED(status))
205 NSLog(@"Error returned from wait().");
209 // Exit with the same exit code as the self-repair child
210 exit(WEXITSTATUS(status));