cf/largefile.m4: Fix build with autoconf-2.72
[heimdal.git] / admin / get.c
blob1c0a6333a5abe29be8218214319ace1acbe99d40
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 free(s);
113 s = tmp;
115 ret = krb5_string_to_keysalts2(context, s, nks, ks);
116 free(s);
117 return ret;
121 kt_get(struct get_options *opt, int argc, char **argv)
123 krb5_error_code ret = 0;
124 krb5_keytab keytab;
125 void *kadm_handle = NULL;
126 krb5_key_salt_tuple *ks = NULL;
127 size_t nks;
128 size_t i;
129 int a, j, keep;
130 unsigned int failed = 0;
132 i = 0;
133 keep = 1;
134 if (opt->keepallold_flag) {
135 keep = 2;
136 i++;
138 if (opt->keepold_flag) {
139 keep = 1;
140 i++;
142 if (opt->pruneall_flag) {
143 keep = 0;
144 i++;
146 if (i > 1) {
147 fprintf(stderr, "use only one of --keepold, --keepallold, or --pruneall\n");
148 return EINVAL;
151 if ((ret = parse_enctypes(opt, &nks, &ks))) {
152 fprintf(stderr, "invalid enctype(s)\n");
153 return ret;
156 if((keytab = ktutil_open_keytab()) == NULL) {
157 free(ks);
158 return 1;
161 if(opt->realm_string)
162 krb5_set_default_realm(context, opt->realm_string);
164 for(a = 0; a < argc; a++){
165 krb5_principal princ_ent;
166 kadm5_principal_ent_rec princ;
167 int mask = 0;
168 krb5_keyblock *keys;
169 int n_keys = 0;
170 int created = 0;
171 krb5_keytab_entry entry;
173 ret = krb5_parse_name(context, argv[a], &princ_ent);
174 if (ret) {
175 krb5_warn(context, ret, "can't parse principal %s", argv[a]);
176 failed++;
177 continue;
179 memset(&princ, 0, sizeof(princ));
180 princ.principal = princ_ent;
181 mask |= KADM5_PRINCIPAL;
182 princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
183 mask |= KADM5_ATTRIBUTES;
184 princ.princ_expire_time = 0;
185 mask |= KADM5_PRINC_EXPIRE_TIME;
187 if(kadm_handle == NULL) {
188 const char *r;
189 if(opt->realm_string != NULL)
190 r = opt->realm_string;
191 else
192 r = krb5_principal_get_realm(context, princ_ent);
193 kadm_handle = open_kadmin_connection(opt->principal_string,
195 opt->admin_server_string,
196 opt->server_port_integer);
197 if(kadm_handle == NULL)
198 break;
201 if (opt->create_flag) {
202 ret = kadm5_create_principal(kadm_handle, &princ, mask, "thisIs_aUseless.password123");
203 if(ret == 0)
204 created = 1;
205 else if(ret != KADM5_DUP) {
206 krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[a]);
207 krb5_free_principal(context, princ_ent);
208 failed++;
209 continue;
212 if (opt->change_keys_flag) {
213 ret = kadm5_randkey_principal_3(kadm_handle, princ_ent, keep, nks, ks,
214 &keys, &n_keys);
215 if (ret) {
216 krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]);
217 krb5_free_principal(context, princ_ent);
218 failed++;
219 continue;
223 ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
224 KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
225 if (ret) {
226 krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[a]);
227 for (j = 0; j < n_keys; j++)
228 krb5_free_keyblock_contents(context, &keys[j]);
229 krb5_free_principal(context, princ_ent);
230 failed++;
231 continue;
233 if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX))
234 krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[a]);
235 princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
236 mask = KADM5_ATTRIBUTES;
237 if(created) {
238 princ.kvno = 1;
239 mask |= KADM5_KVNO;
241 ret = kadm5_modify_principal(kadm_handle, &princ, mask);
242 if (ret) {
243 krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[a]);
244 for (j = 0; j < n_keys; j++)
245 krb5_free_keyblock_contents(context, &keys[j]);
246 krb5_free_principal(context, princ_ent);
247 failed++;
248 continue;
250 for(j = 0; j < n_keys; j++) {
251 entry.principal = princ_ent;
252 entry.vno = princ.kvno;
253 entry.keyblock = keys[j];
254 entry.timestamp = time (NULL);
255 ret = krb5_kt_add_entry(context, keytab, &entry);
256 if (ret)
257 krb5_warn(context, ret, "krb5_kt_add_entry");
258 krb5_free_keyblock_contents(context, &keys[j]);
261 kadm5_free_principal_ent(kadm_handle, &princ);
262 krb5_free_principal(context, princ_ent);
264 if (kadm_handle)
265 kadm5_destroy(kadm_handle);
266 krb5_kt_close(context, keytab);
267 free(ks);
268 return ret != 0 || failed > 0;