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