[2655] in Release_Engineering

home help back first fref pref prev next nref lref last post

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

home help back first fref pref prev next nref lref last post