Path: blob/main/crypto/krb5/src/clients/ksu/krb_auth_su.c
34889 views
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */1/*2* Copyright (c) 1994 by the University of Southern California3*4* EXPORT OF THIS SOFTWARE from the United States of America may5* require a specific license from the United States Government.6* It is the responsibility of any person or organization contemplating7* export to obtain such a license before exporting.8*9* WITHIN THAT CONSTRAINT, permission to copy, modify, and distribute10* this software and its documentation in source and binary forms is11* hereby granted, provided that any documentation or other materials12* related to such distribution or use acknowledge that the software13* was developed by the University of Southern California.14*15* DISCLAIMER OF WARRANTY. THIS SOFTWARE IS PROVIDED "AS IS". The16* University of Southern California MAKES NO REPRESENTATIONS OR17* WARRANTIES, EXPRESS OR IMPLIED. By way of example, but not18* limitation, the University of Southern California MAKES NO19* REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY20* PARTICULAR PURPOSE. The University of Southern21* California shall not be held liable for any liability nor for any22* direct, indirect, or consequential damages with respect to any23* claim by the user or distributor of the ksu software.24*25* KSU was written by: Ari Medvinsky, [email protected]26*/2728#include "ksu.h"293031void plain_dump_principal(krb5_context, krb5_principal);3233krb5_boolean34krb5_auth_check(krb5_context context, krb5_principal client_pname,35char *hostname, krb5_get_init_creds_opt *options,36char *target_user, krb5_ccache cc, int *path_passwd,37uid_t target_uid)38{39krb5_principal client = NULL;40krb5_verify_init_creds_opt vfy_opts;41krb5_creds tgt = { 0 }, tgtq = { 0 };42krb5_error_code retval =0;43int got_it = 0;44krb5_boolean zero_password;45krb5_boolean ok = FALSE;4647*path_passwd = 0;4849if ((retval= krb5_copy_principal(context, client_pname, &client))){50com_err(prog_name, retval, _("while copying client principal"));51goto cleanup;52}5354if ((retval= krb5_copy_principal(context, client, &tgtq.client))){55com_err(prog_name, retval, _("while copying client principal"));56goto cleanup;57}5859if ((retval = ksu_tgtname(context, krb5_princ_realm(context, client),60krb5_princ_realm(context, client),61&tgtq.server))){62com_err(prog_name, retval, _("while creating tgt for local realm"));63goto cleanup;64}6566if (auth_debug){ dump_principal(context, "local tgt principal name", tgtq.server ); }67retval = krb5_cc_retrieve_cred(context, cc,68KRB5_TC_MATCH_SRV_NAMEONLY | KRB5_TC_SUPPORTED_KTYPES,69&tgtq, &tgt);7071if (! retval) retval = krb5_check_exp(context, tgt.times);7273if (retval){74if ((retval != KRB5_CC_NOTFOUND) &&75(retval != KRB5KRB_AP_ERR_TKT_EXPIRED)){76com_err(prog_name, retval, _("while retrieving creds from cache"));77goto cleanup;78}79} else{80got_it = 1;81}8283if (! got_it){8485#ifdef GET_TGT_VIA_PASSWD86if (krb5_seteuid(0)||krb5_seteuid(target_uid)) {87com_err("ksu", errno, _("while switching to target uid"));88goto cleanup;89}909192fprintf(stderr, _("WARNING: Your password may be exposed if you enter "93"it here and are logged \n"));94fprintf(stderr, _(" in remotely using an unsecure "95"(non-encrypted) channel. \n"));9697/*get the ticket granting ticket, via passwd(prompt for passwd)*/98if (ksu_get_tgt_via_passwd(context, client, options, &zero_password,99&tgt) == FALSE) {100krb5_seteuid(0);101102goto cleanup;103}104*path_passwd = 1;105if (krb5_seteuid(0)) {106com_err("ksu", errno, _("while reclaiming root uid"));107goto cleanup;108}109110#else111plain_dump_principal (context, client);112fprintf(stderr,113_("does not have any appropriate tickets in the cache.\n"));114goto cleanup;115116#endif /* GET_TGT_VIA_PASSWD */117118}119120krb5_verify_init_creds_opt_init(&vfy_opts);121krb5_verify_init_creds_opt_set_ap_req_nofail( &vfy_opts, 1);122retval = krb5_verify_init_creds(context, &tgt, NULL, NULL, NULL,123&vfy_opts);124if (retval) {125com_err(prog_name, retval, _("while verifying ticket for server"));126goto cleanup;127}128129ok = TRUE;130131cleanup:132krb5_free_principal(context, client);133krb5_free_cred_contents(context, &tgt);134krb5_free_cred_contents(context, &tgtq);135return ok;136}137138krb5_boolean139ksu_get_tgt_via_passwd(krb5_context context, krb5_principal client,140krb5_get_init_creds_opt *options,141krb5_boolean *zero_password, krb5_creds *creds_out)142{143krb5_boolean ok = FALSE;144krb5_error_code code;145krb5_creds creds = { 0 };146krb5_timestamp now;147unsigned int pwsize;148char password[255], prompt[255], *client_name = NULL;149int result;150151*zero_password = FALSE;152if (creds_out != NULL)153memset(creds_out, 0, sizeof(*creds_out));154155if ((code = krb5_unparse_name(context, client, &client_name))) {156com_err (prog_name, code, _("when unparsing name"));157goto cleanup;158}159160memset(&creds, 0, sizeof(creds));161162if ((code = krb5_timeofday(context, &now))) {163com_err(prog_name, code, _("while getting time of day"));164goto cleanup;165}166167result = snprintf(prompt, sizeof(prompt), _("Kerberos password for %s: "),168client_name);169if (SNPRINTF_OVERFLOW(result, sizeof(prompt))) {170fprintf(stderr,171_("principal name %s too long for internal buffer space\n"),172client_name);173goto cleanup;174}175176pwsize = sizeof(password);177178code = krb5_read_password(context, prompt, 0, password, &pwsize);179if (code ) {180com_err(prog_name, code, _("while reading password for '%s'\n"),181client_name);182goto cleanup;183}184185if ( pwsize == 0) {186fprintf(stderr, _("No password given\n"));187*zero_password = TRUE;188goto cleanup;189}190191code = krb5_get_init_creds_password(context, &creds, client, password,192krb5_prompter_posix, NULL, 0, NULL,193options);194zap(password, sizeof(password));195196197if (code) {198if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)199fprintf(stderr, _("%s: Password incorrect\n"), prog_name);200else201com_err(prog_name, code, _("while getting initial credentials"));202goto cleanup;203}204if (creds_out != NULL) {205*creds_out = creds;206memset(&creds, 0, sizeof(creds));207}208209ok = TRUE;210211cleanup:212krb5_free_cred_contents(context, &creds);213free(client_name);214return ok;215}216217void218dump_principal(krb5_context context, char *str, krb5_principal p)219{220char * stname;221krb5_error_code retval;222223if ((retval = krb5_unparse_name(context, p, &stname))) {224fprintf(stderr, _(" %s while unparsing name\n"),225error_message(retval));226return;227}228fprintf(stderr, " %s: %s\n", str, stname);229free(stname);230}231232void233plain_dump_principal (krb5_context context, krb5_principal p)234{235char * stname;236krb5_error_code retval;237238if ((retval = krb5_unparse_name(context, p, &stname))) {239fprintf(stderr, _(" %s while unparsing name\n"),240error_message(retval));241return;242}243fprintf(stderr, "%s ", stname);244free(stname);245}246247248