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

« back to all changes in this revision

Viewing changes to source/security/gss/put_cred.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 <stdio.h>
 
34
#include <unistd.h>
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include <ctype.h>
 
38
#include <sys/types.h>
 
39
#include <sys/socket.h>
 
40
#include <netinet/in.h>
 
41
#include <netdb.h>
 
42
#include <errno.h>
 
43
#include <sys/stat.h>
 
44
#include <sys/param.h>
 
45
#include <fcntl.h>
 
46
#include <pwd.h>
 
47
#ifdef KERBEROS
 
48
#include <gssapi/gssapi_generic.h>
 
49
#else
 
50
#include <gssapi.h>
 
51
#endif
 
52
#include "sge_gsslib.h"
 
53
#include "msg_gss.h"
 
54
/* #include "sge_language.h" */
 
55
 
 
56
void
 
57
usage(char *progname)
 
58
{
 
59
   char *p;
 
60
   p = (NULL == (p = strrchr(progname,'/'))) ? progname : p+1;
 
61
   fprintf(stderr, MSG_GSS_PUTCRED_USAGE, p);
 
62
   fprintf(stderr, "\n");
 
63
   exit(1);
 
64
}
 
65
 
 
66
 
 
67
int
 
68
main(int argc, char **argv)
 
69
{
 
70
   char *service_name = NULL;
 
71
   gss_cred_id_t server_creds = GSS_C_NO_CREDENTIAL;
 
72
   gss_buffer_desc client_cred;
 
73
   char *username = NULL;
 
74
   int cc=0;
 
75
   int ch;
 
76
   extern int optind;
 
77
   extern char *optarg;
 
78
   char *cmd = NULL, *ecmd = NULL;
 
79
   int verbose=0;
 
80
   char *become_user=NULL;
 
81
   char *change_owner=NULL;
 
82
   char *ccname = getenv("KRB5CCNAME");
 
83
   char ccbuf[1024];
 
84
   int i;
 
85
   char lenbuf[GSSLIB_INTSIZE];
 
86
 
 
87
 
 
88
   if (ccname) {
 
89
      strcpy(ccbuf, ccname);
 
90
      ccname = ccbuf;
 
91
   }
 
92
 
 
93
   while ((ch = getopt(argc, argv, "o:b:vu:s:c:e:")) != EOF) {
 
94
      switch (ch) {
 
95
         case 'b':
 
96
            become_user = optarg;
 
97
            break;
 
98
         case 'o':
 
99
            change_owner = optarg;
 
100
            break;
 
101
         case 'u':
 
102
            username = optarg;
 
103
            break;
 
104
         case 'v':
 
105
            verbose = 1;
 
106
            break;
 
107
         case 's':
 
108
            service_name = optarg;
 
109
            break;
 
110
         case 'c':
 
111
            cmd = optarg;
 
112
            break;
 
113
         case 'e':
 
114
            ecmd = optarg;
 
115
            break;
 
116
         default:
 
117
            usage(argv[0]);
 
118
            break;
 
119
      }
 
120
   }
 
121
 
 
122
   if (argc != optind)
 
123
      usage(argv[0]);
 
124
 
 
125
   gsslib_verbose(verbose);
 
126
 
 
127
   if (verbose) {
 
128
      fprintf(stderr, MSG_GSS_PUTCRED_ARGUMENTS);
 
129
      for (i=0; i<argc; i++)
 
130
         fprintf(stderr, "%s ", argv[i]);
 
131
      fputc('\n', stderr);
 
132
   }
 
133
 
 
134
   /*
 
135
    * get credentials for the SGE/SGE service
 
136
    */
 
137
 
 
138
   if (service_name) {
 
139
 
 
140
      cc = gsslib_acquire_server_credentials(service_name, &server_creds);
 
141
 
 
142
      if (cc) {
 
143
         fputs(gsslib_error(), stderr);
 
144
         return cc;
 
145
      }
 
146
 
 
147
   }
 
148
 
 
149
   /*
 
150
    * read client credentials buffer from stdin
 
151
    */
 
152
 
 
153
   if (read(0, lenbuf, sizeof(lenbuf)) != sizeof(lenbuf)) {
 
154
      fprintf(stderr, "%s\n", MSG_GSS_FAILEDREADINGCREDENTIALLENGTHFROMSTDIN );
 
155
      return 3;
 
156
   }
 
157
   client_cred.length = gsslib_unpackint(lenbuf);
 
158
   if (verbose)
 
159
      fprintf(stderr, "credentials length = %d\n", client_cred.length);
 
160
 
 
161
   if ((client_cred.value = (char *)malloc(client_cred.length)) == 0) {
 
162
      fprintf(stderr, MSG_GSS_COULDNOTALLOCATEXBYTESFORCREDENTIALS_I ,
 
163
              (int) client_cred.length);
 
164
      fprintf(stderr, "\n"); 
 
165
      return 3;
 
166
   }
 
167
 
 
168
   if (read(0, client_cred.value, client_cred.length) != client_cred.length) {
 
169
      fprintf(stderr, "%s\n", MSG_GSS_FAILEDREADINGCREDENTIALFROMSTDIN );
 
170
      return 3;
 
171
   }
 
172
 
 
173
   /*
 
174
    * establish and forward client credentials
 
175
    */
 
176
 
 
177
   cc = gsslib_put_credentials(server_creds, &client_cred, username);
 
178
 
 
179
   if (cc) {
 
180
      fputs(gsslib_error(), stderr);
 
181
      return cc;
 
182
   } else
 
183
      fputs(gsslib_error(), stderr);
 
184
 
 
185
   if (become_user || change_owner) {
 
186
      struct passwd *pw;
 
187
      char *owner;
 
188
 
 
189
      owner = change_owner ? change_owner : become_user;
 
190
 
 
191
      if (!(pw = getpwnam(owner))) {
 
192
         fprintf(stderr, MSG_GSS_COULDNOTGETUSERIDFORXY_SS ,
 
193
                 owner, strerror(errno));
 
194
         fprintf(stderr, "\n");
 
195
         cc = 4;
 
196
         goto error;
 
197
      }
 
198
 
 
199
      /* change ownership of credentials file to user */
 
200
 
 
201
      if (pw->pw_uid != geteuid()) {
 
202
 
 
203
         char *new_ccname = getenv("KRB5CCNAME");
 
204
 
 
205
         if (new_ccname == NULL || strncasecmp(new_ccname, "file:", 5) != 0) {
 
206
            fprintf(stderr, MSG_GSS_COULDNOTCHANGEOWNERSHIPOFCREDENTIALSCACHETOXINVALIDKRB5CCNAME_S, owner);
 
207
            fprintf(stderr, "\n");
 
208
            cc = 4;
 
209
            goto error;
 
210
         }
 
211
 
 
212
         if (chown(&new_ccname[5], pw->pw_uid, pw->pw_gid) < 0) {
 
213
            fprintf(stderr, MSG_GSS_COULDNOTCHANGEOWNERSHIPOFXTOYZ_SSS ,
 
214
                    &new_ccname[5], owner, strerror(errno));
 
215
            fprintf(stderr, "\n");
 
216
            cc = 4;
 
217
            goto error;
 
218
         }
 
219
 
 
220
#ifdef DCE
 
221
 
 
222
         /*
 
223
          * take care of the "extra" DCE credentials files
 
224
          */
 
225
 
 
226
         {
 
227
            char src[MAXPATHLEN];
 
228
 
 
229
            sprintf(src, "%s.data", &new_ccname[5]);
 
230
            chown(src, pw->pw_uid, pw->pw_gid);
 
231
            sprintf(src, "%s.data.db", &new_ccname[5]);
 
232
            chown(src, pw->pw_uid, pw->pw_gid);
 
233
            sprintf(src, "%s.nc", &new_ccname[5]);
 
234
            chown(src, pw->pw_uid, pw->pw_gid);
 
235
         }
 
236
 
 
237
#endif
 
238
 
 
239
      }
 
240
 
 
241
      if (become_user) {
 
242
 
 
243
         if (setgid(pw->pw_gid)<0) {
 
244
            cc = 4;
 
245
            perror(MSG_GSS_PERROR_SETGID);
 
246
            goto error;
 
247
         }
 
248
 
 
249
         if (setuid(pw->pw_uid)<0) {
 
250
            cc = 4;
 
251
            perror(MSG_GSS_PERROR_SETUID );
 
252
            goto error;
 
253
         }
 
254
      }
 
255
   }
 
256
 
 
257
#ifdef DCE
 
258
 
 
259
   /*
 
260
    * Link the user-supplied credentials cache file name to the
 
261
    * DCE credentials cache file if they have different file names
 
262
    */
 
263
 
 
264
   {
 
265
      char *dce_ccname = getenv("KRB5CCNAME");
 
266
      char src[MAXPATHLEN], dst[MAXPATHLEN];
 
267
 
 
268
      fprintf(stderr, "dce_ccname=%s\n", dce_ccname);
 
269
      fprintf(stderr, "ccname=%s\n", ccname);
 
270
 
 
271
      if (cc==0 && ccname && dce_ccname &&
 
272
          strcmp(ccname, dce_ccname)) {
 
273
 
 
274
         if (strncasecmp(ccname, "file:", 5) == 0 &&
 
275
             strncasecmp(dce_ccname, "file:", 5) == 0) {
 
276
 
 
277
            if (symlink(&dce_ccname[5], &ccname[5]) < 0) {
 
278
               fprintf(stderr, MSG_GSS_COULDNOTLINKXTODCECREDENTIALSCACHEFILEYZ_SSS ,
 
279
                       ccname, dce_ccname, strerror(errno));
 
280
               fprintf(stderr, "\n");
 
281
            }
 
282
 
 
283
            sprintf(src, "%s.data", &dce_ccname[5]);
 
284
            sprintf(dst, "%s.data", &ccname[5]);
 
285
            symlink(src, dst);
 
286
 
 
287
            sprintf(src, "%s.data.db", &dce_ccname[5]);
 
288
            sprintf(dst, "%s.data.db", &ccname[5]);
 
289
            symlink(src, dst);
 
290
 
 
291
            sprintf(src, "%s.nc", &dce_ccname[5]);
 
292
            sprintf(dst, "%s.nc", &ccname[5]);
 
293
            symlink(src, dst);
 
294
 
 
295
 
 
296
         } else {
 
297
            fprintf(stderr, MSG_GSS_COULDNOTLINKXTODCECREDENTIALSCACHEFILEYINVALIDKRB5CCNAMEENVIRONMENTVARIABLEFORMAT_SS, ccname, dce_ccname);
 
298
            fprintf(stderr, "\n");
 
299
         }
 
300
      }
 
301
   }
 
302
 
 
303
#endif
 
304
 
 
305
   if (verbose)
 
306
      fprintf(stderr, "KRB5CCNAME=%s\n", getenv("KRB5CCNAME"));
 
307
 
 
308
   if (cmd)
 
309
      system(cmd);
 
310
 
 
311
   if (ecmd) {
 
312
      int eargc = 0;
 
313
      char *eargv[256];
 
314
      eargv[eargc] = strtok(ecmd, " \t");
 
315
      while(eargv[eargc])
 
316
         eargv[++eargc] = strtok(NULL, " \t");
 
317
      execv(eargv[0], eargv);
 
318
      perror("exec failed");
 
319
   }
 
320
 
 
321
error:
 
322
 
 
323
   return cc;
 
324
}
 
325