155682Smarkm/* 2178825Sdfr * Copyright (c) 1997 - 2006 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "kadmin_locl.h" 35178825Sdfr#include "kadmin-commands.h" 3655682Smarkm 37178825SdfrRCSID("$Id: mod.c 21968 2007-10-18 18:50:33Z lha $"); 3855682Smarkm 39178825Sdfrstatic void 40178825Sdfradd_tl(kadm5_principal_ent_rec *princ, int type, krb5_data *data) 4155682Smarkm{ 42178825Sdfr krb5_tl_data *tl, **ptl; 4355682Smarkm 44178825Sdfr tl = ecalloc(1, sizeof(*tl)); 45178825Sdfr tl->tl_data_next = NULL; 46178825Sdfr tl->tl_data_type = KRB5_TL_EXTENSION; 47178825Sdfr tl->tl_data_length = data->length; 48178825Sdfr tl->tl_data_contents = data->data; 49178825Sdfr 50178825Sdfr princ->n_tl_data++; 51178825Sdfr ptl = &princ->tl_data; 52178825Sdfr while (*ptl != NULL) 53178825Sdfr ptl = &(*ptl)->tl_data_next; 54178825Sdfr *ptl = tl; 5555682Smarkm 56178825Sdfr return; 57178825Sdfr} 5855682Smarkm 59178825Sdfrstatic void 60178825Sdfradd_constrained_delegation(krb5_context context, 61178825Sdfr kadm5_principal_ent_rec *princ, 62178825Sdfr struct getarg_strings *strings) 63178825Sdfr{ 64178825Sdfr krb5_error_code ret; 65178825Sdfr HDB_extension ext; 66178825Sdfr krb5_data buf; 67178825Sdfr size_t size; 68178825Sdfr 69178825Sdfr memset(&ext, 0, sizeof(ext)); 70178825Sdfr ext.mandatory = FALSE; 71178825Sdfr ext.data.element = choice_HDB_extension_data_allowed_to_delegate_to; 7255682Smarkm 73178825Sdfr if (strings->num_strings == 1 && strings->strings[0][0] == '\0') { 74178825Sdfr ext.data.u.allowed_to_delegate_to.val = NULL; 75178825Sdfr ext.data.u.allowed_to_delegate_to.len = 0; 76178825Sdfr } else { 77178825Sdfr krb5_principal p; 78178825Sdfr int i; 79178825Sdfr 80178825Sdfr ext.data.u.allowed_to_delegate_to.val = 81178825Sdfr calloc(strings->num_strings, 82178825Sdfr sizeof(ext.data.u.allowed_to_delegate_to.val[0])); 83178825Sdfr ext.data.u.allowed_to_delegate_to.len = strings->num_strings; 84178825Sdfr 85178825Sdfr for (i = 0; i < strings->num_strings; i++) { 86178825Sdfr ret = krb5_parse_name(context, strings->strings[i], &p); 87178825Sdfr ret = copy_Principal(p, &ext.data.u.allowed_to_delegate_to.val[i]); 88178825Sdfr krb5_free_principal(context, p); 89178825Sdfr } 9055682Smarkm } 91178825Sdfr 92178825Sdfr ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length, 93178825Sdfr &ext, &size, ret); 94178825Sdfr free_HDB_extension(&ext); 9555682Smarkm if (ret) 96178825Sdfr abort(); 97178825Sdfr if (buf.length != size) 98178825Sdfr abort(); 9972445Sassar 100178825Sdfr add_tl(princ, KRB5_TL_EXTENSION, &buf); 10155682Smarkm} 10255682Smarkm 103178825Sdfrstatic void 104178825Sdfradd_aliases(krb5_context context, kadm5_principal_ent_rec *princ, 105178825Sdfr struct getarg_strings *strings) 10655682Smarkm{ 10755682Smarkm krb5_error_code ret; 108178825Sdfr HDB_extension ext; 109178825Sdfr krb5_data buf; 110178825Sdfr krb5_principal p; 111178825Sdfr size_t size; 112178825Sdfr int i; 113178825Sdfr 114178825Sdfr memset(&ext, 0, sizeof(ext)); 115178825Sdfr ext.mandatory = FALSE; 116178825Sdfr ext.data.element = choice_HDB_extension_data_aliases; 117178825Sdfr ext.data.u.aliases.case_insensitive = 0; 11855682Smarkm 119178825Sdfr if (strings->num_strings == 1 && strings->strings[0][0] == '\0') { 120178825Sdfr ext.data.u.aliases.aliases.val = NULL; 121178825Sdfr ext.data.u.aliases.aliases.len = 0; 122178825Sdfr } else { 123178825Sdfr ext.data.u.aliases.aliases.val = 124178825Sdfr calloc(strings->num_strings, 125178825Sdfr sizeof(ext.data.u.aliases.aliases.val[0])); 126178825Sdfr ext.data.u.aliases.aliases.len = strings->num_strings; 127178825Sdfr 128178825Sdfr for (i = 0; i < strings->num_strings; i++) { 129178825Sdfr ret = krb5_parse_name(context, strings->strings[i], &p); 130178825Sdfr ret = copy_Principal(p, &ext.data.u.aliases.aliases.val[i]); 131178825Sdfr krb5_free_principal(context, p); 132178825Sdfr } 133178825Sdfr } 13455682Smarkm 135178825Sdfr ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length, 136178825Sdfr &ext, &size, ret); 137178825Sdfr free_HDB_extension(&ext); 13855682Smarkm if (ret) 139178825Sdfr abort(); 140178825Sdfr if (buf.length != size) 141178825Sdfr abort(); 142178825Sdfr 143178825Sdfr add_tl(princ, KRB5_TL_EXTENSION, &buf); 144178825Sdfr} 14555682Smarkm 146178825Sdfrstatic void 147178825Sdfradd_pkinit_acl(krb5_context context, kadm5_principal_ent_rec *princ, 148178825Sdfr struct getarg_strings *strings) 149178825Sdfr{ 150178825Sdfr krb5_error_code ret; 151178825Sdfr HDB_extension ext; 152178825Sdfr krb5_data buf; 153178825Sdfr size_t size; 154178825Sdfr int i; 15555682Smarkm 156178825Sdfr memset(&ext, 0, sizeof(ext)); 157178825Sdfr ext.mandatory = FALSE; 158178825Sdfr ext.data.element = choice_HDB_extension_data_pkinit_acl; 159178825Sdfr ext.data.u.aliases.case_insensitive = 0; 160178825Sdfr 161178825Sdfr if (strings->num_strings == 1 && strings->strings[0][0] == '\0') { 162178825Sdfr ext.data.u.pkinit_acl.val = NULL; 163178825Sdfr ext.data.u.pkinit_acl.len = 0; 164178825Sdfr } else { 165178825Sdfr ext.data.u.pkinit_acl.val = 166178825Sdfr calloc(strings->num_strings, 167178825Sdfr sizeof(ext.data.u.pkinit_acl.val[0])); 168178825Sdfr ext.data.u.pkinit_acl.len = strings->num_strings; 169178825Sdfr 170178825Sdfr for (i = 0; i < strings->num_strings; i++) { 171178825Sdfr ext.data.u.pkinit_acl.val[i].subject = estrdup(strings->strings[i]); 172178825Sdfr } 17355682Smarkm } 17455682Smarkm 175178825Sdfr ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length, 176178825Sdfr &ext, &size, ret); 177178825Sdfr free_HDB_extension(&ext); 178178825Sdfr if (ret) 179178825Sdfr abort(); 180178825Sdfr if (buf.length != size) 181178825Sdfr abort(); 182178825Sdfr 183178825Sdfr add_tl(princ, KRB5_TL_EXTENSION, &buf); 184178825Sdfr} 18555682Smarkm 186178825Sdfrstatic int 187178825Sdfrdo_mod_entry(krb5_principal principal, void *data) 188178825Sdfr{ 189178825Sdfr krb5_error_code ret; 190178825Sdfr kadm5_principal_ent_rec princ; 191178825Sdfr int mask = 0; 192178825Sdfr struct modify_options *e = data; 193178825Sdfr 194178825Sdfr memset (&princ, 0, sizeof(princ)); 195178825Sdfr ret = kadm5_get_principal(kadm_handle, principal, &princ, 196178825Sdfr KADM5_PRINCIPAL | KADM5_ATTRIBUTES | 197178825Sdfr KADM5_MAX_LIFE | KADM5_MAX_RLIFE | 198178825Sdfr KADM5_PRINC_EXPIRE_TIME | 199178825Sdfr KADM5_PW_EXPIRATION); 200178825Sdfr if(ret) 201178825Sdfr return ret; 202178825Sdfr 203178825Sdfr if(e->max_ticket_life_string || 204178825Sdfr e->max_renewable_life_string || 205178825Sdfr e->expiration_time_string || 206178825Sdfr e->pw_expiration_time_string || 207178825Sdfr e->attributes_string || 208178825Sdfr e->kvno_integer != -1 || 209178825Sdfr e->constrained_delegation_strings.num_strings || 210178825Sdfr e->alias_strings.num_strings || 211178825Sdfr e->pkinit_acl_strings.num_strings) { 212178825Sdfr ret = set_entry(context, &princ, &mask, 213178825Sdfr e->max_ticket_life_string, 214178825Sdfr e->max_renewable_life_string, 215178825Sdfr e->expiration_time_string, 216178825Sdfr e->pw_expiration_time_string, 217178825Sdfr e->attributes_string); 218178825Sdfr if(e->kvno_integer != -1) { 219178825Sdfr princ.kvno = e->kvno_integer; 220178825Sdfr mask |= KADM5_KVNO; 22155682Smarkm } 222178825Sdfr if (e->constrained_delegation_strings.num_strings) { 223178825Sdfr add_constrained_delegation(context, &princ, 224178825Sdfr &e->constrained_delegation_strings); 225178825Sdfr mask |= KADM5_TL_DATA; 226178825Sdfr } 227178825Sdfr if (e->alias_strings.num_strings) { 228178825Sdfr add_aliases(context, &princ, &e->alias_strings); 229178825Sdfr mask |= KADM5_TL_DATA; 230178825Sdfr } 231178825Sdfr if (e->pkinit_acl_strings.num_strings) { 232178825Sdfr add_pkinit_acl(context, &princ, &e->pkinit_acl_strings); 233178825Sdfr mask |= KADM5_TL_DATA; 234178825Sdfr } 235178825Sdfr 236178825Sdfr } else 237178825Sdfr ret = edit_entry(&princ, &mask, NULL, 0); 238178825Sdfr if(ret == 0) { 239178825Sdfr ret = kadm5_modify_principal(kadm_handle, &princ, mask); 240178825Sdfr if(ret) 241178825Sdfr krb5_warn(context, ret, "kadm5_modify_principal"); 24255682Smarkm } 243178825Sdfr 24455682Smarkm kadm5_free_principal_ent(kadm_handle, &princ); 245178825Sdfr return ret; 24655682Smarkm} 247178825Sdfr 248178825Sdfrint 249178825Sdfrmod_entry(struct modify_options *opt, int argc, char **argv) 250178825Sdfr{ 251178825Sdfr krb5_error_code ret = 0; 252178825Sdfr int i; 253178825Sdfr 254178825Sdfr for(i = 0; i < argc; i++) { 255178825Sdfr ret = foreach_principal(argv[i], do_mod_entry, "mod", opt); 256178825Sdfr if (ret) 257178825Sdfr break; 258178825Sdfr } 259178825Sdfr return ret != 0; 260178825Sdfr} 261178825Sdfr 262