OSXPreferencePane
[openafs.git] / src / platform / DARWIN / AFSPreference / afshlp.m
1 //
2 //  afshlp.m
3 //  AFSCommander
4 //
5 //  Created by Claudio on 28/06/07.
6 //
7
8
9 #include <sys/types.h>
10 #include <unistd.h>
11 #include <Security/Authorization.h>
12 #include <Security/AuthorizationTags.h>
13 #include <sys/param.h>
14 #include <sys/stat.h>
15 #include <sys/wait.h>
16 #include <sys/types.h>
17 #include <sys/fcntl.h>
18 #include <sys/errno.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <asl.h>
23 #include <sys/event.h>
24 #include <mach-o/dyld.h>
25 #import "TaskUtil.h"
26 #import "AuthUtil.h"
27 #import "PListManager.h"
28
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"
31
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[]);
37
38 int main(int argc, char *argv[])
39 {
40         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
41     char *selfPath;
42         
43         NSLog(@"num of arguments %d", argc);
44         int status = [[AuthUtil shared] autorize];
45         if(status != noErr) exit(-1);
46         
47     // Get the path to the tool's executable
48     getPath(&selfPath);
49
50     //selfRepair(selfPath);
51     // All done with the executable path
52     if(selfPath) free(selfPath);
53         
54         // Now do the real work of running the command.
55     runCommand(argc, argv);
56     [[AuthUtil shared] deautorize];
57     [pool release];
58         
59         return 0;
60 }
61
62 // 
63 void runCommand(int argc, char *argv[])
64 {
65         setuid(0);
66         NSString *cmdString = [NSString stringWithCString:(const char *)argv[1] encoding:NSUTF8StringEncoding];
67
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
72                                                                           args:stopArgs
73                                                                         output:nil];
74
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
79                                                                           args:startArgs
80                                                                         output:nil];
81
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];
92         } else if(argc == 2 && [cmdString rangeOfString:@"check_afs_daemon"].location!=NSNotFound) {
93                 NSString *fsResult = [TaskUtil executeTaskSearchingPath:@"launchctl" args:[NSArray arrayWithObjects: @"list", nil]];
94                 BOOL checkAfsDaemon = (fsResult?([fsResult rangeOfString:@"org.openafs.filesystems.afs"].location != NSNotFound):NO);
95                 printf("afshlp:afs daemon registration result:%d",checkAfsDaemon);
96         }
97 }
98
99 void stopAfs(int argc, char *argv[])
100 {
101         
102         
103         setuid(0);
104         const char *umountArgs[] = {"-f", "/afs", 0L};
105         [[AuthUtil shared] execUnixCommand:"/sbin/umount" 
106                                                                   args:umountArgs
107                                                                 output:nil];
108         
109         const char *afsdArgs[] = {"-shutdown", 0L};
110         [[AuthUtil shared] execUnixCommand:argv[3]
111                                                                   args:afsdArgs
112                                                                 output:nil];
113         
114         const char *kernelExtArgs[] = {argv[2], 0L};
115         [[AuthUtil shared] execUnixCommand:"/sbin/kextunload"
116                                                                   args:kernelExtArgs
117                                                                 output:nil];
118         
119         [[AuthUtil shared] deautorize];
120 }
121
122
123 // Code to get the path to the executable using _NSGetExecutablePath.
124 void getPath(char **selfPathPtr)
125 {
126     uint32_t selfPathSize = MAXPATHLEN;
127     if(!(*selfPathPtr = malloc(selfPathSize)))
128     {
129         exit(-1);
130     }
131     if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) == -1)
132     {
133         // Try reallocating selfPath with the size returned by the function.
134         if(!(*selfPathPtr = realloc(*selfPathPtr, selfPathSize + 1)))
135         {
136             NSLog(@"Could not allocate memory to hold executable path.");
137             exit(-1);
138         }
139         if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) != 0)
140         {
141             NSLog(@"Could not get executable path.");
142             exit(-1);
143         }
144     }
145 }
146
147 // Self-repair code. Found somehwere in internet
148 void selfRepair(char *selfPath)
149 {
150     struct stat st;
151     int fdTool;
152         printf("selfRepair"); 
153         
154 //    [[AuthUtil shared] autorize];
155     
156     // Open tool exclusively, noone can touch it when we work on it, this idea i kepped somewhere in internet
157     fdTool = open(selfPath, O_NONBLOCK | O_RDONLY | O_EXLOCK, 0);
158     
159     if(fdTool == -1)
160     {
161         NSLog(@"Open Filed: %d.", errno);
162         exit(-1);
163     }
164     
165     if(fstat(fdTool, &st))
166     {
167         NSLog(@"fstat failed.");
168         exit(-1);
169     }
170     
171     if(st.st_uid != 0)
172     {
173         fchown(fdTool, 0, st.st_gid);
174     } else  NSLog(@"st_uid = 0");
175     
176     // Disable group and world writability and make setuid root.
177     fchmod(fdTool, (st.st_mode & (~(S_IWGRP | S_IWOTH))) | S_ISUID);
178     
179     close(fdTool);
180     
181     NSLog(@"Self-repair done.");
182 }
183
184
185 // Code to execute the tool in self-repair mode.
186 void runWithSelfRepair(char *selfPath, int argc, char *argv[])
187 {
188     int status;
189     int pid;
190         
191       
192         // Make the qargs array for passing to child the same args of father
193     const char *arguments[] = {argv[1], argv[2], argv[3], "--self-repair", 0L};
194         
195         // Get the privileged AuthorizationRef
196     [[AuthUtil shared] autorize];
197         [[AuthUtil shared] execUnixCommand:selfPath 
198                                                                   args:arguments 
199                                                                 output:nil];
200
201     pid = wait(&status);
202     if(pid == -1 || !WIFEXITED(status))
203     {
204         NSLog(@"Error returned from wait().");
205         exit(-1);
206     }
207     
208     // Exit with the same exit code as the self-repair child
209     exit(WEXITSTATUS(status));
210 }