#ifdef __GNUC__
#ident "$Id: auth_krb4.c,v 1.9 2006/01/24 00:16:03 snsimon Exp $"
#endif
#include <unistd.h>
#include "mechanisms.h"
#include "globals.h"
#include "cfile.h"
#include "krbtf.h"
#ifdef AUTH_KRB4
# include <krb.h>
# ifdef WITH_DES
# ifdef WITH_SSL_DES
# include <openssl/des.h>
# else
# include <des.h>
# endif
# endif
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <sys/stat.h>
#include "auth_krb4.h"
#ifdef DEADCODE
extern int swap_bytes;
#endif
#ifdef AUTH_KRB4
static char default_realm[REALM_SZ];
static cfile config = 0;
static char myhostname[BUFSIZ];
static char *srvtabname = "";
static char *verify_principal = "rcmd";
#endif
#define TF_NAME_LEN 128
#ifndef KRB_TICKET_GRANTING_TICKET
#define KRB_TICKET_GRANTING_TICKET "krbtgt"
#endif
int
auth_krb4_init (
void
)
{
#ifdef AUTH_KRB4
int rc;
char *configname = 0;
if (mech_option)
configname = mech_option;
else if (access(SASLAUTHD_CONF_FILE_DEFAULT, F_OK) == 0)
configname = SASLAUTHD_CONF_FILE_DEFAULT;
if (configname) {
char complaint[1024];
config = cfile_read(configname, complaint, sizeof(complaint));
if (!config) {
syslog(LOG_ERR, "auth_krb4_init %s", complaint);
return -1;
}
}
if (config) {
srvtabname = cfile_getstring(config, "krb4_srvtab", srvtabname);
verify_principal = cfile_getstring(config, "krb4_verify_principal",
verify_principal);
}
if (krbtf_init() == -1) {
syslog(LOG_ERR, "auth_krb4_init krbtf_init failed");
return -1;
}
rc = krb_get_lrealm(default_realm, 1);
if (rc) {
syslog(LOG_ERR, "auth_krb4: krb_get_lrealm: %s",
krb_get_err_text(rc));
return -1;
}
if (gethostname(myhostname, sizeof(myhostname)) < 0) {
syslog(LOG_ERR, "auth_krb4: gethoanem(): %m");
return -1;
}
myhostname[sizeof(myhostname) - 1] = '\0';
return 0;
#else
return -1;
#endif
}
#ifdef AUTH_KRB4
char *
auth_krb4 (
const char *login,
const char *password,
const char *service,
const char *realm_in
)
{
char aname[ANAME_SZ];
const char *realm;
int rc;
char tf_name[TF_NAME_LEN];
char *instance, *user_specified;
KTEXT_ST ticket;
AUTH_DAT kdata;
if (password == NULL) {
syslog(LOG_ERR, "auth_krb4: NULL password?");
return strdup("NO saslauthd internal error");
}
if (krbtf_name(tf_name, sizeof(tf_name)) != 0) {
syslog(LOG_ERR, "auth_krb4: could not generate ticket file name");
return strdup("NO saslauthd internal error");
}
krb_set_tkt_string(tf_name);
strncpy(aname, login, ANAME_SZ-1);
aname[ANAME_SZ-1] = '\0';
instance = "";
if (config) {
char keyname[1024];
snprintf(keyname, sizeof(keyname), "krb4_%s_instance", service);
instance = cfile_getstring(config, keyname, "");
}
user_specified = strchr(aname, '.');
if (user_specified) {
if (instance && instance[0]) {
if (strcmp(user_specified + 1, instance)) {
return strdup("NO saslauthd principal name error");
}
*user_specified = '\0';
} else {
*user_specified = '\0';
instance = user_specified + 1;
}
}
if(realm_in && *realm_in != '\0') {
realm = realm_in;
} else {
realm = default_realm;
}
rc = krb_get_pw_in_tkt(aname, instance, realm,
KRB_TICKET_GRANTING_TICKET,
realm, 1, password);
if (rc == INTK_BADPW || rc == KDC_PR_UNKNOWN) {
return strdup("NO");
} else if (rc != KSUCCESS) {
syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s",
krb_get_err_text(rc));
return strdup("NO saslauthd internal error");
}
rc = krb_mk_req(&ticket, verify_principal, myhostname, default_realm, 0);
if (rc != KSUCCESS) {
syslog(LOG_ERR, "ERROR: auth_krb4: krb_get_pw_in_tkt: %s",
krb_get_err_text(rc));
dest_tkt();
return strdup("NO saslauthd internal error");
}
rc = krb_rd_req(&ticket, verify_principal, myhostname, 0, &kdata, srvtabname);
if (rc != RD_AP_OK) {
syslog(LOG_ERR, "ERROR: auth_krb4: krb_rd_req:%s",
krb_get_err_text(rc));
dest_tkt();
return strdup("NO saslauthd internal error");
}
dest_tkt();
return strdup("OK");
}
#else
char *
auth_krb4 (
const char *login __attribute__((unused)),
const char *password __attribute__((unused)),
const char *service __attribute__((unused)),
const char *realm __attribute__((unused))
)
{
return NULL;
}
#endif