[2655] in Release_Engineering
Changes to V4 Kerberos.....
daemon@ATHENA.MIT.EDU (Theodore Ts'o)
Wed Jun 26 16:38:11 1991
Date: Wed, 26 Jun 91 16:37:31 -0400
From: tytso@ATHENA.MIT.EDU (Theodore Ts'o)
To: rel-eng@ATHENA.MIT.EDU
Reply-To: tytso@ATHENA.MIT.EDU
Sent to rel-eng at Richard's request....
*** ./include/kadm.h.old Fri Jun 14 16:35:08 1991
--- ./include/kadm.h Fri Jun 14 16:50:24 1991
***************
*** 121,126 ****
--- 121,127 ----
#define ADD_ENT 3
#define MOD_ENT 4
#define GET_ENT 5
+ #define CHECK_PW 6
extern long kdb_get_master_key(); /* XXX should be in krb_db.h */
extern long kdb_verify_master_key(); /* XXX ditto */
*** ./lib/kadm/kadm_cli_wrap.c.old Fri Jun 14 16:29:51 1991
--- ./lib/kadm/kadm_cli_wrap.c Mon Jun 24 17:53:33 1991
***************
*** 94,100 ****
/*
* kadm_change_pw
! * recieves : key
*
* Replaces the password (i.e. des key) of the caller with that specified in
* key. Returns no actual data from the master server, since this is called
--- 94,100 ----
/*
* kadm_change_pw
! * recieves : key
*
* Replaces the password (i.e. des key) of the caller with that specified in
* key. Returns no actual data from the master server, since this is called
***************
*** 103,108 ****
--- 103,130 ----
kadm_change_pw(newkey)
des_cblock newkey; /* The DES form of the users key */
{
+ u_char *ret_st;
+ int retval;
+
+ retval = kadm_change_pw2(newkey, 0, &ret_st);
+ if (ret_st)
+ free(ret_st);
+ return(retval);
+ }
+
+ /*
+ * kadm_change_pw2
+ * recieves : key, pw_string, ret_string
+ *
+ * Replaces the password (i.e. des key) of the caller with that specified in
+ * key. Returns no actual data from the master server, since this is called
+ * by a user
+ */
+ kadm_change_pw2(newkey, pwstring, retstring)
+ des_cblock newkey; /* The DES form of the users key */
+ char *pwstring;
+ u_char **retstring;
+ {
int stsize, retc; /* stream size and return code */
u_char *send_st; /* send stream */
u_char *ret_st;
***************
*** 126,136 ****
bcopy((char *) newkey, (char *) &keytmp, 4);
keytmp = htonl(keytmp);
stsize += vts_long(keytmp, &send_st, stsize);
retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz);
free((char *)send_st);
! if (retc == KADM_SUCCESS) {
! free((char *)ret_st);
}
kadm_cli_disconn();
return(retc);
--- 148,165 ----
bcopy((char *) newkey, (char *) &keytmp, 4);
keytmp = htonl(keytmp);
stsize += vts_long(keytmp, &send_st, stsize);
+
+ if (pwstring) {
+ stsize += vts_string(pwstring, &send_st, stsize);
+ }
retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz);
free((char *)send_st);
! if (ret_sz)
! *retstring = ret_st;
! else {
! *retstring = 0;
! free(ret_st);
}
kadm_cli_disconn();
return(retc);
***************
*** 262,267 ****
--- 291,349 ----
}
/*
+ * kadm_check_pw
+ * recieves : key, pw_string, ret_string
+ *
+ * Sends the password to the server and asks it if the password is a
+ * "secure" password or not. Returns the error KADM_INSECURE_PW and
+ * optionally returns a message if the password is not considered secure.
+ */
+ kadm_check_pw(newkey, pwstring, retstring)
+ des_cblock newkey; /* The DES form of the users key */
+ char *pwstring;
+ u_char **retstring;
+ {
+ int stsize, retc; /* stream size and return code */
+ u_char *send_st; /* send stream */
+ u_char *ret_st;
+ int ret_sz;
+ u_long keytmp;
+
+ if ((retc = kadm_cli_conn()) != KADM_SUCCESS)
+ return(retc);
+ /* possible problem with vts_long on a non-multiple of four boundary */
+
+ stsize = 0; /* start of our output packet */
+ send_st = (u_char *) malloc(1);/* to make it reallocable */
+ send_st[stsize++] = (u_char) CHECK_PW;
+
+ /* change key to stream */
+
+ bcopy((char *) (((long *) newkey) + 1), (char *) &keytmp, 4);
+ keytmp = htonl(keytmp);
+ stsize += vts_long(keytmp, &send_st, stsize);
+
+ bcopy((char *) newkey, (char *) &keytmp, 4);
+ keytmp = htonl(keytmp);
+ stsize += vts_long(keytmp, &send_st, stsize);
+
+ if (pwstring) {
+ stsize += vts_string(pwstring, &send_st, stsize);
+ }
+
+ retc = kadm_cli_send(send_st, stsize, &ret_st, &ret_sz);
+ free((char *)send_st);
+ if (ret_sz)
+ *retstring = ret_st;
+ else {
+ *retstring = 0;
+ free(ret_st);
+ }
+ kadm_cli_disconn();
+ return(retc);
+ }
+
+ /*
* kadm_cli_send
* recieves : opcode, packet, packet length, serv_name, serv_inst
* returns : return code from the packet build, the server, or
***************
*** 344,350 ****
ret_dat, ret_siz)) != KADM_SUCCESS)
RET_N_FREE(retdat);
free((char *)act_st);
! #define RET_N_FREE2(r) {free((char *)*ret_dat); clear_secrets(); return(r);}
/* first see if it's a YOULOUSE */
if ((*ret_siz >= KADM_VERSIZE) &&
--- 426,432 ----
ret_dat, ret_siz)) != KADM_SUCCESS)
RET_N_FREE(retdat);
free((char *)act_st);
! #define RET_N_FREE2(r) {free((char *)*ret_dat); *ret_dat = 0; *ret_siz = 0; clear_secrets(); return(r);}
/* first see if it's a YOULOUSE */
if ((*ret_siz >= KADM_VERSIZE) &&
*** ./lib/kadm/kadm_err.et.old Fri Jun 14 16:30:05 1991
--- ./lib/kadm/kadm_err.et Mon Jun 24 18:46:05 1991
***************
*** 49,53 ****
ec KADM_LENGTH_ERROR, "Length mismatch problem"
ec KADM_ILL_WILDCARD, "Illegal use of wildcard"
! ec KADM_DB_INUSE, "Database is locked or in use--try again later"
end
--- 49,55 ----
ec KADM_LENGTH_ERROR, "Length mismatch problem"
ec KADM_ILL_WILDCARD, "Illegal use of wildcard"
! ec KADM_DB_INUSE, "Database locked or in use"
! ec KADM_INSECURE_PW, "Insecure password rejected"
! ec KADM_PW_MISMATCH, "Cleartext password and DES key did not match"
end
*** ./kadmin/kadmin.c.old Mon Jun 17 17:56:03 1991
--- ./kadmin/kadmin.c Mon Jun 24 17:50:47 1991
***************
*** 148,154 ****
(void) sprintf(pw_prompt, "New password for %s:", argv[1]);
if (get_password(&new.key_low, &new.key_high,
! pw_prompt, SWAP) == GOOD_PW) {
status = kadm_mod(&old, &new);
if (status == KADM_SUCCESS) {
printf("Password changed for %s.\n", argv[1]);
--- 148,154 ----
(void) sprintf(pw_prompt, "New password for %s:", argv[1]);
if (get_password(&new.key_low, &new.key_high,
! pw_prompt, SWAP, 0) == GOOD_PW) {
status = kadm_mod(&old, &new);
if (status == KADM_SUCCESS) {
printf("Password changed for %s.\n", argv[1]);
***************
*** 179,184 ****
--- 179,186 ----
unsigned long low, high;
int status;
char prompt_pw[BUFSIZ];
+ char pword[MAX_KPW_LEN];
+ char *ret_st;
if (argc != 1) {
printf("Usage: change_admin_password\n");
***************
*** 189,205 ****
return;
(void) sprintf(prompt_pw, "New password for %s.admin:",myname);
! if (get_password(&low, &high, prompt_pw, DONTSWAP) == GOOD_PW) {
bcopy((char *)&low,(char *) newkey,4);
bcopy((char *)&high, (char *)(((long *) newkey) + 1),4);
low = high = 0L;
! if ((status = kadm_change_pw(newkey)) == KADM_SUCCESS)
printf("Admin password changed\n");
else
printf("kadm error: %s\n",error_message(status));
bzero((char *)newkey, sizeof(newkey));
! } else
printf("Error reading password; password unchanged\n");
#ifndef NO_MULTIPLE
if (!multiple)
clean_up();
--- 191,215 ----
return;
(void) sprintf(prompt_pw, "New password for %s.admin:",myname);
! if (get_password(&low, &high, prompt_pw, DONTSWAP, pword) == GOOD_PW) {
bcopy((char *)&low,(char *) newkey,4);
bcopy((char *)&high, (char *)(((long *) newkey) + 1),4);
low = high = 0L;
! status = kadm_change_pw2(newkey, pword, &ret_st);
! if (ret_st) {
! printf("\n%s\n", ret_st);
! free(ret_st);
! }
! if (status == KADM_SUCCESS)
printf("Admin password changed\n");
else
printf("kadm error: %s\n",error_message(status));
+ bzero(pword, sizeof(pword));
bzero((char *)newkey, sizeof(newkey));
! } else {
printf("Error reading password; password unchanged\n");
+ bzero(pword, sizeof(pword));
+ }
#ifndef NO_MULTIPLE
if (!multiple)
clean_up();
***************
*** 234,240 ****
(void) sprintf(pw_prompt, "Password for %s:", argv[1]);
if (get_password(&new.key_low, &new.key_high,
! pw_prompt, SWAP) == GOOD_PW) {
status = kadm_add(&new);
if (status == KADM_SUCCESS) {
printf("%s added to database.\n", argv[1]);
--- 244,250 ----
(void) sprintf(pw_prompt, "Password for %s:", argv[1]);
if (get_password(&new.key_low, &new.key_high,
! pw_prompt, SWAP, 0) == GOOD_PW) {
status = kadm_add(&new);
if (status == KADM_SUCCESS) {
printf("%s added to database.\n", argv[1]);
***************
*** 451,457 ****
* If we can reach the local realm, initialize to it. Otherwise,
* don't initialize.
*/
! if (kadm_init_link(PWSERV_NAME, KRB_MASTER, krbrlm) != KADM_SUCCESS)
bzero(krbrlm, sizeof(krbrlm));
else
strcpy(krbrlm, default_realm);
--- 461,468 ----
* If we can reach the local realm, initialize to it. Otherwise,
* don't initialize.
*/
! if (kadm_init_link(PWSERV_NAME, KRB_MASTER,
! default_realm) != KADM_SUCCESS)
bzero(krbrlm, sizeof(krbrlm));
else
strcpy(krbrlm, default_realm);
***************
*** 588,597 ****
}
int
! get_password(low, high, prompt, byteswap)
unsigned long *low, *high;
char *prompt;
int byteswap;
{
char new_passwd[MAX_KPW_LEN]; /* new password */
des_cblock newkey;
--- 599,609 ----
}
int
! get_password(low, high, prompt, byteswap, pword)
unsigned long *low, *high;
char *prompt;
int byteswap;
+ char *pword;
{
char new_passwd[MAX_KPW_LEN]; /* new password */
des_cblock newkey;
***************
*** 608,613 ****
--- 620,627 ----
#else
des_string_to_key(new_passwd, newkey);
#endif
+ if (pword)
+ strcpy(pword, new_passwd);
bzero(new_passwd, sizeof(new_passwd));
bcopy((char *) newkey,(char *)low,4);
*** ./kadmin/kadm_server.c.old Fri Jun 14 16:28:21 1991
--- ./kadmin/kadm_server.c Mon Jun 24 18:53:22 1991
***************
*** 20,25 ****
--- 20,39 ----
#include <kadm.h>
#include <kadm_err.h>
+ int fascist_cpw = 0; /* Be fascist about insecure passwords? */
+
+ char bad_pw_err[] =
+ "\007\007\007ERROR: Insecure password not accepted. Please choose another.\n\n";
+
+ char bad_pw_warn[] =
+ "\007\007\007WARNING: You have chosen an insecure password. You may wish to\nchoose a better password.\n\n";
+
+ char check_pw_msg[] =
+ "You have entered an insecure password. You should choose another.\n\n";
+
+ char pw_blurb[] =
+ "A good password is something which is easy for you to remember, but\nthat people who know you won't easily guess. Don't use a word found\nin the dictionary, because someone may run a program that tries all\nthose words. That same program will probably try the names of all\nknown comic-strip characters, rock bands, etc. Please do not let\nanyone else, including friends, know your password. Remember, *YOU*\nare assumed to be responsible for anything done using your password.\n";
+
/*
kadm_ser_cpw - the server side of the change_password routine
recieves : KTEXT, {key}
***************
*** 37,58 ****
int *outlen;
{
unsigned long keylow, keyhigh;
des_cblock newkey;
! int stvlen;
/* take key off the stream, and change the database */
! if ((stvlen = stv_long(dat, &keyhigh, 0, len)) < 0)
return(KADM_LENGTH_ERROR);
! if (stv_long(dat, &keylow, stvlen, len) < 0)
return(KADM_LENGTH_ERROR);
keylow = ntohl(keylow);
keyhigh = ntohl(keyhigh);
bcopy((char *)&keyhigh, (char *)(((long *)newkey) + 1), 4);
bcopy((char *)&keylow, (char *)newkey, 4);
! *datout = 0;
! *outlen = 0;
return(kadm_change(ad->pname, ad->pinst, ad->prealm, newkey));
}
--- 51,123 ----
int *outlen;
{
unsigned long keylow, keyhigh;
+ char pword[MAX_KPW_LEN];
+ int no_pword = 0;
des_cblock newkey;
! int status, stvlen = 0;
! int retval;
! extern char *malloc();
! extern int kadm_approve_pw();
/* take key off the stream, and change the database */
! if ((status = stv_long(dat, &keyhigh, 0, len)) < 0)
return(KADM_LENGTH_ERROR);
! stvlen += status;
! if ((status = stv_long(dat, &keylow, stvlen, len)) < 0)
return(KADM_LENGTH_ERROR);
+ stvlen += status;
+ if ((stvlen = stv_string(dat, pword, stvlen, sizeof(pword), len)) < 0) {
+ no_pword++;
+ pword[0]='\0';
+ }
+ stvlen += status;
keylow = ntohl(keylow);
keyhigh = ntohl(keyhigh);
bcopy((char *)&keyhigh, (char *)(((long *)newkey) + 1), 4);
bcopy((char *)&keylow, (char *)newkey, 4);
! if (retval = kadm_approve_pw(ad->pname, ad->pinst, ad->prealm,
! newkey, no_pword ? 0 : pword)) {
! if (retval == KADM_PW_MISMATCH) {
! /*
! * Very strange!!! This means that the cleartext
! * password which was sent and the DES cblock
! * didn't match!
! */
! (void) log("'%s.%s@%s' sent a password string which didn't match with the DES key?!?",
! ad->pname, ad->pinst, ad->prealm);
! return(retval);
! }
! if (fascist_cpw) {
! *outlen = strlen(bad_pw_err)+strlen(pw_blurb)+1;
! if (*datout = (u_char *) malloc(*outlen)) {
! strcpy(*datout, bad_pw_err);
! strcat(*datout, pw_blurb);
! } else
! *outlen = 0;
! (void) log("'%s.%s@%s' tried to use an insecure password in changepw",
! ad->pname, ad->pinst, ad->prealm);
! #ifdef notdef
! /* For debugging only, probably a bad idea */
! if (!no_pword)
! (void) log("The password was %s\n", pword);
! #endif
! return(retval);
! } else {
! *outlen = strlen(bad_pw_warn) + strlen(pw_blurb)+1;
! if (*datout = (u_char *) malloc(*outlen)) {
! strcpy(*datout, bad_pw_warn);
! strcat(*datout, pw_blurb);
! } else
! *outlen = 0;
! (void) log("'%s.%s@%s' used an insecure password in changepw",
! ad->pname, ad->pinst, ad->prealm);
! }
! } else {
! *datout = 0;
! *outlen = 0;
! }
return(kadm_change(ad->pname, ad->pinst, ad->prealm, newkey));
}
***************
*** 160,164 ****
--- 225,288 ----
*outlen = 0;
return status;
}
+ }
+
+ /*
+ kadm_ser_ckpw - the server side of the check_password routine
+ recieves : KTEXT, {key}
+ returns : CKSUM, RETCODE
+ acl : none
+
+ Checks to see if the des key passed from the caller is a "secure" password.
+ */
+ kadm_ser_ckpw(dat, len, ad, datout, outlen)
+ u_char *dat;
+ int len;
+ AUTH_DAT *ad;
+ u_char **datout;
+ int *outlen;
+ {
+ unsigned long keylow, keyhigh;
+ char pword[MAX_KPW_LEN];
+ int no_pword = 0;
+ des_cblock newkey;
+ int stvlen;
+ int retval;
+ extern char *malloc();
+ extern int kadm_approve_pw();
+
+ /* take key off the stream, and check it */
+
+ if ((stvlen = stv_long(dat, &keyhigh, 0, len)) < 0)
+ return(KADM_LENGTH_ERROR);
+ if ((stvlen = stv_long(dat, &keylow, stvlen, len)) < 0)
+ return(KADM_LENGTH_ERROR);
+ if ((stvlen = stv_string(dat, pword, stvlen, sizeof(pword), len)) < 0) {
+ no_pword++;
+ pword[0]='\0';
+ }
+
+ keylow = ntohl(keylow);
+ keyhigh = ntohl(keyhigh);
+ bcopy((char *)&keyhigh, (char *)(((long *)newkey) + 1), 4);
+ bcopy((char *)&keylow, (char *)newkey, 4);
+ if (retval = kadm_approve_pw(ad->pname, ad->pinst, ad->prealm, newkey,
+ no_pword ? 0 : pword)) {
+ *outlen = strlen(check_pw_msg)+strlen(pw_blurb)+1;
+ if (*datout = (u_char *) malloc(*outlen)) {
+ strcpy(*datout, check_pw_msg);
+ strcat(*datout, pw_blurb);
+ } else
+ *outlen = 0;
+ (void) log("'%s.%s@%s' sent an insecure password to be checked",
+ ad->pname, ad->pinst, ad->prealm);
+ return(retval);
+ } else {
+ *datout = 0;
+ *outlen = 0;
+ (void) log("'%s.%s@%s' sent a secure password to be checked",
+ ad->pname, ad->pinst, ad->prealm);
+ }
+ return(0);
}
*** ./kadmin/kpasswd.c.old Fri Jun 14 16:28:58 1991
--- ./kadmin/kpasswd.c Mon Jun 24 18:27:15 1991
***************
*** 25,30 ****
--- 25,31 ----
#include <sys/types.h>
#include <sys/param.h>
#include <pwd.h>
+ #include <kadm_err.h>
#include "kadm.h"
extern void krb_set_tkt_string();
***************
*** 41,53 ****
--- 42,57 ----
char default_realm[REALM_SZ];
int realm_given = 0; /* True if realm was give on cmdline */
int use_default = 1; /* True if we should use default name */
+ int skip_old = 0; /* True if we should skip getting old pw */
struct passwd *pw;
int status; /* return code */
des_cblock new_key;
+ char pword[MAX_KPW_LEN]; /* storage for the password */
int c;
extern char *optarg;
extern int optind;
char tktstring[MAXPATHLEN];
+ char *ret_st;
void get_pw_new_key();
***************
*** 142,159 ****
(void) sprintf(tktstring, "/tmp/tkt_cpw_%d",getpid());
krb_set_tkt_string(tktstring);
! get_pw_new_key(new_key, name, inst, realm, realm_given);
! if ((status = kadm_init_link("changepw", KRB_MASTER, realm))
! != KADM_SUCCESS)
com_err(argv[0], status, "while initializing");
! else if ((status = kadm_change_pw(new_key)) != KADM_SUCCESS)
! com_err(argv[0], status, " attempting to change password.");
!
if (status != KADM_SUCCESS)
fprintf(stderr,"Password NOT changed.\n");
else
printf("Password changed.\n");
(void) dest_tkt();
if (status)
--- 146,189 ----
(void) sprintf(tktstring, "/tmp/tkt_cpw_%d",getpid());
krb_set_tkt_string(tktstring);
! try_again:
! get_pw_new_key(new_key, pword, name, inst, realm, realm_given, skip_old);
! skip_old++;
! if ((status = kadm_init_link(PWSERV_NAME, KRB_MASTER, realm))
! != KADM_SUCCESS) {
com_err(argv[0], status, "while initializing");
! bzero(pword, sizeof(pword));
! } else {
! #ifdef CHECK_ONLY
! status = kadm_check_pw(new_key, pword, &ret_st);
! #else
! status = kadm_change_pw2(new_key, pword, &ret_st);
! #endif
! bzero(pword, sizeof(pword));
! if (ret_st) {
! printf("\n%s\n", ret_st);
! free(ret_st);
! }
! if (status != KADM_SUCCESS)
! com_err(argv[0], status,
! "while attempting to change password.");
! if (status == KADM_DB_INUSE)
! com_err(argv[0], 0, "Please try again later.");
! if (status == KADM_INSECURE_PW) {
! printf("Please choose another password.\n\n");
! goto try_again;
! }
! }
!
! #ifdef CHECK_ONLY
! fprintf(stderr, "Passwrd NOT changed --- this is a test version of kpasswd.\n");
! #else
if (status != KADM_SUCCESS)
fprintf(stderr,"Password NOT changed.\n");
else
printf("Password changed.\n");
+ #endif
(void) dest_tkt();
if (status)
***************
*** 162,176 ****
exit(0);
}
! void get_pw_new_key(new_key, name, inst, realm, print_realm)
des_cblock new_key;
char *name;
char *inst;
char *realm;
int print_realm; /* True if realm was give on cmdline */
{
char ppromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
- char pword[MAX_KPW_LEN]; /* storage for the password */
char npromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
char local_realm[REALM_SZ];
--- 192,207 ----
exit(0);
}
! void get_pw_new_key(new_key, pword, name, inst, realm, print_realm, skip_old)
des_cblock new_key;
+ char *pword;
char *name;
char *inst;
char *realm;
int print_realm; /* True if realm was give on cmdline */
+ int skip_old;
{
char ppromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
char npromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
char local_realm[REALM_SZ];
***************
*** 185,215 ****
if (strcmp(local_realm, realm))
print_realm++;
! (void) sprintf(ppromp,"Old password for %s%s%s%s%s:",
! name, *inst ? "." : "", inst,
! print_realm ? "@" : "", print_realm ? realm : "");
! if (read_long_pw_string(pword, sizeof(pword)-1, ppromp, 0)) {
! fprintf(stderr, "Error reading old password.\n");
! exit(1);
! }
! if ((status = krb_get_pw_in_tkt(name, inst, realm, PWSERV_NAME,
! KADM_SINST, 1, pword)) != KSUCCESS) {
! if (status == INTK_BADPW) {
! printf("Incorrect old password.\n");
! exit(0);
! }
! else {
! fprintf(stderr, "Kerberos error: %s\n", krb_err_txt[status]);
! exit(1);
! }
}
- bzero(pword, sizeof(pword));
do {
(void) sprintf(npromp,"New Password for %s%s%s%s%s:",
name, *inst ? "." : "", inst,
print_realm ? "@" : "", print_realm ? realm : "");
! if (read_long_pw_string(pword, sizeof(pword)-1, npromp, 1))
go_home("Error reading new password, password unchanged.\n",0);
if (strlen(pword) == 0)
printf("Null passwords are not allowed; try again.\n");
--- 216,249 ----
if (strcmp(local_realm, realm))
print_realm++;
! if (!skip_old) {
! (void) sprintf(ppromp,"Old password for %s%s%s%s%s:",
! name, *inst ? "." : "", inst,
! print_realm ? "@" : "", print_realm ? realm : "");
! if (read_long_pw_string(pword, MAX_KPW_LEN-1, ppromp, 0)) {
! fprintf(stderr, "Error reading old password.\n");
! exit(1);
! }
! if ((status = krb_get_pw_in_tkt(name, inst, realm, PWSERV_NAME,
! KADM_SINST, 1,
! pword)) != KSUCCESS) {
! if (status == INTK_BADPW) {
! printf("Incorrect old password.\n");
! exit(0);
! }
! else {
! fprintf(stderr, "Kerberos error: %s\n",
! krb_err_txt[status]);
! exit(1);
! }
! }
}
do {
(void) sprintf(npromp,"New Password for %s%s%s%s%s:",
name, *inst ? "." : "", inst,
print_realm ? "@" : "", print_realm ? realm : "");
! if (read_long_pw_string(pword, MAX_KPW_LEN-1, npromp, 1))
go_home("Error reading new password, password unchanged.\n",0);
if (strlen(pword) == 0)
printf("Null passwords are not allowed; try again.\n");
***************
*** 221,227 ****
#else
(void) des_string_to_key(pword, new_key);
#endif
- bzero(pword, sizeof(pword));
}
usage(value)
--- 255,260 ----
*** ./kadmin/kadm_funcs.c.old Fri Jun 14 16:29:13 1991
--- ./kadmin/kadm_funcs.c Mon Jun 24 19:18:09 1991
***************
*** 22,27 ****
--- 22,31 ----
*/
#include <sys/param.h>
+ #include <ndbm.h>
+ #include <ctype.h>
+ #include <pwd.h>
+ #include <sys/file.h>
#include <kadm.h>
#include <kadm_err.h>
#include <krb_db.h>
***************
*** 371,373 ****
--- 375,541 ----
}
}
#undef failchange
+
+ check_pw(newpw, checkstr)
+ des_cblock newpw;
+ char *checkstr;
+ {
+ des_cblock checkdes;
+
+ (void) des_string_to_key(checkstr, checkdes);
+ return(!memcmp(checkdes, newpw, sizeof(des_cblock)));
+ }
+
+ char *reverse(str)
+ char *str;
+ {
+ static char newstr[80];
+ char *p, *q;
+ int i;
+
+ i = strlen(str);
+ if (i >= sizeof(newstr))
+ i = sizeof(newstr)-1;
+ p = str+i-1;
+ q = newstr;
+ q[i]='\0';
+ for(; i > 0; i--)
+ *q++ = *p--;
+
+ return(newstr);
+ }
+
+ int lower(str)
+ char *str;
+ {
+ register char *cp;
+ int effect=0;
+
+ for (cp = str; *cp; cp++) {
+ if (isupper(*cp)) {
+ *cp = tolower(*cp);
+ effect++;
+ }
+ }
+ return(effect);
+ }
+
+ des_check_gecos(gecos, newpw)
+ char *gecos;
+ des_cblock newpw;
+ {
+ char *cp, *ncp, *tcp;
+
+ for (cp = gecos; *cp; ) {
+ /* Skip past punctuation */
+ for (; *cp; cp++)
+ if (isalnum(*cp))
+ break;
+ /* Skip to the end of the word */
+ for (ncp = cp; *ncp; ncp++)
+ if (!isalnum(*ncp) && *ncp != '\'')
+ break;
+ /* Delimit end of word */
+ if (*ncp)
+ *ncp++ = '\0';
+ /* Check word to see if it's the password */
+ if (*cp) {
+ if (check_pw(newpw, cp))
+ return(KADM_INSECURE_PW);
+ tcp = reverse(cp);
+ if (check_pw(newpw, tcp))
+ return(KADM_INSECURE_PW);
+ if (lower(cp)) {
+ if (check_pw(newpw, cp))
+ return(KADM_INSECURE_PW);
+ tcp = reverse(cp);
+ if (check_pw(newpw, tcp))
+ return(KADM_INSECURE_PW);
+ }
+ cp = ncp;
+ } else
+ break;
+ }
+ return(0);
+ }
+
+ str_check_gecos(gecos, pwstr)
+ char *gecos;
+ char *pwstr;
+ {
+ char *cp, *ncp, *tcp;
+
+ for (cp = gecos; *cp; ) {
+ /* Skip past punctuation */
+ for (; *cp; cp++)
+ if (isalnum(*cp))
+ break;
+ /* Skip to the end of the word */
+ for (ncp = cp; *ncp; ncp++)
+ if (!isalnum(*ncp) && *ncp != '\'')
+ break;
+ /* Delimit end of word */
+ if (*ncp)
+ *ncp++ = '\0';
+ /* Check word to see if it's the password */
+ if (*cp) {
+ if (!strcasecmp(pwstr, cp))
+ return(KADM_INSECURE_PW);
+ tcp = reverse(cp);
+ if (!strcasecmp(pwstr, tcp))
+ return(KADM_INSECURE_PW);
+ cp = ncp;
+ } else
+ break;
+ }
+ return(0);
+ }
+
+
+ kadm_approve_pw(rname, rinstance, rrealm, newpw, pwstring)
+ char *rname;
+ char *rinstance;
+ char *rrealm;
+ des_cblock newpw;
+ char *pwstring;
+ {
+ static DBM *pwfile = NULL;
+ int retval;
+ datum passwd, entry;
+ struct passwd *ent;
+ #ifdef HESIOD
+ extern struct passwd *hes_getpwnam();
+ #endif
+
+ if (pwstring && !check_pw(newpw, pwstring))
+ /*
+ * Someone's trying to toy with us....
+ */
+ return(KADM_PW_MISMATCH);
+ if (!pwfile) {
+ pwfile = dbm_open(PW_CHECK_FILE, O_RDONLY, 0644);
+ }
+ if (pwfile) {
+ passwd.dptr = (char *) newpw;
+ passwd.dsize = 8;
+ entry = dbm_fetch(pwfile, passwd);
+ if (entry.dptr)
+ return(KADM_INSECURE_PW);
+ }
+ if (check_pw(newpw, rname))
+ return(KADM_INSECURE_PW);
+ #ifdef HESIOD
+ ent = hes_getpwnam(rname);
+ #else
+ ent = getpwnam(rname);
+ #endif
+ if (ent && ent->pw_gecos) {
+ if (pwstring)
+ retval = str_check_gecos(ent->pw_gecos, pwstring);
+ else
+ retval = des_check_gecos(ent->pw_gecos, newpw);
+ if (retval)
+ return(retval);
+ }
+ return(0);
+ }
*** ./kadmin/kadm_server.h.old Fri Jun 14 16:28:46 1991
--- ./kadmin/kadm_server.h Thu Jun 13 23:36:44 1991
***************
*** 44,49 ****
--- 44,52 ----
/* the default syslog file */
#define KADM_SYSLOG "/kerberos/admin_server.syslog"
+ /* where to find the bad password table */
+ #define PW_CHECK_FILE "/kerberos/bad_passwd"
+
#define DEFAULT_ACL_DIR "/kerberos"
#define ADD_ACL_FILE "/admin_acl.add"
#define GET_ACL_FILE "/admin_acl.get"
*** ./kadmin/Imakefile.old Mon Jun 17 13:28:55 1991
--- ./kadmin/Imakefile Mon Jun 17 16:17:25 1991
***************
*** 38,43 ****
program(kpasswd,$(POBJS),${COM_ERR_DEP} ${KADM_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${COM_ERR} ${KADM_LIB} ${KRB_LIB} ${DES_LIB},${PROGDIR})
program(kadmin,$(AOBJS),${SS_LIBDEP} ${COM_ERR_DEP} ${KADM_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${SS_LIB} ${COM_ERR} ${KADM_LIB} ${KRB_LIB} ${DES_LIB},${PROGDIR})
program(ksrvutil,$(UOBJS),${COM_ERR_DEP} ${KADM_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${COM_ERR} ${KADM_LIB} ${KRB_LIB} ${DES_LIB},${PROGDIR})
! program(kadmind,$(SOBJS),${COM_ERR_DEP} ${ACL_LIBDEP} ${KADM_LIBDEP} ${KDB_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${COM_ERR} ${ACL_LIB} ${KADM_LIB} ${KDB_LIB} ${KRB_LIB} ${DES_LIB},${DAEMDIR})
depend:: ${CODE}
--- 38,46 ----
program(kpasswd,$(POBJS),${COM_ERR_DEP} ${KADM_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${COM_ERR} ${KADM_LIB} ${KRB_LIB} ${DES_LIB},${PROGDIR})
program(kadmin,$(AOBJS),${SS_LIBDEP} ${COM_ERR_DEP} ${KADM_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${SS_LIB} ${COM_ERR} ${KADM_LIB} ${KRB_LIB} ${DES_LIB},${PROGDIR})
program(ksrvutil,$(UOBJS),${COM_ERR_DEP} ${KADM_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${COM_ERR} ${KADM_LIB} ${KRB_LIB} ${DES_LIB},${PROGDIR})
! program(kadmind,$(SOBJS),${HESIOD_LIBDEP} ${COM_ERR_DEP} ${ACL_LIBDEP} ${KADM_LIBDEP} ${KDB_LIBDEP} ${KRB_LIBDEP} ${DES_LIBDEP},${HESIOD_LIB} ${COM_ERR} ${ACL_LIB} ${KADM_LIB} ${KDB_LIB} ${KRB_LIB} ${DES_LIB},${DAEMDIR})
! program(build_pwfile,build_pwfile.c,${DES_LIBDEP},-ldbm ${DES_LIB},${PROGDIR})
depend:: ${CODE}
+
+
*** ./kadmin/admin_server.c.old Fri Jun 14 16:28:04 1991
--- ./kadmin/admin_server.c Fri Jun 14 15:29:02 1991
***************
*** 56,61 ****
--- 56,62 ----
int errval;
int c;
extern char *optarg;
+ extern int fascist_cpw;
prog[sizeof(prog)-1]='\0'; /* Terminate... */
(void) strncpy(prog, argv[0], sizeof(prog)-1);
***************
*** 66,72 ****
bzero(krbrlm, sizeof(krbrlm));
! while ((c = getopt(argc, argv, "f:hnd:a:r:")) != EOF)
switch(c) {
case 'f': /* Syslog file name change */
prm.sysfile = optarg;
--- 67,73 ----
bzero(krbrlm, sizeof(krbrlm));
! while ((c = getopt(argc, argv, "f:hnd:a:r:FN")) != EOF)
switch(c) {
case 'f': /* Syslog file name change */
prm.sysfile = optarg;
***************
*** 85,96 ****
exit(1);
}
break;
case 'r':
(void) strncpy(krbrlm, optarg, sizeof(krbrlm) - 1);
break;
case 'h': /* get help on using admin_server */
default:
! printf("Usage: admin_server [-h] [-n] [-r realm] [-d dbname] [-f filename] [-a acldir]\n");
exit(-1); /* failure */
}
--- 86,103 ----
exit(1);
}
break;
+ case 'F':
+ fascist_cpw++;
+ break;
+ case 'N':
+ fascist_cpw = 0;
+ break;
case 'r':
(void) strncpy(krbrlm, optarg, sizeof(krbrlm) - 1);
break;
case 'h': /* get help on using admin_server */
default:
! printf("Usage: admin_server [-h] [-n] [-F] [-N] [-r realm] [-d dbname] [-f filename] [-a acldir]\n");
exit(-1); /* failure */
}
*** ./kadmin/kadm_ser_wrap.c.old Fri Jun 14 16:50:50 1991
--- ./kadmin/kadm_ser_wrap.c Fri Jun 14 16:51:47 1991
***************
*** 175,180 ****
--- 175,184 ----
retval = kadm_ser_mod(msg_st.app_data+1,(int) msg_st.app_length,&ad,
&retdat, &retlen);
break;
+ case CHECK_PW:
+ retval = kadm_ser_ckpw(msg_st.app_data+1,(int) msg_st.app_length,&ad,
+ &retdat, &retlen);
+ break;
default:
clr_cli_secrets();
errpkt(dat, dat_len, KADM_NO_OPCODE);
*** ./kadmin/build_pwfile.c.old Mon Jun 24 18:37:23 1991
--- ./kadmin/build_pwfile.c Wed Jun 19 18:04:02 1991
***************
*** 0 ****
--- 1,87 ----
+ /*
+ * build_pwfile.c --- build a table of bad passwords, keyed by their
+ * des equivalents.
+ *
+ * Written by Theodore Ts'o
+ *
+ * Copyright 1988 by the Massachusetts Institute of Technology.
+ *
+ * For copying and distribution information, please see the file
+ * <mit-copyright.h>.
+ */
+
+ #ifndef lint
+ static char rcsid_build_pwfile_c[] =
+ "$Id$";
+ #endif lint
+
+ #include <mit-copyright.h>
+ #include <stdio.h>
+ #include <sys/param.h>
+ #include <ndbm.h>
+ #include <sys/file.h>
+ #include <kadm.h>
+ #include <kadm_err.h>
+ #include <krb_db.h>
+ #include "kadm_server.h"
+
+ main(argc, argv)
+ int argc;
+ char **argv;
+ {
+ DBM *pwfile;
+ FILE *f;
+ datum passwd, entry;
+ des_cblock key;
+ char word[1024];
+ int len, filenum, i;
+ int wptr;
+
+ if (argc != 2) {
+ fprintf("%s: Usage: %s filename\n", argv[0], argv[0]);
+ exit(1);
+ }
+ if (!(f = fopen(argv[1], "r"))) {
+ perror(argv[1]);
+ exit(1);
+ }
+ pwfile = dbm_open(PW_CHECK_FILE, O_RDWR|O_CREAT, 0644);
+ if (!pwfile) {
+ fprintf(stderr, "Couldn't open %s for writing.\n",
+ PW_CHECK_FILE);
+ perror("dbm_open");
+ exit(1);
+ }
+ filenum = 0;
+ do {
+ filenum++;
+ passwd.dptr = (char *) &i;
+ passwd.dsize = sizeof(filenum);
+ entry.dptr = argv[1];
+ entry.dsize = strlen(argv[1])+1;
+ } while (dbm_store(pwfile, passwd, entry, DBM_INSERT));
+ i = 0;
+ while (!feof(f)) {
+ i++;
+ wptr = (filenum << 24) + i;
+ fgets(word, sizeof(word), f);
+ len = strlen(word);
+ if (len > 0 && word[len-1] == '\n')
+ word[--len] = '\0';
+ des_string_to_key(word, key);
+ passwd.dptr = (char *) key;
+ passwd.dsize = 8;
+ entry.dptr = (char *) &wptr;
+ #ifdef notdef
+ entry.dsize = sizeof(wptr);
+ #else
+ entry.dsize = 0;
+ #endif
+ dbm_store(pwfile, passwd, entry, DBM_REPLACE);
+ }
+ dbm_close(pwfile);
+ exit(0);
+ }
+
+
+
*** ./util/imake.includes/config.Imakefile.old Mon Jun 17 13:21:57 1991
--- ./util/imake.includes/config.Imakefile Mon Jun 17 13:30:52 1991
***************
*** 46,54 ****
INSTALLUCB=$(INSTALLPROG)
#endif
GLOBAL_CDEFS= -DKERBEROS $(SITEDEFS) $(OSDEFS)
! SITEDEFS=-DATHENA $(NOENCFLAG) $(COMPAT) -I$(INCLDIR)
/*
* Operating specific definitions
--- 46,55 ----
INSTALLUCB=$(INSTALLPROG)
#endif
+
GLOBAL_CDEFS= -DKERBEROS $(SITEDEFS) $(OSDEFS)
! SITEDEFS=-DATHENA $(HESIOD) $(NOENCFLAG) $(COMPAT) -I$(INCLDIR)
/*
* Operating specific definitions
***************
*** 186,191 ****
--- 187,203 ----
IMAKE=$(BUILDTOP)/util/imake/imake -I$(BUILDTOP)/util/imake.includes
#else
IMAKE=imake -I$(BUILDTOP)/util/imake.includes -TImake.template
+ #endif
+
+ /*
+ * Set USE_HESIOD to be true if Kerberos should try to use Hesiod.
+ */
+ #define USE_HESIOD
+
+ #ifdef USE_HESIOD
+ HESIOD=-DHESIOD
+ HESIOD_LIB= -lhesiod
+ HESIOD_LIBDEP=
#endif
/*