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