From: fredrik@DOLDA2000.COM Date: Fri, 4 Mar 2005 03:24:43 +0000 (+0000) Subject: First should-be-working version. X-Git-Url: http://git.dolda2000.com/gitweb/?a=commitdiff_plain;h=116e305b36c9f3502f8c301d452350061fb32ffc;p=utils.git First should-be-working version. git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/utils@169 959494ce-11ee-0310-bf91-de5d638817bd --- diff --git a/krb5-agent.c b/krb5-agent.c index 7edd369..2f23567 100644 --- a/krb5-agent.c +++ b/krb5-agent.c @@ -7,12 +7,12 @@ #include #include -#define STD_INTERVAL (3600 * 8) - volatile int died = 0; pid_t child; int execmode = 0, failsafe = 0; int verbose = 0, quiet = 0; +time_t renewat; + krb5_context context = NULL; krb5_ccache ccache = NULL; @@ -20,8 +20,10 @@ void cleanup_krb5(void) { if(ccache != NULL) krb5_cc_close(context, ccache); + ccache = NULL; if(context != NULL) krb5_free_context(context); + context = NULL; } void sighandler(int sig) @@ -30,26 +32,124 @@ void sighandler(int sig) case SIGCHLD: died = 1; break; + case SIGHUP: + case SIGINT: + case SIGTERM: + if(execmode) + kill(child, sig); + break; } } void renew(void) { int ret; + krb5_principal me; + krb5_creds creds; - if(ccache == NULL) + if(context == NULL) return; + if(ccache == NULL) { + if((ret = krb5_cc_default(context, &ccache)) != 0) { + if(!quiet) + fprintf(stderr, "could not initialize Kerberos context: %s\n", error_message(ret)); + return; + } + } + + me = NULL; + memset(&creds, 0, sizeof(creds)); + if((ret = krb5_cc_get_principal(context, ccache, &me)) != 0) { + if(!quiet) + fprintf(stderr, "could not get principal from cache: %s\n", error_message(ret)); + goto out; + } + if((ret = krb5_get_renewed_creds(context, &creds, me, ccache, NULL)) != 0) { + if(!quiet) + fprintf(stderr, "could not get renewed credentials: %s\n", error_message(ret)); + goto out; + } + if((ret = krb5_cc_initialize(context, ccache, me)) != 0) { + if(!quiet) + fprintf(stderr, "could not reinitialize cache: %s\n", error_message(ret)); + krb5_free_cred_contents(context, &creds); + goto out; + } + if((ret = krb5_cc_store_cred(context, ccache, &creds)) != 0) { + if(!quiet) + fprintf(stderr, "could not store renewed credentials: %s\n", error_message(ret)); + krb5_free_cred_contents(context, &creds); + goto out; + } + krb5_free_cred_contents(context, &creds); + if(verbose >= 1) + printf("successfully renewed credentials\n"); + + out: + if(me != NULL) + krb5_free_principal(context, me); +} + +time_t goodrenewtime(void) +{ + int ret; + krb5_principal me; + krb5_cc_cursor cur; + krb5_creds creds; + time_t now, good; + + if(context == NULL) + return(-1); + if(ccache == NULL) { + if((ret = krb5_cc_default(context, &ccache)) != 0) { + if(!quiet) + fprintf(stderr, "could not initialize Kerberos context: %s\n", error_message(ret)); + return(-1); + } + } + + me = NULL; + cur = NULL; + good = -1; + if((ret = krb5_cc_get_principal(context, ccache, &me)) != 0) { + if(!quiet) + fprintf(stderr, "could not get principal from cache: %s\n", error_message(ret)); + goto out; + } + if((ret = krb5_cc_start_seq_get(context, ccache, &cur)) != 0) { + if(!quiet) + fprintf(stderr, "could not open credentials cache: %s\n", error_message(ret)); + goto out; + } + now = time(NULL); + while(!krb5_cc_next_cred(context, ccache, &cur, &creds)) { + if(!strcmp(krb5_princ_component(context, creds.server, 0)->data, KRB5_TGS_NAME) && + !strcmp(krb5_princ_component(context, creds.server, 1)->data, me->realm.data)) { + if(!creds.times.starttime) + creds.times.starttime = creds.times.authtime; + good = (creds.times.starttime + (((creds.times.endtime - creds.times.starttime) * 9) / 10)); + break; + } + krb5_free_cred_contents(context, &creds); + } + + out: + if(cur != NULL) + krb5_cc_end_seq_get(context, ccache, &cur); + if(me != NULL) + krb5_free_principal(context, me); + return(good); } int main(int argc, char **argv) { char *p; int c; - time_t interval, last, now; + time_t interval, now; pid_t wpid; int ret, status; - interval = STD_INTERVAL; + interval = -1; while((c = getopt(argc, argv, "+hi:vqf")) != -1) { switch(c) { case 'v': @@ -63,7 +163,7 @@ int main(int argc, char **argv) break; case 'i': p = optarg + strlen(optarg) - 1; - if((*p >= 'a') || (*p <= 'z')) { + if((*p >= 'a') && (*p <= 'z')) { if(*p == 'm') interval = 60; else if(*p == 'h') @@ -118,8 +218,13 @@ int main(int argc, char **argv) perror(argv[optind]); exit(255); } + signal(SIGHUP, sighandler); + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); } - now = last = time(NULL); + now = time(NULL); + if(interval >= 0) + renewat = now + interval; while(1) { if(died) { wpid = waitpid(-1, &status, WNOHANG); @@ -130,6 +235,7 @@ int main(int argc, char **argv) if(WIFEXITED(status)) { exit(WEXITSTATUS(status)); } else { + cleanup_krb5(); signal(WTERMSIG(status), SIG_DFL); kill(getpid(), WTERMSIG(status)); exit(255); @@ -137,10 +243,24 @@ int main(int argc, char **argv) } died = 0; } - sleep((last + interval) - now); + if(interval < 0) { + if((renewat = goodrenewtime()) < 0) { + renewat = -1; + } else if(verbose >= 2) { + printf("will renew tickets at %s", ctime(&renewat)); + } + } + if(renewat < 0) + sleep(60); + else + sleep(renewat - now); now = time(NULL); - if(now >= last + interval) + if((renewat >= 0) && (now >= renewat)) { renew(); + now = time(NULL); + if(interval >= 0) + renewat = now + interval; + } } }