From 5ed96cd5daa48af752db4781418f32f9258cce94 Mon Sep 17 00:00:00 2001 From: markm Date: Thu, 24 Feb 2000 11:28:20 +0000 Subject: [PATCH] Vendor import of Heimdal 0.2p --- crypto/heimdal/ChangeLog | 20 + crypto/heimdal/NEWS | 6 + crypto/heimdal/configure | 4 +- crypto/heimdal/configure.in | 4 +- crypto/heimdal/kadmin/ChangeLog | 5 + crypto/heimdal/kadmin/load.c | 4 +- crypto/heimdal/kdc/connect.c | 112 +++-- crypto/heimdal/lib/auth/pam/pam.c | 490 +++++++++++++++------- crypto/heimdal/lib/auth/pam/pam.conf.add | 15 +- crypto/heimdal/lib/krb5/Makefile.am | 4 +- crypto/heimdal/lib/krb5/Makefile.in | 4 +- crypto/heimdal/lib/krb5/addr_families.c | 9 +- crypto/heimdal/lib/krb5/expand_hostname.c | 48 ++- crypto/heimdal/lib/roken/ChangeLog | 13 + crypto/heimdal/lib/roken/Makefile.am | 4 +- crypto/heimdal/lib/roken/Makefile.in | 4 +- crypto/heimdal/lib/roken/snprintf.c | 6 +- 17 files changed, 494 insertions(+), 258 deletions(-) diff --git a/crypto/heimdal/ChangeLog b/crypto/heimdal/ChangeLog index 08c03915dc58..b5d265e36723 100644 --- a/crypto/heimdal/ChangeLog +++ b/crypto/heimdal/ChangeLog @@ -1,3 +1,23 @@ +2000-02-20 Assar Westerlund + + * Release 0.2p + +2000-02-19 Assar Westerlund + + * lib/krb5/Makefile.am: set version to 9:1:0 + + * lib/krb5/expand_hostname.c (krb5_expand_hostname): make sure + that realms is filled in even when getaddrinfo fails or does not + return any canonical name + + * kdc/connect.c (descr): add sockaddr and string representation + (*): re-write to use the above mentioned + +2000-02-16 Assar Westerlund + + * lib/krb5/addr_families.c (krb5_parse_address): use + krb5_sockaddr2address to copy the result from getaddrinfo. + 2000-02-14 Assar Westerlund * Release 0.2o diff --git a/crypto/heimdal/NEWS b/crypto/heimdal/NEWS index b9799c772bbc..ead7269f6226 100644 --- a/crypto/heimdal/NEWS +++ b/crypto/heimdal/NEWS @@ -1,3 +1,9 @@ +Changes in release 0.2p: + + * bug fix in `kadmin load/merge' + + * bug fix in krb5_parse_address + Changes in release 0.2o: * gss_{import,export}_sec_context added to libgssapi diff --git a/crypto/heimdal/configure b/crypto/heimdal/configure index 3c92e5f1bf95..24e63e139f98 100755 --- a/crypto/heimdal/configure +++ b/crypto/heimdal/configure @@ -1,6 +1,6 @@ #! /bin/sh -# From configure.in Revision: 1.217 +# From configure.in Revision: 1.218 @@ -911,7 +911,7 @@ fi PACKAGE=heimdal -VERSION=0.2o +VERSION=0.2p if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } diff --git a/crypto/heimdal/configure.in b/crypto/heimdal/configure.in index 3f814c146de8..844aa839abce 100644 --- a/crypto/heimdal/configure.in +++ b/crypto/heimdal/configure.in @@ -1,9 +1,9 @@ dnl Process this file with autoconf to produce a configure script. -AC_REVISION($Revision: 1.217 $) +AC_REVISION($Revision: 1.218 $) AC_INIT(lib/krb5/send_to_kdc.c) AM_CONFIG_HEADER(include/config.h) -AM_INIT_AUTOMAKE(heimdal,0.2o) +AM_INIT_AUTOMAKE(heimdal,0.2p) AC_PREFIX_DEFAULT(/usr/heimdal) diff --git a/crypto/heimdal/kadmin/ChangeLog b/crypto/heimdal/kadmin/ChangeLog index 5a73511680b7..05ee0d4197ae 100644 --- a/crypto/heimdal/kadmin/ChangeLog +++ b/crypto/heimdal/kadmin/ChangeLog @@ -1,3 +1,8 @@ +2000-02-16 Assar Westerlund + + * load.c (doit): check return value from parse_hdbflags2int + correctly + 2000-01-25 Assar Westerlund * load.c: checking all parsing for errors and all memory diff --git a/crypto/heimdal/kadmin/load.c b/crypto/heimdal/kadmin/load.c index cc809b50734b..6a95887cab2f 100644 --- a/crypto/heimdal/kadmin/load.c +++ b/crypto/heimdal/kadmin/load.c @@ -34,7 +34,7 @@ #include "kadmin_locl.h" #include -RCSID("$Id: load.c,v 1.35 2000/01/25 22:59:27 assar Exp $"); +RCSID("$Id: load.c,v 1.36 2000/02/16 16:05:28 assar Exp $"); struct entry { char *principal; @@ -439,7 +439,7 @@ doit(const char *filename, int merge) continue; } - if (parse_hdbflags2int (&ent.flags, e.flags) != 0) { + if (parse_hdbflags2int (&ent.flags, e.flags) != 1) { fprintf (stderr, "%s:%d:error parsing flags (%s)\n", filename, line, e.flags); hdb_free_entry (context, &ent); diff --git a/crypto/heimdal/kdc/connect.c b/crypto/heimdal/kdc/connect.c index a1bbdcbd0892..0ce23b5481cb 100644 --- a/crypto/heimdal/kdc/connect.c +++ b/crypto/heimdal/kdc/connect.c @@ -33,7 +33,7 @@ #include "kdc_locl.h" -RCSID("$Id: connect.c,v 1.69 2000/02/11 17:45:45 assar Exp $"); +RCSID("$Id: connect.c,v 1.70 2000/02/19 18:41:24 assar Exp $"); /* * a tuple describing on what to listen @@ -193,6 +193,10 @@ struct descr { size_t size; size_t len; time_t timeout; + struct sockaddr_storage __ss; + struct sockaddr *sa; + int sock_len; + char addr_string[128]; }; /* @@ -208,6 +212,7 @@ init_socket(struct descr *d, krb5_address *a, int family, int type, int port) int sa_size; memset(d, 0, sizeof(*d)); + d->sa = (struct sockaddr *)&d->__ss; d->s = -1; ret = krb5_addr2sockaddr (a, sa, &sa_size, port); @@ -375,34 +380,36 @@ addr_to_string(struct sockaddr *addr, size_t addr_len, char *str, size_t len) snprintf(str, len, "", addr->sa_family); } +/* + * Handle the request in `buf, len' to socket `d' + */ + static void do_request(void *buf, size_t len, int sendlength, - int socket, struct sockaddr *from, size_t from_len) + struct descr *d) { krb5_error_code ret; krb5_data reply; - char addr[128]; - - addr_to_string(from, from_len, addr, sizeof(addr)); reply.length = 0; - ret = process_request(buf, len, &reply, &sendlength, addr, from); + ret = process_request(buf, len, &reply, &sendlength, + d->addr_string, d->sa); if(reply.length){ - kdc_log(5, "sending %d bytes to %s", reply.length, addr); + kdc_log(5, "sending %d bytes to %s", reply.length, d->addr_string); if(sendlength){ unsigned char len[4]; len[0] = (reply.length >> 24) & 0xff; len[1] = (reply.length >> 16) & 0xff; len[2] = (reply.length >> 8) & 0xff; len[3] = reply.length & 0xff; - if(sendto(socket, len, sizeof(len), 0, from, from_len) < 0) { - kdc_log (0, "sendto(%s): %s", addr, strerror(errno)); + if(sendto(d->s, len, sizeof(len), 0, d->sa, d->sock_len) < 0) { + kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno)); krb5_data_free(&reply); return; } } - if(sendto(socket, reply.data, reply.length, 0, from, from_len) < 0) { - kdc_log (0, "sendto(%s): %s", addr, strerror(errno)); + if(sendto(d->s, reply.data, reply.length, 0, d->sa, d->sock_len) < 0) { + kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno)); krb5_data_free(&reply); return; } @@ -410,16 +417,17 @@ do_request(void *buf, size_t len, int sendlength, } if(ret) kdc_log(0, "Failed processing %lu byte request from %s", - (unsigned long)len, addr); + (unsigned long)len, d->addr_string); } +/* + * Handle incoming data to the UDP socket in `d' + */ + static void handle_udp(struct descr *d) { unsigned char *buf; - struct sockaddr_storage __ss; - struct sockaddr *sa = (struct sockaddr *)&__ss; - int from_len; int n; buf = malloc(max_request); @@ -428,18 +436,15 @@ handle_udp(struct descr *d) return; } - from_len = sizeof(__ss); - n = recvfrom(d->s, buf, max_request, 0, - sa, &from_len); - if(n < 0){ + d->sock_len = sizeof(d->__ss); + n = recvfrom(d->s, buf, max_request, 0, d->sa, &d->sock_len); + if(n < 0) krb5_warn(context, errno, "recvfrom"); - goto out; + else { + addr_to_string (d->sa, d->sock_len, + d->addr_string, sizeof(d->addr_string)); + do_request(buf, n, 0, d); } - if(n == 0) { - goto out; - } - do_request(buf, n, 0, d->s, sa, from_len); -out: free (buf); } @@ -483,14 +488,11 @@ de_http(char *buf) static void add_new_tcp (struct descr *d, int index, int min_free) { - struct sockaddr_storage __ss; - struct sockaddr *sa = (struct sockaddr *)&__ss; int s; - int from_len; - from_len = sizeof(__ss); - s = accept(d[index].s, sa, &from_len); - if(s < 0){ + d->sock_len = sizeof(d->__ss); + s = accept(d[index].s, d->sa, &d->sock_len); + if(s < 0) { krb5_warn(context, errno, "accept"); return; } @@ -502,6 +504,8 @@ add_new_tcp (struct descr *d, int index, int min_free) d[min_free].s = s; d[min_free].timeout = time(NULL) + TCP_TIMEOUT; d[min_free].type = SOCK_STREAM; + addr_to_string (d[min_free].sa, d[min_free].sock_len, + d[min_free].addr_string, sizeof(d[min_free].addr_string)); } /* @@ -564,7 +568,7 @@ handle_vanilla_tcp (struct descr *d) */ static int -handle_http_tcp (struct descr *d, const char *addr) +handle_http_tcp (struct descr *d) { char *s, *p, *t; void *data; @@ -575,7 +579,7 @@ handle_http_tcp (struct descr *d, const char *addr) p = strstr(s, "\r\n"); if (p == NULL) { - kdc_log(0, "Malformed HTTP request from %s", addr); + kdc_log(0, "Malformed HTTP request from %s", d->addr_string); return -1; } *p = 0; @@ -583,12 +587,12 @@ handle_http_tcp (struct descr *d, const char *addr) p = NULL; t = strtok_r(s, " \t", &p); if (t == NULL) { - kdc_log(0, "Malformed HTTP request from %s", addr); + kdc_log(0, "Malformed HTTP request from %s", d->addr_string); return -1; } t = strtok_r(NULL, " \t", &p); if(t == NULL) { - kdc_log(0, "Malformed HTTP request from %s", addr); + kdc_log(0, "Malformed HTTP request from %s", d->addr_string); return -1; } data = malloc(strlen(t)); @@ -599,14 +603,14 @@ handle_http_tcp (struct descr *d, const char *addr) if(*t == '/') t++; if(de_http(t) != 0) { - kdc_log(0, "Malformed HTTP request from %s", addr); + kdc_log(0, "Malformed HTTP request from %s", d->addr_string); kdc_log(5, "Request: %s", t); free(data); return -1; } proto = strtok_r(NULL, " \t", &p); if (proto == NULL) { - kdc_log(0, "Malformed HTTP request from %s", addr); + kdc_log(0, "Malformed HTTP request from %s", d->addr_string); free(data); return -1; } @@ -623,7 +627,7 @@ handle_http_tcp (struct descr *d, const char *addr) "Heimdal?\r\n"; write(d->s, proto, strlen(proto)); write(d->s, msg, strlen(msg)); - kdc_log(0, "HTTP request from %s is non KDC request", addr); + kdc_log(0, "HTTP request from %s is non KDC request", d->addr_string); kdc_log(5, "Request: %s", t); free(data); return -1; @@ -651,10 +655,6 @@ static void handle_tcp(struct descr *d, int index, int min_free) { unsigned char buf[1024]; - char addr[32]; - struct sockaddr_storage __ss; - struct sockaddr *sa = (struct sockaddr *)&__ss; - int from_len; int n; int ret = 0; @@ -663,22 +663,11 @@ handle_tcp(struct descr *d, int index, int min_free) return; } - /* - * We can't trust recvfrom to return an address so we always call - * getpeername. - */ - n = recvfrom(d[index].s, buf, sizeof(buf), 0, NULL, NULL); if(n < 0){ krb5_warn(context, errno, "recvfrom"); return; } - from_len = sizeof(__ss); - if (getpeername(d[index].s, sa, &from_len) < 0) { - krb5_warn(context, errno, "getpeername"); - return; - } - addr_to_string(sa, from_len, addr, sizeof(addr)); if (grow_descr (&d[index], n)) return; memcpy(d[index].buf + d[index].len, buf, n); @@ -690,18 +679,17 @@ handle_tcp(struct descr *d, int index, int min_free) strncmp((char *)d[index].buf, "GET ", 4) == 0 && strncmp((char *)d[index].buf + d[index].len - 4, "\r\n\r\n", 4) == 0) { - ret = handle_http_tcp (&d[index], addr); + ret = handle_http_tcp (&d[index]); if (ret < 0) clear_descr (d + index); } else if (d[index].len > 4) { - kdc_log (0, "TCP data of strange type from %s", addr); + kdc_log (0, "TCP data of strange type from %s", d[index].addr_string); return; } if (ret < 0) return; else if (ret == 1) { - do_request(d[index].buf, d[index].len, 1, - d[index].s, sa, from_len); + do_request(d[index].buf, d[index].len, 1, &d[index]); clear_descr(d + index); } } @@ -725,15 +713,9 @@ loop(void) for(i = 0; i < ndescr; i++){ if(d[i].s >= 0){ if(d[i].type == SOCK_STREAM && - d[i].timeout && d[i].timeout < time(NULL)){ - struct sockaddr sa; - int salen = sizeof(sa); - char addr[32]; - - getpeername(d[i].s, &sa, &salen); - addr_to_string(&sa, salen, addr, sizeof(addr)); + d[i].timeout && d[i].timeout < time(NULL)) { kdc_log(1, "TCP-connection from %s expired after %u bytes", - addr, d[i].len); + d[i].addr_string, d[i].len); clear_descr(&d[i]); continue; } diff --git a/crypto/heimdal/lib/auth/pam/pam.c b/crypto/heimdal/lib/auth/pam/pam.c index d919bf8f83b8..1a385e0cf103 100644 --- a/crypto/heimdal/lib/auth/pam/pam.c +++ b/crypto/heimdal/lib/auth/pam/pam.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997, 1998, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,13 +31,9 @@ * SUCH DAMAGE. */ -/* This code is extremely ugly, and would probably be better off - beeing completely rewritten */ - - #ifdef HAVE_CONFIG_H #include -RCSID("$Id: pam.c,v 1.22 1999/12/02 16:58:37 joda Exp $"); +RCSID("$Id: pam.c,v 1.24 2000/02/18 14:33:06 bg Exp $"); #endif #include @@ -46,198 +42,384 @@ RCSID("$Id: pam.c,v 1.22 1999/12/02 16:58:37 joda Exp $"); #include #include #include +#include -#define PAM_SM_AUTH -#define PAM_SM_SESSION #include #include +#ifndef PAM_AUTHTOK_RECOVERY_ERR /* Fix linsux typo. */ +#define PAM_AUTHTOK_RECOVERY_ERR PAM_AUTHTOK_RECOVER_ERR +#endif #include #include #include -static int -cleanup(pam_handle_t *pamh, void *data, int error_code) +#if 0 +/* Debugging PAM modules is a royal pain, truss helps. */ +#define DEBUG(msg) (access(msg " at line", __LINE__)) +#endif + +static void +log_error(int level, const char *format, ...) { - if(error_code != PAM_SUCCESS) - dest_tkt(); - free(data); + va_list args; + va_start(args, format); + openlog("pam_krb4", LOG_CONS|LOG_PID, LOG_AUTH); + vsyslog(level | LOG_AUTH, format, args); + va_end(args); + closelog(); +} + +enum { + KRB4_DEBUG, + KRB4_USE_FIRST_PASS, + KRB4_TRY_FIRST_PASS, + KRB4_IGNORE_ROOT, + KRB4_NO_VERIFY, + KRB4_REAFSLOG, + KRB4_CTRLS /* Number of ctrl arguments defined. */ +}; + +#define KRB4_DEFAULTS 0 + +static int ctrl_flags = KRB4_DEFAULTS; +#define ctrl_on(x) (krb4_args[x].flag & ctrl_flags) +#define ctrl_off(x) (!ctrl_on(x)) + +typedef struct +{ + const char *token; + unsigned int flag; +} krb4_ctrls_t; + +static krb4_ctrls_t krb4_args[KRB4_CTRLS] = +{ + /* KRB4_DEBUG */ { "debug", 0x01 }, + /* KRB4_USE_FIRST_PASS */ { "use_first_pass", 0x02 }, + /* KRB4_TRY_FIRST_PASS */ { "try_first_pass", 0x04 }, + /* KRB4_IGNORE_ROOT */ { "ignore_root", 0x08 }, + /* KRB4_NO_VERIFY */ { "no_verify", 0x10 }, + /* KRB4_REAFSLOG */ { "reafslog", 0x20 }, +}; + +static void +parse_ctrl(int argc, const char **argv) +{ + int i, j; + + ctrl_flags = KRB4_DEFAULTS; + for (i = 0; i < argc; i++) + { + for (j = 0; j < KRB4_CTRLS; j++) + if (strcmp(argv[i], krb4_args[j].token) == 0) + break; + + if (j >= KRB4_CTRLS) + log_error(LOG_ALERT, "unrecognized option [%s]", *argv); + else + ctrl_flags |= krb4_args[j].flag; + } +} + +static void +pdeb(const char *format, ...) +{ + va_list args; + if (ctrl_off(KRB4_DEBUG)) + return; + va_start(args, format); + openlog("pam_krb4", LOG_PID, LOG_AUTH); + vsyslog(LOG_DEBUG | LOG_AUTH, format, args); + va_end(args); + closelog(); +} + +#define ENTRY(f) pdeb("%s() ruid = %d euid = %d", f, getuid(), geteuid()) + +static void +set_tkt_string(uid_t uid) +{ + char buf[128]; + + snprintf(buf, sizeof(buf), "%s%u", TKT_ROOT, (unsigned)uid); + krb_set_tkt_string(buf); + +#if 0 + /* pam_set_data+pam_get_data are not guaranteed to work, grr. */ + pam_set_data(pamh, "KRBTKFILE", strdup(t), cleanup); + if (pam_get_data(pamh, "KRBTKFILE", (const void**)&tkt) == PAM_SUCCESS) + { + pam_putenv(pamh, var); + } +#endif + + /* We don't want to inherit this variable. + * If we still do, it must have a sane value. */ + if (getenv("KRBTKFILE") != 0) + { + char *var = malloc(sizeof(buf)); + snprintf(var, sizeof(buf), "KRBTKFILE=%s", tkt_string()); + putenv(var); + /* free(var); XXX */ + } +} + +static int +verify_pass(pam_handle_t *pamh, + const char *name, + const char *inst, + const char *pass) +{ + char realm[REALM_SZ]; + int ret, krb_verify, old_euid, old_ruid; + + krb_get_lrealm(realm, 1); + if (ctrl_on(KRB4_NO_VERIFY)) + krb_verify = KRB_VERIFY_SECURE_FAIL; + else + krb_verify = KRB_VERIFY_SECURE; + old_ruid = getuid(); + old_euid = geteuid(); + setreuid(0, 0); + ret = krb_verify_user(name, inst, realm, pass, krb_verify, NULL); + if (setreuid(old_ruid, old_euid) != 0) + { + log_error(LOG_ALERT , "setreuid(%d, %d) failed", old_ruid, old_euid); + exit(1); + } + + switch(ret) { + case KSUCCESS: return PAM_SUCCESS; + case KDC_PR_UNKNOWN: + return PAM_USER_UNKNOWN; + case SKDC_CANT: + case SKDC_RETRY: + case RD_AP_TIME: + return PAM_AUTHINFO_UNAVAIL; + default: + return PAM_AUTH_ERR; + } } static int -doit(pam_handle_t *pamh, char *name, char *inst, char *pwd, char *tkt) +krb4_auth(pam_handle_t *pamh, + int flags, + const char *name, + const char *inst, + struct pam_conv *conv) { - char realm[REALM_SZ]; - int ret; + struct pam_response *resp; + char prompt[128]; + struct pam_message msg, *pmsg = &msg; + int ret; - pam_set_data(pamh, "KRBTKFILE", strdup(tkt), cleanup); - krb_set_tkt_string(tkt); - - krb_get_lrealm(realm, 1); - ret = krb_verify_user(name, inst, realm, pwd, KRB_VERIFY_SECURE, NULL); - memset(pwd, 0, strlen(pwd)); - switch(ret){ - case KSUCCESS: + if (ctrl_on(KRB4_TRY_FIRST_PASS) || ctrl_on(KRB4_USE_FIRST_PASS)) + { + char *pass = 0; + ret = pam_get_item(pamh, PAM_AUTHTOK, (void **) &pass); + if (ret != PAM_SUCCESS) + { + log_error(LOG_ERR , "pam_get_item returned error to get-password"); + return ret; + } + else if (pass != 0 && verify_pass(pamh, name, inst, pass) == PAM_SUCCESS) return PAM_SUCCESS; - case KDC_PR_UNKNOWN: - return PAM_USER_UNKNOWN; - case SKDC_CANT: - case SKDC_RETRY: - case RD_AP_TIME: - return PAM_AUTHINFO_UNAVAIL; - default: - return PAM_AUTH_ERR; + else if (ctrl_on(KRB4_USE_FIRST_PASS)) + return PAM_AUTHTOK_RECOVERY_ERR; /* Wrong password! */ + else + /* We tried the first password but it didn't work, cont. */; } -} -static int -auth_login(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv) -{ - int ret; - struct pam_message msg, *pmsg; - struct pam_response *resp; - char prompt[128]; + msg.msg_style = PAM_PROMPT_ECHO_OFF; + if (*inst == 0) + snprintf(prompt, sizeof(prompt), "%s's Password: ", name); + else + snprintf(prompt, sizeof(prompt), "%s.%s's Password: ", name, inst); + msg.msg = prompt; - pmsg = &msg; - msg.msg_style = PAM_PROMPT_ECHO_OFF; - snprintf(prompt, sizeof(prompt), "%s's Password: ", user); - msg.msg = prompt; - - ret = conv->conv(1, (const struct pam_message**)&pmsg, - &resp, conv->appdata_ptr); - if(ret != PAM_SUCCESS) - return ret; - - { - char tkt[1024]; - struct passwd *pw = getpwnam(user); - - if(pw){ - snprintf(tkt, sizeof(tkt), - "%s%u", TKT_ROOT, (unsigned)pw->pw_uid); - ret = doit(pamh, user, "", resp->resp, tkt); - if(ret == PAM_SUCCESS) - chown(tkt, pw->pw_uid, pw->pw_gid); - }else - ret = PAM_USER_UNKNOWN; - memset(resp->resp, 0, strlen(resp->resp)); - free(resp->resp); - free(resp); - } + ret = conv->conv(1, &pmsg, &resp, conv->appdata_ptr); + if (ret != PAM_SUCCESS) return ret; -} -static int -auth_su(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv) -{ - int ret; - struct passwd *pw; - struct pam_message msg, *pmsg; - struct pam_response *resp; - char prompt[128]; - krb_principal pr; - - pr.realm[0] = 0; - ret = pam_get_user(pamh, &user, "login: "); - if(ret != PAM_SUCCESS) - return ret; - - pw = getpwuid(getuid()); - if(strcmp(user, "root") == 0){ - strlcpy(pr.name, pw->pw_name, sizeof(pr.name)); - strlcpy(pr.instance, "root", sizeof(pr.instance)); - }else{ - strlcpy(pr.name, user, sizeof(pr.name)); - pr.instance[0] = 0; - } - pmsg = &msg; - msg.msg_style = PAM_PROMPT_ECHO_OFF; - snprintf(prompt, sizeof(prompt), "%s's Password: ", krb_unparse_name(&pr)); - msg.msg = prompt; - - ret = conv->conv(1, (const struct pam_message**)&pmsg, - &resp, conv->appdata_ptr); - if(ret != PAM_SUCCESS) - return ret; - + ret = verify_pass(pamh, name, inst, resp->resp); + if (ret == PAM_SUCCESS) { - char tkt[1024]; - - snprintf(tkt, sizeof(tkt),"%s_%s_to_%s", - TKT_ROOT, pw->pw_name, user); - ret = doit(pamh, pr.name, pr.instance, resp->resp, tkt); - if(ret == PAM_SUCCESS) - chown(tkt, pw->pw_uid, pw->pw_gid); - memset(resp->resp, 0, strlen(resp->resp)); - free(resp->resp); - free(resp); + memset(resp->resp, 0, strlen(resp->resp)); /* Erase password! */ + free(resp->resp); + free(resp); } - return ret; + else + { + pam_set_item(pamh, PAM_AUTHTOK, resp->resp); /* Save password. */ + /* free(resp->resp); XXX */ + /* free(resp); XXX */ + } + + return ret; } int -pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) +pam_sm_authenticate(pam_handle_t *pamh, + int flags, + int argc, + const char **argv) { - char *user; - int ret; - struct pam_conv *conv; - ret = pam_get_user(pamh, &user, "login: "); - if(ret != PAM_SUCCESS) - return ret; + char *user; + int ret; + struct pam_conv *conv; + struct passwd *pw; + uid_t uid = -1; + const char *name, *inst; - ret = pam_get_item(pamh, PAM_CONV, (void*)&conv); - if(ret != PAM_SUCCESS) - return ret; + parse_ctrl(argc, argv); + ENTRY("pam_sm_authenticate"); + ret = pam_get_user(pamh, &user, "login: "); + if (ret != PAM_SUCCESS) + return ret; + + if (ctrl_on(KRB4_IGNORE_ROOT) && strcmp(user, "root") == 0) + return PAM_AUTHINFO_UNAVAIL; + + ret = pam_get_item(pamh, PAM_CONV, (void*)&conv); + if (ret != PAM_SUCCESS) + return ret; + + pw = getpwnam(user); + if (pw != 0) + { + uid = pw->pw_uid; + set_tkt_string(uid); + } - if(getuid() != geteuid()) - return auth_su(pamh, flags, user, conv); - else - return auth_login(pamh, flags, user, conv); + if (strcmp(user, "root") == 0 && getuid() != 0) + { + pw = getpwuid(getuid()); + if (pw != 0) + { + name = strdup(pw->pw_name); + inst = "root"; + } + } + else + { + name = user; + inst = ""; + } + + ret = krb4_auth(pamh, flags, name, inst, conv); + + /* + * The realm was lost inside krb_verify_user() so we can't simply do + * a krb_kuserok() when inst != "". + */ + if (ret == PAM_SUCCESS && inst[0] != 0) + { + char realm[REALM_SZ]; + uid_t old_euid = geteuid(); + uid_t old_ruid = getuid(); + + realm[0] = 0; + setreuid(0, 0); /* To read ticket file. */ + if (krb_get_tf_fullname(tkt_string(), 0, 0, realm) != KSUCCESS) + ret = PAM_SERVICE_ERR; + else if (krb_kuserok(name, inst, realm, user) != KSUCCESS) + { + setreuid(0, uid); /* To read ~/.klogin. */ + if (krb_kuserok(name, inst, realm, user) != KSUCCESS) + ret = PAM_PERM_DENIED; + } + + if (ret != PAM_SUCCESS) + { + dest_tkt(); /* Passwd known, ok to kill ticket. */ + log_error(LOG_NOTICE, + "%s.%s@%s is not allowed to log in as %s", + name, inst, realm, user); + } + + if (setreuid(old_ruid, old_euid) != 0) + { + log_error(LOG_ALERT , "setreuid(%d, %d) failed", old_ruid, old_euid); + exit(1); + } + } + + if (ret == PAM_SUCCESS) + chown(tkt_string(), uid, -1); + + /* Sun dtlogin unlock screen does not call any other pam_* funcs. */ + if (ret == PAM_SUCCESS + && ctrl_on(KRB4_REAFSLOG) + && k_hasafs() + && (pw = getpwnam(user)) != 0) + krb_afslog_uid_home(/*cell*/ 0,/*realm_hint*/ 0, pw->pw_uid, pw->pw_dir); + + return ret; } int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { - return PAM_SUCCESS; -} + parse_ctrl(argc, argv); + ENTRY("pam_sm_setcred"); + pdeb("flags = 0x%x", flags); + switch (flags & ~PAM_SILENT) { + case 0: + case PAM_ESTABLISH_CRED: + if (k_hasafs()) + k_setpag(); + /* Fill PAG with credentials below. */ + case PAM_REINITIALIZE_CRED: + case PAM_REFRESH_CRED: + if (k_hasafs()) + { + void *user = 0; + + if (pam_get_item(pamh, PAM_USER, &user) == PAM_SUCCESS) + { + struct passwd *pw = getpwnam((char *)user); + if (pw != 0) + krb_afslog_uid_home(/*cell*/ 0,/*realm_hint*/ 0, + pw->pw_uid, pw->pw_dir); + } + } + break; + case PAM_DELETE_CRED: + dest_tkt(); + if (k_hasafs()) + k_unlog(); + break; + default: + log_error(LOG_ALERT , "pam_sm_setcred: unknown flags 0x%x", flags); + break; + } + + return PAM_SUCCESS; +} int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { - char *tkt, *var; - void *user; - const char *homedir = NULL; + parse_ctrl(argc, argv); + ENTRY("pam_sm_open_session"); - if(pam_get_item (pamh, PAM_USER, &user) == PAM_SUCCESS) { - struct passwd *pwd; - - pwd = getpwnam ((char *)user); - if (pwd != NULL) - homedir = pwd->pw_dir; - } - - pam_get_data(pamh, "KRBTKFILE", (const void**)&tkt); - var = malloc(strlen("KRBTKFILE=") + strlen(tkt) + 1); - strcpy(var, "KRBTKFILE="); - strcat(var, tkt); - putenv(var); - pam_putenv(pamh, var); - if(k_hasafs()){ - k_setpag(); - krb_afslog_home(0, 0, homedir); - } - return PAM_SUCCESS; + return PAM_SUCCESS; } int -pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) +pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char**argv) { - dest_tkt(); - if(k_hasafs()) - k_unlog(); - return PAM_SUCCESS; + parse_ctrl(argc, argv); + ENTRY("pam_sm_close_session"); + + /* This isn't really kosher, but it's handy. */ + dest_tkt(); + if (k_hasafs()) + k_unlog(); + + return PAM_SUCCESS; } diff --git a/crypto/heimdal/lib/auth/pam/pam.conf.add b/crypto/heimdal/lib/auth/pam/pam.conf.add index 42497d2b44a0..64a4915dbf48 100644 --- a/crypto/heimdal/lib/auth/pam/pam.conf.add +++ b/crypto/heimdal/lib/auth/pam/pam.conf.add @@ -1,8 +1,8 @@ To enable PAM in dtlogin and /bin/login under SunOS 5.6 apply this patch: --- /etc/pam.conf.DIST Mon Jul 20 15:37:46 1998 -+++ /etc/pam.conf Tue Nov 30 18:47:22 1999 -@@ -4,12 +4,14 @@ ++++ /etc/pam.conf Tue Feb 15 19:39:12 2000 +@@ -4,15 +4,19 @@ # # Authentication management # @@ -17,12 +17,17 @@ To enable PAM in dtlogin and /bin/login under SunOS 5.6 apply this patch: dtlogin auth required /usr/lib/security/pam_unix.so.1 # rsh auth required /usr/lib/security/pam_rhosts_auth.so.1 -@@ -24,6 +26,8 @@ ++# Reafslog is for dtlogin lock display ++other auth sufficient /usr/athena/lib/pam_krb4.so reafslog + other auth required /usr/lib/security/pam_unix.so.1 + # + # Account management +@@ -24,6 +28,8 @@ # # Session management # -+dtlogin session required /usr/athena/lib/pam_krb4.so -+login session required /usr/athena/lib/pam_krb4.so ++dtlogin session required /usr/athena/lib/pam_krb4.so ++login session required /usr/athena/lib/pam_krb4.so other session required /usr/lib/security/pam_unix.so.1 # # Password management diff --git a/crypto/heimdal/lib/krb5/Makefile.am b/crypto/heimdal/lib/krb5/Makefile.am index a5f60c0de659..df8ac6d84fe6 100644 --- a/crypto/heimdal/lib/krb5/Makefile.am +++ b/crypto/heimdal/lib/krb5/Makefile.am @@ -1,4 +1,4 @@ -# $Id: Makefile.am,v 1.97 2000/02/13 20:35:49 assar Exp $ +# $Id: Makefile.am,v 1.98 2000/02/19 18:53:56 assar Exp $ include $(top_srcdir)/Makefile.am.common @@ -119,7 +119,7 @@ libkrb5_la_SOURCES = \ EXTRA_libkrb5_la_SOURCES = keytab_krb4.c -libkrb5_la_LDFLAGS = -version-info 9:0:0 +libkrb5_la_LDFLAGS = -version-info 9:1:0 $(libkrb5_la_OBJECTS): $(srcdir)/krb5-protos.h $(srcdir)/krb5-private.h diff --git a/crypto/heimdal/lib/krb5/Makefile.in b/crypto/heimdal/lib/krb5/Makefile.in index da4a0fb5b0b6..dbca9de206d5 100644 --- a/crypto/heimdal/lib/krb5/Makefile.in +++ b/crypto/heimdal/lib/krb5/Makefile.in @@ -10,7 +10,7 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# $Id: Makefile.am,v 1.97 2000/02/13 20:35:49 assar Exp $ +# $Id: Makefile.am,v 1.98 2000/02/19 18:53:56 assar Exp $ # $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $ @@ -195,7 +195,7 @@ libkrb5_la_SOURCES = add_et_list.c addr_families.c address.c aname_to_local EXTRA_libkrb5_la_SOURCES = keytab_krb4.c -libkrb5_la_LDFLAGS = -version-info 9:0:0 +libkrb5_la_LDFLAGS = -version-info 9:1:0 libkrb5_la_LIBADD = ../com_err/error.lo ../com_err/com_err.lo diff --git a/crypto/heimdal/lib/krb5/addr_families.c b/crypto/heimdal/lib/krb5/addr_families.c index e8214ba7f212..9b17abdabccd 100644 --- a/crypto/heimdal/lib/krb5/addr_families.c +++ b/crypto/heimdal/lib/krb5/addr_families.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: addr_families.c,v 1.22 1999/12/04 17:53:33 assar Exp $"); +RCSID("$Id: addr_families.c,v 1.23 2000/02/16 02:09:00 assar Exp $"); struct addr_operations { int af; @@ -532,12 +532,7 @@ krb5_parse_address(krb5_context context, ALLOC_SEQ(addresses, n); for (a = ai, i = 0; a != NULL; a = a->ai_next, ++i) { - struct addr_operations *aop = find_af (ai->ai_family); - - addresses->val[i].addr_type = aop->atype; - krb5_data_copy (&addresses->val[i].address, - ai->ai_addr, - ai->ai_addrlen); + krb5_sockaddr2address (ai->ai_addr, &addresses->val[i]); } freeaddrinfo (ai); return 0; diff --git a/crypto/heimdal/lib/krb5/expand_hostname.c b/crypto/heimdal/lib/krb5/expand_hostname.c index 48e9709f967d..3e98e8819e85 100644 --- a/crypto/heimdal/lib/krb5/expand_hostname.c +++ b/crypto/heimdal/lib/krb5/expand_hostname.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: expand_hostname.c,v 1.7 2000/02/02 04:42:57 assar Exp $"); +RCSID("$Id: expand_hostname.c,v 1.8 2000/02/20 02:25:29 assar Exp $"); static krb5_error_code copy_hostname(krb5_context context, @@ -80,6 +80,31 @@ krb5_expand_hostname (krb5_context context, return copy_hostname (context, orig_hostname, new_hostname); } +/* + * handle the case of the hostname being unresolvable and thus identical + */ + +static krb5_error_code +vanilla_hostname (krb5_context context, + const char *orig_hostname, + char **new_hostname, + char ***realms) +{ + krb5_error_code ret; + + ret = copy_hostname (context, orig_hostname, new_hostname); + if (ret) + return ret; + strlwr (*new_hostname); + + ret = krb5_get_host_realm (context, *new_hostname, realms); + if (ret) { + free (*new_hostname); + return ret; + } + return 0; +} + /* * expand `hostname' to a name we believe to be a hostname in newly * allocated space in `host' and return realms in `realms'. @@ -100,21 +125,24 @@ krb5_expand_hostname_realms (krb5_context context, error = getaddrinfo (orig_hostname, NULL, &hints, &ai); if (error) - return copy_hostname (context, orig_hostname, new_hostname); + return vanilla_hostname (context, orig_hostname, new_hostname, + realms); + for (a = ai; a != NULL; a = a->ai_next) { if (a->ai_canonname != NULL) { ret = copy_hostname (context, orig_hostname, new_hostname); - if (ret) - goto out; + if (ret) { + freeaddrinfo (ai); + return ret; + } strlwr (*new_hostname); ret = krb5_get_host_realm (context, *new_hostname, realms); - if (ret == 0) - goto out; + if (ret == 0) { + freeaddrinfo (ai); + return 0; + } free (*new_hostname); } } - ret = copy_hostname (context, orig_hostname, new_hostname); - out: - freeaddrinfo (ai); - return ret; + return vanilla_hostname (context, orig_hostname, new_hostname, realms); } diff --git a/crypto/heimdal/lib/roken/ChangeLog b/crypto/heimdal/lib/roken/ChangeLog index b157494d191b..6da4be0f9fd1 100644 --- a/crypto/heimdal/lib/roken/ChangeLog +++ b/crypto/heimdal/lib/roken/ChangeLog @@ -1,3 +1,16 @@ +2000-02-19 Assar Westerlund + + * Makefile.am: set version to 7:1:2 + +2000-02-16 Assar Westerlund + + * snprintf.c (PARSE_INT_FORMAT): note that shorts are actually + transmitted as ints + (according to the integer protomotion rules) in variable arguments + lists. Therefore, we should not call va_arg with short but rather + with int. See for + original bug report + 2000-02-13 Assar Westerlund * Makefile.am: bump version to 7:0:2 diff --git a/crypto/heimdal/lib/roken/Makefile.am b/crypto/heimdal/lib/roken/Makefile.am index d23fcb3feed6..3d303f89917f 100644 --- a/crypto/heimdal/lib/roken/Makefile.am +++ b/crypto/heimdal/lib/roken/Makefile.am @@ -1,11 +1,11 @@ -# $Id: Makefile.am,v 1.69 2000/02/13 20:34:03 assar Exp $ +# $Id: Makefile.am,v 1.70 2000/02/19 18:53:13 assar Exp $ include $(top_srcdir)/Makefile.am.common CLEANFILES = roken.h make-roken.c print_version.h lib_LTLIBRARIES = libroken.la -libroken_la_LDFLAGS = -version-info 7:0:2 +libroken_la_LDFLAGS = -version-info 7:1:2 noinst_PROGRAMS = make-roken make-print-version diff --git a/crypto/heimdal/lib/roken/Makefile.in b/crypto/heimdal/lib/roken/Makefile.in index 65c3f9903c67..6db39734f3cd 100644 --- a/crypto/heimdal/lib/roken/Makefile.in +++ b/crypto/heimdal/lib/roken/Makefile.in @@ -10,7 +10,7 @@ # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. -# $Id: Makefile.am,v 1.69 2000/02/13 20:34:03 assar Exp $ +# $Id: Makefile.am,v 1.70 2000/02/19 18:53:13 assar Exp $ # $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $ @@ -176,7 +176,7 @@ CHECK_LOCAL = $(PROGRAMS) CLEANFILES = roken.h make-roken.c print_version.h lib_LTLIBRARIES = libroken.la -libroken_la_LDFLAGS = -version-info 7:0:2 +libroken_la_LDFLAGS = -version-info 7:1:2 noinst_PROGRAMS = make-roken make-print-version diff --git a/crypto/heimdal/lib/roken/snprintf.c b/crypto/heimdal/lib/roken/snprintf.c index 0333e8755e8e..4f69e66f43a7 100644 --- a/crypto/heimdal/lib/roken/snprintf.c +++ b/crypto/heimdal/lib/roken/snprintf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995-1997, 1999 Kungliga Tekniska Högskolan + * Copyright (c) 1995-2000 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #ifdef HAVE_CONFIG_H #include -RCSID("$Id: snprintf.c,v 1.24 1999/12/02 16:58:52 joda Exp $"); +RCSID("$Id: snprintf.c,v 1.25 2000/02/16 01:38:52 assar Exp $"); #endif #include #include @@ -265,7 +265,7 @@ append_char(struct state *state, if (long_flag) \ res = (unsig long)va_arg(arg, unsig long); \ else if (short_flag) \ - res = (unsig short)va_arg(arg, unsig short); \ + res = (unsig short)va_arg(arg, unsig int); \ else \ res = (unsig int)va_arg(arg, unsig int)