Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / crypto / dist / heimdal / kadmin / ank.c
blob2de54260012e615e4032b01bf8baf346501e80d4
1 /*
2 * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
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.
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.
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.
34 #include "kadmin_locl.h"
35 #include "kadmin-commands.h"
37 __RCSID("$Heimdal: ank.c 16658 2006-01-25 12:29:46Z lha $"
38 "$NetBSD$");
41 * fetch the default principal corresponding to `princ'
44 static krb5_error_code
45 get_default (kadm5_server_context *context,
46 krb5_principal princ,
47 kadm5_principal_ent_t default_ent)
49 krb5_error_code ret;
50 krb5_principal def_principal;
51 krb5_realm *realm = krb5_princ_realm(context->context, princ);
53 ret = krb5_make_principal (context->context, &def_principal,
54 *realm, "default", NULL);
55 if (ret)
56 return ret;
57 ret = kadm5_get_principal (context, def_principal, default_ent,
58 KADM5_PRINCIPAL_NORMAL_MASK);
59 krb5_free_principal (context->context, def_principal);
60 return ret;
64 * Add the principal `name' to the database.
65 * Prompt for all data not given by the input parameters.
68 static krb5_error_code
69 add_one_principal (const char *name,
70 int rand_key,
71 int rand_password,
72 int use_defaults,
73 char *password,
74 krb5_key_data *key_data,
75 const char *max_ticket_life,
76 const char *max_renewable_life,
77 const char *attributes,
78 const char *expiration,
79 const char *pw_expiration)
81 krb5_error_code ret;
82 kadm5_principal_ent_rec princ, defrec;
83 kadm5_principal_ent_rec *default_ent = NULL;
84 krb5_principal princ_ent = NULL;
85 int mask = 0;
86 int default_mask = 0;
87 char pwbuf[1024];
89 memset(&princ, 0, sizeof(princ));
90 ret = krb5_parse_name(context, name, &princ_ent);
91 if (ret) {
92 krb5_warn(context, ret, "krb5_parse_name");
93 return ret;
95 princ.principal = princ_ent;
96 mask |= KADM5_PRINCIPAL;
98 ret = set_entry(context, &princ, &mask,
99 max_ticket_life, max_renewable_life,
100 expiration, pw_expiration, attributes);
101 if (ret)
102 goto out;
104 default_ent = &defrec;
105 ret = get_default (kadm_handle, princ_ent, default_ent);
106 if (ret) {
107 default_ent = NULL;
108 default_mask = 0;
109 } else {
110 default_mask = KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
111 KADM5_PRINC_EXPIRE_TIME | KADM5_PW_EXPIRATION;
114 if(use_defaults)
115 set_defaults(&princ, &mask, default_ent, default_mask);
116 else
117 if(edit_entry(&princ, &mask, default_ent, default_mask))
118 goto out;
119 if(rand_key || key_data) {
120 princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
121 mask |= KADM5_ATTRIBUTES;
122 random_password (pwbuf, sizeof(pwbuf));
123 password = pwbuf;
124 } else if (rand_password) {
125 random_password (pwbuf, sizeof(pwbuf));
126 password = pwbuf;
127 } else if(password == NULL) {
128 char *princ_name;
129 char *prompt;
131 krb5_unparse_name(context, princ_ent, &princ_name);
132 asprintf (&prompt, "%s's Password: ", princ_name);
133 free (princ_name);
134 ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), prompt, 1);
135 free (prompt);
136 if (ret) {
137 krb5_set_error_string(context, "failed to verify password");
138 ret = KRB5_LIBOS_BADPWDMATCH;
139 goto out;
141 password = pwbuf;
144 ret = kadm5_create_principal(kadm_handle, &princ, mask, password);
145 if(ret) {
146 krb5_warn(context, ret, "kadm5_create_principal");
147 goto out;
149 if(rand_key) {
150 krb5_keyblock *new_keys;
151 int n_keys, i;
152 ret = kadm5_randkey_principal(kadm_handle, princ_ent,
153 &new_keys, &n_keys);
154 if(ret){
155 krb5_warn(context, ret, "kadm5_randkey_principal");
156 n_keys = 0;
158 for(i = 0; i < n_keys; i++)
159 krb5_free_keyblock_contents(context, &new_keys[i]);
160 if (n_keys > 0)
161 free(new_keys);
162 kadm5_get_principal(kadm_handle, princ_ent, &princ,
163 KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
164 princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
165 princ.kvno = 1;
166 kadm5_modify_principal(kadm_handle, &princ,
167 KADM5_ATTRIBUTES | KADM5_KVNO);
168 kadm5_free_principal_ent(kadm_handle, &princ);
169 } else if (key_data) {
170 ret = kadm5_chpass_principal_with_key (kadm_handle, princ_ent,
171 3, key_data);
172 if (ret) {
173 krb5_warn(context, ret, "kadm5_chpass_principal_with_key");
175 kadm5_get_principal(kadm_handle, princ_ent, &princ,
176 KADM5_PRINCIPAL | KADM5_ATTRIBUTES);
177 princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
178 kadm5_modify_principal(kadm_handle, &princ, KADM5_ATTRIBUTES);
179 kadm5_free_principal_ent(kadm_handle, &princ);
180 } else if (rand_password) {
181 char *princ_name;
183 krb5_unparse_name(context, princ_ent, &princ_name);
184 printf ("added %s with password \"%s\"\n", princ_name, password);
185 free (princ_name);
187 out:
188 if (princ_ent)
189 krb5_free_principal (context, princ_ent);
190 if(default_ent)
191 kadm5_free_principal_ent (kadm_handle, default_ent);
192 if (password != NULL)
193 memset (password, 0, strlen(password));
194 return ret;
198 * parse the string `key_string' into `key', returning 0 iff succesful.
202 * the ank command
206 * Parse arguments and add all the principals.
210 add_new_key(struct add_options *opt, int argc, char **argv)
212 krb5_error_code ret = 0;
213 int i;
214 int num;
215 krb5_key_data key_data[3];
216 krb5_key_data *kdp = NULL;
218 num = 0;
219 if (opt->random_key_flag)
220 ++num;
221 if (opt->random_password_flag)
222 ++num;
223 if (opt->password_string)
224 ++num;
225 if (opt->key_string)
226 ++num;
228 if (num > 1) {
229 fprintf (stderr, "give only one of "
230 "--random-key, --random-password, --password, --key\n");
231 return 1;
234 if (opt->key_string) {
235 const char *error;
237 if (parse_des_key (opt->key_string, key_data, &error)) {
238 fprintf (stderr, "failed parsing key \"%s\": %s\n",
239 opt->key_string, error);
240 return 1;
242 kdp = key_data;
245 for(i = 0; i < argc; i++) {
246 ret = add_one_principal (argv[i],
247 opt->random_key_flag,
248 opt->random_password_flag,
249 opt->use_defaults_flag,
250 opt->password_string,
251 kdp,
252 opt->max_ticket_life_string,
253 opt->max_renewable_life_string,
254 opt->attributes_string,
255 opt->expiration_time_string,
256 opt->pw_expiration_time_string);
257 if (ret) {
258 krb5_warn (context, ret, "adding %s", argv[i]);
259 break;
262 if (kdp) {
263 int16_t dummy = 3;
264 kadm5_free_key_data (kadm_handle, &dummy, key_data);
266 return ret != 0;