xref: /freebsd-src/crypto/heimdal/kadmin/check.c (revision 6a068746777241722b2b32c5d0bc443a2a64d80b)
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