Vendor import of Heimdal 0.2p

This commit is contained in:
markm 2000-02-24 11:28:20 +00:00
parent 69414e22b9
commit 5ed96cd5da
17 changed files with 494 additions and 258 deletions

View File

@ -1,3 +1,23 @@
2000-02-20 Assar Westerlund <assar@sics.se>
* Release 0.2p
2000-02-19 Assar Westerlund <assar@sics.se>
* 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 <assar@sics.se>
* lib/krb5/addr_families.c (krb5_parse_address): use
krb5_sockaddr2address to copy the result from getaddrinfo.
2000-02-14 Assar Westerlund <assar@sics.se> 2000-02-14 Assar Westerlund <assar@sics.se>
* Release 0.2o * Release 0.2o

View File

@ -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: Changes in release 0.2o:
* gss_{import,export}_sec_context added to libgssapi * gss_{import,export}_sec_context added to libgssapi

View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# From configure.in Revision: 1.217 # From configure.in Revision: 1.218
@ -911,7 +911,7 @@ fi
PACKAGE=heimdal PACKAGE=heimdal
VERSION=0.2o VERSION=0.2p
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then 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; } { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }

View File

@ -1,9 +1,9 @@
dnl Process this file with autoconf to produce a configure script. 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) AC_INIT(lib/krb5/send_to_kdc.c)
AM_CONFIG_HEADER(include/config.h) AM_CONFIG_HEADER(include/config.h)
AM_INIT_AUTOMAKE(heimdal,0.2o) AM_INIT_AUTOMAKE(heimdal,0.2p)
AC_PREFIX_DEFAULT(/usr/heimdal) AC_PREFIX_DEFAULT(/usr/heimdal)

View File

@ -1,3 +1,8 @@
2000-02-16 Assar Westerlund <assar@sics.se>
* load.c (doit): check return value from parse_hdbflags2int
correctly
2000-01-25 Assar Westerlund <assar@sics.se> 2000-01-25 Assar Westerlund <assar@sics.se>
* load.c: checking all parsing for errors and all memory * load.c: checking all parsing for errors and all memory

View File

@ -34,7 +34,7 @@
#include "kadmin_locl.h" #include "kadmin_locl.h"
#include <kadm5/private.h> #include <kadm5/private.h>
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 { struct entry {
char *principal; char *principal;
@ -439,7 +439,7 @@ doit(const char *filename, int merge)
continue; 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", fprintf (stderr, "%s:%d:error parsing flags (%s)\n",
filename, line, e.flags); filename, line, e.flags);
hdb_free_entry (context, &ent); hdb_free_entry (context, &ent);

View File

@ -33,7 +33,7 @@
#include "kdc_locl.h" #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 * a tuple describing on what to listen
@ -193,6 +193,10 @@ struct descr {
size_t size; size_t size;
size_t len; size_t len;
time_t timeout; 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; int sa_size;
memset(d, 0, sizeof(*d)); memset(d, 0, sizeof(*d));
d->sa = (struct sockaddr *)&d->__ss;
d->s = -1; d->s = -1;
ret = krb5_addr2sockaddr (a, sa, &sa_size, port); 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, "<family=%d>", addr->sa_family); snprintf(str, len, "<family=%d>", addr->sa_family);
} }
/*
* Handle the request in `buf, len' to socket `d'
*/
static void static void
do_request(void *buf, size_t len, int sendlength, 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_error_code ret;
krb5_data reply; krb5_data reply;
char addr[128];
addr_to_string(from, from_len, addr, sizeof(addr));
reply.length = 0; 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){ 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){ if(sendlength){
unsigned char len[4]; unsigned char len[4];
len[0] = (reply.length >> 24) & 0xff; len[0] = (reply.length >> 24) & 0xff;
len[1] = (reply.length >> 16) & 0xff; len[1] = (reply.length >> 16) & 0xff;
len[2] = (reply.length >> 8) & 0xff; len[2] = (reply.length >> 8) & 0xff;
len[3] = reply.length & 0xff; len[3] = reply.length & 0xff;
if(sendto(socket, len, sizeof(len), 0, from, from_len) < 0) { if(sendto(d->s, len, sizeof(len), 0, d->sa, d->sock_len) < 0) {
kdc_log (0, "sendto(%s): %s", addr, strerror(errno)); kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno));
krb5_data_free(&reply); krb5_data_free(&reply);
return; return;
} }
} }
if(sendto(socket, reply.data, reply.length, 0, from, from_len) < 0) { if(sendto(d->s, reply.data, reply.length, 0, d->sa, d->sock_len) < 0) {
kdc_log (0, "sendto(%s): %s", addr, strerror(errno)); kdc_log (0, "sendto(%s): %s", d->addr_string, strerror(errno));
krb5_data_free(&reply); krb5_data_free(&reply);
return; return;
} }
@ -410,16 +417,17 @@ do_request(void *buf, size_t len, int sendlength,
} }
if(ret) if(ret)
kdc_log(0, "Failed processing %lu byte request from %s", 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 static void
handle_udp(struct descr *d) handle_udp(struct descr *d)
{ {
unsigned char *buf; unsigned char *buf;
struct sockaddr_storage __ss;
struct sockaddr *sa = (struct sockaddr *)&__ss;
int from_len;
int n; int n;
buf = malloc(max_request); buf = malloc(max_request);
@ -428,18 +436,15 @@ handle_udp(struct descr *d)
return; return;
} }
from_len = sizeof(__ss); d->sock_len = sizeof(d->__ss);
n = recvfrom(d->s, buf, max_request, 0, n = recvfrom(d->s, buf, max_request, 0, d->sa, &d->sock_len);
sa, &from_len); if(n < 0)
if(n < 0){
krb5_warn(context, errno, "recvfrom"); 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); free (buf);
} }
@ -483,14 +488,11 @@ de_http(char *buf)
static void static void
add_new_tcp (struct descr *d, int index, int min_free) add_new_tcp (struct descr *d, int index, int min_free)
{ {
struct sockaddr_storage __ss;
struct sockaddr *sa = (struct sockaddr *)&__ss;
int s; int s;
int from_len;
from_len = sizeof(__ss); d->sock_len = sizeof(d->__ss);
s = accept(d[index].s, sa, &from_len); s = accept(d[index].s, d->sa, &d->sock_len);
if(s < 0){ if(s < 0) {
krb5_warn(context, errno, "accept"); krb5_warn(context, errno, "accept");
return; return;
} }
@ -502,6 +504,8 @@ add_new_tcp (struct descr *d, int index, int min_free)
d[min_free].s = s; d[min_free].s = s;
d[min_free].timeout = time(NULL) + TCP_TIMEOUT; d[min_free].timeout = time(NULL) + TCP_TIMEOUT;
d[min_free].type = SOCK_STREAM; 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 static int
handle_http_tcp (struct descr *d, const char *addr) handle_http_tcp (struct descr *d)
{ {
char *s, *p, *t; char *s, *p, *t;
void *data; void *data;
@ -575,7 +579,7 @@ handle_http_tcp (struct descr *d, const char *addr)
p = strstr(s, "\r\n"); p = strstr(s, "\r\n");
if (p == NULL) { 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; return -1;
} }
*p = 0; *p = 0;
@ -583,12 +587,12 @@ handle_http_tcp (struct descr *d, const char *addr)
p = NULL; p = NULL;
t = strtok_r(s, " \t", &p); t = strtok_r(s, " \t", &p);
if (t == NULL) { 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; return -1;
} }
t = strtok_r(NULL, " \t", &p); t = strtok_r(NULL, " \t", &p);
if(t == NULL) { 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; return -1;
} }
data = malloc(strlen(t)); data = malloc(strlen(t));
@ -599,14 +603,14 @@ handle_http_tcp (struct descr *d, const char *addr)
if(*t == '/') if(*t == '/')
t++; t++;
if(de_http(t) != 0) { 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); kdc_log(5, "Request: %s", t);
free(data); free(data);
return -1; return -1;
} }
proto = strtok_r(NULL, " \t", &p); proto = strtok_r(NULL, " \t", &p);
if (proto == NULL) { 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); free(data);
return -1; return -1;
} }
@ -623,7 +627,7 @@ handle_http_tcp (struct descr *d, const char *addr)
"<A HREF=\"http://www.pdc.kth.se/heimdal\">Heimdal</A>?\r\n"; "<A HREF=\"http://www.pdc.kth.se/heimdal\">Heimdal</A>?\r\n";
write(d->s, proto, strlen(proto)); write(d->s, proto, strlen(proto));
write(d->s, msg, strlen(msg)); 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); kdc_log(5, "Request: %s", t);
free(data); free(data);
return -1; return -1;
@ -651,10 +655,6 @@ static void
handle_tcp(struct descr *d, int index, int min_free) handle_tcp(struct descr *d, int index, int min_free)
{ {
unsigned char buf[1024]; unsigned char buf[1024];
char addr[32];
struct sockaddr_storage __ss;
struct sockaddr *sa = (struct sockaddr *)&__ss;
int from_len;
int n; int n;
int ret = 0; int ret = 0;
@ -663,22 +663,11 @@ handle_tcp(struct descr *d, int index, int min_free)
return; 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); n = recvfrom(d[index].s, buf, sizeof(buf), 0, NULL, NULL);
if(n < 0){ if(n < 0){
krb5_warn(context, errno, "recvfrom"); krb5_warn(context, errno, "recvfrom");
return; 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)) if (grow_descr (&d[index], n))
return; return;
memcpy(d[index].buf + d[index].len, buf, n); 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, "GET ", 4) == 0 &&
strncmp((char *)d[index].buf + d[index].len - 4, strncmp((char *)d[index].buf + d[index].len - 4,
"\r\n\r\n", 4) == 0) { "\r\n\r\n", 4) == 0) {
ret = handle_http_tcp (&d[index], addr); ret = handle_http_tcp (&d[index]);
if (ret < 0) if (ret < 0)
clear_descr (d + index); clear_descr (d + index);
} else if (d[index].len > 4) { } 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; return;
} }
if (ret < 0) if (ret < 0)
return; return;
else if (ret == 1) { else if (ret == 1) {
do_request(d[index].buf, d[index].len, 1, do_request(d[index].buf, d[index].len, 1, &d[index]);
d[index].s, sa, from_len);
clear_descr(d + index); clear_descr(d + index);
} }
} }
@ -725,15 +713,9 @@ loop(void)
for(i = 0; i < ndescr; i++){ for(i = 0; i < ndescr; i++){
if(d[i].s >= 0){ if(d[i].s >= 0){
if(d[i].type == SOCK_STREAM && if(d[i].type == SOCK_STREAM &&
d[i].timeout && d[i].timeout < time(NULL)){ 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));
kdc_log(1, "TCP-connection from %s expired after %u bytes", 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]); clear_descr(&d[i]);
continue; continue;
} }

View File

@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@ -31,13 +31,9 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
/* This code is extremely ugly, and would probably be better off
beeing completely rewritten */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include<config.h> #include<config.h>
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 #endif
#include <stdio.h> #include <stdio.h>
@ -46,198 +42,384 @@ RCSID("$Id: pam.c,v 1.22 1999/12/02 16:58:37 joda Exp $");
#include <pwd.h> #include <pwd.h>
#include <unistd.h> #include <unistd.h>
#include <sys/types.h> #include <sys/types.h>
#include <syslog.h>
#define PAM_SM_AUTH
#define PAM_SM_SESSION
#include <security/pam_appl.h> #include <security/pam_appl.h>
#include <security/pam_modules.h> #include <security/pam_modules.h>
#ifndef PAM_AUTHTOK_RECOVERY_ERR /* Fix linsux typo. */
#define PAM_AUTHTOK_RECOVERY_ERR PAM_AUTHTOK_RECOVER_ERR
#endif
#include <netinet/in.h> #include <netinet/in.h>
#include <krb.h> #include <krb.h>
#include <kafs.h> #include <kafs.h>
static int #if 0
cleanup(pam_handle_t *pamh, void *data, int error_code) /* 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) va_list args;
dest_tkt(); va_start(args, format);
free(data); 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; 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 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]; struct pam_response *resp;
int ret; char prompt[128];
struct pam_message msg, *pmsg = &msg;
int ret;
pam_set_data(pamh, "KRBTKFILE", strdup(tkt), cleanup); if (ctrl_on(KRB4_TRY_FIRST_PASS) || ctrl_on(KRB4_USE_FIRST_PASS))
krb_set_tkt_string(tkt); {
char *pass = 0;
krb_get_lrealm(realm, 1); ret = pam_get_item(pamh, PAM_AUTHTOK, (void **) &pass);
ret = krb_verify_user(name, inst, realm, pwd, KRB_VERIFY_SECURE, NULL); if (ret != PAM_SUCCESS)
memset(pwd, 0, strlen(pwd)); {
switch(ret){ log_error(LOG_ERR , "pam_get_item returned error to get-password");
case KSUCCESS: return ret;
}
else if (pass != 0 && verify_pass(pamh, name, inst, pass) == PAM_SUCCESS)
return PAM_SUCCESS; return PAM_SUCCESS;
case KDC_PR_UNKNOWN: else if (ctrl_on(KRB4_USE_FIRST_PASS))
return PAM_USER_UNKNOWN; return PAM_AUTHTOK_RECOVERY_ERR; /* Wrong password! */
case SKDC_CANT: else
case SKDC_RETRY: /* We tried the first password but it didn't work, cont. */;
case RD_AP_TIME:
return PAM_AUTHINFO_UNAVAIL;
default:
return PAM_AUTH_ERR;
} }
}
static int msg.msg_style = PAM_PROMPT_ECHO_OFF;
auth_login(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv) if (*inst == 0)
{ snprintf(prompt, sizeof(prompt), "%s's Password: ", name);
int ret; else
struct pam_message msg, *pmsg; snprintf(prompt, sizeof(prompt), "%s.%s's Password: ", name, inst);
struct pam_response *resp; msg.msg = prompt;
char prompt[128];
pmsg = &msg; ret = conv->conv(1, &pmsg, &resp, conv->appdata_ptr);
msg.msg_style = PAM_PROMPT_ECHO_OFF; if (ret != PAM_SUCCESS)
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);
}
return ret; return ret;
}
static int ret = verify_pass(pamh, name, inst, resp->resp);
auth_su(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv) if (ret == PAM_SUCCESS)
{
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;
{ {
char tkt[1024]; memset(resp->resp, 0, strlen(resp->resp)); /* Erase password! */
free(resp->resp);
snprintf(tkt, sizeof(tkt),"%s_%s_to_%s", free(resp);
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);
} }
return ret; else
{
pam_set_item(pamh, PAM_AUTHTOK, resp->resp); /* Save password. */
/* free(resp->resp); XXX */
/* free(resp); XXX */
}
return ret;
} }
int 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; char *user;
int ret; int ret;
struct pam_conv *conv; struct pam_conv *conv;
ret = pam_get_user(pamh, &user, "login: "); struct passwd *pw;
if(ret != PAM_SUCCESS) uid_t uid = -1;
return ret; const char *name, *inst;
ret = pam_get_item(pamh, PAM_CONV, (void*)&conv); parse_ctrl(argc, argv);
if(ret != PAM_SUCCESS) ENTRY("pam_sm_authenticate");
return ret;
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()) if (strcmp(user, "root") == 0 && getuid() != 0)
return auth_su(pamh, flags, user, conv); {
else pw = getpwuid(getuid());
return auth_login(pamh, flags, user, conv); 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 int
pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) 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 int
pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
{ {
char *tkt, *var; parse_ctrl(argc, argv);
void *user; ENTRY("pam_sm_open_session");
const char *homedir = NULL;
if(pam_get_item (pamh, PAM_USER, &user) == PAM_SUCCESS) { return 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;
} }
int 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(); parse_ctrl(argc, argv);
if(k_hasafs()) ENTRY("pam_sm_close_session");
k_unlog();
return PAM_SUCCESS; /* This isn't really kosher, but it's handy. */
dest_tkt();
if (k_hasafs())
k_unlog();
return PAM_SUCCESS;
} }

View File

@ -1,8 +1,8 @@
To enable PAM in dtlogin and /bin/login under SunOS 5.6 apply this patch: 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.DIST Mon Jul 20 15:37:46 1998
+++ /etc/pam.conf Tue Nov 30 18:47:22 1999 +++ /etc/pam.conf Tue Feb 15 19:39:12 2000
@@ -4,12 +4,14 @@ @@ -4,15 +4,19 @@
# #
# Authentication management # 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 dtlogin auth required /usr/lib/security/pam_unix.so.1
# #
rsh auth required /usr/lib/security/pam_rhosts_auth.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 # Session management
# #
+dtlogin 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 +login session required /usr/athena/lib/pam_krb4.so
other session required /usr/lib/security/pam_unix.so.1 other session required /usr/lib/security/pam_unix.so.1
# #
# Password management # Password management

View File

@ -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 include $(top_srcdir)/Makefile.am.common
@ -119,7 +119,7 @@ libkrb5_la_SOURCES = \
EXTRA_libkrb5_la_SOURCES = keytab_krb4.c 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 $(libkrb5_la_OBJECTS): $(srcdir)/krb5-protos.h $(srcdir)/krb5-private.h

View File

@ -10,7 +10,7 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. # 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 $ # $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 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 libkrb5_la_LIBADD = ../com_err/error.lo ../com_err/com_err.lo

View File

@ -33,7 +33,7 @@
#include "krb5_locl.h" #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 { struct addr_operations {
int af; int af;
@ -532,12 +532,7 @@ krb5_parse_address(krb5_context context,
ALLOC_SEQ(addresses, n); ALLOC_SEQ(addresses, n);
for (a = ai, i = 0; a != NULL; a = a->ai_next, ++i) { for (a = ai, i = 0; a != NULL; a = a->ai_next, ++i) {
struct addr_operations *aop = find_af (ai->ai_family); krb5_sockaddr2address (ai->ai_addr, &addresses->val[i]);
addresses->val[i].addr_type = aop->atype;
krb5_data_copy (&addresses->val[i].address,
ai->ai_addr,
ai->ai_addrlen);
} }
freeaddrinfo (ai); freeaddrinfo (ai);
return 0; return 0;

View File

@ -33,7 +33,7 @@
#include "krb5_locl.h" #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 static krb5_error_code
copy_hostname(krb5_context context, copy_hostname(krb5_context context,
@ -80,6 +80,31 @@ krb5_expand_hostname (krb5_context context,
return copy_hostname (context, orig_hostname, new_hostname); 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 * expand `hostname' to a name we believe to be a hostname in newly
* allocated space in `host' and return realms in `realms'. * 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); error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
if (error) 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) { for (a = ai; a != NULL; a = a->ai_next) {
if (a->ai_canonname != NULL) { if (a->ai_canonname != NULL) {
ret = copy_hostname (context, orig_hostname, new_hostname); ret = copy_hostname (context, orig_hostname, new_hostname);
if (ret) if (ret) {
goto out; freeaddrinfo (ai);
return ret;
}
strlwr (*new_hostname); strlwr (*new_hostname);
ret = krb5_get_host_realm (context, *new_hostname, realms); ret = krb5_get_host_realm (context, *new_hostname, realms);
if (ret == 0) if (ret == 0) {
goto out; freeaddrinfo (ai);
return 0;
}
free (*new_hostname); free (*new_hostname);
} }
} }
ret = copy_hostname (context, orig_hostname, new_hostname); return vanilla_hostname (context, orig_hostname, new_hostname, realms);
out:
freeaddrinfo (ai);
return ret;
} }

View File

@ -1,3 +1,16 @@
2000-02-19 Assar Westerlund <assar@sics.se>
* Makefile.am: set version to 7:1:2
2000-02-16 Assar Westerlund <assar@sics.se>
* 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 <http://www.debian.org/Bugs/db/57/57919.html> for
original bug report
2000-02-13 Assar Westerlund <assar@sics.se> 2000-02-13 Assar Westerlund <assar@sics.se>
* Makefile.am: bump version to 7:0:2 * Makefile.am: bump version to 7:0:2

View File

@ -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 include $(top_srcdir)/Makefile.am.common
CLEANFILES = roken.h make-roken.c print_version.h CLEANFILES = roken.h make-roken.c print_version.h
lib_LTLIBRARIES = libroken.la 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 noinst_PROGRAMS = make-roken make-print-version

View File

@ -10,7 +10,7 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. # 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 $ # $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 CLEANFILES = roken.h make-roken.c print_version.h
lib_LTLIBRARIES = libroken.la 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 noinst_PROGRAMS = make-roken make-print-version

View File

@ -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). * (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved. * All rights reserved.
* *
@ -33,7 +33,7 @@
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
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 #endif
#include <stdio.h> #include <stdio.h>
#include <stdarg.h> #include <stdarg.h>
@ -265,7 +265,7 @@ append_char(struct state *state,
if (long_flag) \ if (long_flag) \
res = (unsig long)va_arg(arg, unsig long); \ res = (unsig long)va_arg(arg, unsig long); \
else if (short_flag) \ else if (short_flag) \
res = (unsig short)va_arg(arg, unsig short); \ res = (unsig short)va_arg(arg, unsig int); \
else \ else \
res = (unsig int)va_arg(arg, unsig int) res = (unsig int)va_arg(arg, unsig int)