int /* R: -1 on failure, else 0 */ auth_krb4_init ( /* PARAMETERS */ void /* no parameters */ /* END PARAMETERS */ ) { #ifdef AUTH_KRB4 /* VARIABLES */ int rc; /* return code holder */ char *configname = 0; /* END VARIABLES */ 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 /* ! AUTH_KRB4 */ return -1; #endif /* ! AUTH_KRB4 */ }
static int form_principal_name ( const char *user, const char *service, const char *realm, char *pname, int pnamelen ) { const char *forced_instance = 0; int plen; plen = strlcpy(pname, user, pnamelen); user = pname; if (config && cfile_getswitch(config, "krb5_conv_krb4_instance", 0)) { char *krb4_instance; if ((krb4_instance = strchr(pname, '.'))) *krb4_instance = '/'; } if (config) { char keyname[1024]; snprintf(keyname, sizeof (keyname), "krb5_%s_instance", service); forced_instance = cfile_getstring(config, keyname, 0); } if (forced_instance) { char *user_specified; if ((user_specified = strchr(user, '/'))) { if (strcmp(user_specified + 1, forced_instance)) { /* user not allowed to override sysadmin */ return -1; } else { /* don't need to force--user already asked for it */ forced_instance = 0; } } } /* form user[/instance][@realm] */ plen += snprintf(pname+plen, pnamelen-plen, "%s%s%s%s", (forced_instance ? "/" : ""), (forced_instance ? forced_instance : ""), ((realm && realm[0]) ? "@" : ""), ((realm && realm[0]) ? realm : "") ); if ((plen <= 0) || (plen >= pnamelen)) return -1; /* Perhaps we should uppercase the realm? */ return 0; }
int /* R: -1 on failure, else 0 */ auth_krb5_init ( /* PARAMETERS */ void /* no parameters */ /* END PARAMETERS */ ) { #ifdef AUTH_KRB5 int rc; char *configname = 0; if (krbtf_init() == -1) { syslog(LOG_ERR, "auth_krb5_init krbtf_init failed"); return -1; } 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]; if (!(config = cfile_read(configname, complaint, (int)sizeof (complaint)))) { syslog(LOG_ERR, "auth_krb5_init %s", complaint); return -1; } } if (config) { keytabname = cfile_getstring(config, "krb5_keytab", keytabname); verify_principal = cfile_getstring(config, "krb5_verify_principal", verify_principal); } return 0; #else return -1; #endif }
int auth_httpform_init ( /* PARAMETERS */ void /* no parameters */ /* END PARAMETERS */ ) { /* VARIABLES */ int rc; char *configname = NULL; struct addrinfo hints; /* END VARIABLES */ /* name of config file may be given with -O option */ if (mech_option) configname = mech_option; else if (access(SASLAUTHD_CONF_FILE_DEFAULT, F_OK) == 0) configname = SASLAUTHD_CONF_FILE_DEFAULT; /* open and read config file */ if (configname) { char complaint[1024]; if (!(config = cfile_read(configname, complaint, sizeof (complaint)))) { syslog(LOG_ERR, "auth_httpform_init %s", complaint); return -1; } } if (config) { r_host = cfile_getstring(config, "httpform_host", r_host); r_port = cfile_getstring(config, "httpform_port", r_port); r_uri = cfile_getstring(config, "httpform_uri", r_uri); formdata = cfile_getstring(config, "httpform_data", formdata); } if (formdata == NULL || r_uri == NULL) { syslog(LOG_ERR, "auth_httpform_init formdata and uri must be specified"); return -1; } /* lookup the host/port - taken from auth_rimap */ if (ai) freeaddrinfo(ai); memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_CANONNAME; if ((rc = getaddrinfo(r_host, r_port, &hints, &ai)) != 0) { syslog(LOG_ERR, "auth_httpform_init: getaddrinfo %s/%s: %s", r_host, r_port, gai_strerror(rc)); return -1; } /* Make sure we have AF_INET or AF_INET6 addresses. */ if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { syslog(LOG_ERR, "auth_httpform_init: no IP address info for %s", ai->ai_canonname ? ai->ai_canonname : r_host); freeaddrinfo(ai); ai = NULL; return -1; } return 0; }
char * /* R: allocated response string */ auth_krb4 ( /* PARAMETERS */ const char *login, /* I: plaintext authenticator */ const char *password, /* I: plaintext password */ const char *service, const char *realm_in /* END PARAMETERS */ ) { /* VARIABLES */ char aname[ANAME_SZ]; /* Kerberos principal */ const char *realm; /* Kerberos realm to authenticate in */ int rc; /* return code */ char tf_name[TF_NAME_LEN]; /* Ticket file name */ char *instance, *user_specified; KTEXT_ST ticket; AUTH_DAT kdata; /* END VARIABLES */ /* * Make sure we have a password. If this is NULL the call * to krb_get_pw_in_tkt below would try to prompt for * one interactively. */ 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]) { /* sysadmin specified a (mandatory) instance */ if (strcmp(user_specified + 1, instance)) { return strdup("NO saslauthd principal name error"); } /* nuke instance from "aname"-- matches what's already in "instance" */ *user_specified = '\0'; } else { /* sysadmin has no preference, so we shift * instance name from "aname" to "instance" */ *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"); } /* if the TGT wasn't spoofed, it should entitle us to an rcmd ticket... */ 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"); } /* .. and that ticket should match our secret host key */ 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"); }