From: Paul Park Date: Mon, 5 Jun 1995 18:22:26 +0000 (+0000) Subject: Add support for specifiable ccache and ticket lifetime for kadm X-Git-Tag: krb5-1.0-beta6~1859 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=8480456b39cbf60ec1e28bc2a31e5da6884e70d5;p=krb5.git Add support for specifiable ccache and ticket lifetime for kadm git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5944 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/src/lib/kadm/ChangeLog b/src/lib/kadm/ChangeLog index 20ec998e2..fd6eccb8a 100644 --- a/src/lib/kadm/ChangeLog +++ b/src/lib/kadm/ChangeLog @@ -1,3 +1,13 @@ + +Mon Jun 5 14:15:37 EDT 1995 Paul Park (pjpark@mit.edu) + * adm_conn.c - Rework kadm_get_ccache() and kadm_get_creds() so that + we can specify differing credentials caches and the lifetime + of obtained tickets if not using an existing ccache. This + changes the calling sequence of krb5_adm_connect(), adding + two arguments: a ccache name and a (delta) lifetime. Default + ccache name changes formats to tkt_kadm_ and default + lifetime is 10 minutes. + Fri Jun 2 17:56:03 1995 Keith Vetter (keithv@fusion.com) * adm_conn.c: used SOCKET_ERRNO instead of errno and diff --git a/src/lib/kadm/adm_conn.c b/src/lib/kadm/adm_conn.c index 058ca5051..1c269b6c0 100644 --- a/src/lib/kadm/adm_conn.c +++ b/src/lib/kadm/adm_conn.c @@ -34,16 +34,20 @@ #include #endif /* HAVE_PWD_H */ +/* Default ticket life is 10 minutes */ +#define KADM_DEFAULT_LIFETIME (10*60) + /* * Strings */ -static char *kadm_cache_name_fmt = "FILE:/tmp/tkt_kpw_%d"; +static char *kadm_cache_name_fmt = "FILE:/tmp/tkt_kadm_%d"; /* * Prototypes for local functions */ static krb5_error_code kadm_get_ccache PROTOTYPE((krb5_context, + char *, char *, krb5_ccache *, krb5_principal *)); @@ -53,7 +57,8 @@ static krb5_error_code kadm_get_creds krb5_principal, krb5_creds *, char *, - char *)); + char *, + krb5_timestamp)); static krb5_error_code kadm_contact_server PROTOTYPE((krb5_context, krb5_data *, @@ -73,9 +78,10 @@ static krb5_error_code kadm_get_auth * Allocates new ccache and client. */ static krb5_error_code -kadm_get_ccache(kcontext, user, ccache, client) +kadm_get_ccache(kcontext, user, ccname, ccache, client) krb5_context kcontext; char *user; + char *ccname; krb5_ccache *ccache; krb5_principal *client; { @@ -83,9 +89,11 @@ kadm_get_ccache(kcontext, user, ccache, client) char *name; int did_malloc = 0; char new_cache[MAXPATHLEN]; + krb5_principal tprinc; /* Initialize. */ *client = (krb5_principal) NULL; + tprinc = (krb5_principal) NULL; /* * If a name specified, then use that one, else get it from our @@ -118,22 +126,37 @@ kadm_get_ccache(kcontext, user, ccache, client) if (kret = krb5_parse_name(kcontext, name, client)) goto cleanup; + if (!ccname) { #ifdef _WINDOWS - strcpy (new_cache, "FILE:"); - GetTempFileName (0, "tkt", 0, new_cache+5); + strcpy (new_cache, "FILE:"); + GetTempFileName (0, "tkt", 0, new_cache+5); #else - (void) sprintf(new_cache, kadm_cache_name_fmt, getpid()); + (void) sprintf(new_cache, kadm_cache_name_fmt, getpid()); #endif /* _WINDOWS */ + } + else + sprintf(new_cache, "FILE:%s", ccname); - if (kret = krb5_cc_resolve(kcontext, new_cache, ccache)) + /* + * We only need to resolve the credentials cache if one hasn't + * been supplied to us. + */ + if (!(*ccache) && (kret = krb5_cc_resolve(kcontext, new_cache, ccache))) goto cleanup; - kret = krb5_cc_initialize(kcontext, *ccache, *client); + /* XXX assumes a file ccache */ + if ((kret = krb5_cc_get_principal(kcontext, *ccache, &tprinc)) == + KRB5_FCC_NOFILE) + kret = krb5_cc_initialize(kcontext, *ccache, *client); + cleanup: if (did_malloc) free(name); + if (tprinc) + krb5_free_principal(kcontext, tprinc); + if (kret) { if (*client) krb5_free_principal(kcontext, *client); @@ -149,18 +172,20 @@ kadm_get_ccache(kcontext, user, ccache, client) * Allocates new principal for creds->server. */ static krb5_error_code -kadm_get_creds(kcontext, ccache, client, creds, prompt, oldpw) +kadm_get_creds(kcontext, ccache, client, creds, prompt, oldpw, tlife) krb5_context kcontext; krb5_ccache ccache; krb5_principal client; krb5_creds *creds; char *prompt; char *oldpw; + krb5_timestamp tlife; { char *client_name; krb5_error_code kret; krb5_address **my_addresses; int old_pwsize; + krb5_creds tcreds; /* Initialize */ my_addresses = (krb5_address **) NULL; @@ -191,27 +216,68 @@ kadm_get_creds(kcontext, ccache, client, creds, prompt, oldpw) 0)) goto cleanup; - if (prompt != (char *) NULL) { - /* Read the password */ - old_pwsize = KRB5_ADM_MAX_PASSWORD_LEN; - if (kret = krb5_read_password(kcontext, - prompt, - (char *) NULL, - oldpw, - &old_pwsize)) + /* Attempt to retrieve an appropriate entry from the credentials cache. */ + if ((kret = krb5_cc_retrieve_cred(kcontext, + ccache, + KRB5_TC_MATCH_SRV_NAMEONLY, + creds, + &tcreds)) + == KRB5_CC_NOTFOUND) { + krb5_timestamp jetzt; + + if (prompt != (char *) NULL) { + /* Read the password */ + old_pwsize = KRB5_ADM_MAX_PASSWORD_LEN; + if (kret = krb5_read_password(kcontext, + prompt, + (char *) NULL, + oldpw, + &old_pwsize)) + goto cleanup; + } + + if (kret = krb5_timeofday(kcontext, &jetzt)) goto cleanup; + + if (tlife > 0) + creds->times.endtime = jetzt + tlife; + else + creds->times.endtime = jetzt + KADM_DEFAULT_LIFETIME; + + /* Get our initial ticket */ + kret = krb5_get_in_tkt_with_password(kcontext, + 0, + my_addresses, + NULL, + NULL, + oldpw, + ccache, + creds, + 0); } + else { + krb5_principal sclient, sserver; - /* Get our initial ticket */ - kret = krb5_get_in_tkt_with_password(kcontext, - 0, - my_addresses, - NULL, - NULL, - oldpw, - ccache, - creds, - 0); + if (!kret) { + /* + * We found the credentials cache entry - copy it out. + * + * We'd like to just blast tcreds on top of creds, but we cannot. + * other logic uses the client data, and rather than going and + * chasing all that logic down, might as well pretend that we just + * filled in all the other muck. + */ + sclient = creds->client; + sserver = creds->server; + memcpy((char *) creds, (char *) &tcreds, sizeof(tcreds)); + if (creds->client) + krb5_free_principal(kcontext, creds->client); + if (creds->server) + krb5_free_principal(kcontext, creds->server); + creds->client = sclient; + creds->server = sserver; + } + } cleanup: if (kret) { @@ -523,21 +589,27 @@ kadm_get_auth(kcontext, ctxp, local, remote) /* * krb5_adm_connect() - Establish the connection to the service. * + * If *ccachep is not null, then that ccache is used to establish the identity + * of the caller. (Argument list is ugly, I know) + * * Errors are not reported by this routine. * Cleanup after successful invocation must: - * destroy ccache. + * destroy/close ccache. * free auth_context * close socket. */ krb5_error_code INTERFACE -krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp, ccachep) +krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp, + ccachep, ccname, tlife) krb5_context kcontext; /* Context handle (In ) */ char *user; /* User specified (In ) */ char *prompt; /* Old password prompt (In ) */ char *opassword; /* Old Password (I/O) */ int *sockp; /* Socket for conn. (Out) */ krb5_auth_context **ctxp; /* Auth context (Out) */ - krb5_ccache *ccachep; /* Credentials cache (Out) */ + krb5_ccache *ccachep; /* Credentials cache (I/O) */ + char *ccname; /* Cred cache name (In ) */ + krb5_timestamp tlife; /* Ticket lifetime (In ) */ { krb5_error_code kret; krb5_principal client; @@ -547,6 +619,7 @@ krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp, ccachep) krb5_data response_data; krb5_address *local_addr; krb5_address *remote_addr; + krb5_boolean ccache_supplied; char *server; @@ -557,12 +630,12 @@ krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp, ccachep) local_addr = remote_addr = (krb5_address *) NULL; client = (krb5_principal) NULL; *ctxp = (krb5_auth_context *) NULL; - *ccachep = (krb5_ccache) NULL; + ccache_supplied = (*ccachep != (krb5_ccache) NULL); /* * Find the appropriate credentials cache and set up our identity. */ - if (kret = kadm_get_ccache(kcontext, user, ccachep, &client)) + if (kret = kadm_get_ccache(kcontext, user, ccname, ccachep, &client)) goto cleanup; /* @@ -573,7 +646,8 @@ krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp, ccachep) client, &creds, prompt, - opassword)) + opassword, + tlife)) goto cleanup; /* @@ -652,7 +726,7 @@ krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp, ccachep) krb5_free_principal(kcontext, creds.server); if (client) krb5_free_principal(kcontext, client); - if (*ccachep) { + if (*ccachep && !ccache_supplied) { krb5_cc_destroy(kcontext, *ccachep); *ccachep = (krb5_ccache) NULL; } @@ -663,6 +737,9 @@ krb5_adm_connect(kcontext, user, prompt, opassword, sockp, ctxp, ccachep) /* * krb5_adm_disconnect() - Disconnect from the administrative service. + * + * If ccache is supplied, then it is destroyed. Otherwise, the ccache is + * the caller's responsibility to close. */ void INTERFACE krb5_adm_disconnect(kcontext, socketp, auth_context, ccache)