From 70e4fce9048577e132d6b23ca17ac32fc1970b32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Love=20H=C3=B6rnquist=20=C3=85strand?= Date: Tue, 19 Jul 2005 17:08:11 +0000 Subject: [PATCH] =?UTF-8?q?Add=20Kerberos=205=20klist,=20old=20patch=20fro?= =?UTF-8?q?m=20Tomas=20Nystr=C3=B6m=20(remove=20krb4=20support).=20Support?= =?UTF-8?q?=20klist=20in=20client=20for=20kerberos=205=20clase.=20Clean=20?= =?UTF-8?q?up=20delegation=20of=20gss=20tokens=20and=20do=20afslog.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@15666 ec53bebd-3082-4978-b11e-865c3cabbd6b --- appl/ftp/ftp/cmds.c | 14 +++ appl/ftp/ftp/cmdtab.c | 8 ++ appl/ftp/ftp/kauth.c | 14 --- appl/ftp/ftpd/Makefile.am | 1 + appl/ftp/ftpd/extern.h | 5 +- appl/ftp/ftpd/ftpcmd.y | 20 ++-- appl/ftp/ftpd/ftpd.c | 2 +- appl/ftp/ftpd/gss_userok.c | 43 ++++----- appl/ftp/ftpd/kauth.c | 182 +++++++++++++++---------------------- 9 files changed, 132 insertions(+), 157 deletions(-) diff --git a/appl/ftp/ftp/cmds.c b/appl/ftp/ftp/cmds.c index cfb1c7fc0..6956d89ab 100644 --- a/appl/ftp/ftp/cmds.c +++ b/appl/ftp/ftp/cmds.c @@ -2126,3 +2126,17 @@ newer(int argc, char **argv) printf("Local file \"%s\" is newer than remote file \"%s\"\n", argv[2], argv[1]); } + +void +klist(int argc, char **argv) +{ + int ret; + if(argc != 1){ + printf("usage: %s\n", argv[0]); + code = -1; + return; + } + + ret = command("SITE KLIST"); + code = (ret == COMPLETE); +} diff --git a/appl/ftp/ftp/cmdtab.c b/appl/ftp/ftp/cmdtab.c index 60284d47d..66e687814 100644 --- a/appl/ftp/ftp/cmdtab.c +++ b/appl/ftp/ftp/cmdtab.c @@ -107,7 +107,11 @@ char verbosehelp[] = "toggle verbose mode"; char prothelp[] = "set protection level"; #ifdef KRB4 char kauthhelp[] = "get remote tokens"; +#endif +#if defined(KRB4) || defined(KRB5) char klisthelp[] = "show remote tickets"; +#endif +#ifdef KRB4 char kdestroyhelp[] = "destroy remote tickets"; char krbtkfilehelp[] = "set filename of remote tickets"; #endif @@ -192,7 +196,11 @@ struct cmd cmdtab[] = { { "prot", prothelp, 0, 1, 0, sec_prot }, #ifdef KRB4 { "kauth", kauthhelp, 0, 1, 0, kauth }, +#endif +#if defined(KRB4) || defined(KRB5) { "klist", klisthelp, 0, 1, 0, klist }, +#endif +#ifdef KRB4 { "kdestroy", kdestroyhelp, 0, 1, 0, kdestroy }, { "krbtkfile", krbtkfilehelp, 0, 1, 0, krbtkfile }, #endif diff --git a/appl/ftp/ftp/kauth.c b/appl/ftp/ftp/kauth.c index 4fb0c94fc..b3ee75e0c 100644 --- a/appl/ftp/ftp/kauth.c +++ b/appl/ftp/ftp/kauth.c @@ -143,20 +143,6 @@ kauth(int argc, char **argv) code = 0; } -void -klist(int argc, char **argv) -{ - int ret; - if(argc != 1){ - printf("usage: %s\n", argv[0]); - code = -1; - return; - } - - ret = command("SITE KLIST"); - code = (ret == COMPLETE); -} - void kdestroy(int argc, char **argv) { diff --git a/appl/ftp/ftpd/Makefile.am b/appl/ftp/ftpd/Makefile.am index f0b801fcb..8a5723835 100644 --- a/appl/ftp/ftpd/Makefile.am +++ b/appl/ftp/ftpd/Makefile.am @@ -26,6 +26,7 @@ ftpd_SOURCES = \ popen.c \ security.c \ kauth.c \ + klist.c \ $(krb4_sources) \ $(krb5_sources) diff --git a/appl/ftp/ftpd/extern.h b/appl/ftp/ftpd/extern.h index 8bc594e78..db40f2fdd 100644 --- a/appl/ftp/ftpd/extern.h +++ b/appl/ftp/ftpd/extern.h @@ -107,9 +107,12 @@ void klist(void); void cond_kdestroy(void); void kdestroy(void); void krbtkfile(const char *tkfile); -void afslog(const char *cell); +void afslog(const char *, int); void afsunlog(void); +extern int do_destroy_tickets; +extern char *k5ccname; + int find(char *); int builtin_ls(FILE*, const char*); diff --git a/appl/ftp/ftpd/ftpcmd.y b/appl/ftp/ftpd/ftpcmd.y index b763b745f..9a530b0dd 100644 --- a/appl/ftp/ftpd/ftpcmd.y +++ b/appl/ftp/ftpd/ftpcmd.y @@ -524,12 +524,8 @@ cmd } | SITE SP KLIST CRLF check_login { -#ifdef KRB4 if($5) klist(); -#else - reply(500, "Command not implemented."); -#endif } | SITE SP KDESTROY CRLF check_login { @@ -559,7 +555,7 @@ cmd if(guest) reply(500, "Can't be done as guest."); else if($5) - afslog(NULL); + afslog(NULL, 0); #else reply(500, "Command not implemented."); #endif @@ -570,7 +566,7 @@ cmd if(guest) reply(500, "Can't be done as guest."); else if($7) - afslog($5); + afslog($5, 0); if($5) free($5); #else @@ -1391,13 +1387,13 @@ help(struct tab *ctab, char *s) { struct tab *c; int width, NCMDS; - char *type; + char *t; char buf[1024]; if (ctab == sitetab) - type = "SITE "; + t = "SITE "; else - type = ""; + t = ""; width = 0, NCMDS = 0; for (c = ctab; c->name != NULL; c++) { int len = strlen(c->name); @@ -1412,7 +1408,7 @@ help(struct tab *ctab, char *s) int columns, lines; lreply(214, "The following %scommands are recognized %s.", - type, "(* =>'s unimplemented)"); + t, "(* =>'s unimplemented)"); columns = 76 / width; if (columns == 0) columns = 1; @@ -1448,9 +1444,9 @@ help(struct tab *ctab, char *s) return; } if (c->implemented) - reply(214, "Syntax: %s%s %s", type, c->name, c->help); + reply(214, "Syntax: %s%s %s", t, c->name, c->help); else - reply(214, "%s%-*s\t%s; unimplemented.", type, width, + reply(214, "%s%-*s\t%s; unimplemented.", t, width, c->name, c->help); } diff --git a/appl/ftp/ftpd/ftpd.c b/appl/ftp/ftpd/ftpd.c index 35e14d8af..81e91eba3 100644 --- a/appl/ftp/ftpd/ftpd.c +++ b/appl/ftp/ftpd/ftpd.c @@ -1891,7 +1891,7 @@ dologout(int status) if (logged_in) { seteuid((uid_t)0); ftpd_logwtmp(ttyline, "", ""); -#ifdef KRB4 +#if KRB4 || KRB5 cond_kdestroy(); #endif } diff --git a/appl/ftp/ftpd/gss_userok.c b/appl/ftp/ftpd/gss_userok.c index cd666df21..4bde47e60 100644 --- a/appl/ftp/ftpd/gss_userok.c +++ b/appl/ftp/ftpd/gss_userok.c @@ -76,23 +76,15 @@ gss_userok(void *app_data, char *username) /* gss_add_cred() ? */ if (data->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { krb5_ccache ccache = NULL; - char* ticketfile; - struct passwd *pw; + const char* ticketfile; + struct passwd *kpw; - pw = getpwnam(username); - - if (pw == NULL) { - ret = 1; - goto fail; - } - - asprintf (&ticketfile, "%s%u", KRB5_DEFAULT_CCROOT, - (unsigned)pw->pw_uid); - - ret = krb5_cc_resolve(gssapi_krb5_context, ticketfile, &ccache); + ret = krb5_cc_gen_new(gssapi_krb5_context, &krb5_fcc_ops, &ccache); if (ret) - goto fail; - + goto fail; + + ticketfile = krb5_cc_get_name(gssapi_krb5_context, ccache); + ret = gss_krb5_copy_ccache(&minor_status, data->delegated_cred_handle, ccache); @@ -101,17 +93,26 @@ gss_userok(void *app_data, char *username) goto fail; } - chown (ticketfile+5, pw->pw_uid, pw->pw_gid); + do_destroy_tickets = 1; + + kpw = getpwnam(username); - if (k_hasafs()) { - krb5_afslog(gssapi_krb5_context, ccache, 0, 0); - } - esetenv ("KRB5CCNAME", ticketfile, 1); + if (kpw == NULL) { + unlink(ticketfile); + ret = 1; + goto fail; + } + + chown (ticketfile, kpw->pw_uid, kpw->pw_gid); + asprintf(&k5ccname, "FILE:%s", ticketfile); + if (k5ccname) { + esetenv ("KRB5CCNAME", k5ccname, 1); + } + afslog(NULL, 1); fail: if (ccache) krb5_cc_close(gssapi_krb5_context, ccache); - free(ticketfile); } gss_release_cred(&minor_status, &data->delegated_cred_handle); diff --git a/appl/ftp/ftpd/kauth.c b/appl/ftp/ftpd/kauth.c index d879e7f20..252c968ba 100644 --- a/appl/ftp/ftpd/kauth.c +++ b/appl/ftp/ftpd/kauth.c @@ -35,6 +35,13 @@ RCSID("$Id$"); +#if defined(KRB4) || defined(KRB5) + +int do_destroy_tickets = 1; +char *k5ccname; + +#endif + #ifdef KRB4 static KTEXT_ST cip; @@ -43,8 +50,6 @@ static time_t local_time; static krb_principal pr; -static int do_destroy_tickets = 1; - static int save_tkt(const char *user, const char *instance, @@ -238,108 +243,6 @@ short_date(int32_t dp) return (cp); } -void -klist(void) -{ - int err; - - char *file = tkt_string(); - - krb_principal pr; - - char buf1[128], buf2[128]; - int header = 1; - CREDENTIALS c; - - - - err = tf_init(file, R_TKT_FIL); - if(err != KSUCCESS){ - reply(500, "%s", krb_get_err_text(err)); - return; - } - tf_close(); - - /* - * We must find the realm of the ticket file here before calling - * tf_init because since the realm of the ticket file is not - * really stored in the principal section of the file, the - * routine we use must itself call tf_init and tf_close. - */ - err = krb_get_tf_realm(file, pr.realm); - if(err != KSUCCESS){ - reply(500, "%s", krb_get_err_text(err)); - return; - } - - err = tf_init(file, R_TKT_FIL); - if(err != KSUCCESS){ - reply(500, "%s", krb_get_err_text(err)); - return; - } - - err = tf_get_pname(pr.name); - if(err != KSUCCESS){ - reply(500, "%s", krb_get_err_text(err)); - return; - } - err = tf_get_pinst(pr.instance); - if(err != KSUCCESS){ - reply(500, "%s", krb_get_err_text(err)); - return; - } - - /* - * You may think that this is the obvious place to get the - * realm of the ticket file, but it can't be done here as the - * routine to do this must open the ticket file. This is why - * it was done before tf_init. - */ - - lreply(200, "Ticket file: %s", tkt_string()); - - lreply(200, "Principal: %s", krb_unparse_name(&pr)); - while ((err = tf_get_cred(&c)) == KSUCCESS) { - if (header) { - lreply(200, "%-15s %-15s %s", - " Issued", " Expires", " Principal (kvno)"); - header = 0; - } - strlcpy(buf1, short_date(c.issue_date), sizeof(buf1)); - c.issue_date = krb_life_to_time(c.issue_date, c.lifetime); - if (time(0) < (unsigned long) c.issue_date) - strlcpy(buf2, short_date(c.issue_date), sizeof(buf2)); - else - strlcpy(buf2, ">>> Expired <<< ", sizeof(buf2)); - lreply(200, "%s %s %s (%d)", buf1, buf2, - krb_unparse_name_long(c.service, c.instance, c.realm), c.kvno); - } - if (header && err == EOF) { - lreply(200, "No tickets in file."); - } - reply(200, " "); -} - -/* - * Only destroy if we created the tickets - */ - -void -cond_kdestroy(void) -{ - if (do_destroy_tickets) - dest_tkt(); - afsunlog(); -} - -void -kdestroy(void) -{ - dest_tkt(); - afsunlog(); - reply(200, "Tickets destroyed"); -} - void krbtkfile(const char *tkfile) { @@ -350,10 +253,68 @@ krbtkfile(const char *tkfile) #endif /* KRB4 */ +#ifdef KRB5 + +static void +dest_cc(void) +{ + krb5_context context; + krb5_error_code ret; + krb5_ccache id; + + ret = krb5_init_context(&context); + if (ret == 0) { + if (k5ccname) + ret = krb5_cc_resolve(context, k5ccname, &id); + else + ret = krb5_cc_default (context, &id); + if (ret) + krb5_free_context(context); + } + if (ret == 0) { + krb5_cc_destroy(context, id); + krb5_free_context (context); + } +} +#endif + #if defined(KRB4) || defined(KRB5) +/* + * Only destroy if we created the tickets + */ + void -afslog(const char *cell) +cond_kdestroy(void) +{ + if (do_destroy_tickets) { +#if KRB4 + dest_tkt(); +#endif +#if KRB5 + dest_cc(); +#endif + do_destroy_tickets = 0; + } + afsunlog(); +} + +void +kdestroy(void) +{ +#if KRB4 + dest_tkt(); +#endif +#if KRB5 + dest_cc(); +#endif + afsunlog(); + reply(200, "Tickets destroyed"); +} + + +void +afslog(const char *cell, int quiet) { if(k_hasafs()) { #ifdef KRB5 @@ -363,7 +324,10 @@ afslog(const char *cell) ret = krb5_init_context(&context); if (ret == 0) { - ret = krb5_cc_default(context, &id); + if (k5ccname) + ret = krb5_cc_resolve(context, k5ccname, &id); + else + ret = krb5_cc_default(context, &id); if (ret) krb5_free_context(context); } @@ -376,9 +340,11 @@ afslog(const char *cell) #ifdef KRB4 krb_afslog(cell, 0); #endif - reply(200, "afslog done"); + if (!quiet) + reply(200, "afslog done"); } else { - reply(200, "no AFS present"); + if (!quiet) + reply(200, "no AFS present"); } }