1*0a6a1f1dSLionel Sambuc /* $NetBSD: ank.c,v 1.1.1.2 2014/04/24 12:45:27 pettai Exp $ */
2ebfedea0SLionel Sambuc
3ebfedea0SLionel Sambuc /*
4ebfedea0SLionel Sambuc * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
5ebfedea0SLionel Sambuc * (Royal Institute of Technology, Stockholm, Sweden).
6ebfedea0SLionel Sambuc * All rights reserved.
7ebfedea0SLionel Sambuc *
8ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
9ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
10ebfedea0SLionel Sambuc * are met:
11ebfedea0SLionel Sambuc *
12ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
13ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
14ebfedea0SLionel Sambuc *
15ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
16ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
17ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
18ebfedea0SLionel Sambuc *
19ebfedea0SLionel Sambuc * 3. Neither the name of the Institute nor the names of its contributors
20ebfedea0SLionel Sambuc * may be used to endorse or promote products derived from this software
21ebfedea0SLionel Sambuc * without specific prior written permission.
22ebfedea0SLionel Sambuc *
23ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
24ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
27ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33ebfedea0SLionel Sambuc * SUCH DAMAGE.
34ebfedea0SLionel Sambuc */
35ebfedea0SLionel Sambuc
36ebfedea0SLionel Sambuc #include "kadmin_locl.h"
37ebfedea0SLionel Sambuc #include "kadmin-commands.h"
38ebfedea0SLionel Sambuc
39ebfedea0SLionel Sambuc /*
40ebfedea0SLionel Sambuc * fetch the default principal corresponding to `princ'
41ebfedea0SLionel Sambuc */
42ebfedea0SLionel Sambuc
43ebfedea0SLionel Sambuc static krb5_error_code
get_default(kadm5_server_context * contextp,krb5_principal princ,kadm5_principal_ent_t default_ent)44*0a6a1f1dSLionel Sambuc get_default (kadm5_server_context *contextp,
45ebfedea0SLionel Sambuc krb5_principal princ,
46ebfedea0SLionel Sambuc kadm5_principal_ent_t default_ent)
47ebfedea0SLionel Sambuc {
48ebfedea0SLionel Sambuc krb5_error_code ret;
49ebfedea0SLionel Sambuc krb5_principal def_principal;
50*0a6a1f1dSLionel Sambuc krb5_const_realm realm = krb5_principal_get_realm(contextp->context, princ);
51ebfedea0SLionel Sambuc
52*0a6a1f1dSLionel Sambuc ret = krb5_make_principal (contextp->context, &def_principal,
53ebfedea0SLionel Sambuc realm, "default", NULL);
54ebfedea0SLionel Sambuc if (ret)
55ebfedea0SLionel Sambuc return ret;
56*0a6a1f1dSLionel Sambuc ret = kadm5_get_principal (contextp, def_principal, default_ent,
57ebfedea0SLionel Sambuc KADM5_PRINCIPAL_NORMAL_MASK);
58*0a6a1f1dSLionel Sambuc krb5_free_principal (contextp->context, def_principal);
59ebfedea0SLionel Sambuc return ret;
60ebfedea0SLionel Sambuc }
61ebfedea0SLionel Sambuc
62ebfedea0SLionel Sambuc /*
63ebfedea0SLionel Sambuc * Add the principal `name' to the database.
64ebfedea0SLionel Sambuc * Prompt for all data not given by the input parameters.
65ebfedea0SLionel Sambuc */
66ebfedea0SLionel Sambuc
67ebfedea0SLionel Sambuc static krb5_error_code
add_one_principal(const char * name,int rand_key,int rand_password,int use_defaults,char * password,krb5_key_data * key_data,const char * max_ticket_life,const char * max_renewable_life,const char * attributes,const char * expiration,const char * pw_expiration)68ebfedea0SLionel Sambuc add_one_principal (const char *name,
69ebfedea0SLionel Sambuc int rand_key,
70ebfedea0SLionel Sambuc int rand_password,
71ebfedea0SLionel Sambuc int use_defaults,
72ebfedea0SLionel Sambuc char *password,
73ebfedea0SLionel Sambuc krb5_key_data *key_data,
74ebfedea0SLionel Sambuc const char *max_ticket_life,
75ebfedea0SLionel Sambuc const char *max_renewable_life,
76ebfedea0SLionel Sambuc const char *attributes,
77ebfedea0SLionel Sambuc const char *expiration,
78ebfedea0SLionel Sambuc const char *pw_expiration)
79ebfedea0SLionel Sambuc {
80ebfedea0SLionel Sambuc krb5_error_code ret;
81ebfedea0SLionel Sambuc kadm5_principal_ent_rec princ, defrec;
82ebfedea0SLionel Sambuc kadm5_principal_ent_rec *default_ent = NULL;
83ebfedea0SLionel Sambuc krb5_principal princ_ent = NULL;
84ebfedea0SLionel Sambuc int mask = 0;
85ebfedea0SLionel Sambuc int default_mask = 0;
86ebfedea0SLionel Sambuc char pwbuf[1024];
87ebfedea0SLionel Sambuc
88ebfedea0SLionel Sambuc memset(&princ, 0, sizeof(princ));
89ebfedea0SLionel Sambuc ret = krb5_parse_name(context, name, &princ_ent);
90ebfedea0SLionel Sambuc if (ret) {
91ebfedea0SLionel Sambuc krb5_warn(context, ret, "krb5_parse_name");
92ebfedea0SLionel Sambuc return ret;
93ebfedea0SLionel Sambuc }
94ebfedea0SLionel Sambuc princ.principal = princ_ent;
95ebfedea0SLionel Sambuc mask |= KADM5_PRINCIPAL;
96ebfedea0SLionel Sambuc
97ebfedea0SLionel Sambuc ret = set_entry(context, &princ, &mask,
98ebfedea0SLionel Sambuc max_ticket_life, max_renewable_life,
99ebfedea0SLionel Sambuc expiration, pw_expiration, attributes);
100ebfedea0SLionel Sambuc if (ret)
101ebfedea0SLionel Sambuc goto out;
102ebfedea0SLionel Sambuc
103ebfedea0SLionel Sambuc default_ent = &defrec;
104ebfedea0SLionel Sambuc ret = get_default (kadm_handle, princ_ent, default_ent);
105ebfedea0SLionel Sambuc if (ret) {
106ebfedea0SLionel Sambuc default_ent = NULL;
107ebfedea0SLionel Sambuc default_mask = 0;
108ebfedea0SLionel Sambuc } else {
109ebfedea0SLionel Sambuc default_mask = KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
110ebfedea0SLionel Sambuc KADM5_PRINC_EXPIRE_TIME | KADM5_PW_EXPIRATION;
111ebfedea0SLionel Sambuc }
112ebfedea0SLionel Sambuc
113ebfedea0SLionel Sambuc if(use_defaults)
114ebfedea0SLionel Sambuc set_defaults(&princ, &mask, default_ent, default_mask);
115ebfedea0SLionel Sambuc else
116ebfedea0SLionel Sambuc if(edit_entry(&princ, &mask, default_ent, default_mask))
117ebfedea0SLionel Sambuc goto out;
118ebfedea0SLionel Sambuc if(rand_key || key_data) {
119ebfedea0SLionel Sambuc princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
120ebfedea0SLionel Sambuc mask |= KADM5_ATTRIBUTES;
121ebfedea0SLionel Sambuc random_password (pwbuf, sizeof(pwbuf));
122ebfedea0SLionel Sambuc password = pwbuf;
123ebfedea0SLionel Sambuc } else if (rand_password) {
124ebfedea0SLionel Sambuc random_password (pwbuf, sizeof(pwbuf));
125ebfedea0SLionel Sambuc password = pwbuf;
126ebfedea0SLionel Sambuc } else if(password == NULL) {
127ebfedea0SLionel Sambuc char *princ_name;
128ebfedea0SLionel Sambuc char *prompt;
129ebfedea0SLionel Sambuc
130ebfedea0SLionel Sambuc krb5_unparse_name(context, princ_ent, &princ_name);
131ebfedea0SLionel Sambuc asprintf (&prompt, "%s's Password: ", princ_name);
132ebfedea0SLionel Sambuc free (princ_name);
133ebfedea0SLionel Sambuc ret = UI_UTIL_read_pw_string (pwbuf, sizeof(pwbuf), prompt, 1);
134ebfedea0SLionel Sambuc free (prompt);
135ebfedea0SLionel Sambuc if (ret) {
136ebfedea0SLionel Sambuc ret = KRB5_LIBOS_BADPWDMATCH;
137ebfedea0SLionel Sambuc krb5_set_error_message(context, ret, "failed to verify password");
138ebfedea0SLionel Sambuc goto out;
139ebfedea0SLionel Sambuc }
140ebfedea0SLionel Sambuc password = pwbuf;
141ebfedea0SLionel Sambuc }
142ebfedea0SLionel Sambuc
143ebfedea0SLionel Sambuc ret = kadm5_create_principal(kadm_handle, &princ, mask, password);
144ebfedea0SLionel Sambuc if(ret) {
145ebfedea0SLionel Sambuc krb5_warn(context, ret, "kadm5_create_principal");
146ebfedea0SLionel Sambuc goto out;
147ebfedea0SLionel Sambuc }
148ebfedea0SLionel Sambuc if(rand_key) {
149ebfedea0SLionel Sambuc krb5_keyblock *new_keys;
150ebfedea0SLionel Sambuc int n_keys, i;
151ebfedea0SLionel Sambuc ret = kadm5_randkey_principal(kadm_handle, princ_ent,
152ebfedea0SLionel Sambuc &new_keys, &n_keys);
153ebfedea0SLionel Sambuc if(ret){
154ebfedea0SLionel Sambuc krb5_warn(context, ret, "kadm5_randkey_principal");
155ebfedea0SLionel Sambuc n_keys = 0;
156ebfedea0SLionel Sambuc }
157ebfedea0SLionel Sambuc for(i = 0; i < n_keys; i++)
158ebfedea0SLionel Sambuc krb5_free_keyblock_contents(context, &new_keys[i]);
159ebfedea0SLionel Sambuc if (n_keys > 0)
160ebfedea0SLionel Sambuc free(new_keys);
161ebfedea0SLionel Sambuc kadm5_get_principal(kadm_handle, princ_ent, &princ,
162ebfedea0SLionel Sambuc KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
163ebfedea0SLionel Sambuc princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
164ebfedea0SLionel Sambuc princ.kvno = 1;
165ebfedea0SLionel Sambuc kadm5_modify_principal(kadm_handle, &princ,
166ebfedea0SLionel Sambuc KADM5_ATTRIBUTES | KADM5_KVNO);
167ebfedea0SLionel Sambuc kadm5_free_principal_ent(kadm_handle, &princ);
168ebfedea0SLionel Sambuc } else if (key_data) {
169ebfedea0SLionel Sambuc ret = kadm5_chpass_principal_with_key (kadm_handle, princ_ent,
170ebfedea0SLionel Sambuc 3, key_data);
171ebfedea0SLionel Sambuc if (ret) {
172ebfedea0SLionel Sambuc krb5_warn(context, ret, "kadm5_chpass_principal_with_key");
173ebfedea0SLionel Sambuc }
174ebfedea0SLionel Sambuc kadm5_get_principal(kadm_handle, princ_ent, &princ,
175ebfedea0SLionel Sambuc KADM5_PRINCIPAL | KADM5_ATTRIBUTES);
176ebfedea0SLionel Sambuc princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
177ebfedea0SLionel Sambuc kadm5_modify_principal(kadm_handle, &princ, KADM5_ATTRIBUTES);
178ebfedea0SLionel Sambuc kadm5_free_principal_ent(kadm_handle, &princ);
179ebfedea0SLionel Sambuc } else if (rand_password) {
180ebfedea0SLionel Sambuc char *princ_name;
181ebfedea0SLionel Sambuc
182ebfedea0SLionel Sambuc krb5_unparse_name(context, princ_ent, &princ_name);
183ebfedea0SLionel Sambuc printf ("added %s with password \"%s\"\n", princ_name, password);
184ebfedea0SLionel Sambuc free (princ_name);
185ebfedea0SLionel Sambuc }
186ebfedea0SLionel Sambuc out:
187ebfedea0SLionel Sambuc if (princ_ent)
188ebfedea0SLionel Sambuc krb5_free_principal (context, princ_ent);
189ebfedea0SLionel Sambuc if(default_ent)
190ebfedea0SLionel Sambuc kadm5_free_principal_ent (kadm_handle, default_ent);
191ebfedea0SLionel Sambuc if (password != NULL)
192ebfedea0SLionel Sambuc memset (password, 0, strlen(password));
193ebfedea0SLionel Sambuc return ret;
194ebfedea0SLionel Sambuc }
195ebfedea0SLionel Sambuc
196ebfedea0SLionel Sambuc /*
197ebfedea0SLionel Sambuc * parse the string `key_string' into `key', returning 0 iff succesful.
198ebfedea0SLionel Sambuc */
199ebfedea0SLionel Sambuc
200ebfedea0SLionel Sambuc /*
201ebfedea0SLionel Sambuc * the ank command
202ebfedea0SLionel Sambuc */
203ebfedea0SLionel Sambuc
204ebfedea0SLionel Sambuc /*
205ebfedea0SLionel Sambuc * Parse arguments and add all the principals.
206ebfedea0SLionel Sambuc */
207ebfedea0SLionel Sambuc
208ebfedea0SLionel Sambuc int
add_new_key(struct add_options * opt,int argc,char ** argv)209ebfedea0SLionel Sambuc add_new_key(struct add_options *opt, int argc, char **argv)
210ebfedea0SLionel Sambuc {
211ebfedea0SLionel Sambuc krb5_error_code ret = 0;
212ebfedea0SLionel Sambuc int i;
213ebfedea0SLionel Sambuc int num;
214ebfedea0SLionel Sambuc krb5_key_data key_data[3];
215ebfedea0SLionel Sambuc krb5_key_data *kdp = NULL;
216ebfedea0SLionel Sambuc
217ebfedea0SLionel Sambuc num = 0;
218ebfedea0SLionel Sambuc if (opt->random_key_flag)
219ebfedea0SLionel Sambuc ++num;
220ebfedea0SLionel Sambuc if (opt->random_password_flag)
221ebfedea0SLionel Sambuc ++num;
222ebfedea0SLionel Sambuc if (opt->password_string)
223ebfedea0SLionel Sambuc ++num;
224ebfedea0SLionel Sambuc if (opt->key_string)
225ebfedea0SLionel Sambuc ++num;
226ebfedea0SLionel Sambuc
227ebfedea0SLionel Sambuc if (num > 1) {
228ebfedea0SLionel Sambuc fprintf (stderr, "give only one of "
229ebfedea0SLionel Sambuc "--random-key, --random-password, --password, --key\n");
230ebfedea0SLionel Sambuc return 1;
231ebfedea0SLionel Sambuc }
232ebfedea0SLionel Sambuc
233ebfedea0SLionel Sambuc if (opt->key_string) {
234ebfedea0SLionel Sambuc const char *error;
235ebfedea0SLionel Sambuc
236ebfedea0SLionel Sambuc if (parse_des_key (opt->key_string, key_data, &error)) {
237ebfedea0SLionel Sambuc fprintf (stderr, "failed parsing key \"%s\": %s\n",
238ebfedea0SLionel Sambuc opt->key_string, error);
239ebfedea0SLionel Sambuc return 1;
240ebfedea0SLionel Sambuc }
241ebfedea0SLionel Sambuc kdp = key_data;
242ebfedea0SLionel Sambuc }
243ebfedea0SLionel Sambuc
244ebfedea0SLionel Sambuc for(i = 0; i < argc; i++) {
245ebfedea0SLionel Sambuc ret = add_one_principal (argv[i],
246ebfedea0SLionel Sambuc opt->random_key_flag,
247ebfedea0SLionel Sambuc opt->random_password_flag,
248ebfedea0SLionel Sambuc opt->use_defaults_flag,
249ebfedea0SLionel Sambuc opt->password_string,
250ebfedea0SLionel Sambuc kdp,
251ebfedea0SLionel Sambuc opt->max_ticket_life_string,
252ebfedea0SLionel Sambuc opt->max_renewable_life_string,
253ebfedea0SLionel Sambuc opt->attributes_string,
254ebfedea0SLionel Sambuc opt->expiration_time_string,
255ebfedea0SLionel Sambuc opt->pw_expiration_time_string);
256ebfedea0SLionel Sambuc if (ret) {
257ebfedea0SLionel Sambuc krb5_warn (context, ret, "adding %s", argv[i]);
258ebfedea0SLionel Sambuc break;
259ebfedea0SLionel Sambuc }
260ebfedea0SLionel Sambuc }
261ebfedea0SLionel Sambuc if (kdp) {
262ebfedea0SLionel Sambuc int16_t dummy = 3;
263ebfedea0SLionel Sambuc kadm5_free_key_data (kadm_handle, &dummy, key_data);
264ebfedea0SLionel Sambuc }
265ebfedea0SLionel Sambuc return ret != 0;
266ebfedea0SLionel Sambuc }
267