Vendor import of Heimdal 0.2p
This commit is contained in:
parent
69414e22b9
commit
5ed96cd5da
@ -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
|
||||
|
@ -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
|
||||
|
4
crypto/heimdal/configure
vendored
4
crypto/heimdal/configure
vendored
@ -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; }
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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,13 +488,10 @@ 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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -726,14 +714,8 @@ loop(void)
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
@ -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,37 +42,152 @@ 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);
|
||||
return PAM_SUCCESS;
|
||||
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
|
||||
doit(pam_handle_t *pamh, char *name, char *inst, char *pwd, char *tkt)
|
||||
verify_pass(pam_handle_t *pamh,
|
||||
const char *name,
|
||||
const char *inst,
|
||||
const char *pass)
|
||||
{
|
||||
char realm[REALM_SZ];
|
||||
int ret;
|
||||
|
||||
pam_set_data(pamh, "KRBTKFILE", strdup(tkt), cleanup);
|
||||
krb_set_tkt_string(tkt);
|
||||
int ret, krb_verify, old_euid, old_ruid;
|
||||
|
||||
krb_get_lrealm(realm, 1);
|
||||
ret = krb_verify_user(name, inst, realm, pwd, KRB_VERIFY_SECURE, NULL);
|
||||
memset(pwd, 0, strlen(pwd));
|
||||
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;
|
||||
@ -92,143 +203,209 @@ doit(pam_handle_t *pamh, char *name, char *inst, char *pwd, char *tkt)
|
||||
}
|
||||
|
||||
static int
|
||||
auth_login(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv)
|
||||
krb4_auth(pam_handle_t *pamh,
|
||||
int flags,
|
||||
const char *name,
|
||||
const char *inst,
|
||||
struct pam_conv *conv)
|
||||
{
|
||||
int ret;
|
||||
struct pam_message msg, *pmsg;
|
||||
struct pam_response *resp;
|
||||
char prompt[128];
|
||||
struct pam_message msg, *pmsg = &msg;
|
||||
int ret;
|
||||
|
||||
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;
|
||||
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. */;
|
||||
}
|
||||
|
||||
pmsg = &msg;
|
||||
msg.msg_style = PAM_PROMPT_ECHO_OFF;
|
||||
snprintf(prompt, sizeof(prompt), "%s's Password: ", user);
|
||||
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;
|
||||
|
||||
ret = conv->conv(1, (const struct pam_message**)&pmsg,
|
||||
&resp, conv->appdata_ptr);
|
||||
ret = conv->conv(1, &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);
|
||||
ret = verify_pass(pamh, name, inst, resp->resp);
|
||||
if (ret == PAM_SUCCESS)
|
||||
chown(tkt, pw->pw_uid, pw->pw_gid);
|
||||
}else
|
||||
ret = PAM_USER_UNKNOWN;
|
||||
memset(resp->resp, 0, strlen(resp->resp));
|
||||
{
|
||||
memset(resp->resp, 0, strlen(resp->resp)); /* Erase password! */
|
||||
free(resp->resp);
|
||||
free(resp);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int
|
||||
auth_su(pam_handle_t *pamh, int flags, char *user, struct pam_conv *conv)
|
||||
else
|
||||
{
|
||||
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;
|
||||
pam_set_item(pamh, PAM_AUTHTOK, resp->resp); /* Save password. */
|
||||
/* free(resp->resp); XXX */
|
||||
/* free(resp); XXX */
|
||||
}
|
||||
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];
|
||||
|
||||
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);
|
||||
}
|
||||
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;
|
||||
struct passwd *pw;
|
||||
uid_t uid = -1;
|
||||
const char *name, *inst;
|
||||
|
||||
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);
|
||||
if (strcmp(user, "root") == 0 && getuid() != 0)
|
||||
{
|
||||
pw = getpwuid(getuid());
|
||||
if (pw != 0)
|
||||
{
|
||||
name = strdup(pw->pw_name);
|
||||
inst = "root";
|
||||
}
|
||||
}
|
||||
else
|
||||
return auth_login(pamh, flags, user, conv);
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -236,8 +413,13 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||
int
|
||||
pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char**argv)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
@ -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,7 +17,12 @@ 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
|
||||
#
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
strlwr (*new_hostname);
|
||||
ret = krb5_get_host_realm (context, *new_hostname, realms);
|
||||
if (ret == 0)
|
||||
goto out;
|
||||
free (*new_hostname);
|
||||
}
|
||||
}
|
||||
ret = copy_hostname (context, orig_hostname, new_hostname);
|
||||
out:
|
||||
if (ret) {
|
||||
freeaddrinfo (ai);
|
||||
return ret;
|
||||
}
|
||||
strlwr (*new_hostname);
|
||||
ret = krb5_get_host_realm (context, *new_hostname, realms);
|
||||
if (ret == 0) {
|
||||
freeaddrinfo (ai);
|
||||
return 0;
|
||||
}
|
||||
free (*new_hostname);
|
||||
}
|
||||
}
|
||||
return vanilla_hostname (context, orig_hostname, new_hostname, realms);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user