1c19800e8SDoug Rabson /*
2*ae771770SStanislav Sedov * Copyright (c) 2005 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson * All rights reserved.
5c19800e8SDoug Rabson *
6c19800e8SDoug Rabson * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson * are met:
9c19800e8SDoug Rabson *
10c19800e8SDoug Rabson * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson *
13c19800e8SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson * documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson *
17c19800e8SDoug Rabson * 3. Neither the name of the Institute nor the names of its contributors
18c19800e8SDoug Rabson * may be used to endorse or promote products derived from this software
19c19800e8SDoug Rabson * without specific prior written permission.
20c19800e8SDoug Rabson *
21c19800e8SDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22c19800e8SDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24c19800e8SDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25c19800e8SDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26c19800e8SDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27c19800e8SDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28c19800e8SDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29c19800e8SDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30c19800e8SDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31c19800e8SDoug Rabson * SUCH DAMAGE.
32c19800e8SDoug Rabson */
33c19800e8SDoug Rabson
34c19800e8SDoug Rabson /*
35c19800e8SDoug Rabson * Check database for strange configurations on default principals
36c19800e8SDoug Rabson */
37c19800e8SDoug Rabson
38c19800e8SDoug Rabson #include "kadmin_locl.h"
39c19800e8SDoug Rabson #include "kadmin-commands.h"
40c19800e8SDoug Rabson
41c19800e8SDoug Rabson static int
get_check_entry(const char * name,kadm5_principal_ent_rec * ent)42c19800e8SDoug Rabson get_check_entry(const char *name, kadm5_principal_ent_rec *ent)
43c19800e8SDoug Rabson {
44c19800e8SDoug Rabson krb5_error_code ret;
45c19800e8SDoug Rabson krb5_principal principal;
46c19800e8SDoug Rabson
47c19800e8SDoug Rabson ret = krb5_parse_name(context, name, &principal);
48c19800e8SDoug Rabson if (ret) {
49c19800e8SDoug Rabson krb5_warn(context, ret, "krb5_unparse_name: %s", name);
50c19800e8SDoug Rabson return 1;
51c19800e8SDoug Rabson }
52c19800e8SDoug Rabson
53c19800e8SDoug Rabson memset(ent, 0, sizeof(*ent));
54c19800e8SDoug Rabson ret = kadm5_get_principal(kadm_handle, principal, ent, 0);
55c19800e8SDoug Rabson krb5_free_principal(context, principal);
56c19800e8SDoug Rabson if(ret)
57c19800e8SDoug Rabson return 1;
58c19800e8SDoug Rabson
59c19800e8SDoug Rabson return 0;
60c19800e8SDoug Rabson }
61c19800e8SDoug Rabson
62c19800e8SDoug Rabson
63c19800e8SDoug Rabson static int
do_check_entry(krb5_principal principal,void * data)64c19800e8SDoug Rabson do_check_entry(krb5_principal principal, void *data)
65c19800e8SDoug Rabson {
66c19800e8SDoug Rabson krb5_error_code ret;
67c19800e8SDoug Rabson kadm5_principal_ent_rec princ;
68c19800e8SDoug Rabson char *name;
69c19800e8SDoug Rabson int i;
70c19800e8SDoug Rabson
71c19800e8SDoug Rabson ret = krb5_unparse_name(context, principal, &name);
72c19800e8SDoug Rabson if (ret)
73c19800e8SDoug Rabson return 1;
74c19800e8SDoug Rabson
75c19800e8SDoug Rabson memset (&princ, 0, sizeof(princ));
76c19800e8SDoug Rabson ret = kadm5_get_principal(kadm_handle, principal, &princ,
77c19800e8SDoug Rabson KADM5_PRINCIPAL | KADM5_KEY_DATA);
78c19800e8SDoug Rabson if(ret) {
79c19800e8SDoug Rabson krb5_warn(context, ret, "Failed to get principal: %s", name);
80c19800e8SDoug Rabson free(name);
81c19800e8SDoug Rabson return 0;
82c19800e8SDoug Rabson }
83c19800e8SDoug Rabson
84c19800e8SDoug Rabson for (i = 0; i < princ.n_key_data; i++) {
85c19800e8SDoug Rabson size_t keysize;
86c19800e8SDoug Rabson ret = krb5_enctype_keysize(context,
87c19800e8SDoug Rabson princ.key_data[i].key_data_type[0],
88c19800e8SDoug Rabson &keysize);
89*ae771770SStanislav Sedov if (ret == 0 && keysize != (size_t)princ.key_data[i].key_data_length[0]) {
90c19800e8SDoug Rabson krb5_warnx(context,
91c19800e8SDoug Rabson "Principal %s enctype %d, wrong length: %lu\n",
92c19800e8SDoug Rabson name, princ.key_data[i].key_data_type[0],
93c19800e8SDoug Rabson (unsigned long)princ.key_data[i].key_data_length);
94c19800e8SDoug Rabson }
95c19800e8SDoug Rabson }
96c19800e8SDoug Rabson
97c19800e8SDoug Rabson free(name);
98c19800e8SDoug Rabson kadm5_free_principal_ent(kadm_handle, &princ);
99c19800e8SDoug Rabson
100c19800e8SDoug Rabson return 0;
101c19800e8SDoug Rabson }
102c19800e8SDoug Rabson
103c19800e8SDoug Rabson int
check(void * opt,int argc,char ** argv)104c19800e8SDoug Rabson check(void *opt, int argc, char **argv)
105c19800e8SDoug Rabson {
106c19800e8SDoug Rabson kadm5_principal_ent_rec ent;
107c19800e8SDoug Rabson krb5_error_code ret;
108c19800e8SDoug Rabson char *realm = NULL, *p, *p2;
109c19800e8SDoug Rabson int found;
110c19800e8SDoug Rabson
111c19800e8SDoug Rabson if (argc == 0) {
112c19800e8SDoug Rabson ret = krb5_get_default_realm(context, &realm);
113c19800e8SDoug Rabson if (ret) {
114c19800e8SDoug Rabson krb5_warn(context, ret, "krb5_get_default_realm");
115c19800e8SDoug Rabson goto fail;
116c19800e8SDoug Rabson }
117c19800e8SDoug Rabson } else {
118c19800e8SDoug Rabson realm = strdup(argv[0]);
119c19800e8SDoug Rabson if (realm == NULL) {
120c19800e8SDoug Rabson krb5_warnx(context, "malloc");
121c19800e8SDoug Rabson goto fail;
122c19800e8SDoug Rabson }
123c19800e8SDoug Rabson }
124c19800e8SDoug Rabson
125c19800e8SDoug Rabson /*
126c19800e8SDoug Rabson * Check krbtgt/REALM@REALM
127c19800e8SDoug Rabson *
128c19800e8SDoug Rabson * For now, just check existance
129c19800e8SDoug Rabson */
130c19800e8SDoug Rabson
131c19800e8SDoug Rabson if (asprintf(&p, "%s/%s@%s", KRB5_TGS_NAME, realm, realm) == -1) {
132c19800e8SDoug Rabson krb5_warn(context, errno, "asprintf");
133c19800e8SDoug Rabson goto fail;
134c19800e8SDoug Rabson }
135c19800e8SDoug Rabson
136c19800e8SDoug Rabson ret = get_check_entry(p, &ent);
137c19800e8SDoug Rabson if (ret) {
138c19800e8SDoug Rabson printf("%s doesn't exist, are you sure %s is a realm in your database",
139c19800e8SDoug Rabson p, realm);
140c19800e8SDoug Rabson free(p);
141c19800e8SDoug Rabson goto fail;
142c19800e8SDoug Rabson }
143c19800e8SDoug Rabson free(p);
144c19800e8SDoug Rabson
145c19800e8SDoug Rabson kadm5_free_principal_ent(kadm_handle, &ent);
146c19800e8SDoug Rabson
147c19800e8SDoug Rabson /*
148c19800e8SDoug Rabson * Check kadmin/admin@REALM
149c19800e8SDoug Rabson */
150c19800e8SDoug Rabson
151c19800e8SDoug Rabson if (asprintf(&p, "kadmin/admin@%s", realm) == -1) {
152c19800e8SDoug Rabson krb5_warn(context, errno, "asprintf");
153c19800e8SDoug Rabson goto fail;
154c19800e8SDoug Rabson }
155c19800e8SDoug Rabson
156c19800e8SDoug Rabson ret = get_check_entry(p, &ent);
157c19800e8SDoug Rabson if (ret) {
158c19800e8SDoug Rabson printf("%s doesn't exist, "
159c19800e8SDoug Rabson "there is no way to do remote administration", p);
160c19800e8SDoug Rabson free(p);
161c19800e8SDoug Rabson goto fail;
162c19800e8SDoug Rabson }
163c19800e8SDoug Rabson free(p);
164c19800e8SDoug Rabson
165c19800e8SDoug Rabson kadm5_free_principal_ent(kadm_handle, &ent);
166c19800e8SDoug Rabson
167c19800e8SDoug Rabson /*
168c19800e8SDoug Rabson * Check kadmin/changepw@REALM
169c19800e8SDoug Rabson */
170c19800e8SDoug Rabson
171c19800e8SDoug Rabson if (asprintf(&p, "kadmin/changepw@%s", realm) == -1) {
172c19800e8SDoug Rabson krb5_warn(context, errno, "asprintf");
173c19800e8SDoug Rabson goto fail;
174c19800e8SDoug Rabson }
175c19800e8SDoug Rabson
176c19800e8SDoug Rabson ret = get_check_entry(p, &ent);
177c19800e8SDoug Rabson if (ret) {
178c19800e8SDoug Rabson printf("%s doesn't exist, "
179c19800e8SDoug Rabson "there is no way to do change password", p);
180c19800e8SDoug Rabson free(p);
181c19800e8SDoug Rabson goto fail;
182c19800e8SDoug Rabson }
183c19800e8SDoug Rabson free(p);
184c19800e8SDoug Rabson
185c19800e8SDoug Rabson kadm5_free_principal_ent(kadm_handle, &ent);
186c19800e8SDoug Rabson
187c19800e8SDoug Rabson /*
188c19800e8SDoug Rabson * Check for duplicate afs keys
189c19800e8SDoug Rabson */
190c19800e8SDoug Rabson
191c19800e8SDoug Rabson p2 = strdup(realm);
192c19800e8SDoug Rabson if (p2 == NULL) {
193c19800e8SDoug Rabson krb5_warn(context, errno, "malloc");
194c19800e8SDoug Rabson goto fail;
195c19800e8SDoug Rabson }
196c19800e8SDoug Rabson strlwr(p2);
197c19800e8SDoug Rabson
198c19800e8SDoug Rabson if (asprintf(&p, "afs/%s@%s", p2, realm) == -1) {
199c19800e8SDoug Rabson krb5_warn(context, errno, "asprintf");
200c19800e8SDoug Rabson free(p2);
201c19800e8SDoug Rabson goto fail;
202c19800e8SDoug Rabson }
203c19800e8SDoug Rabson free(p2);
204c19800e8SDoug Rabson
205c19800e8SDoug Rabson ret = get_check_entry(p, &ent);
206c19800e8SDoug Rabson free(p);
207c19800e8SDoug Rabson if (ret == 0) {
208c19800e8SDoug Rabson kadm5_free_principal_ent(kadm_handle, &ent);
209c19800e8SDoug Rabson found = 1;
210c19800e8SDoug Rabson } else
211c19800e8SDoug Rabson found = 0;
212c19800e8SDoug Rabson
213c19800e8SDoug Rabson if (asprintf(&p, "afs@%s", realm) == -1) {
214c19800e8SDoug Rabson krb5_warn(context, errno, "asprintf");
215c19800e8SDoug Rabson goto fail;
216c19800e8SDoug Rabson }
217c19800e8SDoug Rabson
218c19800e8SDoug Rabson ret = get_check_entry(p, &ent);
219c19800e8SDoug Rabson free(p);
220c19800e8SDoug Rabson if (ret == 0) {
221c19800e8SDoug Rabson kadm5_free_principal_ent(kadm_handle, &ent);
222c19800e8SDoug Rabson if (found) {
223c19800e8SDoug Rabson krb5_warnx(context, "afs@REALM and afs/cellname@REALM both exists");
224c19800e8SDoug Rabson goto fail;
225c19800e8SDoug Rabson }
226c19800e8SDoug Rabson }
227c19800e8SDoug Rabson
228c19800e8SDoug Rabson foreach_principal("*", do_check_entry, "check", NULL);
229c19800e8SDoug Rabson
230c19800e8SDoug Rabson free(realm);
231c19800e8SDoug Rabson return 0;
232c19800e8SDoug Rabson fail:
233c19800e8SDoug Rabson free(realm);
234c19800e8SDoug Rabson return 1;
235c19800e8SDoug Rabson }
236