OSX AFSBackgrounder fix minor bug
[openafs.git] / src / platform / DARWIN / AFSPreference / AuthUtil.m
1 //
2 //  AuthUtil.m
3 //  AFSCommander
4 //
5 //  Created by Claudio Bisegni on 21/06/07.
6 //  Copyright 2007 INFN - National Institute of Nuclear Physics. All rights reserved.
7 //
8
9 #import "AuthUtil.h"
10 //#include <stdio.h>
11 #include <sys/types.h>
12 #include <sys/uio.h>
13 #include <unistd.h>
14 static AuthUtil *sharedAuthUtil = nil;
15
16 @implementation AuthUtil
17
18 +(AuthUtil*) shared
19 {
20         @synchronized(self) {
21         if (sharedAuthUtil == nil) {
22             [[self alloc] init]; // assignment not done here
23         }
24     }
25     return sharedAuthUtil;
26 }
27
28 + (id)allocWithZone:(NSZone *)zone
29 {
30     @synchronized(self) {
31         if (sharedAuthUtil == nil) {
32             sharedAuthUtil = [super allocWithZone:zone];
33             return sharedAuthUtil;  // assignment and return on first allocation
34         }
35     }
36     return nil; //on subsequent allocation attempts return nil
37 }
38
39 - (id)copyWithZone:(NSZone *)zone
40 {
41     return self;
42 }
43
44 // -------------------------------------------------------------------------------
45 //  init:
46 // -------------------------------------------------------------------------------
47 -(id) init {
48         [super init];
49         authorizationRef = nil; 
50         return self;
51 }
52
53 // -------------------------------------------------------------------------------
54 //  autorize:
55 // -------------------------------------------------------------------------------
56 -(OSStatus) autorize
57 {
58         OSStatus status = noErr;
59         AuthorizationFlags flags;
60         AuthorizationItem myItems = {kAuthorizationRightExecute, 0, NULL, 0};
61         AuthorizationRights myRights = {1, &myItems};
62         flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
63         
64         /*if(authorizationRef) {
65                 [self deautorize];
66         }*/
67         
68         // chek if autorization is valid for and old password request
69         status = AuthorizationCopyRights (authorizationRef, &myRights, NULL, flags, NULL );
70
71         if (status != errAuthorizationSuccess) { 
72                 //
73                 flags = kAuthorizationFlagDefaults;
74                 if(!authorizationRef){
75                         status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, flags, &authorizationRef);
76                         if (status != errAuthorizationSuccess) {
77                                 return status;
78                         }
79                 }
80                 
81                 flags = kAuthorizationFlagDefaults | kAuthorizationFlagInteractionAllowed | kAuthorizationFlagPreAuthorize | kAuthorizationFlagExtendRights;
82                 status = AuthorizationCopyRights (authorizationRef, &myRights, NULL, flags, NULL );
83
84                 if (status != errAuthorizationSuccess) {
85                         AuthorizationFree (authorizationRef, kAuthorizationFlagDefaults);
86                         return status;
87                 }
88         }
89
90         return status;
91 }
92
93
94 // -------------------------------------------------------------------------------
95 //  deatorize:
96 // -------------------------------------------------------------------------------
97 -(BOOL) deautorize
98 {
99         OSStatus status = 0L;
100         if(authorizationRef){
101                 status = AuthorizationFree (authorizationRef, kAuthorizationFlagDefaults);
102                 authorizationRef = 0L; 
103         }
104         return status == noErr;
105 }
106
107
108 // -------------------------------------------------------------------------------
109 //  authorization:
110 // -------------------------------------------------------------------------------
111 -(AuthorizationRef) authorization
112 {
113         return authorizationRef;
114 }
115
116 // -------------------------------------------------------------------------------
117 //  authorization:
118 // -------------------------------------------------------------------------------
119 -(NSData*) extFormAuth {
120         AuthorizationExternalForm extAuth; // external authorization
121         NSData *authorizationData = nil;
122         if(AuthorizationMakeExternalForm([self authorization], &extAuth))
123     {
124         NSLog(@"Could not create external authorization form.");
125                 return nil;
126         }
127         authorizationData = [NSData dataWithBytes:&extAuth length:sizeof(AuthorizationExternalForm)];
128         return authorizationData;
129 }
130
131 // -------------------------------------------------------------------------------
132 //  execUnixCommand:
133 // -------------------------------------------------------------------------------
134 -(OSStatus) execUnixCommand:(const char*) commandPath args:(const char*[])args output:(NSMutableString*)output
135 {
136         OSStatus status = noErr;
137         FILE *commandOutIn = NULL;
138         char buff[1024];
139         int pid, pidStatus;
140
141         status = AuthorizationExecuteWithPrivileges (authorizationRef, commandPath, kAuthorizationFlagDefaults , (char *const *)args, &commandOutIn);
142         if (status == errAuthorizationSuccess && commandOutIn){
143                 for(;;)
144                 {
145                         int bytesRead = read(fileno (commandOutIn), buff, sizeof (buff));
146                         if (bytesRead < 1) break;
147                         //write (fileno (stdout), buff, bytesRead);
148                         if(output) {
149                                 [output appendString:[NSString stringWithCString:buff length:bytesRead]];
150                         }
151                 }
152         }
153         if(commandOutIn){
154                 fflush(commandOutIn);
155                 fclose(commandOutIn);
156         }
157         // whait for comand finish
158         pid = wait( &pidStatus );
159         if (pid == -1 || !WIFEXITED( pidStatus ))
160         {
161                 NSLog( @"Error: problem with wait pid status: %d", pidStatus );
162                 return 1;
163         }
164         return status;
165 }
166
167 - (id)retain
168 {
169     return self;
170 }
171
172 - (unsigned)retainCount
173 {
174     return UINT_MAX;  //denotes an object that cannot be released
175 }
176
177 - (void)release
178 {
179     //do nothing
180 }
181
182 - (id)autorelease
183 {
184     return self;
185 }
186 @end