/ kadmin / cpw.c
cpw.c
  1  /*
  2   * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
  3   * (Royal Institute of Technology, Stockholm, Sweden).
  4   * All rights reserved.
  5   *
  6   * Redistribution and use in source and binary forms, with or without
  7   * modification, are permitted provided that the following conditions
  8   * are met:
  9   *
 10   * 1. Redistributions of source code must retain the above copyright
 11   *    notice, this list of conditions and the following disclaimer.
 12   *
 13   * 2. Redistributions in binary form must reproduce the above copyright
 14   *    notice, this list of conditions and the following disclaimer in the
 15   *    documentation and/or other materials provided with the distribution.
 16   *
 17   * 3. Neither the name of the Institute nor the names of its contributors
 18   *    may be used to endorse or promote products derived from this software
 19   *    without specific prior written permission.
 20   *
 21   * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 22   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 24   * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 25   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 27   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 28   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 29   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 30   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 31   * SUCH DAMAGE.
 32   */
 33  
 34  #include "kadmin_locl.h"
 35  #include "kadmin-commands.h"
 36  
 37  struct cpw_entry_data {
 38      int keepold;
 39      int random_key;
 40      int random_password;
 41      char *password;
 42      krb5_key_data *key_data;
 43  };
 44  
 45  static int
 46  set_random_key (krb5_principal principal, int keepold)
 47  {
 48      krb5_error_code ret;
 49      int i;
 50      krb5_keyblock *keys;
 51      int num_keys;
 52  
 53      ret = kadm5_randkey_principal_3(kadm_handle, principal, keepold, 0, NULL,
 54  				    &keys, &num_keys);
 55      if(ret)
 56  	return ret;
 57      for(i = 0; i < num_keys; i++)
 58  	krb5_free_keyblock_contents(context, &keys[i]);
 59      free(keys);
 60      return 0;
 61  }
 62  
 63  static int
 64  set_random_password (krb5_principal principal, int keepold)
 65  {
 66      krb5_error_code ret;
 67      char pw[128];
 68  
 69      random_password (pw, sizeof(pw));
 70      ret = kadm5_chpass_principal_3(kadm_handle, principal, keepold, 0, NULL, pw);
 71      if (ret == 0) {
 72  	char *princ_name;
 73  
 74  	krb5_unparse_name(context, principal, &princ_name);
 75  
 76  	printf ("%s's password set to \"%s\"\n", princ_name, pw);
 77  	free (princ_name);
 78      }
 79      memset (pw, 0, sizeof(pw));
 80      return ret;
 81  }
 82  
 83  static int
 84  set_password (krb5_principal principal, char *password, int keepold)
 85  {
 86      krb5_error_code ret = 0;
 87      char pwbuf[128];
 88  
 89      if(password == NULL) {
 90  	char *princ_name;
 91  	char *prompt;
 92  
 93  	krb5_unparse_name(context, principal, &princ_name);
 94  	asprintf(&prompt, "%s's Password: ", princ_name);
 95  	free (princ_name);
 96  	ret = UI_UTIL_read_pw_string(pwbuf, sizeof(pwbuf), prompt, 1);
 97  	free (prompt);
 98  	if(ret){
 99  	    return 0; /* XXX error code? */
100  	}
101  	password = pwbuf;
102      }
103      if(ret == 0)
104  	ret = kadm5_chpass_principal_3(kadm_handle, principal, keepold, 0, NULL,
105  				       password);
106      memset(pwbuf, 0, sizeof(pwbuf));
107      return ret;
108  }
109  
110  static int
111  set_key_data (krb5_principal principal, krb5_key_data *key_data, int keepold)
112  {
113      krb5_error_code ret;
114  
115      ret = kadm5_chpass_principal_with_key_3(kadm_handle, principal, keepold,
116  					    3, key_data);
117      return ret;
118  }
119  
120  static int
121  do_cpw_entry(krb5_principal principal, void *data)
122  {
123      struct cpw_entry_data *e = data;
124  
125      if (e->random_key)
126  	return set_random_key (principal, e->keepold);
127      else if (e->random_password)
128  	return set_random_password (principal, e->keepold);
129      else if (e->key_data)
130  	return set_key_data (principal, e->key_data, e->keepold);
131      else
132  	return set_password (principal, e->password, e->keepold);
133  }
134  
135  int
136  cpw_entry(struct passwd_options *opt, int argc, char **argv)
137  {
138      krb5_error_code ret = 0;
139      int i;
140      struct cpw_entry_data data;
141      int num;
142      krb5_key_data key_data[3];
143  
144      data.keepold = opt->keepold_flag;
145      data.random_key = opt->random_key_flag;
146      data.random_password = opt->random_password_flag;
147      data.password = opt->password_string;
148      data.key_data	 = NULL;
149  
150      num = 0;
151      if (data.random_key)
152  	++num;
153      if (data.random_password)
154  	++num;
155      if (data.password)
156  	++num;
157      if (opt->key_string)
158  	++num;
159  
160      if (num > 1) {
161  	fprintf (stderr, "give only one of "
162  		"--random-key, --random-password, --password, --key\n");
163  	return 1;
164      }
165  
166      if (opt->key_string) {
167  	const char *error;
168  
169  	if (parse_des_key (opt->key_string, key_data, &error)) {
170  	    fprintf (stderr, "failed parsing key \"%s\": %s\n",
171  		     opt->key_string, error);
172  	    return 1;
173  	}
174  	data.key_data = key_data;
175      }
176  
177      for(i = 0; i < argc; i++)
178  	ret = foreach_principal(argv[i], do_cpw_entry, "cpw", &data);
179  
180      if (data.key_data) {
181  	int16_t dummy;
182  	kadm5_free_key_data (kadm_handle, &dummy, key_data);
183      }
184  
185      return ret != 0;
186  }