5860844acd55d3fdd4d172e089a64d4116b3c316
[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  void stopAfs(int argc, char *argv[]);
29  void getPath(char **selfPathPtr);
30  void selfRepair(char *selfPath);
31  void runWithSelfRepair(char *selfPath,int argc, char *argv[]);
32  void runCommand(int argc, char *argv[]);
33
34 int main(int argc, char *argv[])
35 {
36         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
37     char *selfPath;
38         
39         NSLog(@"num of arguments %d", argc);
40         int status = [[AuthUtil shared] autorize];
41         if(status != noErr) exit(-1);
42         
43     // Get the path to the tool's executable
44     getPath(&selfPath);
45
46     //selfRepair(selfPath);
47     // All done with the executable path
48     if(selfPath) free(selfPath);
49         
50         // Now do the real work of running the command.
51     runCommand(argc, argv);
52     [[AuthUtil shared] deautorize];
53     [pool release];
54         
55         return 0;
56 }
57
58 // 
59 void runCommand(int argc, char *argv[])
60 {
61         NSString *cmdString = [NSString stringWithCString:(const char *)argv[1] encoding:NSUTF8StringEncoding];
62
63         if(argc == 4 && [cmdString rangeOfString:@"stop_afs"].location!=NSNotFound ){
64                 NSLog(@"Stop afs from helper");
65                 stopAfs(argc, argv);
66         } else  if(argc == 4 && [cmdString rangeOfString:@"start_afs"].location!=NSNotFound){
67                 NSLog(@"Start afs from helper");
68                 setuid(0);
69                 const char *startArgs[] = {argv[2], argv[3], 0L};
70                 [[AuthUtil shared] execUnixCommand:argv[1] 
71                                                                           args:startArgs
72                                                                         output:nil];
73         } else if(argc == 4 && [cmdString rangeOfString:@"enable_krb5_startup"].location!=NSNotFound) {
74                 NSLog(@"Manage KRB5 at login time with option %s from helper", argv[2]);
75                 setuid(0);
76                 int arg2 = atoi(argv[2]);
77                 [PListManager krb5TiketAtLoginTime:[[NSNumber numberWithInt:arg2] boolValue]];
78                 
79         } else if(argc == 5 && [cmdString rangeOfString:@"start_afs_at_startup"].location!=NSNotFound){
80                 setuid(0);
81                 NSLog(@"Manage start_afs_at_startup with option %s from helper", argv[2]);
82                 [PListManager manageAfsStartupLaunchdFile:YES 
83                                                                  afsStartupScript:[NSString stringWithCString:argv[2]]
84                                                                           afsBasePath:[NSString stringWithCString:argv[4]]
85                                                                                  afsdPath:[NSString stringWithCString:argv[3]]];
86         }
87 }
88
89 void stopAfs(int argc, char *argv[])
90 {
91         
92         
93         setuid(0);
94         const char *umountArgs[] = {"-f", "/afs", 0L};
95         [[AuthUtil shared] execUnixCommand:"/sbin/umount" 
96                                                                   args:umountArgs
97                                                                 output:nil];
98         
99         const char *afsdArgs[] = {"-shutdown", 0L};
100         [[AuthUtil shared] execUnixCommand:argv[3]
101                                                                   args:afsdArgs
102                                                                 output:nil];
103         
104         const char *kernelExtArgs[] = {argv[2], 0L};
105         [[AuthUtil shared] execUnixCommand:"/sbin/kextunload"
106                                                                   args:kernelExtArgs
107                                                                 output:nil];
108         
109         [[AuthUtil shared] deautorize];
110 }
111
112
113 // Code to get the path to the executable using _NSGetExecutablePath.
114 void getPath(char **selfPathPtr)
115 {
116     uint32_t selfPathSize = MAXPATHLEN;
117     if(!(*selfPathPtr = malloc(selfPathSize)))
118     {
119         exit(-1);
120     }
121     if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) == -1)
122     {
123         // Try reallocating selfPath with the size returned by the function.
124         if(!(*selfPathPtr = realloc(*selfPathPtr, selfPathSize + 1)))
125         {
126             NSLog(@"Could not allocate memory to hold executable path.");
127             exit(-1);
128         }
129         if(_NSGetExecutablePath(*selfPathPtr, &selfPathSize) != 0)
130         {
131             NSLog(@"Could not get executable path.");
132             exit(-1);
133         }
134     }
135 }
136
137 // Self-repair code. Found somehwere in internet
138 void selfRepair(char *selfPath)
139 {
140     struct stat st;
141     int fdTool;
142         printf("selfRepair"); 
143         
144 //    [[AuthUtil shared] autorize];
145     
146     // Open tool exclusively, noone can touch it when we work on it, this idea i kepped somewhere in internet
147     fdTool = open(selfPath, O_NONBLOCK | O_RDONLY | O_EXLOCK, 0);
148     
149     if(fdTool == -1)
150     {
151         NSLog(@"Open Filed: %d.", errno);
152         exit(-1);
153     }
154     
155     if(fstat(fdTool, &st))
156     {
157         NSLog(@"fstat failed.");
158         exit(-1);
159     }
160     
161     if(st.st_uid != 0)
162     {
163         fchown(fdTool, 0, st.st_gid);
164     } else  NSLog(@"st_uid = 0");
165     
166     // Disable group and world writability and make setuid root.
167     fchmod(fdTool, (st.st_mode & (~(S_IWGRP | S_IWOTH))) | S_ISUID);
168     
169     close(fdTool);
170     
171     NSLog(@"Self-repair done.");
172 }
173
174
175 // Code to execute the tool in self-repair mode.
176 void runWithSelfRepair(char *selfPath, int argc, char *argv[])
177 {
178     int status;
179     int pid;
180         
181       
182         // Make the qargs array for passing to child the same args of father
183     const char *arguments[] = {argv[1], argv[2], argv[3], "--self-repair", 0L};
184         
185         // Get the privileged AuthorizationRef
186     [[AuthUtil shared] autorize];
187         [[AuthUtil shared] execUnixCommand:selfPath 
188                                                                   args:arguments 
189                                                                 output:nil];
190
191     pid = wait(&status);
192     if(pid == -1 || !WIFEXITED(status))
193     {
194         NSLog(@"Error returned from wait().");
195         exit(-1);
196     }
197     
198     // Exit with the same exit code as the self-repair child
199     exit(WEXITSTATUS(status));
200 }