get.c revision 178826
11590Srgrimes/* 21590Srgrimes * Copyright (c) 1997-2004 Kungliga Tekniska H�gskolan 31590Srgrimes * (Royal Institute of Technology, Stockholm, Sweden). 41590Srgrimes * All rights reserved. 51590Srgrimes * 61590Srgrimes * Redistribution and use in source and binary forms, with or without 71590Srgrimes * modification, are permitted provided that the following conditions 81590Srgrimes * are met: 91590Srgrimes * 101590Srgrimes * 1. Redistributions of source code must retain the above copyright 111590Srgrimes * notice, this list of conditions and the following disclaimer. 121590Srgrimes * 131590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141590Srgrimes * notice, this list of conditions and the following disclaimer in the 151590Srgrimes * documentation and/or other materials provided with the distribution. 161590Srgrimes * 171590Srgrimes * 3. Neither the name of the Institute nor the names of its contributors 181590Srgrimes * may be used to endorse or promote products derived from this software 191590Srgrimes * without specific prior written permission. 201590Srgrimes * 211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241590Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311590Srgrimes * SUCH DAMAGE. 321590Srgrimes */ 331590Srgrimes 341590Srgrimes#include "ktutil_locl.h" 351590Srgrimes 361590SrgrimesRCSID("$Id: get.c 15583 2005-07-07 21:44:37Z lha $"); 371590Srgrimes 3898552Smarkmstatic void* 391590Srgrimesopen_kadmin_connection(char *principal, 401590Srgrimes const char *realm, 411590Srgrimes char *admin_server, 4298552Smarkm int server_port) 431590Srgrimes{ 4498552Smarkm static kadm5_config_params conf; 4598552Smarkm krb5_error_code ret; 4698552Smarkm void *kadm_handle; 471590Srgrimes memset(&conf, 0, sizeof(conf)); 481590Srgrimes 491590Srgrimes if(realm) { 501590Srgrimes conf.realm = strdup(realm); 51204359Sed if (conf.realm == NULL) { 52204359Sed krb5_set_error_string(context, "malloc: out of memory"); 531590Srgrimes return NULL; 541590Srgrimes } 551590Srgrimes conf.mask |= KADM5_CONFIG_REALM; 561590Srgrimes } 571590Srgrimes 581590Srgrimes if (admin_server) { 591590Srgrimes conf.admin_server = admin_server; 601590Srgrimes conf.mask |= KADM5_CONFIG_ADMIN_SERVER; 611590Srgrimes } 621590Srgrimes 631590Srgrimes if (server_port) { 641590Srgrimes conf.kadmind_port = htons(server_port); 651590Srgrimes conf.mask |= KADM5_CONFIG_KADMIND_PORT; 661590Srgrimes } 671590Srgrimes 681590Srgrimes /* should get realm from each principal, instead of doing 691590Srgrimes everything with the same (local) realm */ 701590Srgrimes 711590Srgrimes ret = kadm5_init_with_password_ctx(context, 7298552Smarkm principal, 7398552Smarkm NULL, 741590Srgrimes KADM5_ADMIN_SERVICE, 7598552Smarkm &conf, 0, 0, 761590Srgrimes &kadm_handle); 7798552Smarkm free(conf.realm); 7898552Smarkm if(ret) { 791590Srgrimes krb5_warn(context, ret, "kadm5_init_with_password"); 8098552Smarkm return NULL; 811590Srgrimes } 821590Srgrimes return kadm_handle; 831590Srgrimes} 841590Srgrimes 851590Srgrimesint 861590Srgrimeskt_get(struct get_options *opt, int argc, char **argv) 871590Srgrimes{ 881590Srgrimes krb5_error_code ret = 0; 891590Srgrimes krb5_keytab keytab; 901590Srgrimes void *kadm_handle = NULL; 911590Srgrimes krb5_enctype *etypes = NULL; 921590Srgrimes size_t netypes = 0; 931590Srgrimes int i, j; 9498552Smarkm unsigned int failed = 0; 9598698Scharnier 961590Srgrimes if((keytab = ktutil_open_keytab()) == NULL) 971590Srgrimes return 1; 981590Srgrimes 991590Srgrimes if(opt->realm_string) 1001590Srgrimes krb5_set_default_realm(context, opt->realm_string); 1011590Srgrimes 1021590Srgrimes if (opt->enctypes_strings.num_strings != 0) { 1031590Srgrimes 10498552Smarkm etypes = malloc (opt->enctypes_strings.num_strings * sizeof(*etypes)); 10598698Scharnier if (etypes == NULL) { 1061590Srgrimes krb5_warnx(context, "malloc failed"); 1071590Srgrimes goto out; 1081590Srgrimes } 1091590Srgrimes netypes = opt->enctypes_strings.num_strings; 1101590Srgrimes for(i = 0; i < netypes; i++) { 1111590Srgrimes ret = krb5_string_to_enctype(context, 1121590Srgrimes opt->enctypes_strings.strings[i], 1131590Srgrimes &etypes[i]); 1141590Srgrimes if(ret) { 1151590Srgrimes krb5_warnx(context, "unrecognized enctype: %s", 11698698Scharnier opt->enctypes_strings.strings[i]); 1171590Srgrimes goto out; 1181590Srgrimes } 11998698Scharnier } 1201590Srgrimes } 1211590Srgrimes 1221590Srgrimes 1231590Srgrimes for(i = 0; i < argc; i++){ 1241590Srgrimes krb5_principal princ_ent; 1251590Srgrimes kadm5_principal_ent_rec princ; 1261590Srgrimes int mask = 0; 1271590Srgrimes krb5_keyblock *keys; 1281590Srgrimes int n_keys; 1291590Srgrimes int created = 0; 1301590Srgrimes krb5_keytab_entry entry; 1311590Srgrimes 1321590Srgrimes ret = krb5_parse_name(context, argv[i], &princ_ent); 13398552Smarkm if (ret) { 1341590Srgrimes krb5_warn(context, ret, "can't parse principal %s", argv[i]); 1351590Srgrimes failed++; 1361590Srgrimes continue; 1371590Srgrimes } 1381590Srgrimes memset(&princ, 0, sizeof(princ)); 1391590Srgrimes princ.principal = princ_ent; 1401590Srgrimes mask |= KADM5_PRINCIPAL; 1411590Srgrimes princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX; 1421590Srgrimes mask |= KADM5_ATTRIBUTES; 1431590Srgrimes princ.princ_expire_time = 0; 1441590Srgrimes mask |= KADM5_PRINC_EXPIRE_TIME; 1451590Srgrimes 1461590Srgrimes if(kadm_handle == NULL) { 1471590Srgrimes const char *r; 1481590Srgrimes if(opt->realm_string != NULL) 1491590Srgrimes r = opt->realm_string; 1501590Srgrimes else 1511590Srgrimes r = krb5_principal_get_realm(context, princ_ent); 1521590Srgrimes kadm_handle = open_kadmin_connection(opt->principal_string, 1531590Srgrimes r, 1541590Srgrimes opt->admin_server_string, 1551590Srgrimes opt->server_port_integer); 1561590Srgrimes if(kadm_handle == NULL) 1571590Srgrimes break; 1581590Srgrimes } 1591590Srgrimes 1601590Srgrimes ret = kadm5_create_principal(kadm_handle, &princ, mask, "x"); 1611590Srgrimes if(ret == 0) 1621590Srgrimes created = 1; 1631590Srgrimes else if(ret != KADM5_DUP) { 1641590Srgrimes krb5_warn(context, ret, "kadm5_create_principal(%s)", argv[i]); 1651590Srgrimes krb5_free_principal(context, princ_ent); 1661590Srgrimes failed++; 1671590Srgrimes continue; 1681590Srgrimes } 1691590Srgrimes ret = kadm5_randkey_principal(kadm_handle, princ_ent, &keys, &n_keys); 1701590Srgrimes if (ret) { 1711590Srgrimes krb5_warn(context, ret, "kadm5_randkey_principal(%s)", argv[i]); 1721590Srgrimes krb5_free_principal(context, princ_ent); 1731590Srgrimes failed++; 1741590Srgrimes continue; 1751590Srgrimes } 1761590Srgrimes 1771590Srgrimes ret = kadm5_get_principal(kadm_handle, princ_ent, &princ, 1781590Srgrimes KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES); 1791590Srgrimes if (ret) { 1801590Srgrimes krb5_warn(context, ret, "kadm5_get_principal(%s)", argv[i]); 1811590Srgrimes for (j = 0; j < n_keys; j++) 1821590Srgrimes krb5_free_keyblock_contents(context, &keys[j]); 1831590Srgrimes krb5_free_principal(context, princ_ent); 1841590Srgrimes failed++; 1851590Srgrimes continue; 1861590Srgrimes } 1871590Srgrimes if(!created && (princ.attributes & KRB5_KDB_DISALLOW_ALL_TIX)) 1881590Srgrimes krb5_warnx(context, "%s: disallow-all-tix flag set - clearing", argv[i]); 1891590Srgrimes princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX); 1901590Srgrimes mask = KADM5_ATTRIBUTES; 1911590Srgrimes if(created) { 1921590Srgrimes princ.kvno = 1; 1931590Srgrimes mask |= KADM5_KVNO; 1941590Srgrimes } 1951590Srgrimes ret = kadm5_modify_principal(kadm_handle, &princ, mask); 1961590Srgrimes if (ret) { 19798552Smarkm krb5_warn(context, ret, "kadm5_modify_principal(%s)", argv[i]); 1981590Srgrimes for (j = 0; j < n_keys; j++) 1991590Srgrimes krb5_free_keyblock_contents(context, &keys[j]); 2001590Srgrimes krb5_free_principal(context, princ_ent); 2011590Srgrimes failed++; 2021590Srgrimes continue; 2031590Srgrimes } 2041590Srgrimes for(j = 0; j < n_keys; j++) { 2051590Srgrimes int do_add = TRUE; 2061590Srgrimes 2071590Srgrimes if (netypes) { 2081590Srgrimes int k; 2091590Srgrimes 2101590Srgrimes do_add = FALSE; 2111590Srgrimes for (k = 0; k < netypes; ++k) 2121590Srgrimes if (keys[j].keytype == etypes[k]) { 2131590Srgrimes do_add = TRUE; 21498552Smarkm break; 2151590Srgrimes } 2161590Srgrimes } 2171590Srgrimes if (do_add) { 218 entry.principal = princ_ent; 219 entry.vno = princ.kvno; 220 entry.keyblock = keys[j]; 221 entry.timestamp = time (NULL); 222 ret = krb5_kt_add_entry(context, keytab, &entry); 223 if (ret) 224 krb5_warn(context, ret, "krb5_kt_add_entry"); 225 } 226 krb5_free_keyblock_contents(context, &keys[j]); 227 } 228 229 kadm5_free_principal_ent(kadm_handle, &princ); 230 krb5_free_principal(context, princ_ent); 231 } 232 out: 233 free(etypes); 234 if (kadm_handle) 235 kadm5_destroy(kadm_handle); 236 krb5_kt_close(context, keytab); 237 return ret != 0 || failed > 0; 238} 239