* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* %sccs.include.redist.c%
static char sccsid
[] = "@(#)krb_passwd.c 8.2 (Berkeley) %G%";
#include <sys/resource.h>
#include <kerberosIV/des.h>
#include <kerberosIV/krb.h>
#include "kpasswd_proto.h"
static void send_update
__P((int, char *, char *));
static void recv_ack
__P((int));
static void cleanup
__P((void));
static void finish
__P((void));
static struct timeval timeout
= { CLIENT_KRB_TIMEOUT
, 0 };
static struct kpasswd_data proto_data
;
static Key_schedule osched
;
static Key_schedule random_schedule
;
static char realm
[REALM_SZ
], krbhst
[MAX_HSTNM
];
char pass
[_PASSWORD_LEN
], password
[_PASSWORD_LEN
];
static struct rlimit rl
= { 0, 0 };
(void)signal(SIGHUP
, SIG_IGN
);
(void)signal(SIGINT
, SIG_IGN
);
(void)signal(SIGTSTP
, SIG_IGN
);
if (setrlimit(RLIMIT_CORE
, &rl
) < 0) {
if ((se
= getservbyname(SERVICE
, PROTO
)) == NULL
) {
warnx("couldn't find entry for service %s/%s",
if ((rval
= krb_get_lrealm(realm
,1)) != KSUCCESS
) {
warnx("couldn't get local Kerberos realm: %s",
if ((rval
= krb_get_krbhst(krbhst
, realm
, 1)) != KSUCCESS
) {
warnx("couldn't get Kerberos host: %s",
if ((host
= gethostbyname(krbhst
)) == NULL
) {
warnx("couldn't get host entry for krb host %s",
sin
.sin_family
= host
->h_addrtype
;
memmove((char *) &sin
.sin_addr
, host
->h_addr
, host
->h_length
);
sin
.sin_port
= se
->s_port
;
if ((sock
= socket(AF_INET
, SOCK_STREAM
, IPPROTO_TCP
)) < 0) {
if (connect(sock
, (struct sockaddr
*) &sin
, sizeof(sin
)) < 0) {
authopts
, /* NOT mutual */
&ticket
, /* (filled in) */
krbhst
, /* instance (krbhst) */
(u_long
) getpid(), /* checksum */
warnx("Kerberos sendauth error: %s", krb_err_txt
[rval
]);
krb_get_cred("krbtgt", realm
, realm
, &cred
);
(void)printf("Changing Kerberos password for %s.%s@%s.\n",
cred
.pname
, cred
.pinst
, realm
);
if (des_read_pw_string(pass
,
sizeof(pass
)-1, "Old Kerberos password:", 0)) {
warnx("error reading old Kerberos password");
(void)des_string_to_key(pass
, okey
);
(void)des_key_sched(okey
, osched
);
(void)des_set_key(okey
, osched
);
/* wait on the verification string */
select(sock
+ 1, &readfds
, (fd_set
*) 0, (fd_set
*) 0, &timeout
);
if ((rval
< 1) || !FD_ISSET(sock
, &readfds
)) {
warnx("timed out (aborted)");
warnx("select failed (aborted)");
/* read verification string */
if (des_read(sock
, &proto_data
, sizeof(proto_data
)) !=
warnx("couldn't read verification string (aborted)");
(void)signal(SIGHUP
, finish
);
(void)signal(SIGINT
, finish
);
if (strcmp(SECURE_STRING
, proto_data
.secure_msg
) != 0) {
/* don't complain loud if user just hit return */
if (pass
== NULL
|| (!*pass
))
(void)fprintf(stderr
, "Sorry\n");
(void)des_key_sched(proto_data
.random_key
, random_schedule
);
(void)des_set_key(proto_data
.random_key
, random_schedule
);
(void)memset(pass
, 0, sizeof(pass
));
if (des_read_pw_string(pass
,
sizeof(pass
)-1, "New Kerberos password:", 0)) {
warnx("error reading new Kerberos password (aborted)");
if (des_read_pw_string(password
,
sizeof(password
)-1, "Retype new Kerberos password:", 0)) {
warnx("error reading new Kerberos password (aborted)");
if (strcmp(password
, pass
) != 0) {
warnx("password mismatch (aborted)");
(void)printf("using NULL password\n");
send_update(sock
, password
, SECURE_STRING
);
select(sock
+ 1, &readfds
, (fd_set
*) 0, (fd_set
*) 0, &timeout
);
if ((rval
< 1) || !FD_ISSET(sock
, &readfds
)) {
warnx("timed out reading ACK (aborted)");
warnx("select failed (aborted)");
send_update(dest
, pwd
, str
)
static struct update_data ud
;
(void)strncpy(ud
.secure_msg
, str
, _PASSWORD_LEN
);
(void)strncpy(ud
.pw
, pwd
, sizeof(ud
.pw
));
if (des_write(dest
, &ud
, sizeof(ud
)) != sizeof(ud
)) {
warnx("couldn't write pw update (abort)");
memset((char *)&ud
, 0, sizeof(ud
));
cc
= des_read(remote
, buf
, sizeof(buf
));
warnx("error reading acknowledgement (aborted)");
(void)memset((char *)&proto_data
, 0, sizeof(proto_data
));
(void)memset((char *)okey
, 0, sizeof(okey
));
(void)memset((char *)osched
, 0, sizeof(osched
));
(void)memset((char *)random_schedule
, 0, sizeof(random_schedule
));