155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2006 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 "kadmin_locl.h" 35178825Sdfr#include "kadmin-commands.h" 3655682Smarkm 37178825Sdfrstatic void 38178825Sdfradd_tl(kadm5_principal_ent_rec *princ, int type, krb5_data *data) 3955682Smarkm{ 40178825Sdfr krb5_tl_data *tl, **ptl; 4155682Smarkm 42178825Sdfr tl = ecalloc(1, sizeof(*tl)); 43178825Sdfr tl->tl_data_next = NULL; 44178825Sdfr tl->tl_data_type = KRB5_TL_EXTENSION; 45178825Sdfr tl->tl_data_length = data->length; 46178825Sdfr tl->tl_data_contents = data->data; 47233294Sstas 48178825Sdfr princ->n_tl_data++; 49178825Sdfr ptl = &princ->tl_data; 50178825Sdfr while (*ptl != NULL) 51178825Sdfr ptl = &(*ptl)->tl_data_next; 52178825Sdfr *ptl = tl; 5355682Smarkm 54178825Sdfr return; 55178825Sdfr} 5655682Smarkm 57178825Sdfrstatic void 58233294Sstasadd_constrained_delegation(krb5_context contextp, 59178825Sdfr kadm5_principal_ent_rec *princ, 60178825Sdfr struct getarg_strings *strings) 61178825Sdfr{ 62178825Sdfr krb5_error_code ret; 63178825Sdfr HDB_extension ext; 64178825Sdfr krb5_data buf; 65233294Sstas size_t size = 0; 66233294Sstas 67178825Sdfr memset(&ext, 0, sizeof(ext)); 68178825Sdfr ext.mandatory = FALSE; 69178825Sdfr ext.data.element = choice_HDB_extension_data_allowed_to_delegate_to; 7055682Smarkm 71178825Sdfr if (strings->num_strings == 1 && strings->strings[0][0] == '\0') { 72178825Sdfr ext.data.u.allowed_to_delegate_to.val = NULL; 73178825Sdfr ext.data.u.allowed_to_delegate_to.len = 0; 74178825Sdfr } else { 75178825Sdfr krb5_principal p; 76178825Sdfr int i; 77178825Sdfr 78233294Sstas ext.data.u.allowed_to_delegate_to.val = 79233294Sstas calloc(strings->num_strings, 80178825Sdfr sizeof(ext.data.u.allowed_to_delegate_to.val[0])); 81178825Sdfr ext.data.u.allowed_to_delegate_to.len = strings->num_strings; 82233294Sstas 83178825Sdfr for (i = 0; i < strings->num_strings; i++) { 84233294Sstas ret = krb5_parse_name(contextp, strings->strings[i], &p); 85233294Sstas if (ret) 86233294Sstas abort(); 87178825Sdfr ret = copy_Principal(p, &ext.data.u.allowed_to_delegate_to.val[i]); 88233294Sstas if (ret) 89233294Sstas abort(); 90233294Sstas krb5_free_principal(contextp, p); 91178825Sdfr } 9255682Smarkm } 93178825Sdfr 94178825Sdfr ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length, 95178825Sdfr &ext, &size, ret); 96178825Sdfr free_HDB_extension(&ext); 9755682Smarkm if (ret) 98178825Sdfr abort(); 99178825Sdfr if (buf.length != size) 100178825Sdfr abort(); 10172445Sassar 102178825Sdfr add_tl(princ, KRB5_TL_EXTENSION, &buf); 10355682Smarkm} 10455682Smarkm 105178825Sdfrstatic void 106233294Sstasadd_aliases(krb5_context contextp, kadm5_principal_ent_rec *princ, 107178825Sdfr struct getarg_strings *strings) 10855682Smarkm{ 10955682Smarkm krb5_error_code ret; 110178825Sdfr HDB_extension ext; 111178825Sdfr krb5_data buf; 112178825Sdfr krb5_principal p; 113233294Sstas size_t size = 0; 114178825Sdfr int i; 115233294Sstas 116178825Sdfr memset(&ext, 0, sizeof(ext)); 117178825Sdfr ext.mandatory = FALSE; 118178825Sdfr ext.data.element = choice_HDB_extension_data_aliases; 119178825Sdfr ext.data.u.aliases.case_insensitive = 0; 12055682Smarkm 121178825Sdfr if (strings->num_strings == 1 && strings->strings[0][0] == '\0') { 122178825Sdfr ext.data.u.aliases.aliases.val = NULL; 123178825Sdfr ext.data.u.aliases.aliases.len = 0; 124178825Sdfr } else { 125233294Sstas ext.data.u.aliases.aliases.val = 126233294Sstas calloc(strings->num_strings, 127178825Sdfr sizeof(ext.data.u.aliases.aliases.val[0])); 128178825Sdfr ext.data.u.aliases.aliases.len = strings->num_strings; 129233294Sstas 130178825Sdfr for (i = 0; i < strings->num_strings; i++) { 131233294Sstas ret = krb5_parse_name(contextp, strings->strings[i], &p); 132178825Sdfr ret = copy_Principal(p, &ext.data.u.aliases.aliases.val[i]); 133233294Sstas krb5_free_principal(contextp, p); 134178825Sdfr } 135178825Sdfr } 13655682Smarkm 137178825Sdfr ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length, 138178825Sdfr &ext, &size, ret); 139178825Sdfr free_HDB_extension(&ext); 14055682Smarkm if (ret) 141178825Sdfr abort(); 142178825Sdfr if (buf.length != size) 143178825Sdfr abort(); 144233294Sstas 145178825Sdfr add_tl(princ, KRB5_TL_EXTENSION, &buf); 146178825Sdfr} 14755682Smarkm 148178825Sdfrstatic void 149233294Sstasadd_pkinit_acl(krb5_context contextp, kadm5_principal_ent_rec *princ, 150178825Sdfr struct getarg_strings *strings) 151178825Sdfr{ 152178825Sdfr krb5_error_code ret; 153178825Sdfr HDB_extension ext; 154178825Sdfr krb5_data buf; 155233294Sstas size_t size = 0; 156178825Sdfr int i; 157233294Sstas 158178825Sdfr memset(&ext, 0, sizeof(ext)); 159178825Sdfr ext.mandatory = FALSE; 160178825Sdfr ext.data.element = choice_HDB_extension_data_pkinit_acl; 161178825Sdfr ext.data.u.aliases.case_insensitive = 0; 162178825Sdfr 163178825Sdfr if (strings->num_strings == 1 && strings->strings[0][0] == '\0') { 164178825Sdfr ext.data.u.pkinit_acl.val = NULL; 165178825Sdfr ext.data.u.pkinit_acl.len = 0; 166178825Sdfr } else { 167233294Sstas ext.data.u.pkinit_acl.val = 168233294Sstas calloc(strings->num_strings, 169178825Sdfr sizeof(ext.data.u.pkinit_acl.val[0])); 170178825Sdfr ext.data.u.pkinit_acl.len = strings->num_strings; 171233294Sstas 172178825Sdfr for (i = 0; i < strings->num_strings; i++) { 173178825Sdfr ext.data.u.pkinit_acl.val[i].subject = estrdup(strings->strings[i]); 174178825Sdfr } 17555682Smarkm } 17655682Smarkm 177178825Sdfr ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length, 178178825Sdfr &ext, &size, ret); 179178825Sdfr free_HDB_extension(&ext); 180178825Sdfr if (ret) 181178825Sdfr abort(); 182178825Sdfr if (buf.length != size) 183178825Sdfr abort(); 184233294Sstas 185178825Sdfr add_tl(princ, KRB5_TL_EXTENSION, &buf); 186178825Sdfr} 18755682Smarkm 188178825Sdfrstatic int 189178825Sdfrdo_mod_entry(krb5_principal principal, void *data) 190178825Sdfr{ 191178825Sdfr krb5_error_code ret; 192178825Sdfr kadm5_principal_ent_rec princ; 193178825Sdfr int mask = 0; 194178825Sdfr struct modify_options *e = data; 195233294Sstas 196178825Sdfr memset (&princ, 0, sizeof(princ)); 197178825Sdfr ret = kadm5_get_principal(kadm_handle, principal, &princ, 198233294Sstas KADM5_PRINCIPAL | KADM5_ATTRIBUTES | 199178825Sdfr KADM5_MAX_LIFE | KADM5_MAX_RLIFE | 200178825Sdfr KADM5_PRINC_EXPIRE_TIME | 201178825Sdfr KADM5_PW_EXPIRATION); 202233294Sstas if(ret) 203178825Sdfr return ret; 204178825Sdfr 205233294Sstas if(e->max_ticket_life_string || 206178825Sdfr e->max_renewable_life_string || 207178825Sdfr e->expiration_time_string || 208178825Sdfr e->pw_expiration_time_string || 209178825Sdfr e->attributes_string || 210178825Sdfr e->kvno_integer != -1 || 211178825Sdfr e->constrained_delegation_strings.num_strings || 212178825Sdfr e->alias_strings.num_strings || 213178825Sdfr e->pkinit_acl_strings.num_strings) { 214233294Sstas ret = set_entry(context, &princ, &mask, 215233294Sstas e->max_ticket_life_string, 216233294Sstas e->max_renewable_life_string, 217233294Sstas e->expiration_time_string, 218233294Sstas e->pw_expiration_time_string, 219178825Sdfr e->attributes_string); 220178825Sdfr if(e->kvno_integer != -1) { 221178825Sdfr princ.kvno = e->kvno_integer; 222178825Sdfr mask |= KADM5_KVNO; 22355682Smarkm } 224178825Sdfr if (e->constrained_delegation_strings.num_strings) { 225178825Sdfr add_constrained_delegation(context, &princ, 226178825Sdfr &e->constrained_delegation_strings); 227178825Sdfr mask |= KADM5_TL_DATA; 228178825Sdfr } 229178825Sdfr if (e->alias_strings.num_strings) { 230178825Sdfr add_aliases(context, &princ, &e->alias_strings); 231178825Sdfr mask |= KADM5_TL_DATA; 232178825Sdfr } 233178825Sdfr if (e->pkinit_acl_strings.num_strings) { 234178825Sdfr add_pkinit_acl(context, &princ, &e->pkinit_acl_strings); 235178825Sdfr mask |= KADM5_TL_DATA; 236178825Sdfr } 237178825Sdfr 238178825Sdfr } else 239178825Sdfr ret = edit_entry(&princ, &mask, NULL, 0); 240178825Sdfr if(ret == 0) { 241178825Sdfr ret = kadm5_modify_principal(kadm_handle, &princ, mask); 242178825Sdfr if(ret) 243178825Sdfr krb5_warn(context, ret, "kadm5_modify_principal"); 24455682Smarkm } 245233294Sstas 24655682Smarkm kadm5_free_principal_ent(kadm_handle, &princ); 247178825Sdfr return ret; 24855682Smarkm} 249178825Sdfr 250178825Sdfrint 251178825Sdfrmod_entry(struct modify_options *opt, int argc, char **argv) 252178825Sdfr{ 253178825Sdfr krb5_error_code ret = 0; 254178825Sdfr int i; 255178825Sdfr 256178825Sdfr for(i = 0; i < argc; i++) { 257178825Sdfr ret = foreach_principal(argv[i], do_mod_entry, "mod", opt); 258178825Sdfr if (ret) 259178825Sdfr break; 260178825Sdfr } 261178825Sdfr return ret != 0; 262178825Sdfr} 263178825Sdfr 264