155682Smarkm/* 2233294Sstas * Copyright (c) 1997-2004 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "ktutil_locl.h" 3555682Smarkm 36233294SstasRCSID("$Id$"); 3755682Smarkm 3890926Snectarstatic void* 3990926Snectaropen_kadmin_connection(char *principal, 40233294Sstas const char *realm, 41233294Sstas char *admin_server, 4290926Snectar int server_port) 4390926Snectar{ 4490926Snectar static kadm5_config_params conf; 4590926Snectar krb5_error_code ret; 4690926Snectar void *kadm_handle; 4790926Snectar memset(&conf, 0, sizeof(conf)); 4890926Snectar 4990926Snectar if(realm) { 50178825Sdfr conf.realm = strdup(realm); 51178825Sdfr if (conf.realm == NULL) { 52233294Sstas krb5_set_error_message(context, 0, "malloc: out of memory"); 53178825Sdfr return NULL; 54178825Sdfr } 5590926Snectar conf.mask |= KADM5_CONFIG_REALM; 5690926Snectar } 57233294Sstas 5890926Snectar if (admin_server) { 5990926Snectar conf.admin_server = admin_server; 6090926Snectar conf.mask |= KADM5_CONFIG_ADMIN_SERVER; 6190926Snectar } 6290926Snectar 6390926Snectar if (server_port) { 6490926Snectar conf.kadmind_port = htons(server_port); 6590926Snectar conf.mask |= KADM5_CONFIG_KADMIND_PORT; 6690926Snectar } 6790926Snectar 6890926Snectar /* should get realm from each principal, instead of doing 6990926Snectar everything with the same (local) realm */ 7090926Snectar 71233294Sstas ret = kadm5_init_with_password_ctx(context, 7290926Snectar principal, 7390926Snectar NULL, 7490926Snectar KADM5_ADMIN_SERVICE, 75233294Sstas &conf, 0, 0, 7690926Snectar &kadm_handle); 77178825Sdfr free(conf.realm); 7890926Snectar if(ret) { 7990926Snectar krb5_warn(context, ret, "kadm5_init_with_password"); 8090926Snectar return NULL; 8190926Snectar } 8290926Snectar return kadm_handle; 8390926Snectar} 8490926Snectar 8555682Smarkmint 86178825Sdfrkt_get(struct get_options *opt, int argc, char **argv) 8755682Smarkm{ 8878527Sassar krb5_error_code ret = 0; 8978527Sassar krb5_keytab keytab; 9078527Sassar void *kadm_handle = NULL; 9178527Sassar krb5_enctype *etypes = NULL; 9278527Sassar size_t netypes = 0; 93233294Sstas size_t i; 94233294Sstas int a, j; 95178825Sdfr unsigned int failed = 0; 96233294Sstas 9790926Snectar if((keytab = ktutil_open_keytab()) == NULL) 9878527Sassar return 1; 9978527Sassar 100178825Sdfr if(opt->realm_string) 101178825Sdfr krb5_set_default_realm(context, opt->realm_string); 10290926Snectar 103178825Sdfr if (opt->enctypes_strings.num_strings != 0) { 10478527Sassar 105178825Sdfr etypes = malloc (opt->enctypes_strings.num_strings * sizeof(*etypes)); 10678527Sassar if (etypes == NULL) { 10778527Sassar krb5_warnx(context, "malloc failed"); 10878527Sassar goto out; 10978527Sassar } 110178825Sdfr netypes = opt->enctypes_strings.num_strings; 11178527Sassar for(i = 0; i < netypes; i++) { 112233294Sstas ret = krb5_string_to_enctype(context, 113233294Sstas opt->enctypes_strings.strings[i], 11478527Sassar &etypes[i]); 11578527Sassar if(ret) { 11678527Sassar krb5_warnx(context, "unrecognized enctype: %s", 117178825Sdfr opt->enctypes_strings.strings[i]); 11878527Sassar goto out; 11978527Sassar } 12078527Sassar } 12178527Sassar } 12278527Sassar 123233294Sstas 124233294Sstas for(a = 0; a < argc; a++){ 12555682Smarkm krb5_principal princ_ent; 12655682Smarkm kadm5_principal_ent_rec princ; 12755682Smarkm int mask = 0; 12855682Smarkm krb5_keyblock *keys; 12955682Smarkm int n_keys; 13055682Smarkm int created = 0; 13155682Smarkm krb5_keytab_entry entry; 13255682Smarkm 133233294Sstas ret = krb5_parse_name(context, argv[a], &princ_ent); 134142403Snectar if (ret) { 135233294Sstas krb5_warn(context, ret, "can't parse principal %s", argv[a]); 136178825Sdfr failed++; 137142403Snectar continue; 138142403Snectar } 13955682Smarkm memset(&princ, 0, sizeof(princ)); 14055682Smarkm princ.principal = princ_ent; 14155682Smarkm mask |= KADM5_PRINCIPAL; 14255682Smarkm princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; 14355682Smarkm mask |= KADM5_ATTRIBUTES; 14455682Smarkm princ.princ_expire_time = 0; 14555682Smarkm mask |= KADM5_PRINC_EXPIRE_TIME; 14690926Snectar 14790926Snectar if(kadm_handle == NULL) { 14890926Snectar const char *r; 149178825Sdfr if(opt->realm_string != NULL) 150178825Sdfr r = opt->realm_string; 15190926Snectar else 15290926Snectar r = krb5_principal_get_realm(context, princ_ent); 153233294Sstas kadm_handle = open_kadmin_connection(opt->principal_string, 154233294Sstas r, 155233294Sstas opt->admin_server_string, 156178825Sdfr opt->server_port_integer); 157178825Sdfr if(kadm_handle == NULL) 15890926Snectar break; 15990926Snectar } 160233294Sstas 16155682Smarkm ret = kadm5_create_principal(kadm_handle, &princ, mask, "x"); 16255682Smarkm if(ret == 0) 163178825Sdfr created = 1; 16455682Smarkm else if(ret != KADM5_DUP) { 165233294Sstas krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[a]); 16655682Smarkm krb5_free_principal(context, princ_ent); 167178825Sdfr failed++; 16855682Smarkm continue; 16955682Smarkm } 17055682Smarkm ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys); 17172445Sassar if (ret) { 172233294Sstas krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[a]); 17372445Sassar krb5_free_principal(context, princ_ent); 174178825Sdfr failed++; 17572445Sassar continue; 17672445Sassar } 177233294Sstas 178233294Sstas ret = kadm5_get_principal(kadm_handle, princ_ent, &princ, 17955682Smarkm KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES); 18072445Sassar if (ret) { 181233294Sstas krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[a]); 18272445Sassar for (j = 0; j < n_keys; j++) 18372445Sassar krb5_free_keyblock_contents(context, &keys[j]); 18472445Sassar krb5_free_principal(context, princ_ent); 185178825Sdfr failed++; 18672445Sassar continue; 18772445Sassar } 188178825Sdfr if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX)) 189233294Sstas krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[a]); 19055682Smarkm princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX); 19155682Smarkm mask = KADM5_ATTRIBUTES; 19255682Smarkm if(created) { 19355682Smarkm princ.kvno = 1; 19455682Smarkm mask |= KADM5_KVNO; 19555682Smarkm } 19655682Smarkm ret = kadm5_modify_principal(kadm_handle, &princ, mask); 19772445Sassar if (ret) { 198233294Sstas krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[a]); 19972445Sassar for (j = 0; j < n_keys; j++) 20072445Sassar krb5_free_keyblock_contents(context, &keys[j]); 20172445Sassar krb5_free_principal(context, princ_ent); 202178825Sdfr failed++; 20372445Sassar continue; 20472445Sassar } 20555682Smarkm for(j = 0; j < n_keys; j++) { 20678527Sassar int do_add = TRUE; 20778527Sassar 20878527Sassar if (netypes) { 209233294Sstas size_t k; 21078527Sassar 21178527Sassar do_add = FALSE; 212178825Sdfr for (k = 0; k < netypes; ++k) 213178825Sdfr if (keys[j].keytype == etypes[k]) { 21478527Sassar do_add = TRUE; 21578527Sassar break; 21678527Sassar } 21778527Sassar } 21878527Sassar if (do_add) { 21978527Sassar entry.principal = princ_ent; 22078527Sassar entry.vno = princ.kvno; 22178527Sassar entry.keyblock = keys[j]; 22278527Sassar entry.timestamp = time (NULL); 22378527Sassar ret = krb5_kt_add_entry(context, keytab, &entry); 22478527Sassar if (ret) 22578527Sassar krb5_warn(context, ret, "krb5_kt_add_entry"); 22678527Sassar } 22755682Smarkm krb5_free_keyblock_contents(context, &keys[j]); 22855682Smarkm } 229233294Sstas 23055682Smarkm kadm5_free_principal_ent(kadm_handle, &princ); 23155682Smarkm krb5_free_principal(context, princ_ent); 23255682Smarkm } 23378527Sassar out: 23478527Sassar free(etypes); 23578527Sassar if (kadm_handle) 23678527Sassar kadm5_destroy(kadm_handle); 23778527Sassar krb5_kt_close(context, keytab); 238178825Sdfr return ret != 0 || failed > 0; 23955682Smarkm} 240