From: Ezra Peisach Date: Mon, 11 Jun 2001 16:14:23 +0000 (+0000) Subject: * setenv.c: Add prototype for _findenv to avoid inconsistancy of X-Git-Tag: krb5-1.3-alpha1~1434 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=2b93e5f1ff2d15fd754aee9eb832b4c07ba3ec68;p=krb5.git * setenv.c: Add prototype for _findenv to avoid inconsistancy of static vs. extern. * heuristic.c (find_either_ticket): Change krb5_tgtname() to ksu_tgtname(). * ccache.c: Include and for start() prototype. * krb_auth_su.c: Reindent for readability. Remove defunct code. Change use of krb5_tgtname to ksu_tgtname(). * ksu.h: Include k5-util.h for krb5_seteuid() prototype. Add prototype for ksu_tgtname. Add prototype for unsetenv() if not defined. * main.c: Include grp.h for initgroups() prototype. Cleanup assignment in conditional warning. Reindent for readability. Arguments to print_status made consistant with regard to long vs. int. Change krb5_tgtname to ksu_tgtname. (do not use an internal krb5 function that is not advertised). git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@13328 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/clients/ksu/ChangeLog b/src/clients/ksu/ChangeLog index f2dc459d9..daa4cd5ce 100644 --- a/src/clients/ksu/ChangeLog +++ b/src/clients/ksu/ChangeLog @@ -1,3 +1,27 @@ +2001-06-11 Ezra Peisach + + * setenv.c: Add prototype for _findenv to avoid inconsistancy of + static vs. extern. + + * heuristic.c (find_either_ticket): Change krb5_tgtname() to + ksu_tgtname(). + + * ccache.c: Include and for start() + prototype. + + * krb_auth_su.c: Reindent for readability. Remove defunct + code. Change use of krb5_tgtname to ksu_tgtname(). + + * ksu.h: Include k5-util.h for krb5_seteuid() prototype. Add + prototype for ksu_tgtname. Add prototype for unsetenv() if not + defined. + + * main.c: Include grp.h for initgroups() prototype. Cleanup + assignment in conditional warning. Reindent for + readability. Arguments to print_status made consistant with regard + to long vs. int. Change krb5_tgtname to ksu_tgtname. (do not use + an internal krb5 function that is not advertised). + 2001-06-05 Ezra Peisach * authorization.c, heuristic.c, krb_auth_su.c, main.c, setenv.c: diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c index 065762e7a..62d76aa87 100644 --- a/src/clients/ksu/ccache.c +++ b/src/clients/ksu/ccache.c @@ -27,6 +27,8 @@ #include "ksu.h" #include "adm_proto.h" +#include +#include /****************************************************************** krb5_cache_copy diff --git a/src/clients/ksu/heuristic.c b/src/clients/ksu/heuristic.c index 76d697744..471184d7e 100644 --- a/src/clients/ksu/heuristic.c +++ b/src/clients/ksu/heuristic.c @@ -418,7 +418,7 @@ krb5_error_code find_either_ticket (context, cc, client, end_server, found) return retval; if (temp_found == FALSE){ - retval = krb5_tgtname(context, + retval = ksu_tgtname(context, krb5_princ_realm(context, client), krb5_princ_realm(context, client), &kdc_server); diff --git a/src/clients/ksu/krb_auth_su.c b/src/clients/ksu/krb_auth_su.c index 4e6bf127b..233cb1179 100644 --- a/src/clients/ksu/krb_auth_su.c +++ b/src/clients/ksu/krb_auth_su.c @@ -37,16 +37,9 @@ static krb5_error_code krb5_verify_tkt_def void plain_dump_principal (); -krb5_data tgtname = { - 0, - KRB5_TGS_NAME_SIZE, - KRB5_TGS_NAME -}; - /* * Try no preauthentication first; then try the encrypted timestamp */ -krb5_preauthtype preauth_list[2] = { 0, -1 }; krb5_preauthtype * preauth_ptr = NULL; @@ -58,179 +51,183 @@ krb5_boolean krb5_auth_check(context, client_pname, hostname, options, char *hostname; opt_info *options; char *target_user; -uid_t target_uid; + uid_t target_uid; krb5_ccache cc; int *path_passwd; { -krb5_principal client, server; -krb5_creds tgt, tgtq, in_creds, * out_creds; -krb5_creds **tgts = NULL; /* list of ticket granting tickets */ - -krb5_ticket * target_tkt; /* decrypted ticket for server */ -krb5_error_code retval =0; -int got_it = 0; -krb5_boolean zero_password; - - *path_passwd = 0; - memset((char *) &tgtq, 0, sizeof(tgtq)); - memset((char *) &tgt, 0, sizeof(tgt)); - memset((char *) &in_creds, 0, sizeof(krb5_creds)); - + krb5_principal client, server; + krb5_creds tgt, tgtq, in_creds, * out_creds; + krb5_creds **tgts = NULL; /* list of ticket granting tickets */ + + krb5_ticket * target_tkt; /* decrypted ticket for server */ + krb5_error_code retval =0; + int got_it = 0; + krb5_boolean zero_password; + + *path_passwd = 0; + memset((char *) &tgtq, 0, sizeof(tgtq)); + memset((char *) &tgt, 0, sizeof(tgt)); + memset((char *) &in_creds, 0, sizeof(krb5_creds)); + - if ((retval= krb5_copy_principal(context, client_pname, &client))){ - com_err(prog_name, retval,"while copying client principal"); - return (FALSE) ; - } - - if (auth_debug) - { dump_principal(context, "krb5_auth_check: Client principal name", client); } - - if ((retval = krb5_sname_to_principal(context, hostname, NULL, - KRB5_NT_SRV_HST, &server))){ - com_err(prog_name, retval, - "while creating server %s principal name", hostname); - krb5_free_principal(context, client); - return (FALSE) ; - } - - if (auth_debug) - { dump_principal(context, "krb5_auth_check: Server principal name", server); } - - - - /* check if ticket is already in the cache, if it is - then use it. - */ - if( krb5_fast_auth(context, client, server, target_user, cc) == TRUE){ - if (auth_debug ){ - fprintf (stderr,"Authenticated via fast_auth \n"); - } - return TRUE; - } - - /* check to see if the local tgt is in the cache */ - - if ((retval= krb5_copy_principal(context, client, &tgtq.client))){ - com_err(prog_name, retval,"while copying client principal"); - return (FALSE) ; + if ((retval= krb5_copy_principal(context, client_pname, &client))){ + com_err(prog_name, retval,"while copying client principal"); + return (FALSE) ; + } + + if (auth_debug) { + dump_principal(context, "krb5_auth_check: Client principal name", + client); + } + + if ((retval = krb5_sname_to_principal(context, hostname, NULL, + KRB5_NT_SRV_HST, &server))){ + com_err(prog_name, retval, + "while creating server %s principal name", hostname); + krb5_free_principal(context, client); + return (FALSE) ; + } + + if (auth_debug) { + dump_principal(context, "krb5_auth_check: Server principal name", + server); + } + + + + /* check if ticket is already in the cache, if it is + then use it. + */ + if( krb5_fast_auth(context, client, server, target_user, cc) == TRUE){ + if (auth_debug ){ + fprintf (stderr,"Authenticated via fast_auth \n"); } + return TRUE; + } + + /* check to see if the local tgt is in the cache */ + + if ((retval= krb5_copy_principal(context, client, &tgtq.client))){ + com_err(prog_name, retval,"while copying client principal"); + return (FALSE) ; + } + + if ((retval = ksu_tgtname(context, krb5_princ_realm(context, client), + krb5_princ_realm(context, client), + &tgtq.server))){ + com_err(prog_name, retval, "while creating tgt for local realm"); + krb5_free_principal(context, client); + krb5_free_principal(context, server); + return (FALSE) ; + } - if ((retval = krb5_tgtname(context, krb5_princ_realm(context, client), - krb5_princ_realm(context, client), - &tgtq.server))){ - com_err(prog_name, retval, "while creating tgt for local realm"); - krb5_free_principal(context, client); - krb5_free_principal(context, server); - return (FALSE) ; - } - - if (auth_debug){ dump_principal(context, "local tgt principal name", tgtq.server ); } - retval = krb5_cc_retrieve_cred(context, cc, - KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES, - &tgtq, &tgt); - - if (! retval) retval = krb5_check_exp(context, tgt.times); - - if (retval){ - if ((retval != KRB5_CC_NOTFOUND) && - (retval != KRB5KRB_AP_ERR_TKT_EXPIRED)){ - com_err(prog_name, retval, - "while retrieving creds from cache"); - return (FALSE) ; - } - } else{ - got_it = 1; + if (auth_debug){ dump_principal(context, "local tgt principal name", tgtq.server ); } + retval = krb5_cc_retrieve_cred(context, cc, + KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES, + &tgtq, &tgt); + + if (! retval) retval = krb5_check_exp(context, tgt.times); + + if (retval){ + if ((retval != KRB5_CC_NOTFOUND) && + (retval != KRB5KRB_AP_ERR_TKT_EXPIRED)){ + com_err(prog_name, retval, + "while retrieving creds from cache"); + return (FALSE) ; } + } else{ + got_it = 1; + } + + if (! got_it){ - if (! got_it){ - #ifdef GET_TGT_VIA_PASSWD - if (krb5_seteuid(0)||krb5_seteuid(target_uid)) { + if (krb5_seteuid(0)||krb5_seteuid(target_uid)) { com_err("ksu", errno, "while switching to target uid"); return FALSE; - } - - - fprintf(stderr,"WARNING: Your password may be exposed if you enter it here and are logged \n"); - fprintf(stderr," in remotely using an unsecure (non-encrypted) channel. \n"); + } - /*get the ticket granting ticket, via passwd(promt for passwd)*/ - if (krb5_get_tkt_via_passwd (context, &cc, client, tgtq.server, - options, & zero_password) == FALSE){ -krb5_seteuid(0); - - return FALSE; - } - *path_passwd = 1; - if (krb5_seteuid(0)) { - com_err("ksu", errno, "while reclaiming root uid"); - return FALSE; - } + fprintf(stderr,"WARNING: Your password may be exposed if you enter it here and are logged \n"); + fprintf(stderr," in remotely using an unsecure (non-encrypted) channel. \n"); + + /*get the ticket granting ticket, via passwd(promt for passwd)*/ + if (krb5_get_tkt_via_passwd (context, &cc, client, tgtq.server, + options, & zero_password) == FALSE){ + krb5_seteuid(0); + + return FALSE; + } + *path_passwd = 1; + if (krb5_seteuid(0)) { + com_err("ksu", errno, "while reclaiming root uid"); + return FALSE; + } + #else plain_dump_principal (client); fprintf(stderr,"does not have any appropriate tickets in the cache.\n"); return FALSE; - + #endif /* GET_TGT_VIA_PASSWD */ - } - - if ((retval= krb5_copy_principal(context, client, &in_creds.client))){ - com_err(prog_name, retval,"while copying client principal"); - return (FALSE) ; - } + } + + if ((retval= krb5_copy_principal(context, client, &in_creds.client))){ + com_err(prog_name, retval,"while copying client principal"); + return (FALSE) ; + } + + if ((retval= krb5_copy_principal(context, server, &in_creds.server))){ + com_err(prog_name, retval,"while copying client principal"); + return (FALSE) ; + } + + if ((retval = krb5_get_cred_from_kdc(context, cc, &in_creds, + &out_creds, &tgts))){ + com_err(prog_name, retval, "while geting credentials from kdc"); + return (FALSE); + } + - if ((retval= krb5_copy_principal(context, server, &in_creds.server))){ - com_err(prog_name, retval,"while copying client principal"); - return (FALSE) ; - } + if (auth_debug){ + fprintf(stderr,"krb5_auth_check: got ticket for end server \n"); + dump_principal(context, "out_creds->server", out_creds->server ); + } + + + if (tgts){ + register int i =0; - if ((retval = krb5_get_cred_from_kdc(context, cc, &in_creds, - &out_creds, &tgts))){ - com_err(prog_name, retval, "while geting credentials from kdc"); - return (FALSE); + if (auth_debug){ + fprintf(stderr, "krb5_auth_check: went via multiple realms"); } - - - if (auth_debug){ - fprintf(stderr,"krb5_auth_check: got ticket for end server \n"); - dump_principal(context, "out_creds->server", out_creds->server ); - } - - - if (tgts){ - register int i =0; - - if (auth_debug){ - fprintf(stderr, "krb5_auth_check: went via multiple realms"); - } - while (tgts[i]){ - if ((retval=krb5_cc_store_cred(context,cc,tgts[i]))) { - com_err(prog_name, retval, - "while storing credentials from cross-realm walk"); - return (FALSE); - } - i++; - } - krb5_free_tgt_creds(context, tgts); - } - - retval = krb5_verify_tkt_def(context, client, server, - &out_creds->keyblock, &out_creds->ticket, - &target_tkt); - if (retval) { - com_err(prog_name, retval, "while verifying ticket for server"); - return (FALSE); - } - - if ((retval = krb5_cc_store_cred(context, cc, out_creds))){ + while (tgts[i]){ + if ((retval=krb5_cc_store_cred(context,cc,tgts[i]))) { com_err(prog_name, retval, - "While storing credentials"); + "while storing credentials from cross-realm walk"); return (FALSE); + } + i++; } + krb5_free_tgt_creds(context, tgts); + } + + retval = krb5_verify_tkt_def(context, client, server, + &out_creds->keyblock, &out_creds->ticket, + &target_tkt); + if (retval) { + com_err(prog_name, retval, "while verifying ticket for server"); + return (FALSE); + } + + if ((retval = krb5_cc_store_cred(context, cc, out_creds))){ + com_err(prog_name, retval, + "While storing credentials"); + return (FALSE); + } - return (TRUE); + return (TRUE); } /* krb5_fast_auth checks if ticket for the end server is already in @@ -244,39 +241,39 @@ krb5_boolean krb5_fast_auth(context, client, server, target_user, cc) krb5_ccache cc; { -krb5_creds tgt, tgtq; -krb5_ticket * target_tkt; -krb5_error_code retval; - - memset((char *) &tgtq, 0, sizeof(tgtq)); - memset((char *) &tgt, 0, sizeof(tgt)); - - if ((retval= krb5_copy_principal(context, client, &tgtq.client))){ - com_err(prog_name, retval,"while copying client principal"); - return (FALSE) ; - } - - if ((retval= krb5_copy_principal(context, server, &tgtq.server))){ - com_err(prog_name, retval,"while copying client principal"); - return (FALSE) ; - } - - if ((retval = krb5_cc_retrieve_cred(context, cc, - KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES, - &tgtq, &tgt))){ - if (auth_debug) - com_err(prog_name, retval,"While Retrieving credentials"); - return (FALSE) ; - - } - - if ((retval = krb5_verify_tkt_def(context, client, server, &tgt.keyblock, - &tgt.ticket, &target_tkt))){ - com_err(prog_name, retval, "while verifing ticket for server"); - return (FALSE); - } - - return TRUE; + krb5_creds tgt, tgtq; + krb5_ticket * target_tkt; + krb5_error_code retval; + + memset((char *) &tgtq, 0, sizeof(tgtq)); + memset((char *) &tgt, 0, sizeof(tgt)); + + if ((retval= krb5_copy_principal(context, client, &tgtq.client))){ + com_err(prog_name, retval,"while copying client principal"); + return (FALSE) ; + } + + if ((retval= krb5_copy_principal(context, server, &tgtq.server))){ + com_err(prog_name, retval,"while copying client principal"); + return (FALSE) ; + } + + if ((retval = krb5_cc_retrieve_cred(context, cc, + KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES, + &tgtq, &tgt))){ + if (auth_debug) + com_err(prog_name, retval,"While Retrieving credentials"); + return (FALSE) ; + + } + + if ((retval = krb5_verify_tkt_def(context, client, server, &tgt.keyblock, + &tgt.ticket, &target_tkt))){ + com_err(prog_name, retval, "while verifing ticket for server"); + return (FALSE); + } + + return TRUE; } static krb5_error_code @@ -291,108 +288,108 @@ krb5_verify_tkt_def(context, client, server, cred_ses_key, /* OUT */ krb5_ticket **clear_ticket; { -krb5_keytab keytabid; -krb5_enctype enctype; -krb5_keytab_entry ktentry; -krb5_keyblock *tkt_key = NULL; -krb5_ticket * tkt = NULL; -krb5_error_code retval =0; -krb5_keyblock * tkt_ses_key; - - if ((retval = decode_krb5_ticket(scr_ticket, &tkt))){ - return retval; - } - - if (server && !krb5_principal_compare(context, server, tkt->server)){ - return KRB5KRB_AP_WRONG_PRINC; - } - - if (auth_debug){ - fprintf(stderr,"krb5_verify_tkt_def: verified target server\n"); - dump_principal(context, "server", server); - dump_principal(context, "tkt->server", tkt->server); - } - - /* get the default keytab */ - if ((retval = krb5_kt_default(context, &keytabid))){ - krb5_free_ticket(context, tkt); - return retval; - } - - enctype = tkt->enc_part.enctype; - - if ((retval = krb5_kt_get_entry(context, keytabid, server, - tkt->enc_part.kvno, enctype, &ktentry))){ - krb5_free_ticket(context, tkt); - return retval; - } - - krb5_kt_close(context, keytabid); - - if ((retval = krb5_copy_keyblock(context, &ktentry.key, &tkt_key))){ - krb5_free_ticket(context, tkt); - krb5_kt_free_entry(context, &ktentry); - return retval; - } + krb5_keytab keytabid; + krb5_enctype enctype; + krb5_keytab_entry ktentry; + krb5_keyblock *tkt_key = NULL; + krb5_ticket * tkt = NULL; + krb5_error_code retval =0; + krb5_keyblock * tkt_ses_key; + + if ((retval = decode_krb5_ticket(scr_ticket, &tkt))){ + return retval; + } + + if (server && !krb5_principal_compare(context, server, tkt->server)){ + return KRB5KRB_AP_WRONG_PRINC; + } + + if (auth_debug){ + fprintf(stderr,"krb5_verify_tkt_def: verified target server\n"); + dump_principal(context, "server", server); + dump_principal(context, "tkt->server", tkt->server); + } + + /* get the default keytab */ + if ((retval = krb5_kt_default(context, &keytabid))){ + krb5_free_ticket(context, tkt); + return retval; + } + enctype = tkt->enc_part.enctype; + + if ((retval = krb5_kt_get_entry(context, keytabid, server, + tkt->enc_part.kvno, enctype, &ktentry))){ + krb5_free_ticket(context, tkt); + return retval; + } + + krb5_kt_close(context, keytabid); + + if ((retval = krb5_copy_keyblock(context, &ktentry.key, &tkt_key))){ + krb5_free_ticket(context, tkt); + krb5_kt_free_entry(context, &ktentry); + return retval; + } + /* decrypt the ticket */ - if ((retval = krb5_decrypt_tkt_part(context, tkt_key, tkt))) { - krb5_free_ticket(context, tkt); - krb5_kt_free_entry(context, &ktentry); - krb5_free_keyblock(context, tkt_key); - return(retval); - } - - /* Check to make sure ticket hasn't expired */ - retval = krb5_check_exp(context, tkt->enc_part2->times); - if (retval) { - if (auth_debug && (retval == KRB5KRB_AP_ERR_TKT_EXPIRED)) { - fprintf(stderr, - "krb5_verify_tkt_def: ticket has expired"); - } - krb5_free_ticket(context, tkt); - krb5_kt_free_entry(context, &ktentry); - krb5_free_keyblock(context, tkt_key); - return KRB5KRB_AP_ERR_TKT_EXPIRED; - } + if ((retval = krb5_decrypt_tkt_part(context, tkt_key, tkt))) { + krb5_free_ticket(context, tkt); + krb5_kt_free_entry(context, &ktentry); + krb5_free_keyblock(context, tkt_key); + return(retval); + } - if (!krb5_principal_compare(context, client, tkt->enc_part2->client)) { - krb5_free_ticket(context, tkt); - krb5_kt_free_entry(context, &ktentry); - krb5_free_keyblock(context, tkt_key); - return KRB5KRB_AP_ERR_BADMATCH; + /* Check to make sure ticket hasn't expired */ + retval = krb5_check_exp(context, tkt->enc_part2->times); + if (retval) { + if (auth_debug && (retval == KRB5KRB_AP_ERR_TKT_EXPIRED)) { + fprintf(stderr, + "krb5_verify_tkt_def: ticket has expired"); } - - if (auth_debug){ - fprintf(stderr, - "krb5_verify_tkt_def: verified client's identity\n"); - dump_principal(context, "client", client); - dump_principal(context, "tkt->enc_part2->client",tkt->enc_part2->client); - } - - tkt_ses_key = tkt->enc_part2->session; - - if (cred_ses_key->enctype != tkt_ses_key->enctype || - cred_ses_key->length != tkt_ses_key->length || - memcmp((char *)cred_ses_key->contents, - (char *)tkt_ses_key->contents, cred_ses_key->length)) { - - krb5_free_ticket(context, tkt); - krb5_kt_free_entry(context, &ktentry); - krb5_free_keyblock(context, tkt_key); - return KRB5KRB_AP_ERR_BAD_INTEGRITY; - } - - if (auth_debug){ - fprintf(stderr, - "krb5_verify_tkt_def: session keys match \n"); - } - - *clear_ticket = tkt; + krb5_free_ticket(context, tkt); krb5_kt_free_entry(context, &ktentry); krb5_free_keyblock(context, tkt_key); - return 0; - + return KRB5KRB_AP_ERR_TKT_EXPIRED; + } + + if (!krb5_principal_compare(context, client, tkt->enc_part2->client)) { + krb5_free_ticket(context, tkt); + krb5_kt_free_entry(context, &ktentry); + krb5_free_keyblock(context, tkt_key); + return KRB5KRB_AP_ERR_BADMATCH; + } + + if (auth_debug){ + fprintf(stderr, + "krb5_verify_tkt_def: verified client's identity\n"); + dump_principal(context, "client", client); + dump_principal(context, "tkt->enc_part2->client",tkt->enc_part2->client); + } + + tkt_ses_key = tkt->enc_part2->session; + + if (cred_ses_key->enctype != tkt_ses_key->enctype || + cred_ses_key->length != tkt_ses_key->length || + memcmp((char *)cred_ses_key->contents, + (char *)tkt_ses_key->contents, cred_ses_key->length)) { + + krb5_free_ticket(context, tkt); + krb5_kt_free_entry(context, &ktentry); + krb5_free_keyblock(context, tkt_key); + return KRB5KRB_AP_ERR_BAD_INTEGRITY; + } + + if (auth_debug){ + fprintf(stderr, + "krb5_verify_tkt_def: session keys match \n"); + } + + *clear_ticket = tkt; + krb5_kt_free_entry(context, &ktentry); + krb5_free_keyblock(context, tkt_key); + return 0; + } @@ -413,7 +410,7 @@ krb5_boolean krb5_get_tkt_via_passwd (context, ccache, client, server, *zero_password = FALSE; - + if ((code = krb5_unparse_name(context, client, &client_name))) { com_err (prog_name, code, "when unparsing name"); return (FALSE); @@ -438,43 +435,43 @@ krb5_boolean krb5_get_tkt_via_passwd (context, ccache, client, server, my_creds.times.starttime = 0; /* start timer when request gets to KDC */ - + my_creds.times.endtime = now + options->lifetime; if (options->opt & KDC_OPT_RENEWABLE) { my_creds.times.renew_till = now + options->rlife; } else my_creds.times.renew_till = 0; - if (strlen (client_name) + 80 > sizeof (prompt)) { - fprintf (stderr, - "principal name %s too long for internal buffer space\n", - client_name); - return FALSE; - } - (void) sprintf(prompt,"Kerberos password for %s: ", client_name); - - pwsize = sizeof(password); - - code = krb5_read_password(context, prompt, 0, password, &pwsize); - if (code ) { - com_err(prog_name, code, "while reading password for '%s'\n", - client_name); - memset(password, 0, sizeof(password)); - return (FALSE); - } - - if ( pwsize == 0) { - fprintf(stderr, "No password given\n"); - *zero_password = TRUE; - memset(password, 0, sizeof(password)); - return (FALSE); - } - - code = krb5_get_in_tkt_with_password(context, options->opt, - 0, NULL, preauth_ptr, - password, *ccache, &my_creds, 0); - memset(password, 0, sizeof(password)); - + if (strlen (client_name) + 80 > sizeof (prompt)) { + fprintf (stderr, + "principal name %s too long for internal buffer space\n", + client_name); + return FALSE; + } + (void) sprintf(prompt,"Kerberos password for %s: ", client_name); + + pwsize = sizeof(password); + + code = krb5_read_password(context, prompt, 0, password, &pwsize); + if (code ) { + com_err(prog_name, code, "while reading password for '%s'\n", + client_name); + memset(password, 0, sizeof(password)); + return (FALSE); + } + + if ( pwsize == 0) { + fprintf(stderr, "No password given\n"); + *zero_password = TRUE; + memset(password, 0, sizeof(password)); + return (FALSE); + } + + code = krb5_get_in_tkt_with_password(context, options->opt, + 0, NULL, preauth_ptr, + password, *ccache, &my_creds, 0); + memset(password, 0, sizeof(password)); + if (code) { if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) @@ -513,80 +510,9 @@ void plain_dump_principal (context, p) fprintf(stderr, "%s ", stname); } -#if 0 -krb5_error_code get_tgt_via_login_list(context, server, cc, k5login_plist, - client, got_it) - krb5_context context; - krb5_principal server; - krb5_ccache cc; - char **k5login_plist; - krb5_principal *client; - int *got_it; -{ - -krb5_creds tgt, tgtq; -int i =0; -krb5_principal temp_client; -krb5_error_code retval =0; - *got_it=0; - - if (! k5login_plist ) return 0; - - memset((char *) &tgtq, 0, sizeof(tgtq)); - memset((char *) &tgt, 0, sizeof(tgt)); - - while(k5login_plist[i]){ - if (retval = krb5_parse_name(context, k5login_plist[i], - &temp_client)){ - return retval; - } - - - if (retval= krb5_copy_principal(context, temp_client, - &tgtq.client)){ - return retval ; - } - - /* check to see if the local tgt is in the cache */ - - if (retval = krb5_tgtname(context, - krb5_princ_realm(context, temp_client), - krb5_princ_realm(context, temp_client), - &tgtq.server)){ - return retval ; - } - - retval = krb5_cc_retrieve_cred(context, cc, - KRB5_TC_MATCH_SRV_NAMEONLY, - &tgtq, &tgt); - - if (! retval) retval = krb5_check_exp(context, tgt.times); - - if (retval){ - if ((retval != KRB5_CC_NOTFOUND) && - (retval != KRB5KRB_AP_ERR_TKT_EXPIRED)){ - return retval ; - } - } else{ - if (auth_debug){ - fprintf(stderr,"Auth via k5login name %s\n", - k5login_plist[i]); - } - - *got_it = 1; - *client = temp_client; - break; - } - - i++; - } - - return 0; -} -#endif /********************************************************************** -returns the principal that is closes to client. plist contains +returns the principal that is closest to client. plist contains a principal list obtained from .k5login and parhaps .k5users file. This routine gets called before getting the password for a tgt. A principal is picked that has the best chance of getting in. @@ -599,58 +525,58 @@ krb5_error_code get_best_principal(context, plist, client) char **plist; krb5_principal *client; { -krb5_error_code retval =0; -krb5_principal temp_client, best_client = NULL; - -int i = 0, nelem; - - if (! plist ) return 0; - - nelem = krb5_princ_size(context, *client); - - while(plist[i]){ - - if ((retval = krb5_parse_name(context, plist[i], &temp_client))){ - return retval; - } - - if (krb5_princ_realm(context, *client)->length == - krb5_princ_realm(context, temp_client)->length - && (!memcmp (krb5_princ_realm(context, *client)->data, - krb5_princ_realm(context, temp_client)->data, - krb5_princ_realm(context, temp_client)->length))){ - - - if(nelem){ - krb5_data *p1 = - krb5_princ_component(context, *client, 0); - krb5_data *p2 = - krb5_princ_component(context, temp_client, 0); - - if ((p1->length == p2->length) && - (!memcmp(p1->data,p2->data,p1->length))){ - - if (auth_debug){ - fprintf(stderr, - "get_best_principal: compare with %s\n", - plist[i]); - } - - if(best_client){ - if(krb5_princ_size(context, best_client) > - krb5_princ_size(context, temp_client)){ - best_client = temp_client; - } - }else{ - best_client = temp_client; - } - } + krb5_error_code retval =0; + krb5_principal temp_client, best_client = NULL; + + int i = 0, nelem; + + if (! plist ) return 0; + + nelem = krb5_princ_size(context, *client); + + while(plist[i]){ + + if ((retval = krb5_parse_name(context, plist[i], &temp_client))){ + return retval; + } + + if (krb5_princ_realm(context, *client)->length == + krb5_princ_realm(context, temp_client)->length + && (!memcmp (krb5_princ_realm(context, *client)->data, + krb5_princ_realm(context, temp_client)->data, + krb5_princ_realm(context, temp_client)->length))){ + + + if(nelem){ + krb5_data *p1 = + krb5_princ_component(context, *client, 0); + krb5_data *p2 = + krb5_princ_component(context, temp_client, 0); + + if ((p1->length == p2->length) && + (!memcmp(p1->data,p2->data,p1->length))){ + + if (auth_debug){ + fprintf(stderr, + "get_best_principal: compare with %s\n", + plist[i]); + } + + if(best_client){ + if(krb5_princ_size(context, best_client) > + krb5_princ_size(context, temp_client)){ + best_client = temp_client; } - + }else{ + best_client = temp_client; + } } - i++; - } - - if (best_client) *client = best_client; - return 0; + } + + } + i++; + } + + if (best_client) *client = best_client; + return 0; } diff --git a/src/clients/ksu/ksu.h b/src/clients/ksu/ksu.h index 230c59651..c8c21ed99 100644 --- a/src/clients/ksu/ksu.h +++ b/src/clients/ksu/ksu.h @@ -26,6 +26,7 @@ */ #include "k5-int.h" +#include "k5-util.h" #include #include "com_err.h" #include @@ -233,6 +234,10 @@ extern krb5_error_code get_best_princ_for_target PROTOTYPE((krb5_context, int, int, char *, char *, krb5_ccache, opt_info *, char *, char *, krb5_principal *, int *)); +extern krb5_error_code ksu_tgtname PROTOTYPE((krb5_context, const krb5_data *, + const krb5_data *, + krb5_principal *tgtprinc)); + #ifndef min #define min(a,b) ((a) > (b) ? (b) : (a)) #endif /* min */ @@ -243,3 +248,7 @@ extern char *krb5_lname_file; /* Note: print this out just be sure extern void *xmalloc (), *xrealloc (), *xcalloc(); extern char *xstrdup (); + +#ifndef HAVE_UNSETENV +void unsetenv PROTOTYPE((char *)); +#endif diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c index 17b33cdca..e77166624 100644 --- a/src/clients/ksu/main.c +++ b/src/clients/ksu/main.c @@ -30,6 +30,7 @@ #include #include #include +#include /* globals */ char * prog_name; @@ -60,7 +61,7 @@ char * get_dir_of_file(); ill specified arguments to commands */ 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); + 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 ... */ @@ -73,50 +74,50 @@ static uid_t source_uid, target_uid; int main (argc, argv) - int argc; - char ** argv; + int argc; + char ** argv; { -int hp =0; -int some_rest_copy = 0; -int all_rest_copy = 0; -char *localhostname = NULL; -opt_info options; -int option=0; -int statusp=0; -krb5_error_code retval = 0; -krb5_principal client = NULL; -krb5_ccache cc_target = NULL; -krb5_context ksu_context; -char * cc_target_tag = NULL; -char * target_user = NULL; -char * source_user; - -krb5_ccache cc_source = NULL; -const char * cc_source_tag = NULL; -uid_t source_gid, target_gid; -const char * cc_source_tag_tmp = NULL; -char * cc_target_tag_tmp=NULL; -char * cmd = NULL, * exec_cmd = NULL; -int errflg = 0; -krb5_boolean auth_val; -krb5_boolean authorization_val = FALSE; -int path_passwd = 0; -int done =0,i,j; -uid_t ruid = getuid (); -struct passwd *pwd=NULL, *target_pwd ; -char * shell; -char ** params; -int keep_target_cache = 0; -int child_pid, child_pgrp, ret_pid; -extern char * getpass(), *crypt(); -int pargc; -char ** pargv; -struct stat st_temp; -krb5_boolean stored = FALSE; -krb5_principal kdc_server; -krb5_boolean zero_password; -char * dir_of_cc_target; - + int hp =0; + int some_rest_copy = 0; + int all_rest_copy = 0; + char *localhostname = NULL; + opt_info options; + int option=0; + int statusp=0; + krb5_error_code retval = 0; + krb5_principal client = NULL; + krb5_ccache cc_target = NULL; + krb5_context ksu_context; + char * cc_target_tag = NULL; + char * target_user = NULL; + char * source_user; + + krb5_ccache cc_source = NULL; + const char * cc_source_tag = NULL; + uid_t source_gid, target_gid; + const char * cc_source_tag_tmp = NULL; + char * cc_target_tag_tmp=NULL; + char * cmd = NULL, * exec_cmd = NULL; + int errflg = 0; + krb5_boolean auth_val; + krb5_boolean authorization_val = FALSE; + int path_passwd = 0; + int done =0,i,j; + uid_t ruid = getuid (); + struct passwd *pwd=NULL, *target_pwd ; + char * shell; + char ** params; + int keep_target_cache = 0; + int child_pid, child_pgrp, ret_pid; + extern char * getpass(), *crypt(); + int pargc; + char ** pargv; + struct stat st_temp; + krb5_boolean stored = FALSE; + krb5_principal kdc_server; + krb5_boolean zero_password; + char * dir_of_cc_target; + options.opt = KRB5_DEFAULT_OPTIONS; options.lifetime = KRB5_DEFAULT_TKT_LIFE; options.rlife =0; @@ -147,35 +148,35 @@ char * dir_of_cc_target; #ifndef LOG_NDELAY #define LOG_NDELAY 0 #endif - + #ifndef LOG_AUTH /* 4.2 syslog */ openlog(prog_name, LOG_PID|LOG_NDELAY); #else openlog(prog_name, LOG_PID | LOG_AUTH | LOG_NDELAY, LOG_AUTH); #endif /* 4.2 syslog */ - + if (( argc == 1) || (argv[1][0] == '-')){ - target_user = xstrdup("root"); - pargc = argc; - pargv = argv; - } else { - target_user = xstrdup(argv[1]); - pargc = argc -1; - - if ((pargv =(char **) calloc(pargc +1,sizeof(char *)))==NULL){ - com_err(prog_name, errno, "while allocating memory"); - exit(1); - } - - pargv[pargc] = NULL; - pargv[0] = argv[0]; - - for(i =1; i< pargc; i ++){ - pargv[i] = argv[i + 1]; - } - } - + target_user = xstrdup("root"); + pargc = argc; + pargv = argv; + } else { + target_user = xstrdup(argv[1]); + pargc = argc -1; + + if ((pargv =(char **) calloc(pargc +1,sizeof(char *)))==NULL){ + com_err(prog_name, errno, "while allocating memory"); + exit(1); + } + + pargv[pargc] = NULL; + pargv[0] = argv[0]; + + for(i =1; i< pargc; i ++){ + pargv[i] = argv[i + 1]; + } + } + if (krb5_seteuid (ruid)) { com_err (prog_name, errno, "while setting euid to source user"); exit (1); @@ -197,13 +198,13 @@ char * dir_of_cc_target; take care of params argument */ optind --; if (auth_debug){printf("Before get_params optind=%d\n", optind);} - + if ((retval = get_params( & optind, pargc, pargv, ¶ms))){ com_err(prog_name, retval, "when gathering parameters"); errflg++; } if(auth_debug){ printf("After get_params optind=%d\n", optind);} - done = 1; + done = 1; break; case 'p': options.opt |= KDC_OPT_PROXIABLE; @@ -231,9 +232,9 @@ char * dir_of_cc_target; com_err(prog_name, retval, "when parsing name %s", optarg); errflg++; } - + options.princ = 1; - + break; #ifdef DEBUG case 'D': @@ -260,19 +261,19 @@ char * dir_of_cc_target; if (cc_source_tag == NULL) { cc_source_tag = xstrdup(optarg); if ( strchr(cc_source_tag, ':')){ - cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1; - - if( stat( cc_source_tag_tmp, &st_temp)){ - com_err (prog_name, errno, - "while looking for credentials file %s", - cc_source_tag_tmp); - exit (1); - } + cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1; + + if( stat( cc_source_tag_tmp, &st_temp)){ + com_err (prog_name, errno, + "while looking for credentials file %s", + cc_source_tag_tmp); + exit (1); + } } else { - fprintf(stderr,"malformed credential cache name %s\n", - cc_source_tag); - errflg++; + fprintf(stderr,"malformed credential cache name %s\n", + cc_source_tag); + errflg++; } } else { @@ -313,485 +314,489 @@ char * dir_of_cc_target; if (auth_debug){ for(j=1; params[j] != NULL; j++){ - fprintf (stderr,"params[%d]= %s\n", j,params[j]); + fprintf (stderr,"params[%d]= %s\n", j,params[j]); } } - /***********************************/ - source_user = getlogin(); /*checks for the the login name in /etc/utmp*/ - - /* verify that that the user exists and get his passwd structure */ - - if (source_user == NULL ||(pwd = getpwnam(source_user)) == NULL || - pwd->pw_uid != ruid){ - pwd = getpwuid(ruid); - } - - if (pwd == NULL) { - 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); - source_uid = pwd->pw_uid; - source_gid = pwd->pw_gid; - - - if (!strcmp(SOURCE_USER_LOGIN, target_user)){ - target_user = xstrdup (source_user); - } - - if ((target_pwd = getpwnam(target_user)) == NULL){ - fprintf(stderr, "ksu: unknown login %s\n", target_user); - exit(1); - } - target_uid = target_pwd->pw_uid; - target_gid = target_pwd->pw_gid; - - init_auth_names(target_pwd->pw_dir); - - /***********************************/ - - if (cc_source_tag == NULL){ - cc_source_tag = krb5_cc_default_name(ksu_context); - cc_source_tag_tmp = strchr(cc_source_tag, ':'); - if (cc_source_tag_tmp == 0) - cc_source_tag_tmp = cc_source_tag; - else - cc_source_tag_tmp++; - } - - /* 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 (((retval = krb5_cc_set_flags(ksu_context, cc_source, 0x0)) != 0) - && (retval != KRB5_FCC_NOFILE)) { + /***********************************/ + source_user = getlogin(); /*checks for the the login name in /etc/utmp*/ + + /* verify that that the user exists and get his passwd structure */ + + if (source_user == NULL ||(pwd = getpwnam(source_user)) == NULL || + pwd->pw_uid != ruid){ + pwd = getpwuid(ruid); + } + + if (pwd == NULL) { + 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); + source_uid = pwd->pw_uid; + source_gid = pwd->pw_gid; + + + if (!strcmp(SOURCE_USER_LOGIN, target_user)){ + target_user = xstrdup (source_user); + } + + if ((target_pwd = getpwnam(target_user)) == NULL){ + fprintf(stderr, "ksu: unknown login %s\n", target_user); + exit(1); + } + target_uid = target_pwd->pw_uid; + target_gid = target_pwd->pw_gid; + + init_auth_names(target_pwd->pw_dir); + + /***********************************/ + + if (cc_source_tag == NULL){ + cc_source_tag = krb5_cc_default_name(ksu_context); + cc_source_tag_tmp = strchr(cc_source_tag, ':'); + if (cc_source_tag_tmp == 0) + cc_source_tag_tmp = cc_source_tag; + else + cc_source_tag_tmp++; + } + + /* 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 (((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, - &options, cmd, localhostname, &client, &hp))){ - com_err(prog_name,retval, "while selecting the best principal"); - exit(1); - } - - /* We may be running as either source or target, depending on - what happened; become source.*/ - if ( geteuid() != source_uid) { - if (krb5_seteuid(0) || krb5_seteuid(source_uid) ) { + } + if ((retval = get_best_princ_for_target(ksu_context, source_uid, + target_uid, source_user, + target_user, cc_source, + &options, cmd, localhostname, + &client, &hp))){ + com_err(prog_name,retval, "while selecting the best principal"); + exit(1); + } + + /* We may be running as either source or target, depending on + what happened; become source.*/ + if ( geteuid() != source_uid) { + if (krb5_seteuid(0) || krb5_seteuid(source_uid) ) { com_err(prog_name, errno, "while returning to source uid after finding best principal"); exit(1); - } - } - - if (auth_debug){ - if (hp){ - fprintf(stderr, - "GET_best_princ_for_target result: NOT AUTHORIZED\n"); - }else{ - fprintf(stderr, - "GET_best_princ_for_target result-best principal "); - plain_dump_principal (ksu_context, client); - fprintf(stderr,"\n"); - } } - + } + + if (auth_debug){ if (hp){ - if (gb_err) fprintf(stderr, "%s", gb_err); - fprintf(stderr,"account %s: authorization failed\n",target_user); - exit(1); - } - - if (cc_target_tag == NULL) { - - cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE ,sizeof(char)); - /* make sure that the new ticket file does not already exist - This is run as source_uid because it is reasonable to - require the source user to have write to where the target - cache will be created.*/ - - do { - sprintf(cc_target_tag, "%s%ld.%d", - KRB5_SECONDARY_CACHE, - (long) target_uid, gen_sym()); - cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1; - - }while ( !stat ( cc_target_tag_tmp, &st_temp)); - } - - - dir_of_cc_target = get_dir_of_file(cc_target_tag_tmp); - - if (access(dir_of_cc_target, R_OK | W_OK )){ fprintf(stderr, - "%s does not have correct permissions for %s\n", - source_user, cc_target_tag); - exit(1); - } - - if (auth_debug){ - fprintf(stderr, " source cache = %s\n", cc_source_tag); - fprintf(stderr, " target cache = %s\n", cc_target_tag); + "GET_best_princ_for_target result: NOT AUTHORIZED\n"); + }else{ + fprintf(stderr, + "GET_best_princ_for_target result-best principal "); + plain_dump_principal (ksu_context, client); + fprintf(stderr,"\n"); } - - /* - Only when proper authentication and authorization - takes place, the target user becomes the owner of the cache. - */ - - /* we continue to run as source uid until - the middle of the copy, when becomewe become the target user - The cache is owned by the target user.*/ + } + + if (hp){ + if (gb_err) fprintf(stderr, "%s", gb_err); + fprintf(stderr,"account %s: authorization failed\n",target_user); + exit(1); + } + + if (cc_target_tag == NULL) { + cc_target_tag = (char *)xcalloc(KRB5_SEC_BUFFSIZE ,sizeof(char)); + /* make sure that the new ticket file does not already exist + This is run as source_uid because it is reasonable to + require the source user to have write to where the target + cache will be created.*/ - /* 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 ((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); - } + do { + sprintf(cc_target_tag, "%s%ld.%d", + KRB5_SECONDARY_CACHE, + (long) target_uid, gen_sym()); + cc_target_tag_tmp = strchr(cc_target_tag, ':') + 1; + }while ( !stat ( cc_target_tag_tmp, &st_temp)); + } + + + dir_of_cc_target = get_dir_of_file(cc_target_tag_tmp); + + if (access(dir_of_cc_target, R_OK | W_OK )){ + fprintf(stderr, + "%s does not have correct permissions for %s\n", + source_user, cc_target_tag); + exit(1); + } + + if (auth_debug){ + fprintf(stderr, " source cache = %s\n", cc_source_tag); + fprintf(stderr, " target cache = %s\n", cc_target_tag); + } + + /* + Only when proper authentication and authorization + takes place, the target user becomes the owner of the cache. + */ + + /* we continue to run as source uid until + the middle of the copy, when becomewe become the target user + The cache is owned by the target user.*/ + + + /* 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 ((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); } - /* Become root for authentication*/ - - if (krb5_seteuid(0)) { + } 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*/ + + if (krb5_seteuid(0)) { com_err(prog_name, errno, "while reclaiming root uid"); exit(1); - } - - if ((source_uid == 0) || (target_uid == source_uid)){ + } + + if ((source_uid == 0) || (target_uid == source_uid)){ #ifdef GET_TGT_VIA_PASSWD - if ((!all_rest_copy) && options.princ && (stored == FALSE)){ - if ((retval = krb5_tgtname(ksu_context, - krb5_princ_realm (ksu_context, client), - krb5_princ_realm(ksu_context, client), - &kdc_server))){ - com_err(prog_name, retval, - "while creating tgt for local realm"); - sweep_up(ksu_context, cc_target); - exit(1); - } - - fprintf(stderr,"WARNING: Your password may be exposed if you enter it here and are logged\n"); - fprintf(stderr," in remotely using an unsecure (non-encrypted) channel.\n"); - if (krb5_get_tkt_via_passwd (ksu_context, &cc_target, client, + if ((!all_rest_copy) && options.princ && (stored == FALSE)){ + if ((retval = ksu_tgtname(ksu_context, + krb5_princ_realm (ksu_context, client), + krb5_princ_realm(ksu_context, client), + &kdc_server))){ + com_err(prog_name, retval, + "while creating tgt for local realm"); + sweep_up(ksu_context, cc_target); + exit(1); + } + + fprintf(stderr,"WARNING: Your password may be exposed if you enter it here and are logged\n"); + fprintf(stderr," in remotely using an unsecure (non-encrypted) channel.\n"); + if (krb5_get_tkt_via_passwd (ksu_context, &cc_target, client, kdc_server, &options, &zero_password) == FALSE){ - - if (zero_password == FALSE){ - fprintf(stderr,"Goodbye\n"); - sweep_up(ksu_context, cc_target); - exit(1); - } - - fprintf(stderr, - "Could not get a tgt for "); - plain_dump_principal (ksu_context, client); - fprintf(stderr, "\n"); - - } - } -#endif /* GET_TGT_VIA_PASSWD */ - } - - /* if the user is root or same uid then authentication is not neccesary, - root gets in automatically */ - - if (source_uid && (source_uid != target_uid)) { - char * client_name; - - auth_val = krb5_auth_check(ksu_context, client, localhostname, &options, - target_user,cc_target, &path_passwd, target_uid); - /* if Kerberos authentication failed then exit */ - if (auth_val ==FALSE){ - fprintf(stderr, "Authentication failed.\n"); - syslog(LOG_WARNING, - "'%s %s' authentication failed for %s%s", - prog_name,target_user,source_user,ontty()); - sweep_up(ksu_context, cc_target); - exit(1); + if (zero_password == FALSE){ + fprintf(stderr,"Goodbye\n"); + sweep_up(ksu_context, cc_target); + exit(1); } - + + fprintf(stderr, + "Could not get a tgt for "); + plain_dump_principal (ksu_context, client); + fprintf(stderr, "\n"); + + } + } +#endif /* GET_TGT_VIA_PASSWD */ + } + + /* if the user is root or same uid then authentication is not neccesary, + root gets in automatically */ + + if (source_uid && (source_uid != target_uid)) { + char * client_name; + + auth_val = krb5_auth_check(ksu_context, client, localhostname, &options, + target_user,cc_target, &path_passwd, target_uid); + + /* if Kerberos authentication failed then exit */ + if (auth_val ==FALSE){ + fprintf(stderr, "Authentication failed.\n"); + syslog(LOG_WARNING, + "'%s %s' authentication failed for %s%s", + prog_name,target_user,source_user,ontty()); + sweep_up(ksu_context, cc_target); + exit(1); + } + #if 0 - /* At best, this avoids a single kdc request - It is hard to implement dealing with file permissions and - is unnecessary. It is important - 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){ - - if ((retval = krb5_ccache_overwrite(ksu_context, cc_target, cc_source, - client))){ - com_err (prog_name, retval, - "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, cc_target); - exit(1); - } - if (chown(cc_source_tag_tmp, source_uid, source_gid)){ - com_err(prog_name, errno, - "while changing owner for %s", - cc_source_tag_tmp); - exit(1); - } - } + /* At best, this avoids a single kdc request + It is hard to implement dealing with file permissions and + is unnecessary. It is important + 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){ + + if ((retval = krb5_ccache_overwrite(ksu_context, cc_target, cc_source, + client))){ + com_err (prog_name, retval, + "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, cc_target); + exit(1); + } + if (chown(cc_source_tag_tmp, source_uid, source_gid)){ + com_err(prog_name, errno, + "while changing owner for %s", + cc_source_tag_tmp); + exit(1); + } + } #endif /*0*/ - if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) { - com_err (prog_name, retval, "When unparsing name"); - sweep_up(ksu_context, cc_target); - exit(1); - } - - print_status("Authenticated %s\n", client_name); - syslog(LOG_NOTICE,"'%s %s' authenticated %s for %s%s", - prog_name,target_user,client_name, - source_user,ontty()); - - /* 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, cc_target); - exit(1); - } + if ((retval = krb5_unparse_name(ksu_context, client, &client_name))) { + com_err (prog_name, retval, "When unparsing name"); + sweep_up(ksu_context, cc_target); + exit(1); + } + + print_status("Authenticated %s\n", client_name); + syslog(LOG_NOTICE,"'%s %s' authenticated %s for %s%s", + prog_name,target_user,client_name, + source_user,ontty()); + + /* 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, cc_target); + exit(1); + } + + if ((retval = krb5_authorization(ksu_context, client,target_user, + 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, 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, cc_target); + exit(1); + } + if (authorization_val == TRUE){ + + if (cmd) { + print_status( + "Account %s: authorization for %s for execution of\n", + target_user, client_name); + print_status(" %s successful\n",exec_cmd); + syslog(LOG_NOTICE, + "Account %s: authorization for %s for execution of %s successful", + target_user, client_name, exec_cmd); - if ((retval = krb5_authorization(ksu_context, client,target_user, - 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, 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, cc_target); - exit(1); - } - if (authorization_val == TRUE){ - - if (cmd) { - print_status( - "Account %s: authorization for %s for execution of\n", - target_user, client_name); - print_status(" %s successful\n",exec_cmd); - syslog(LOG_NOTICE, - "Account %s: authorization for %s for execution of %s successful", - target_user, client_name, exec_cmd); - - }else{ - print_status( - "Account %s: authorization for %s successful\n", + }else{ + print_status( + "Account %s: authorization for %s successful\n", target_user, client_name); - syslog(LOG_NOTICE, - "Account %s: authorization for %s successful", - target_user, client_name); - } - }else { - if (cmd){ - if (exec_cmd){ /* was used to pass back the error msg */ - fprintf(stderr, "%s", exec_cmd ); - syslog(LOG_WARNING, "%s",exec_cmd); - } - fprintf(stderr, - "Account %s: authorization for %s for execution of %s failed\n", - target_user, client_name, cmd ); - syslog(LOG_WARNING, - "Account %s: authorization for %s for execution of %s failed", - target_user, client_name, cmd ); - - }else{ - fprintf(stderr, - "Account %s: authorization of %s failed\n", - target_user, client_name); - syslog(LOG_WARNING, - "Account %s: authorization of %s failed", - target_user, client_name); - - } - - sweep_up(ksu_context, cc_target); - exit(1); + syslog(LOG_NOTICE, + "Account %s: authorization for %s successful", + target_user, client_name); + } + }else { + if (cmd){ + if (exec_cmd){ /* was used to pass back the error msg */ + fprintf(stderr, "%s", exec_cmd ); + syslog(LOG_WARNING, "%s",exec_cmd); } + fprintf(stderr, + "Account %s: authorization for %s for execution of %s failed\n", + target_user, client_name, cmd ); + syslog(LOG_WARNING, + "Account %s: authorization for %s for execution of %s failed", + target_user, client_name, cmd ); + + }else{ + fprintf(stderr, + "Account %s: authorization of %s failed\n", + target_user, client_name); + syslog(LOG_WARNING, + "Account %s: authorization of %s failed", + target_user, client_name); + + } + + sweep_up(ksu_context, cc_target); + exit(1); } - - 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, cc_target); - exit(1); - } + } + + 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, cc_target); + exit(1); } - - if (all_rest_copy){ - if ((retval = krb5_cc_initialize(ksu_context, cc_target, client))){ - com_err(prog_name, retval, - "while erasing target cache"); - exit(1); - } - + } + + if (all_rest_copy){ + if ((retval = krb5_cc_initialize(ksu_context, cc_target, client))){ + com_err(prog_name, retval, + "while erasing target cache"); + exit(1); } - - /* get the shell of the user, this will be the shell used by su */ - target_pwd = getpwnam(target_user); - - if (target_pwd->pw_shell) - shell = xstrdup(target_pwd->pw_shell); - else { - shell = _DEF_CSH; /* default is cshell */ - } - + + } + + /* get the shell of the user, this will be the shell used by su */ + target_pwd = getpwnam(target_user); + + if (target_pwd->pw_shell) + shell = xstrdup(target_pwd->pw_shell); + else { + shell = _DEF_CSH; /* default is cshell */ + } + #ifdef HAVE_GETUSERSHELL - - /* insist that the target login uses a standard shell (root is omited) */ - - if (!standard_shell(target_pwd->pw_shell) && source_uid) { - fprintf(stderr, "ksu: permission denied (shell).\n"); - sweep_up(ksu_context, cc_target); - exit(1); - } + + /* insist that the target login uses a standard shell (root is omited) */ + + if (!standard_shell(target_pwd->pw_shell) && source_uid) { + fprintf(stderr, "ksu: permission denied (shell).\n"); + sweep_up(ksu_context, cc_target); + exit(1); + } #endif /* HAVE_GETUSERSHELL */ + + if (target_pwd->pw_uid){ - if (target_pwd->pw_uid){ - - if(set_env_var("USER", target_pwd->pw_name)){ - fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - 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, cc_target); - exit(1); - } - - if(set_env_var( "SHELL", shell)){ - fprintf(stderr,"ksu: couldn't set environment variable USER\n"); - sweep_up(ksu_context, cc_target); - exit(1); - } - - /* set the cc env name to target */ - - 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, cc_target); - exit(1); - } - - /* set permissions */ - if (setgid(target_pwd->pw_gid) < 0) { - perror("ksu: setgid"); - 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, cc_target); - exit(1); - } - - if ( ! strcmp(target_user, source_user)){ - print_status("Leaving uid as %s (%d)\n", - target_user, target_pwd->pw_uid); - }else{ - print_status("Changing uid to %s (%d)\n", - target_user, target_pwd->pw_uid); - } - + if(set_env_var("USER", target_pwd->pw_name)){ + fprintf(stderr,"ksu: couldn't set environment variable USER\n"); + 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, cc_target); + exit(1); + } + + if(set_env_var( "SHELL", shell)){ + fprintf(stderr,"ksu: couldn't set environment variable USER\n"); + sweep_up(ksu_context, cc_target); + exit(1); + } + + /* set the cc env name to target */ + + 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, cc_target); + exit(1); + } + + /* set permissions */ + if (setgid(target_pwd->pw_gid) < 0) { + perror("ksu: setgid"); + 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, cc_target); + exit(1); + } + + if ( ! strcmp(target_user, source_user)){ + print_status("Leaving uid as %s (%ld)\n", + target_user, (long) target_pwd->pw_uid); + }else{ + print_status("Changing uid to %s (%ld)\n", + target_user, target_pwd->pw_uid); + } + #ifdef HAVE_SETLUID - /* - * If we're on a system which keeps track of login uids, then - * set the login uid. If this fails this opens up a problem on DEC OSF - * with C2 enabled. - */ - if (setluid((uid_t) pwd->pw_uid) < 0) { - perror("setluid"); - sweep_up(ksu_context, cc_target); - exit(1); - } + /* + * If we're on a system which keeps track of login uids, then + * set the login uid. If this fails this opens up a problem on DEC OSF + * with C2 enabled. + */ + if (setluid((uid_t) pwd->pw_uid) < 0) { + perror("setluid"); + 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, cc_target); - exit(1); - } - - if (access( cc_target_tag_tmp, R_OK | W_OK )){ - com_err(prog_name, errno, - "%s does not have correct permissions for %s, %s aborted", - target_user, cc_target_tag_tmp, prog_name); - exit(1); - } - - if ( cc_source) - krb5_cc_close(ksu_context, cc_source); - - if (cmd){ - if ((source_uid == 0) || (source_uid == target_uid )){ - exec_cmd = cmd; - } - - if( !exec_cmd){ - fprintf(stderr, - "Internal error: command %s did not get resolved\n",cmd); - exit(1); - } - - params[0] = exec_cmd; - } - else{ - params[0] = shell; + + if (setuid(target_pwd->pw_uid) < 0) { + perror("ksu: setuid"); + sweep_up(ksu_context, cc_target); + exit(1); + } + + if (access( cc_target_tag_tmp, R_OK | W_OK )){ + com_err(prog_name, errno, + "%s does not have correct permissions for %s, %s aborted", + target_user, cc_target_tag_tmp, prog_name); + exit(1); + } + + if ( cc_source) + krb5_cc_close(ksu_context, cc_source); + + if (cmd){ + if ((source_uid == 0) || (source_uid == target_uid )){ + exec_cmd = cmd; } - - if (auth_debug){ - fprintf(stderr, "program to be execed %s\n",params[0]); + + if( !exec_cmd){ + fprintf(stderr, + "Internal error: command %s did not get resolved\n",cmd); + exit(1); } - - if( keep_target_cache ) { - execv(params[0], params); - com_err(prog_name, errno, "while trying to execv %s", - params[0]); - sweep_up(ksu_context, cc_target); - exit(1); + + params[0] = exec_cmd; + } + else{ + params[0] = shell; + } + + if (auth_debug){ + fprintf(stderr, "program to be execed %s\n",params[0]); + } + + if( keep_target_cache ) { + execv(params[0], params); + com_err(prog_name, errno, "while trying to execv %s", + params[0]); + sweep_up(ksu_context, cc_target); + exit(1); }else{ statusp = 1; switch ((child_pid = fork())) { @@ -836,31 +841,31 @@ krb5_seteuid(0); /*So we have some chance of sweeping up*/ int standard_shell(sh) char *sh; { -register char *cp; -char *getusershell(); - - while ((cp = getusershell()) != NULL) - if (!strcmp(cp, sh)) - return (1); - return (0); + register char *cp; + char *getusershell(); + + while ((cp = getusershell()) != NULL) + if (!strcmp(cp, sh)) + return (1); + return (0); } #endif /* HAVE_GETUSERSHELL */ static char * ontty() { -char *p, *ttyname(); -static char buf[MAXPATHLEN + 4]; - - buf[0] = 0; - if ((p = ttyname(STDERR_FILENO))) { - if (strlen (p) > MAXPATHLEN) { - fprintf (stderr, "terminal name %s too long\n", p); - exit (1); - } - sprintf(buf, " on %s", p); - } - return (buf); + char *p, *ttyname(); + static char buf[MAXPATHLEN + 4]; + + buf[0] = 0; + if ((p = ttyname(STDERR_FILENO))) { + if (strlen (p) > MAXPATHLEN) { + fprintf (stderr, "terminal name %s too long\n", p); + exit (1); + } + sprintf(buf, " on %s", p); + } + return (buf); } @@ -868,15 +873,15 @@ static int set_env_var(name, value) char *name; char *value; { -char * env_var_buf; - - /* allocate extra two spaces, one for the = and one for the \0 */ - env_var_buf = (char *) xcalloc(2 + strlen(name) + strlen(value), - sizeof(char)); - - sprintf(env_var_buf,"%s=%s",name, value); - return putenv(env_var_buf); - + char * env_var_buf; + + /* allocate extra two spaces, one for the = and one for the \0 */ + env_var_buf = (char *) xcalloc(2 + strlen(name) + strlen(value), + sizeof(char)); + + sprintf(env_var_buf,"%s=%s",name, value); + return putenv(env_var_buf); + } static void sweep_up(context, cc) @@ -889,7 +894,7 @@ static void sweep_up(context, cc) krb5_seteuid(0); krb5_seteuid(target_uid); - + cc_name = krb5_cc_get_name(context, cc); if ( ! stat(cc_name, &st_temp)){ if ((retval = krb5_cc_destroy(context, cc))){ @@ -898,6 +903,7 @@ static void sweep_up(context, cc) } } } + /***************************************************************** get_params is to be called for the -a option or -e option to collect all params passed in for the shell or for @@ -916,23 +922,22 @@ get_params(optind, pargc, pargv, params) char ***params; { -int i,j; -char ** ret_params; -int size = pargc - *optind + 2; - - if ((ret_params = (char **) calloc(size, sizeof (char *)))== NULL ){ - return errno; - } - - for (i = *optind, j=1; i < pargc; i++,j++){ - ret_params[j] = pargv[i]; - *optind = *optind + 1; - } - - ret_params[size-1] = NULL; - *params = ret_params; -return 0; - + int i,j; + char ** ret_params; + int size = pargc - *optind + 2; + + if ((ret_params = (char **) calloc(size, sizeof (char *)))== NULL ){ + return errno; + } + + for (i = *optind, j=1; i < pargc; i++,j++){ + ret_params[j] = pargv[i]; + *optind = *optind + 1; + } + + ret_params[size-1] = NULL; + *params = ret_params; + return 0; } static @@ -943,19 +948,19 @@ void print_status (va_alist) va_dcl #endif { - va_list ap; + va_list ap; #ifndef HAVE_STDARG_H - char *fmt; - va_start (ap); - fmt = va_arg (ap, char*); - if (!quiet) vfprintf(stderr, fmt, ap); - va_end(ap); + char *fmt; + va_start (ap); + fmt = va_arg (ap, char*); + if (!quiet) vfprintf(stderr, fmt, ap); + va_end(ap); #else - if (! quiet){ - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - } + if (! quiet){ + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + } #endif } @@ -967,7 +972,7 @@ char *get_dir_of_file(path) char * ptr; temp_path = xstrdup(path); - + if ((ptr = strrchr( temp_path, '/'))) { *ptr = '\0'; } else { @@ -978,3 +983,15 @@ char *get_dir_of_file(path) } return temp_path; } + +krb5_error_code +ksu_tgtname(context, server, client, tgtprinc) + krb5_context context; + const krb5_data *server, *client; + krb5_principal *tgtprinc; +{ + return krb5_build_principal_ext(context, tgtprinc, client->length, client->data, + KRB5_TGS_NAME_SIZE, KRB5_TGS_NAME, + server->length, server->data, + 0); +} diff --git a/src/clients/ksu/setenv.c b/src/clients/ksu/setenv.c index 173a2ba5f..7563454b8 100644 --- a/src/clients/ksu/setenv.c +++ b/src/clients/ksu/setenv.c @@ -20,6 +20,8 @@ #include #include +static char *_findenv(); + /* * setenv -- * Set the value of the environmental variable "name" to be @@ -35,7 +37,7 @@ setenv(name, value, rewrite) static int alloced; /* if allocated space before */ register char *C; int l_value, offset; - char *malloc(), *realloc(), *_findenv(); + char *malloc(), *realloc(); if (*value == '=') /* no `=' in value */ ++value; @@ -76,7 +78,7 @@ setenv(name, value, rewrite) malloc((u_int)((int)(C - name) + l_value + 2)))) return(-1); for (C = environ[offset]; (*C = *name++) &&( *C != '='); ++C); - for (*C++ = '='; *C++ = *value++;); + for (*C++ = '='; (*C++ = *value++) != NULL;); return(0); } #endif @@ -93,7 +95,6 @@ unsetenv(name) extern char **environ; register char **P; int offset; - char *_findenv(); while (_findenv(name, &offset)) /* if set multiple times */ for (P = &environ[offset];; ++P) @@ -130,7 +131,6 @@ getenv(name) char *name; { int offset; - char *_findenv(); return(_findenv(name, &offset)); }