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