/* MODULE: krbtf */ /* * Copyright (c) 2001 Carnegie Mellon University. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The name "Carnegie Mellon University" must not be used to * endorse or promote products derived from this software without * prior written permission. For permission or any other legal * details, please contact * Office of Technology Transfer * Carnegie Mellon University * 5000 Forbes Avenue * Pittsburgh, PA 15213-3890 * (412) 268-4387, fax: (412) 268-7395 * tech-transfer@andrew.cmu.edu * * 4. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by Computing Services * at Carnegie Mellon University (http://www.cmu.edu/computing/)." * * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ /* * Dec 4, 2002 by Dave Eckhardt <davide+receptionist@cs.cmu.edu> * $Id: krbtf.c,v 1.4 2006/01/24 00:16:04 snsimon Exp $ * This is inspired by code which was identical in both * auth_krb4.c and auth_krb5.c. This code is shared * between the two implementations, contains protection * against a race condition, and, when possible, uses * Heimdal krb5's memory-only credential caches to avoid * needless disk i/o. */ #ifdef __GNUC__ #ident "$Id: krbtf.c,v 1.4 2006/01/24 00:16:04 snsimon Exp $" #endif /* PUBLIC DEPENDENCIES */ #include <unistd.h> #include <stdlib.h> #include <errno.h> #ifdef SASLAUTHD_THREADED /* is this really used??? */ #include <pthread.h> #endif /* SASLAUTHD_THREADED */ #include "mechanisms.h" #include <sys/types.h> #include <sys/stat.h> #include <string.h> #include <syslog.h> #ifdef AUTH_KRB4 #include <auth_krb4.h> #define WANT_KRBTF #endif /* WANT_KRBTF */ #ifdef AUTH_KRB5 #include <auth_krb5.h> #define WANT_KRBTF #endif /* WANT_KRBTF */ #ifdef WANT_KRBTF /* PRIVATE DEPENDENCIES */ /* globals */ /* privates */ static char tf_dir[] = PATH_SASLAUTHD_RUNDIR "/.tf"; static char *tfn_cookie = 0; static int tfn_cookie_len = 0; static char pidstring[80]; int pidstring_len = 0; /* END PRIVATE DEPENDENCIES */ #endif /* WANT_KRBTF */ /* FUNCTION: krbtf_init */ /* SYNOPSIS * Initialize the Kerberos IV/V ticket-file/credential-cache common code * * When possible, use Heimdal krb5's memory-only credential caches-- * this saves a whole bunch of useless disk i/o's to create and destroy * a file which we don't want anybody to see anyway. * * If not, this function will create a private directory for ticket * files and cache getpid() for later use. Therefore, we must be * called AFTER main() does whatever fork()ing it wants. * * END SYNOPSIS */ int /* R: -1 on failure, else 0 */ krbtf_init ( /* PARAMETERS */ void /* no parameters */ /* END PARAMETERS */ ) { #ifdef WANT_KRBTF /* VARIABLES */ int rc; /* return code holder */ struct stat sb; /* stat() work area */ /* END VARIABLES */ authmech_t *authmech; #ifdef AUTH_KRB5 for (authmech = mechanisms; authmech->name != NULL; authmech++ ) { if (authmech->initialize != auth_krb5_init) continue; /* This execution is using krb5 */ /* Both MIT krb5 and Heimdal support MEMORY: ccaches */ tfn_cookie = "MEMORY:0"; tfn_cookie_len = (int)strlen(tfn_cookie); return 0; } #endif /* AUTH_KRB5 */ if (((rc = mkdir(tf_dir, 0700)) == 0) || (errno == EEXIST)) { if ((rc = lstat(tf_dir, &sb)) == 0) { if (sb.st_mode & S_IFLNK) { syslog(LOG_ERR, "krbtf_init: %s is a symbolic link", tf_dir); return -1; } } } if (rc != 0) { syslog(LOG_ERR, "krbtf_init %s: %m", tf_dir); return -1; } /* cache getpid() for use in filenames */ if ((pidstring_len = snprintf(pidstring, sizeof (pidstring), "%d", getpid())) >= sizeof (pidstring)) { syslog(LOG_ERR, "krbtf_init pidstring too long(!?)"); return -1; } return 0; #else /* WANT_KRBTF */ syslog(LOG_ERR, "krbtf_init: not compiled!"); return -1; #endif /* WANT_KRBTF */ } /* END FUNCTION: krbtf_init */ /* FUNCTION: krbtf_name */ /* SYNOPSIS * Spit a ticket-file/credentical-cache name into caller's array. * * If we can, emit the magic cookie for a memory-only krb5 ccname * END SYNOPSIS */ int /* R: -1 on failure, else 0 */ krbtf_name ( /* PARAMETERS */ char *tfname, /* O: where caller wants name */ int len /* I: available length */ /* END PARAMETERS */ ) { #ifdef WANT_KRBTF if (tfn_cookie_len) { if (tfn_cookie_len + 1 > len) { syslog(LOG_ERR, "krbtf_name: cookie name (%s) too long", tfn_cookie); return -1; } strcpy(tfname, tfn_cookie); } else { int dir_len = (int)sizeof (tf_dir) - 1; /* don't count the null */ int want_len = dir_len + 1 + pidstring_len + 1; if (want_len > len) { syslog(LOG_ERR, "krbtf_name: need room for %d bytes, got %d", want_len, len); return -1; } strcpy(tfname, tf_dir); tfname += dir_len; len -= dir_len; *tfname++ = '/'; len--; strcpy(tfname, pidstring); #ifdef SASLAUTHD_THREADED /* is this really used??? */ tfname += pidstring_len; len -= pidstring_len; if (snprintf(tfname, len, "_%d", pthread_self() >= len)) { syslog(LOG_ERR, "krbtf_name: no room for thread id"); return -1; } #endif /* SASLAUTHD_THREADED */ } return 0; #else /* WANT_KRBTF */ syslog(LOG_ERR, "krbtf_name: not compiled!"); return -1; #endif /* WANT_KRBTF */ } /* END FUNCTION: krbtf_name */ /* END MODULE: krbtf */