darwin: minimal afsbackgrounder ticket fix
[openafs.git] / src / platform / DARWIN / AFSPreference / Krb5Util.m
1 //
2 //  Krb5Util.m
3 //  OpenAFS
4 //
5 //  Created by Claudio Bisegni on 20/03/10.
6 //  Copyright 2010 INFN. All rights reserved.
7 //
8
9 #import "Krb5Util.h"
10
11 @implementation Krb5Util
12 +(KLStatus) getNewTicketIfNotPresent {
13         KLPrincipal             princ = nil;
14         KLStatus                kstatus = noErr;
15         char                    *princName = 0L;
16         KLBoolean       outFoundValidTickets = false;
17         KLLoginOptions  inLoginOptions = nil;
18
19         @try{
20                 kstatus = KLCacheHasValidTickets(nil, kerberosVersion_All, &outFoundValidTickets, nil, nil);
21                 if(!outFoundValidTickets) {
22                     kstatus = KLCreateLoginOptions(&inLoginOptions);
23                     if (kstatus != noErr)
24                         @throw [NSException exceptionWithName:@"Krb5Util"
25                                             reason:@"getNewTicketIfNotPresent"
26                                             userInfo:nil];
27 #if !(defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6))
28                     else {
29                         KLLifetime valuel;
30                         KLSize sizel = sizeof (valuel);
31                         KLBoolean value;
32                         KLSize size = sizeof (value);
33                         kstatus = KLGetDefaultLoginOption (loginOption_DefaultTicketLifetime, &valuel, &sizel);
34
35                         if (kstatus == noErr)
36                             kstatus = KLLoginOptionsSetTicketLifetime
37                                 (inLoginOptions, valuel);
38
39                         kstatus = KLGetDefaultLoginOption
40                             (loginOption_DefaultRenewableTicket, &value,
41                              &size);
42                         if (kstatus == noErr)
43                             if ((value != 0) &&
44                                 ((kstatus = KLGetDefaultLoginOption
45                                   (loginOption_DefaultRenewableLifetime,
46                                    &value, &size)) == noErr))
47                                 kstatus = KLLoginOptionsSetRenewableLifetime
48                                 (inLoginOptions, value);
49                             else {
50                                 kstatus = KLLoginOptionsSetRenewableLifetime(inLoginOptions, 0L);
51                         }
52                         kstatus = KLGetDefaultLoginOption
53                             (loginOption_DefaultForwardableTicket, &value,
54                              &size);
55
56                         if (kstatus == noErr)
57                             kstatus = KLLoginOptionsSetForwardable
58                                 (inLoginOptions, value);
59
60                         kstatus = KLGetDefaultLoginOption
61                             (loginOption_DefaultProxiableTicket, &value,
62                              &size);
63
64                         if (kstatus == noErr)
65                             kstatus = KLLoginOptionsSetProxiable
66                                 (inLoginOptions, value);
67
68                         kstatus = KLGetDefaultLoginOption
69                             (loginOption_DefaultAddresslessTicket, &value,
70                              &size);
71
72                         if (kstatus == noErr)
73                             kstatus = KLLoginOptionsSetAddressless
74                                 (inLoginOptions, value);
75                     }
76 #endif
77                     if (kstatus == noErr)
78                         kstatus = KLAcquireNewInitialTickets(nil,
79                                                              inLoginOptions,
80                                                              &princ,
81                                                              &princName);
82                     if(kstatus != noErr && kstatus != klUserCanceledErr)
83                         @throw [NSException exceptionWithName:@"Krb5Util"
84                                             reason:@"getNewTicketIfNotPresent"
85                                             userInfo:nil];
86                     if (inLoginOptions != NULL) {
87                         KLDisposeLoginOptions (inLoginOptions);
88                     }
89                 }
90         }
91         @catch (NSException * e) {
92                 @throw e;
93         }
94         @finally {
95                 KLDisposeString (princName);
96                 KLDisposePrincipal (princ);
97         }
98         return kstatus;
99 }
100
101 +(KLStatus) renewTicket:(NSTimeInterval)secToExpire
102                           renewTime:(NSTimeInterval)renewTime {
103         KLPrincipal             princ = nil;
104         KLStatus                kstatus = noErr;
105         char                    *princName = 0L;
106         KLTime          expireStartTime;
107         KLLoginOptions  inLoginOptions;
108         KLLifetime      inTicketLifetime = renewTime;
109         NSDate                  *expirationDate = nil;
110         @try {
111                 //prepare the login option
112                 kstatus = KLCreateLoginOptions(&inLoginOptions);
113                 //set the lifetime of ticket
114                 kstatus = KLLoginOptionsSetTicketLifetime (inLoginOptions,  inTicketLifetime);
115                 kstatus = KLLoginOptionsSetRenewableLifetime (inLoginOptions, 0L);
116                 kstatus = KLLoginOptionsSetTicketStartTime (inLoginOptions, 0);
117                 //set the preference renewable time
118                 //kstatus =  KLLoginOptionsSetRenewableLifetime (inLoginOptions, inTicketLifetime);
119                 //check the start time
120                 kstatus = KLTicketExpirationTime (nil, kerberosVersion_All, &expireStartTime);
121                 expirationDate = [NSDate dateWithTimeIntervalSince1970:expireStartTime];
122
123                 //NSLog(@"Ticket Expiration time: %@", [expirationDate description]);
124                 NSTimeInterval secondToExpireTime = [expirationDate timeIntervalSinceNow];
125                 if(secondToExpireTime <= secToExpire) {
126 #if defined(MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6)
127                         krb5_creds in;
128                         krb5_error_code ret;
129                         krb5_ccache id = NULL;
130                         static dispatch_once_t once = 0;
131                         static krb5_context kcontext;
132                         krb5_principal me=NULL;
133                         krb5_principal server=NULL;
134                         krb5_timestamp now;
135
136                         dispatch_once(&once, ^{
137                                         krb5_init_context(&kcontext);
138                                 });
139
140                         krb5_timeofday(kcontext, &now);
141                         memset((char *)&in, 0, sizeof(in));
142                         in.times.starttime = 0;
143                         in.times.endtime = now + inTicketLifetime;
144                         in.times.renew_till = now + inTicketLifetime;
145
146                         krb5_cc_default(kcontext, &id);
147                         if (ret == 0) {
148                                 ret = krb5_cc_get_principal(kcontext, id,
149                                                             &me);
150                                 in.client = me;
151                         }
152                         if (ret == 0) {
153                           ret = krb5_build_principal_ext(kcontext, &server,
154                                                        krb5_princ_realm(kcontext,
155                                                                         in.client)->length,
156                                                        krb5_princ_realm(kcontext,
157                                                                         in.client)->data,
158                                                        6, "krbtgt",
159                                                        krb5_princ_realm(kcontext,
160                                                                         in.client)->length,
161                                                        krb5_princ_realm(kcontext,
162                                                                         in.client)->data,
163                                                        0);
164                         }
165                         if (ret == 0) {
166                           in.server = server;
167                           ret = krb5_get_renewed_creds(kcontext, &in, me, id, server);
168                         }
169                         if (ret == 0) {
170                           ret = krb5_cc_initialize (kcontext, id, me);
171                           ret = krb5_cc_store_cred(kcontext, id, &in);
172                           krb5_cc_close(kcontext,id);
173                         }
174                         krb5_free_principal(kcontext, server);
175 #else
176                         KLPrincipal klprinc = nil;
177                         kstatus = KLRenewInitialTickets ( klprinc, inLoginOptions, nil, nil);
178 #endif
179
180 #if 0
181                         /* handoff to growl agent? */
182                         kstatus = KLTicketExpirationTime (nil, kerberosVersion_All, &expireStartTime);
183                         expirationDate = [NSDate dateWithTimeIntervalSince1970:expireStartTime];
184                         BuildNotificationInfo(@"Ticket Renewed Unitl %@", expirationDate,  callbackInfo->dcref, callbackInfo->regref, callbackInfo->icon);
185 #endif
186                 }
187         }
188         @catch (NSException * e) {
189                 @throw e;
190         }
191         @finally {
192                 KLDisposeString (princName);
193                 KLDisposePrincipal (princ);
194                 KLDisposeLoginOptions(inLoginOptions);
195         }
196         return kstatus;
197 }
198 @end