155682Smarkm/* 2233294Sstas * Copyright (c) 1995 - 2005 Kungliga Tekniska H��gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 5233294Sstas * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 9233294Sstas * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 12233294Sstas * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 16233294Sstas * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 20233294Sstas * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#ifdef HAVE_CONFIG_H 3555682Smarkm#include <config.h> 3655682Smarkm#endif 3755682Smarkm 38233294SstasRCSID("$Id$"); 3955682Smarkm 4055682Smarkm#include <stdio.h> 4155682Smarkm#include <stdlib.h> 4255682Smarkm#include <string.h> 4355682Smarkm#include <unistd.h> 4455682Smarkm#ifdef HAVE_SYS_TYPES_H 4555682Smarkm#include <sys/types.h> 4655682Smarkm#endif 4755682Smarkm#include <time.h> 4855682Smarkm#ifdef HAVE_FCNTL_H 4955682Smarkm#include <fcntl.h> 5055682Smarkm#endif 5155682Smarkm#ifdef HAVE_PWD_H 5255682Smarkm#include <pwd.h> 5355682Smarkm#endif 5455682Smarkm 5555682Smarkm#ifdef KRB5 5655682Smarkm#include <krb5.h> 5755682Smarkm#endif 5855682Smarkm#include <kafs.h> 5955682Smarkm 6055682Smarkm#include <err.h> 6155682Smarkm#include <roken.h> 62102644Snectar#include <getarg.h> 6355682Smarkm 64178825Sdfr#ifndef TKT_ROOT 65178825Sdfr#define TKT_ROOT "/tmp/tkt" 66178825Sdfr#endif 67178825Sdfr 68102644Snectarstatic int help_flag; 69102644Snectarstatic int version_flag; 70102644Snectarstatic int c_flag; 71178825Sdfr#ifdef KRB5 72178825Sdfrstatic char *typename_arg; 73178825Sdfr#endif 74102644Snectar 75102644Snectarstruct getargs getargs[] = { 76102644Snectar { NULL, 'c', arg_flag, &c_flag }, 77178825Sdfr#ifdef KRB5 78178825Sdfr { "cache-type", 0, arg_string, &typename_arg }, 79178825Sdfr#endif 80102644Snectar { "version", 0, arg_flag, &version_flag }, 81102644Snectar { "help", 'h', arg_flag, &help_flag }, 82102644Snectar}; 83102644Snectar 84102644Snectarstatic int num_args = sizeof(getargs) / sizeof(getargs[0]); 85102644Snectar 86102644Snectarstatic void 87102644Snectarusage(int ecode) 88102644Snectar{ 89102644Snectar arg_printusage(getargs, num_args, NULL, "command [args...]"); 90102644Snectar exit(ecode); 91102644Snectar} 92102644Snectar 9355682Smarkm/* 9455682Smarkm * Run command with a new ticket file / credentials cache / token 9555682Smarkm */ 9655682Smarkm 9755682Smarkmint 9855682Smarkmmain(int argc, char **argv) 9955682Smarkm{ 100178825Sdfr int f; 101178825Sdfr char tf[1024]; 102178825Sdfr char *p; 10355682Smarkm 104178825Sdfr char *path; 105178825Sdfr char **args; 106233294Sstas unsigned int i; 107178825Sdfr int optind = 0; 10855682Smarkm 109178825Sdfr setprogname(argv[0]); 110178825Sdfr if(getarg(getargs, num_args, argc, argv, &optind)) 111178825Sdfr usage(1); 112178825Sdfr if(help_flag) 113178825Sdfr usage(0); 114178825Sdfr if(version_flag) { 115178825Sdfr print_version(NULL); 116178825Sdfr exit(0); 117178825Sdfr } 118102644Snectar 119178825Sdfr argc -= optind; 120178825Sdfr argv += optind; 121102644Snectar 12255682Smarkm#ifdef KRB5 123178825Sdfr { 124178825Sdfr krb5_error_code ret; 125178825Sdfr krb5_context context; 126178825Sdfr krb5_ccache id; 127178825Sdfr const char *name; 12855682Smarkm 129178825Sdfr ret = krb5_init_context(&context); 130178825Sdfr if (ret) /* XXX should this really call exit ? */ 131178825Sdfr errx(1, "no kerberos 5 support"); 132178825Sdfr 133233294Sstas ret = krb5_cc_new_unique(context, typename_arg, NULL, &id); 134178825Sdfr if (ret) 135178825Sdfr krb5_err(context, 1, ret, "Failed generating credential cache"); 136178825Sdfr 137178825Sdfr name = krb5_cc_get_name(context, id); 138178825Sdfr if (name == NULL) 139178825Sdfr krb5_errx(context, 1, "Generated credential cache have no name"); 140178825Sdfr 141233294Sstas snprintf(tf, sizeof(tf), "%s:%s", krb5_cc_get_type(context, id), name); 142178825Sdfr 143178825Sdfr ret = krb5_cc_close(context, id); 144178825Sdfr if (ret) 145178825Sdfr krb5_err(context, 1, ret, "Failed closing credential cache"); 146178825Sdfr 147178825Sdfr krb5_free_context(context); 148178825Sdfr 149178825Sdfr esetenv("KRB5CCNAME", tf, 1); 150178825Sdfr } 15155682Smarkm#endif 15255682Smarkm 153178825Sdfr snprintf (tf, sizeof(tf), "%s_XXXXXX", TKT_ROOT); 154178825Sdfr f = mkstemp (tf); 155178825Sdfr if (f < 0) 156178825Sdfr err(1, "mkstemp failed"); 157178825Sdfr close (f); 158178825Sdfr unlink (tf); 159178825Sdfr esetenv("KRBTKFILE", tf, 1); 16055682Smarkm 161178825Sdfr i = 0; 162178825Sdfr 163178825Sdfr args = (char **) malloc((argc + 10)*sizeof(char *)); 164178825Sdfr if (args == NULL) 165178825Sdfr errx (1, "Out of memory allocating %lu bytes", 166178825Sdfr (unsigned long)((argc + 10)*sizeof(char *))); 167233294Sstas 168178825Sdfr if(*argv == NULL) { 169178825Sdfr path = getenv("SHELL"); 170178825Sdfr if(path == NULL){ 171178825Sdfr struct passwd *pw = k_getpwuid(geteuid()); 172233294Sstas if (pw == NULL) 173233294Sstas errx(1, "no such user: %d", (int)geteuid()); 174178825Sdfr path = strdup(pw->pw_shell); 175178825Sdfr } 176178825Sdfr } else { 177178825Sdfr path = strdup(*argv++); 17855682Smarkm } 179178825Sdfr if (path == NULL) 180178825Sdfr errx (1, "Out of memory copying path"); 181233294Sstas 182178825Sdfr p=strrchr(path, '/'); 183178825Sdfr if(p) 184178825Sdfr args[i] = strdup(p+1); 185178825Sdfr else 186178825Sdfr args[i] = strdup(path); 18755682Smarkm 188178825Sdfr if (args[i++] == NULL) 189178825Sdfr errx (1, "Out of memory copying arguments"); 190233294Sstas 191178825Sdfr while(*argv) 192178825Sdfr args[i++] = *argv++; 19355682Smarkm 194178825Sdfr args[i++] = NULL; 19555682Smarkm 196178825Sdfr if(k_hasafs()) 197178825Sdfr k_setpag(); 19855682Smarkm 199178825Sdfr unsetenv("PAGPID"); 200178825Sdfr execvp(path, args); 201178825Sdfr if (errno == ENOENT || c_flag) { 202178825Sdfr char **sh_args = malloc ((i + 2) * sizeof(char *)); 203233294Sstas unsigned int j; 20455682Smarkm 205178825Sdfr if (sh_args == NULL) 206178825Sdfr errx (1, "Out of memory copying sh arguments"); 207178825Sdfr for (j = 1; j < i; ++j) 208178825Sdfr sh_args[j + 2] = args[j]; 209178825Sdfr sh_args[0] = "sh"; 210178825Sdfr sh_args[1] = "-c"; 211178825Sdfr sh_args[2] = path; 212178825Sdfr execv ("/bin/sh", sh_args); 213178825Sdfr } 214178825Sdfr err (1, "execvp"); 21555682Smarkm} 216