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>
* 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:
* gss_{import,export}_sec_context added to libgssapi

View File

@ -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; }

View File

@ -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)

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>
* load.c: checking all parsing for errors and all memory

View File

@ -34,7 +34,7 @@
#include "kadmin_locl.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 {
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);

View File

@ -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, "<family=%d>", 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)
"<A HREF=\"http://www.pdc.kth.se/heimdal\">Heimdal</A>?\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;
}

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).
* 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<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
#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 <unistd.h>
#include <sys/types.h>
#include <syslog.h>
#define PAM_SM_AUTH
#define PAM_SM_SESSION
#include <security/pam_appl.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 <krb.h>
#include <kafs.h>
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;
}

View File

@ -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

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
@ -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

View File

@ -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

View File

@ -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;

View File

@ -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);
}

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>
* 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
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

View File

@ -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

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).
* All rights reserved.
*
@ -33,7 +33,7 @@
#ifdef HAVE_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
#include <stdio.h>
#include <stdarg.h>
@ -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)