1*e0895134Schristos /* $NetBSD: check.c,v 1.1.1.3 2017/01/28 20:46:42 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 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)); 56*e0895134Schristos 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 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 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 /* 190*e0895134Schristos * Check default@REALM 191*e0895134Schristos * 192*e0895134Schristos * Check that disallow-all-tix is set on the default principal 193*e0895134Schristos * (or that the entry doesn't exists) 194*e0895134Schristos */ 195*e0895134Schristos 196*e0895134Schristos if (asprintf(&p, "default@%s", realm) == -1) { 197*e0895134Schristos krb5_warn(context, errno, "asprintf"); 198*e0895134Schristos goto fail; 199*e0895134Schristos } 200*e0895134Schristos 201*e0895134Schristos ret = get_check_entry(p, &ent); 202*e0895134Schristos if (ret == 0) { 203*e0895134Schristos if ((ent.attributes & KRB5_KDB_DISALLOW_ALL_TIX) == 0) { 204*e0895134Schristos printf("default template entry is not disabled\n"); 205*e0895134Schristos ret = EINVAL; 206*e0895134Schristos } 207*e0895134Schristos kadm5_free_principal_ent(kadm_handle, &ent); 208*e0895134Schristos 209*e0895134Schristos } else { 210*e0895134Schristos ret = 0; 211*e0895134Schristos } 212*e0895134Schristos 213*e0895134Schristos free(p); 214*e0895134Schristos 215*e0895134Schristos if (ret) 216*e0895134Schristos goto fail; 217*e0895134Schristos 218*e0895134Schristos /* 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