diff options
Diffstat (limited to 'src/clients/ksu/main.c')
-rw-r--r-- | src/clients/ksu/main.c | 227 |
1 files changed, 92 insertions, 135 deletions
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c index 77a4996..58d3031 100644 --- a/src/clients/ksu/main.c +++ b/src/clients/ksu/main.c @@ -42,7 +42,7 @@ int quiet = 0; #define _DEF_CSH "/bin/csh" static int set_env_var PROTOTYPE((char *, char *)); -static void sweep_up PROTOTYPE((krb5_context, int, krb5_ccache)); +static void sweep_up PROTOTYPE((krb5_context, krb5_ccache)); static char * ontty PROTOTYPE((void)); #ifdef HAVE_STDARG_H static void print_status( const char *fmt, ...) @@ -61,7 +61,6 @@ char * get_dir_of_file(); void usage (){ fprintf(stderr, "Usage: %s [target user] [-n principal] [-c source cachename] [-C target cachename] [-k] [-D] [-r time] [-pf] [-l lifetime] [-zZ] [-q] [-e command [args... ] ] [-a [args... ] ]\n", prog_name); - } /* for Ultrix and friends ... */ @@ -69,8 +68,6 @@ void usage (){ #define MAXHOSTNAMELEN 64 #endif -#define DEBUG - /* These are file static so sweep_up can get to them*/ static uid_t source_uid, target_uid; @@ -86,7 +83,6 @@ char *localhostname = NULL; opt_info options; int option=0; int statusp=0; -int use_source_cache = 0; krb5_error_code retval = 0; krb5_principal client = NULL; krb5_ccache cc_target = NULL; @@ -106,7 +102,7 @@ krb5_boolean auth_val; krb5_boolean authorization_val = FALSE; int path_passwd = 0; int done =0,i,j; -uid_t ruid; +uid_t ruid = getuid (); struct passwd *pwd=NULL, *target_pwd ; char * shell; char ** params; @@ -142,6 +138,11 @@ char * dir_of_cc_source; if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; prog_name = argv[0]; + if (strlen (prog_name) > 50) { + /* this many chars *after* last / ?? */ + com_err(prog_name, 0, "program name too long - quitting to avoid triggering system logging bugs"); + exit (1); + } #ifndef LOG_NDELAY @@ -176,7 +177,10 @@ char * dir_of_cc_source; } } - + if (krb5_seteuid (ruid)) { + com_err (prog_name, errno, "while setting euid to source user"); + exit (1); + } while(!done && ((option = getopt(pargc, pargv,"n:c:r:a:zZDfpkql:e:")) != -1)){ switch (option) { case 'r': @@ -232,22 +236,24 @@ char * dir_of_cc_source; options.princ = 1; break; +#ifdef DEBUG case 'D': auth_debug = 1; - break; + break; +#endif case 'z': some_rest_copy = 1; - if(all_rest_copy || use_source_cache){ + if(all_rest_copy) { fprintf(stderr, - "-z option is mutually exclusive with -Z and -C .\n"); + "-z option is mutually exclusive with -Z.\n"); errflg++; } break; case 'Z': all_rest_copy = 1; - if(some_rest_copy || use_source_cache){ + if(some_rest_copy) { fprintf(stderr, - "-Z option is mutually exclusive with -z and -C .\n"); + "-Z option is mutually exclusive with -z.\n"); errflg++; } break; @@ -258,10 +264,10 @@ char * dir_of_cc_source; cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1; if( stat( cc_source_tag_tmp, &st_temp)){ - fprintf(stderr,"File %s does not exist\n", - cc_source_tag_tmp); - errflg++; - + com_err (prog_name, errno, + "while looking for credentials file %s", + cc_source_tag_tmp); + exit (1); } } else { @@ -313,10 +319,9 @@ char * dir_of_cc_source; } /***********************************/ - ruid = getuid(); source_user = getlogin(); /*checks for the the login name in /etc/utmp*/ - /* verify that that the user exists and get his passwd structure */ + /* verify that that the user exists and get his passwd structure */ if (source_user == NULL ||(pwd = getpwnam(source_user)) == NULL || pwd->pw_uid != ruid){ @@ -327,6 +332,12 @@ char * dir_of_cc_source; fprintf(stderr, "ksu: who are you?\n"); exit(1); } + if (pwd->pw_uid != ruid) { + fprintf (stderr, "Your uid doesn't match your passwd entry?!\n"); + exit (1); + } + /* Okay, now we have *some* passwd entry that matches the + current real uid. */ /* allocate space and copy the usernamane there */ source_user = xstrdup(pwd->pw_name); @@ -357,23 +368,17 @@ char * dir_of_cc_source; else cc_source_tag_tmp++; } - if (krb5_seteuid(source_uid)) { - com_err ( prog_name, errno, "while setting euid to source user"); - exit(1); - } - + /* get a handle for the cache */ if ((retval = krb5_cc_resolve(ksu_context, cc_source_tag, &cc_source))){ com_err(prog_name, retval,"while getting source cache"); exit(1); } - if(!use_source_cache) { - if (((retval = krb5_cc_set_flags(ksu_context, cc_source, 0x0)) != 0) - && (retval != KRB5_FCC_NOFILE)) { + if (((retval = krb5_cc_set_flags(ksu_context, cc_source, 0x0)) != 0) + && (retval != KRB5_FCC_NOFILE)) { com_err(prog_name, retval, "while opening ccache"); exit(1); - } } if ((retval = get_best_princ_for_target(ksu_context, source_uid, target_uid, source_user, target_user, cc_source, @@ -409,29 +414,6 @@ char * dir_of_cc_source; exit(1); } - if (stat(cc_source_tag_tmp, &st_temp)){ - if (use_source_cache){ - - dir_of_cc_source = get_dir_of_file(cc_source_tag_tmp); - - - if (access(dir_of_cc_source, R_OK | W_OK )){ - fprintf(stderr, - "%s does not have correct permissions for %s\n", - source_user, cc_source_tag); - exit(1); - } - - if ((retval = krb5_cc_initialize(ksu_context, cc_source, - client))){ - com_err(prog_name, retval, - "while initializing source cache"); - exit(1); - } - } - } - - if (cc_target_tag == NULL) { cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE ,sizeof(char)); @@ -450,8 +432,7 @@ char * dir_of_cc_source; } - dir_of_cc_target = get_dir_of_file( use_source_cache ? - cc_source_tag_tmp: cc_target_tag_tmp); + dir_of_cc_target = get_dir_of_file(cc_target_tag_tmp); if (access(dir_of_cc_target, R_OK | W_OK )){ fprintf(stderr, @@ -475,48 +456,33 @@ char * dir_of_cc_source; The cache is owned by the target user.*/ - if (! use_source_cache){ - - /* if root ksu's to a regular user, then - then only the credentials for that particular user - should be copied */ + /* if root ksu's to a regular user, then + then only the credentials for that particular user + should be copied */ - if ((source_uid == 0) && (target_uid != 0)) { + if ((source_uid == 0) && (target_uid != 0)) { - if ((retval = krb5_ccache_copy_restricted(ksu_context, cc_source, - cc_target_tag, client, &cc_target, &stored, target_uid))){ - com_err (prog_name, retval, - "while copying cache %s to %s", - krb5_cc_get_name(ksu_context, cc_source),cc_target_tag); - exit(1); - } - - } else{ - if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, - client,&cc_target, &stored, target_uid))){ - com_err (prog_name, retval, - "while copying cache %s to %s", - krb5_cc_get_name(ksu_context, cc_source), - cc_target_tag); - exit(1); - } - - } - - } - else{ - cc_target = cc_source; - cc_target_tag = (char *) cc_source_tag; - cc_target_tag_tmp = (char *) cc_source_tag_tmp; - - if ((retval=krb5_find_princ_in_cache(ksu_context, cc_target,client, &stored))){ - com_err (prog_name, retval, - "while searching for client in source ccache"); - exit(1); - } + if ((retval = krb5_ccache_copy_restricted(ksu_context, cc_source, + cc_target_tag, client, &cc_target, &stored, target_uid))){ + com_err (prog_name, retval, + "while copying cache %s to %s", + krb5_cc_get_name(ksu_context, cc_source),cc_target_tag); + exit(1); + } + } else { + if ((retval = krb5_ccache_copy(ksu_context, cc_source, cc_target_tag, + client,&cc_target, &stored, target_uid))) { + com_err (prog_name, retval, + "while copying cache %s to %s", + krb5_cc_get_name(ksu_context, cc_source), + cc_target_tag); + exit(1); + } + } - /* Become root for authentication*/ + + /* Become root for authentication*/ if (krb5_seteuid(0)) { com_err(prog_name, errno, "while reclaiming root uid"); @@ -532,7 +498,7 @@ char * dir_of_cc_source; &kdc_server))){ com_err(prog_name, retval, "while creating tgt for local realm"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -544,8 +510,7 @@ char * dir_of_cc_source; if (zero_password == FALSE){ fprintf(stderr,"Goodbye\n"); - sweep_up(ksu_context, use_source_cache, - cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -574,7 +539,7 @@ char * dir_of_cc_source; syslog(LOG_WARNING, "'%s %s' authentication failed for %s%s", prog_name,target_user,source_user,ontty()); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -585,7 +550,7 @@ char * dir_of_cc_source; to properly handle races in chown if this code is ever re-enabled. */ /* cache the tickets if possible in the source cache */ - if (!path_passwd && !use_source_cache){ + if (!path_passwd){ if ((retval = krb5_ccache_overwrite(ksu_context, cc_target, cc_source, client))){ @@ -593,7 +558,7 @@ char * dir_of_cc_source; "while copying cache %s to %s", krb5_cc_get_name(ksu_context, cc_target), krb5_cc_get_name(ksu_context, cc_source)); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (chown(cc_source_tag_tmp, source_uid, source_gid)){ @@ -607,7 +572,7 @@ char * dir_of_cc_source; if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) { com_err (prog_name, retval, "When unparsing name"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -619,7 +584,7 @@ char * dir_of_cc_source; /* Run authorization as target.*/ if (krb5_seteuid(target_uid)) { com_err(prog_name, errno, "while switching to target for authorization check"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -627,13 +592,13 @@ char * dir_of_cc_source; cmd, &authorization_val, &exec_cmd))){ com_err(prog_name,retval,"while checking authorization"); krb5_seteuid(0); /*So we have some chance of sweeping up*/ - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (krb5_seteuid(0)) { com_err(prog_name, errno, "while switching back from target after authorization check"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (authorization_val == TRUE){ @@ -678,7 +643,7 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ } - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } } @@ -686,7 +651,7 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if( some_rest_copy){ if ((retval = krb5_ccache_filter(ksu_context, cc_target, client))){ com_err(prog_name,retval,"while calling cc_filter"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } } @@ -715,7 +680,7 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if (!standard_shell(target_pwd->pw_shell) && source_uid) { fprintf(stderr, "ksu: permission denied (shell).\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } #endif /* HAVE_GETUSERSHELL */ @@ -724,20 +689,20 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if(set_env_var("USER", target_pwd->pw_name)){ fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } } if(set_env_var( "HOME", target_pwd->pw_dir)){ fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if(set_env_var( "SHELL", shell)){ fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -746,26 +711,21 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if(set_env_var( KRB5_ENV_CCNAME, cc_target_tag)){ fprintf(stderr,"ksu: couldn't set environment variable %s\n", KRB5_ENV_CCNAME); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } - - if (!use_source_cache){ - - } - /* set permissions */ if (setgid(target_pwd->pw_gid) < 0) { perror("ksu: setgid"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } if (initgroups(target_user, target_pwd->pw_gid)) { fprintf(stderr, "ksu: initgroups failed.\n"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -785,14 +745,14 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ */ if (setluid((uid_t) pwd->pw_uid) < 0) { perror("setluid"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } #endif /* HAVE_SETLUID */ if (setuid(target_pwd->pw_uid) < 0) { perror("ksu: setuid"); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); } @@ -827,11 +787,11 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ fprintf(stderr, "program to be execed %s\n",params[0]); } - if( keep_target_cache || use_source_cache ) { + if( keep_target_cache ) { execv(params[0], params); com_err(prog_name, errno, "while trying to execv %s", params[0]); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit(1); }else{ statusp = 1; @@ -858,11 +818,11 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ if (ret_pid == -1) { com_err(prog_name, errno, "while calling waitpid"); } - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit (statusp); case -1: com_err(prog_name, errno, "while trying to fork."); - sweep_up(ksu_context, use_source_cache, cc_target); + sweep_up(ksu_context, cc_target); exit (1); case 0: execv(params[0], params); @@ -920,27 +880,24 @@ char * env_var_buf; } -static void sweep_up(context, use_source_cache, cc) +static void sweep_up(context, cc) krb5_context context; - int use_source_cache; krb5_ccache cc; { -krb5_error_code retval; -char * cc_name; -struct stat st_temp; + krb5_error_code retval; + char * cc_name; + struct stat st_temp; -krb5_seteuid(0); -krb5_seteuid(target_uid); + krb5_seteuid(0); + krb5_seteuid(target_uid); -if (! use_source_cache){ - cc_name = krb5_cc_get_name(context, cc); - if ( ! stat(cc_name, &st_temp)){ - if ((retval = krb5_cc_destroy(context, cc))){ - com_err(prog_name, retval, - "while destroying cache"); - } - } + cc_name = krb5_cc_get_name(context, cc); + if ( ! stat(cc_name, &st_temp)){ + if ((retval = krb5_cc_destroy(context, cc))){ + com_err(prog_name, retval, + "while destroying cache"); } + } } /***************************************************************** get_params is to be called for the -a option or -e option to |