~ubuntu-branches/ubuntu/utopic/gridengine/utopic

« back to all changes in this revision

Viewing changes to source/security/krb/krb_util.c

  • Committer: Bazaar Package Importer
  • Author(s): Mark Hymers
  • Date: 2008-06-25 22:36:13 UTC
  • Revision ID: james.westby@ubuntu.com-20080625223613-tvd9xlhuoct9kyhm
Tags: upstream-6.2~beta2
ImportĀ upstreamĀ versionĀ 6.2~beta2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*___INFO__MARK_BEGIN__*/
 
2
/*************************************************************************
 
3
 * 
 
4
 *  The Contents of this file are made available subject to the terms of
 
5
 *  the Sun Industry Standards Source License Version 1.2
 
6
 * 
 
7
 *  Sun Microsystems Inc., March, 2001
 
8
 * 
 
9
 * 
 
10
 *  Sun Industry Standards Source License Version 1.2
 
11
 *  =================================================
 
12
 *  The contents of this file are subject to the Sun Industry Standards
 
13
 *  Source License Version 1.2 (the "License"); You may not use this file
 
14
 *  except in compliance with the License. You may obtain a copy of the
 
15
 *  License at http://gridengine.sunsource.net/Gridengine_SISSL_license.html
 
16
 * 
 
17
 *  Software provided under this License is provided on an "AS IS" basis,
 
18
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 
19
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 
20
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 
21
 *  See the License for the specific provisions governing your rights and
 
22
 *  obligations concerning the Software.
 
23
 * 
 
24
 *   The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 
25
 * 
 
26
 *   Copyright: 2001 by Sun Microsystems, Inc.
 
27
 * 
 
28
 *   All Rights Reserved.
 
29
 * 
 
30
 ************************************************************************/
 
31
/*___INFO__MARK_END__*/
 
32
 
 
33
#include <pwd.h>
 
34
#include <stdio.h>
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include <time.h>
 
38
#include <sys/types.h>
 
39
#include <sys/stat.h>
 
40
#include <sys/socket.h>
 
41
#include <netinet/in.h>
 
42
#include <netdb.h>
 
43
 
 
44
#include "basis_types.h"
 
45
#include "sge_all_listsL.h"
 
46
#include "commlib.h"
 
47
 
 
48
#include "sge.h"
 
49
#include "sgermon.h"
 
50
#include "sge_log.h"
 
51
#include "sge_time.h"
 
52
#include "sge_uidgid.h"
 
53
 
 
54
#include "sge_prog.h"
 
55
#include "msg_krb.h"
 
56
 
 
57
#include "krb_data.h"
 
58
#include "krb_lib.h"
 
59
 
 
60
#include "sge_krbL.h"
 
61
#include "krb5.h"                               /* Kerberos stuff       */
 
62
#include "com_err.h"
 
63
 
 
64
 
 
65
/*
 
66
 * krb_renew_tgts - Renew TGTs on behalf of the job client. This routine
 
67
 * gets the TGT out of the job entry, decrypts it, and checks to see if
 
68
 * the TGT needs renewing.  If it does, it renews the TGT and stores the
 
69
 * new TGT back into the job entry.  This routine is executed in both the
 
70
 * qmaster and the execd.
 
71
 */
 
72
 
 
73
#define FLAGS2OPTS(flags) (flags & KDC_TKT_COMMON_MASK)
 
74
 
 
75
int
 
76
krb_renew_tgts(
 
77
lList *joblist 
 
78
) {
 
79
   krb5_error_code rc;
 
80
   static u_long32 next_time = 0;
 
81
   u_long32 now = sge_get_gmt();
 
82
   lListElem *job;
 
83
   krb5_context context = krb_context();
 
84
   krb5_timestamp time_now;
 
85
   krb_global_data_t *gsd = krb_gsd();
 
86
 
 
87
   DENTER(TOP_LAYER, "krb_renew_tgts");
 
88
 
 
89
 
 
90
   if ((now = sge_get_gmt())<next_time) {
 
91
      DEXIT;
 
92
      return 0;
 
93
   }
 
94
 
 
95
   if ((rc = krb5_timeofday(context, &time_now))) {
 
96
      ERROR((SGE_EVENT, MSG_KRB_KRB5TIMEOFDAYFAILEDX_S ,
 
97
             error_message(rc)));
 
98
      DEXIT;
 
99
      return -1;
 
100
   }
 
101
 
 
102
   /* renew job TGT's */
 
103
 
 
104
   for_each(job, joblist) {
 
105
 
 
106
      krb5_error_code rc;
 
107
      krb5_creds ** tgt_creds = NULL;
 
108
      krb5_data tgtbuf;
 
109
      const char *tgtstr = NULL;
 
110
 
 
111
      tgtbuf.length = 0;
 
112
 
 
113
      /* get TGT out of job entry */
 
114
 
 
115
      if ((tgtstr = lGetString(job, JB_tgt))) {
 
116
 
 
117
         tgtbuf.data = krb_str2bin(tgtstr, NULL, &tgtbuf.length);
 
118
 
 
119
         if (tgtbuf.length) {
 
120
 
 
121
            /* decrypt the TGT using the daemon key */
 
122
 
 
123
            if ((rc = krb_decrypt_tgt_creds(&tgtbuf, &tgt_creds))) {
 
124
 
 
125
               ERROR((SGE_EVENT, MSG_KRB_COULDNOTDECRYPTTGTFORJOBXY_DS,
 
126
                      sge_u32c(lGetUlong(job, JB_job_number)),
 
127
                      error_message(rc)));
 
128
 
 
129
            }
 
130
 
 
131
            if (rc == 0 && tgt_creds) {
 
132
 
 
133
               krb5_creds *tgt = *tgt_creds;
 
134
 
 
135
               /*
 
136
                * If TGT is renewable and TGT expiration time is not past
 
137
                * and is within the SGE renewal threshold and the TGT
 
138
                * renewal period is not past, then renew the TGT
 
139
                */
 
140
 
 
141
               if (tgt->ticket_flags & KDC_OPT_RENEWABLE &&
 
142
                   tgt->times.endtime > time_now &&
 
143
                   tgt->times.renew_till > time_now &&
 
144
                   tgt->times.endtime < time_now + gsd->tgt_renew_threshold) {
 
145
 
 
146
                  krb5_creds *new_creds[2];
 
147
                  krb5_creds creds;
 
148
 
 
149
                  memset(new_creds, 0, sizeof(new_creds));
 
150
                  memset(&creds, 0 ,sizeof(creds));
 
151
 
 
152
                  /* renew the TGT */
 
153
 
 
154
                  if (((rc = krb5_copy_principal(context, (*tgt_creds)->server,
 
155
                        &creds.server))) ||
 
156
                      ((rc = krb5_copy_principal(context, (*tgt_creds)->client,
 
157
                        &creds.client))) ||
 
158
                      ((rc = krb5_get_cred_via_tkt(context, tgt,
 
159
                        FLAGS2OPTS(tgt->ticket_flags)|KDC_OPT_RENEW,
 
160
                        tgt->addresses, &creds, &new_creds[0])))) {
 
161
 
 
162
                     ERROR((SGE_EVENT, MSG_KRB_COULDNOTRENEWTGTFORJOBXY_DS, 
 
163
                  sge_u32c(lGetUlong(job, JB_job_number)),
 
164
                                 error_message(rc)));
 
165
 
 
166
                  }
 
167
 
 
168
                  krb5_free_cred_contents(context, &creds);
 
169
 
 
170
                  if (rc == 0) {
 
171
                     krb5_data outbuf;
 
172
 
 
173
                     /* store the new TGT back into the job entry */
 
174
 
 
175
                     outbuf.length = 0;
 
176
 
 
177
                     if ((rc = krb_encrypt_tgt_creds(new_creds, &outbuf))) {
 
178
 
 
179
                        ERROR((SGE_EVENT, MSG_KRB_COULDNOTECRYPTTGTFORJOBXY_DS,
 
180
                sge_u32c(lGetUlong(job, JB_job_number)),
 
181
                               error_message(rc)));
 
182
 
 
183
                     } else {
 
184
 
 
185
                        lSetString(job, JB_tgt,
 
186
                              krb_bin2str(outbuf.data, outbuf.length, NULL));
 
187
                     }
 
188
 
 
189
                     /* if we are called by the execd, also store the
 
190
                        new TGT in the credentials cache of the user */
 
191
 
 
192
                     if (!strcmp(prognames[EXECD], gsd->progname)) {
 
193
                         
 
194
                        int retries = MAX_NIS_RETRIES;
 
195
                        struct passwd *pw = NULL;
 
196
 
 
197
                        while (retries-- && !pw)
 
198
                           pw = getpwnam(lGetString(job, JB_owner));
 
199
 
 
200
                        if (pw) {
 
201
 
 
202
                           if ((krb_store_forwarded_tgt(pw->pw_uid,
 
203
                                    lGetUlong(job, JB_job_number),
 
204
                                    new_creds))) {
 
205
 
 
206
                               ERROR((SGE_EVENT, MSG_KRB_COULDNOTSTORERENEWEDTGTFORXJOBY_SD,
 
207
                                      lGetString(job, JB_owner),
 
208
                                      sge_u32c(lGetUlong(job, JB_job_number))));
 
209
                           }
 
210
 
 
211
                        } else {
 
212
 
 
213
                           ERROR((SGE_EVENT, MSG_KRB_COULDNOTGETUSERIDFORXY_SD , lGetString(job, JB_owner),
 
214
                                  sge_u32c(lGetUlong(job, JB_job_number))));
 
215
                        }
 
216
                     }
 
217
 
 
218
                     if (outbuf.length)
 
219
                        krb5_xfree(outbuf.data);
 
220
 
 
221
                  }
 
222
 
 
223
      if (!mconf_get_simulate_jobs()) {
 
224
         job_write_spool_file(job, 0, NULL, SPOOL_DEFAULT);;
 
225
      }
 
226
 
 
227
                  if (new_creds[0])
 
228
                     krb5_free_creds(context, new_creds[0]);
 
229
 
 
230
               }
 
231
            }
 
232
         }
 
233
 
 
234
         if (tgtbuf.length)
 
235
            krb5_xfree(tgtbuf.data);
 
236
 
 
237
         if (tgt_creds)
 
238
            krb5_free_tgt_creds(context, tgt_creds);
 
239
 
 
240
      }
 
241
 
 
242
   }
 
243
 
 
244
   next_time = now + gsd->tgt_renew_interval;
 
245
 
 
246
   DEXIT;
 
247
   return 0;
 
248
}
 
249