diff --git a/appl/ftp/ftp/gssapi.c b/appl/ftp/ftp/gssapi.c index 9eb629620..93f973c17 100644 --- a/appl/ftp/ftp/gssapi.c +++ b/appl/ftp/ftp/gssapi.c @@ -48,6 +48,7 @@ struct gss_data { gss_ctx_id_t context_hdl; char *client_name; gss_cred_id_t delegated_cred_handle; + void *mech_data; }; static int @@ -277,6 +278,7 @@ gss_adat(void *app_data, void *buf, size_t len) } int gss_userok(void*, char*); +int gss_session(void*, char*); struct sec_server_mech gss_server_mech = { "GSSAPI", @@ -292,7 +294,8 @@ struct sec_server_mech gss_server_mech = { gss_adat, NULL, /* pbsz */ NULL, /* ccc */ - gss_userok + gss_userok, + gss_session }; #else /* FTP_SERVER */ diff --git a/appl/ftp/ftp/security.c b/appl/ftp/ftp/security.c index 8b7fcbced..0e1a5a7e9 100644 --- a/appl/ftp/ftp/security.c +++ b/appl/ftp/ftp/security.c @@ -583,6 +583,14 @@ sec_userok(char *userstr) return 0; } +int +sec_session(char *user) +{ + if(sec_complete) + return (*mech->session)(app_data, user); + return 0; +} + char *ftp_command; void diff --git a/appl/ftp/ftp/security.h b/appl/ftp/ftp/security.h index 38a4b7c0c..99e6b2c38 100644 --- a/appl/ftp/ftp/security.h +++ b/appl/ftp/ftp/security.h @@ -70,6 +70,7 @@ struct sec_server_mech { size_t (*pbsz)(void *, size_t); int (*ccc)(void*); int (*userok)(void*, char*); + int (*session)(void*, char*); }; #define AUTH_OK 0 diff --git a/appl/ftp/ftpd/ftpd.c b/appl/ftp/ftpd/ftpd.c index cbbebe850..8ec6b1679 100644 --- a/appl/ftp/ftpd/ftpd.c +++ b/appl/ftp/ftpd/ftpd.c @@ -280,10 +280,6 @@ main(int argc, char **argv) krb_set_tkt_string(tkfile); #endif } -#if defined(KRB4) || defined(KRB5) - if(k_hasafs()) - k_setpag(); -#endif if(getarg(args, num_args, argc, argv, &optind)) usage(1); @@ -595,9 +591,10 @@ user(char *name) if (logging) strlcpy(curname, name, sizeof(curname)); if(sec_complete) { - if(sec_userok(name) == 0) + if(sec_userok(name) == 0) { do_login(232, name); - else + sec_session(name); + } else reply(530, "User %s access denied.", name); } else { #ifdef OTP @@ -727,6 +724,10 @@ int do_login(int code, char *passwd) return -1; } initgroups(pw->pw_name, pw->pw_gid); +#if defined(KRB4) || defined(KRB5) + if(k_hasafs()) + k_setpag(); +#endif /* open wtmp before chroot */ ftpd_logwtmp(ttyline, pw->pw_name, remotehost); diff --git a/appl/ftp/ftpd/gss_userok.c b/appl/ftp/ftpd/gss_userok.c index 9aa753e58..8e329d07b 100644 --- a/appl/ftp/ftpd/gss_userok.c +++ b/appl/ftp/ftpd/gss_userok.c @@ -41,41 +41,70 @@ RCSID("$Id$"); What is the correct way to do this? */ +struct gss_krb5_data { + krb5_context context; +}; + /* XXX sync with gssapi.c */ struct gss_data { gss_ctx_id_t context_hdl; char *client_name; gss_cred_id_t delegated_cred_handle; + void *mech_data; }; int gss_userok(void*, char*); /* to keep gcc happy */ +int gss_session(void*, char*); /* to keep gcc happy */ int gss_userok(void *app_data, char *username) { struct gss_data *data = app_data; - krb5_context context; krb5_error_code ret; krb5_principal client; - OM_uint32 minor_status; + struct gss_krb5_data *kdata; - ret = krb5_init_context(&context); - if (ret) + kdata = calloc(1, sizeof(struct gss_krb5_data)); + if (kdata == NULL) return 1; + data->mech_data = kdata; - ret = krb5_parse_name(context, data->client_name, &client); - if(ret) { - krb5_free_context(context); + ret = krb5_init_context(&(kdata->context)); + if (ret) { + free(kdata); return 1; } - ret = krb5_kuserok(context, client, username); + + ret = krb5_parse_name(kdata->context, data->client_name, &client); + if(ret) { + krb5_free_context(kdata->context); + free(kdata); + return 1; + } + ret = krb5_kuserok(kdata->context, client, username); if (!ret) { - krb5_free_principal(context, client); - krb5_free_context(context); + krb5_free_principal(kdata->context, client); + krb5_free_context(kdata->context); + free(kdata); return 1; } ret = 0; + krb5_free_principal(kdata->context, client); + return ret; +} + +int +gss_session(void *app_data, char *username) +{ + struct gss_data *data = app_data; + krb5_error_code ret; + OM_uint32 minor_status; + struct gss_krb5_data *kdata; + + ret = 0; + + kdata = (struct gss_krb5_data *)(data->mech_data); /* more of krb-depend stuff :-( */ /* gss_add_cred() ? */ @@ -84,11 +113,11 @@ gss_userok(void *app_data, char *username) const char* ticketfile; struct passwd *kpw; - ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache); + ret = krb5_cc_gen_new(kdata->context, &krb5_fcc_ops, &ccache); if (ret) goto fail; - ticketfile = krb5_cc_get_name(context, ccache); + ticketfile = krb5_cc_get_name(kdata->context, ccache); ret = gss_krb5_copy_ccache(&minor_status, data->delegated_cred_handle, @@ -116,11 +145,11 @@ gss_userok(void *app_data, char *username) afslog(NULL, 1); fail: if (ccache) - krb5_cc_close(context, ccache); + krb5_cc_close(kdata->context, ccache); } gss_release_cred(&minor_status, &data->delegated_cred_handle); - krb5_free_principal(context, client); - krb5_free_context(context); + krb5_free_context(kdata->context); + free(kdata); return ret; }