cf: check libdb-6 for db_create
[heimdal.git] / admin / get.c
blobf56e50f43599cbc0d25fd95fba2544fa667eba32
1 /*
2 * Copyright (c) 1997-2004 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 "ktutil_locl.h"
36 RCSID("$Id$");
38 static void*
39 open_kadmin_connection(char *principal,
40 const char *realm,
41 char *admin_server,
42 int server_port)
44 static kadm5_config_params conf;
45 krb5_error_code ret;
46 void *kadm_handle;
47 memset(&conf, 0, sizeof(conf));
49 if(realm) {
50 conf.realm = strdup(realm);
51 if (conf.realm == NULL) {
52 krb5_set_error_message(context, 0, "malloc: out of memory");
53 return NULL;
55 conf.mask |= KADM5_CONFIG_REALM;
58 if (admin_server) {
59 conf.admin_server = admin_server;
60 conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
63 if (server_port) {
64 conf.kadmind_port = htons(server_port);
65 conf.mask |= KADM5_CONFIG_KADMIND_PORT;
68 /* should get realm from each principal, instead of doing
69 everything with the same (local) realm */
71 ret = kadm5_init_with_password_ctx(context,
72 principal,
73 NULL,
74 KADM5_ADMIN_SERVICE,
75 &conf, 0, 0,
76 &kadm_handle);
77 free(conf.realm);
78 if(ret) {
79 krb5_warn(context, ret, "kadm5_init_with_password");
80 return NULL;
82 return kadm_handle;
85 static int
86 parse_enctypes(struct get_options *opt,
87 size_t *nks,
88 krb5_key_salt_tuple **ks)
90 const char *str;
91 char *s = NULL;
92 char *tmp;
93 size_t i;
94 int ret;
96 *nks = 0;
97 *ks = NULL;
98 if (opt->enctypes_strings.num_strings == 0) {
99 str = krb5_config_get_string(context, NULL, "libdefaults",
100 "supported_enctypes", NULL);
101 if (str == NULL)
102 str = "aes128-cts-hmac-sha1-96";
103 return krb5_string_to_keysalts2(context, str, nks, ks);
106 for (i = 0; i < opt->enctypes_strings.num_strings; i++) {
107 if (asprintf(&tmp, "%s%s%s", i ? s : "", i ? "," : "",
108 opt->enctypes_strings.strings[i]) == -1) {
109 free(s);
110 return krb5_enomem(context);
112 s = tmp;
114 ret = krb5_string_to_keysalts2(context, s, nks, ks);
115 free(s);
116 return ret;
120 kt_get(struct get_options *opt, int argc, char **argv)
122 krb5_error_code ret = 0;
123 krb5_keytab keytab;
124 void *kadm_handle = NULL;
125 krb5_key_salt_tuple *ks = NULL;
126 size_t nks;
127 size_t i;
128 int a, j, keep;
129 unsigned int failed = 0;
131 i = 0;
132 keep = 1;
133 if (opt->keepallold_flag) {
134 keep = 2;
135 i++;
137 if (opt->keepold_flag) {
138 keep = 1;
139 i++;
141 if (opt->pruneall_flag) {
142 keep = 0;
143 i++;
145 if (i > 1) {
146 fprintf(stderr, "use only one of --keepold, --keepallold, or --pruneall\n");
147 return EINVAL;
150 if ((ret = parse_enctypes(opt, &nks, &ks))) {
151 fprintf(stderr, "invalid enctype(s)\n");
152 return ret;
155 if((keytab = ktutil_open_keytab()) == NULL) {
156 free(ks);
157 return 1;
160 if(opt->realm_string)
161 krb5_set_default_realm(context, opt->realm_string);
163 for(a = 0; a < argc; a++){
164 krb5_principal princ_ent;
165 kadm5_principal_ent_rec princ;
166 int mask = 0;
167 krb5_keyblock *keys;
168 int n_keys;
169 int created = 0;
170 krb5_keytab_entry entry;
172 ret = krb5_parse_name(context, argv[a], &princ_ent);
173 if (ret) {
174 krb5_warn(context, ret, "can't parse principal %s", argv[a]);
175 failed++;
176 continue;
178 memset(&princ, 0, sizeof(princ));
179 princ.principal = princ_ent;
180 mask |= KADM5_PRINCIPAL;
181 princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
182 mask |= KADM5_ATTRIBUTES;
183 princ.princ_expire_time = 0;
184 mask |= KADM5_PRINC_EXPIRE_TIME;
186 if(kadm_handle == NULL) {
187 const char *r;
188 if(opt->realm_string != NULL)
189 r = opt->realm_string;
190 else
191 r = krb5_principal_get_realm(context, princ_ent);
192 kadm_handle = open_kadmin_connection(opt->principal_string,
194 opt->admin_server_string,
195 opt->server_port_integer);
196 if(kadm_handle == NULL)
197 break;
200 ret = kadm5_create_principal(kadm_handle, &princ, mask, "thisIs_aUseless.password123");
201 if(ret == 0)
202 created = 1;
203 else if(ret != KADM5_DUP) {
204 krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[a]);
205 krb5_free_principal(context, princ_ent);
206 failed++;
207 continue;
209 ret = kadm5_randkey_principal_3(kadm_handle, princ_ent, keep, nks, ks,
210 &keys, &n_keys);
211 if (ret) {
212 krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]);
213 krb5_free_principal(context, princ_ent);
214 failed++;
215 continue;
218 ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
219 KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
220 if (ret) {
221 krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[a]);
222 for (j = 0; j < n_keys; j++)
223 krb5_free_keyblock_contents(context, &keys[j]);
224 krb5_free_principal(context, princ_ent);
225 failed++;
226 continue;
228 if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX))
229 krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[a]);
230 princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
231 mask = KADM5_ATTRIBUTES;
232 if(created) {
233 princ.kvno = 1;
234 mask |= KADM5_KVNO;
236 ret = kadm5_modify_principal(kadm_handle, &princ, mask);
237 if (ret) {
238 krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[a]);
239 for (j = 0; j < n_keys; j++)
240 krb5_free_keyblock_contents(context, &keys[j]);
241 krb5_free_principal(context, princ_ent);
242 failed++;
243 continue;
245 for(j = 0; j < n_keys; j++) {
246 entry.principal = princ_ent;
247 entry.vno = princ.kvno;
248 entry.keyblock = keys[j];
249 entry.timestamp = time (NULL);
250 ret = krb5_kt_add_entry(context, keytab, &entry);
251 if (ret)
252 krb5_warn(context, ret, "krb5_kt_add_entry");
253 krb5_free_keyblock_contents(context, &keys[j]);
256 kadm5_free_principal_ent(kadm_handle, &princ);
257 krb5_free_principal(context, princ_ent);
259 if (kadm_handle)
260 kadm5_destroy(kadm_handle);
261 krb5_kt_close(context, keytab);
262 free(ks);
263 return ret != 0 || failed > 0;