xref: /freebsd/crypto/heimdal/kadmin/cpw.c (revision 908e960ea6343acd9515d89d5d5696f9d8bf090c)
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 RCSID("$Id: cpw.c 16755 2006-02-18 23:30:32Z lha $");
38 
39 struct cpw_entry_data {
40     int random_key;
41     int random_password;
42     char *password;
43     krb5_key_data *key_data;
44 };
45 
46 static int
47 set_random_key (krb5_principal principal)
48 {
49     krb5_error_code ret;
50     int i;
51     krb5_keyblock *keys;
52     int num_keys;
53 
54     ret = kadm5_randkey_principal(kadm_handle, principal, &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)
65 {
66     krb5_error_code ret;
67     char pw[128];
68 
69     random_password (pw, sizeof(pw));
70     ret = kadm5_chpass_principal(kadm_handle, principal, 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)
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(kadm_handle, principal, password);
105     memset(pwbuf, 0, sizeof(pwbuf));
106     return ret;
107 }
108 
109 static int
110 set_key_data (krb5_principal principal, krb5_key_data *key_data)
111 {
112     krb5_error_code ret;
113 
114     ret = kadm5_chpass_principal_with_key (kadm_handle, principal,
115 					   3, key_data);
116     return ret;
117 }
118 
119 static int
120 do_cpw_entry(krb5_principal principal, void *data)
121 {
122     struct cpw_entry_data *e = data;
123 
124     if (e->random_key)
125 	return set_random_key (principal);
126     else if (e->random_password)
127 	return set_random_password (principal);
128     else if (e->key_data)
129 	return set_key_data (principal, e->key_data);
130     else
131 	return set_password (principal, e->password);
132 }
133 
134 int
135 cpw_entry(struct passwd_options *opt, int argc, char **argv)
136 {
137     krb5_error_code ret = 0;
138     int i;
139     struct cpw_entry_data data;
140     int num;
141     krb5_key_data key_data[3];
142 
143     data.random_key = opt->random_key_flag;
144     data.random_password = opt->random_password_flag;
145     data.password = opt->password_string;
146     data.key_data	 = NULL;
147 
148     num = 0;
149     if (data.random_key)
150 	++num;
151     if (data.random_password)
152 	++num;
153     if (data.password)
154 	++num;
155     if (opt->key_string)
156 	++num;
157 
158     if (num > 1) {
159 	fprintf (stderr, "give only one of "
160 		"--random-key, --random-password, --password, --key\n");
161 	return 1;
162     }
163 
164     if (opt->key_string) {
165 	const char *error;
166 
167 	if (parse_des_key (opt->key_string, key_data, &error)) {
168 	    fprintf (stderr, "failed parsing key \"%s\": %s\n",
169 		     opt->key_string, error);
170 	    return 1;
171 	}
172 	data.key_data = key_data;
173     }
174 
175     for(i = 0; i < argc; i++)
176 	ret = foreach_principal(argv[i], do_cpw_entry, "cpw", &data);
177 
178     if (data.key_data) {
179 	int16_t dummy;
180 	kadm5_free_key_data (kadm_handle, &dummy, key_data);
181     }
182 
183     return ret != 0;
184 }
185