Home | History | Annotate | Line # | Download | only in kadmin
      1 /*	$NetBSD: mod.c,v 1.3 2023/06/19 21:41:41 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997 - 2006 Kungliga Tekniska Hgskolan
      5  * (Royal Institute of Technology, Stockholm, Sweden).
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * 3. Neither the name of the Institute nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #include "kadmin_locl.h"
     37 #include "kadmin-commands.h"
     38 
     39 static void
     40 add_tl(kadm5_principal_ent_rec *princ, int type, krb5_data *data)
     41 {
     42     krb5_tl_data *tl, **ptl;
     43 
     44     tl = ecalloc(1, sizeof(*tl));
     45     tl->tl_data_next = NULL;
     46     tl->tl_data_type = type;
     47     tl->tl_data_length = data->length;
     48     tl->tl_data_contents = data->data;
     49 
     50     princ->n_tl_data++;
     51     ptl = &princ->tl_data;
     52     while (*ptl != NULL)
     53 	ptl = &(*ptl)->tl_data_next;
     54     *ptl = tl;
     55 
     56     return;
     57 }
     58 
     59 static void
     60 add_constrained_delegation(krb5_context contextp,
     61 			   kadm5_principal_ent_rec *princ,
     62 			   struct getarg_strings *strings)
     63 {
     64     krb5_error_code ret;
     65     HDB_extension ext;
     66     krb5_data buf;
     67     size_t size = 0;
     68 
     69     memset(&ext, 0, sizeof(ext));
     70     ext.mandatory = FALSE;
     71     ext.data.element = choice_HDB_extension_data_allowed_to_delegate_to;
     72 
     73     if (strings->num_strings == 1 && strings->strings[0][0] == '\0') {
     74 	ext.data.u.allowed_to_delegate_to.val = NULL;
     75 	ext.data.u.allowed_to_delegate_to.len = 0;
     76     } else {
     77 	krb5_principal p;
     78 	int i;
     79 
     80 	ext.data.u.allowed_to_delegate_to.val =
     81 	    calloc(strings->num_strings,
     82 		   sizeof(ext.data.u.allowed_to_delegate_to.val[0]));
     83 	ext.data.u.allowed_to_delegate_to.len = strings->num_strings;
     84 
     85 	for (i = 0; i < strings->num_strings; i++) {
     86 	    ret = krb5_parse_name(contextp, strings->strings[i], &p);
     87 	    if (ret)
     88 		abort();
     89 	    ret = copy_Principal(p, &ext.data.u.allowed_to_delegate_to.val[i]);
     90 	    if (ret)
     91 		abort();
     92 	    krb5_free_principal(contextp, p);
     93 	}
     94     }
     95 
     96     ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
     97 		       &ext, &size, ret);
     98     free_HDB_extension(&ext);
     99     if (ret)
    100 	abort();
    101     if (buf.length != size)
    102 	abort();
    103 
    104     add_tl(princ, KRB5_TL_EXTENSION, &buf);
    105 }
    106 
    107 static void
    108 add_aliases(krb5_context contextp, kadm5_principal_ent_rec *princ,
    109 	    struct getarg_strings *strings)
    110 {
    111     krb5_error_code ret = 0;
    112     HDB_extension ext;
    113     krb5_data buf;
    114     krb5_principal p;
    115     size_t size = 0;
    116     int i;
    117 
    118     memset(&ext, 0, sizeof(ext));
    119     ext.mandatory = FALSE;
    120     ext.data.element = choice_HDB_extension_data_aliases;
    121     ext.data.u.aliases.case_insensitive = 0;
    122 
    123     if (strings->num_strings == 1 && strings->strings[0][0] == '\0') {
    124 	ext.data.u.aliases.aliases.val = NULL;
    125 	ext.data.u.aliases.aliases.len = 0;
    126     } else {
    127 	ext.data.u.aliases.aliases.val =
    128 	    calloc(strings->num_strings,
    129 		   sizeof(ext.data.u.aliases.aliases.val[0]));
    130 	ext.data.u.aliases.aliases.len = strings->num_strings;
    131 
    132 	for (i = 0; ret == 0 && i < strings->num_strings; i++) {
    133 	    ret = krb5_parse_name(contextp, strings->strings[i], &p);
    134             if (ret)
    135                 krb5_err(contextp, 1, ret, "Could not parse alias %s",
    136                          strings->strings[i]);
    137             if (ret == 0)
    138                 ret = copy_Principal(p, &ext.data.u.aliases.aliases.val[i]);
    139             if (ret)
    140                 krb5_err(contextp, 1, ret, "Could not copy parsed alias %s",
    141                          strings->strings[i]);
    142 	    krb5_free_principal(contextp, p);
    143 	}
    144     }
    145 
    146     ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
    147 		       &ext, &size, ret);
    148     free_HDB_extension(&ext);
    149     if (ret)
    150 	abort();
    151     if (buf.length != size)
    152 	abort();
    153 
    154     add_tl(princ, KRB5_TL_EXTENSION, &buf);
    155 }
    156 
    157 static void
    158 add_pkinit_acl(krb5_context contextp, kadm5_principal_ent_rec *princ,
    159 	       struct getarg_strings *strings)
    160 {
    161     krb5_error_code ret;
    162     HDB_extension ext;
    163     krb5_data buf;
    164     size_t size = 0;
    165     int i;
    166 
    167     memset(&ext, 0, sizeof(ext));
    168     ext.mandatory = FALSE;
    169     ext.data.element = choice_HDB_extension_data_pkinit_acl;
    170     ext.data.u.aliases.case_insensitive = 0;
    171 
    172     if (strings->num_strings == 1 && strings->strings[0][0] == '\0') {
    173 	ext.data.u.pkinit_acl.val = NULL;
    174 	ext.data.u.pkinit_acl.len = 0;
    175     } else {
    176 	ext.data.u.pkinit_acl.val =
    177 	    calloc(strings->num_strings,
    178 		   sizeof(ext.data.u.pkinit_acl.val[0]));
    179 	ext.data.u.pkinit_acl.len = strings->num_strings;
    180 
    181 	for (i = 0; i < strings->num_strings; i++) {
    182 	    ext.data.u.pkinit_acl.val[i].subject = estrdup(strings->strings[i]);
    183 	}
    184     }
    185 
    186     ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
    187 		       &ext, &size, ret);
    188     free_HDB_extension(&ext);
    189     if (ret)
    190 	abort();
    191     if (buf.length != size)
    192 	abort();
    193 
    194     add_tl(princ, KRB5_TL_EXTENSION, &buf);
    195 }
    196 
    197 static void
    198 add_kvno_diff(krb5_context contextp, kadm5_principal_ent_rec *princ,
    199 	      int is_svc_diff, krb5_kvno kvno_diff)
    200 {
    201     krb5_error_code ret;
    202     HDB_extension ext;
    203     krb5_data buf;
    204     size_t size = 0;
    205 
    206     if (kvno_diff < 0)
    207 	return;
    208     if (kvno_diff > 2048)
    209 	kvno_diff = 2048;
    210 
    211     if (is_svc_diff) {
    212 	ext.data.element = choice_HDB_extension_data_hist_kvno_diff_svc;
    213 	ext.data.u.hist_kvno_diff_svc = (unsigned int)kvno_diff;
    214     } else {
    215 	ext.data.element = choice_HDB_extension_data_hist_kvno_diff_clnt;
    216 	ext.data.u.hist_kvno_diff_clnt = (unsigned int)kvno_diff;
    217     }
    218     ASN1_MALLOC_ENCODE(HDB_extension, buf.data, buf.length,
    219 		       &ext, &size, ret);
    220     if (ret)
    221 	abort();
    222     if (buf.length != size)
    223 	abort();
    224 
    225     add_tl(princ, KRB5_TL_EXTENSION, &buf);
    226 }
    227 
    228 static int
    229 do_mod_entry(krb5_principal principal, void *data)
    230 {
    231     krb5_error_code ret;
    232     kadm5_principal_ent_rec princ;
    233     int mask = 0;
    234     struct modify_options *e = data;
    235 
    236     memset (&princ, 0, sizeof(princ));
    237     ret = kadm5_get_principal(kadm_handle, principal, &princ,
    238 			      KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
    239 			      KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
    240 			      KADM5_PRINC_EXPIRE_TIME |
    241 			      KADM5_PW_EXPIRATION);
    242     if(ret)
    243 	return ret;
    244 
    245     if(e->max_ticket_life_string ||
    246        e->max_renewable_life_string ||
    247        e->expiration_time_string ||
    248        e->pw_expiration_time_string ||
    249        e->attributes_string ||
    250        e->policy_string ||
    251        e->kvno_integer != -1 ||
    252        e->constrained_delegation_strings.num_strings ||
    253        e->alias_strings.num_strings ||
    254        e->pkinit_acl_strings.num_strings ||
    255        e->hist_kvno_diff_clnt_integer != -1 ||
    256        e->hist_kvno_diff_svc_integer != -1) {
    257 	ret = set_entry(context, &princ, &mask,
    258 			e->max_ticket_life_string,
    259 			e->max_renewable_life_string,
    260 			e->expiration_time_string,
    261 			e->pw_expiration_time_string,
    262 			e->attributes_string,
    263 			e->policy_string);
    264 	if(e->kvno_integer != -1) {
    265 	    princ.kvno = e->kvno_integer;
    266 	    mask |= KADM5_KVNO;
    267 	}
    268 	if (e->constrained_delegation_strings.num_strings) {
    269 	    add_constrained_delegation(context, &princ,
    270 				       &e->constrained_delegation_strings);
    271 	    mask |= KADM5_TL_DATA;
    272 	}
    273 	if (e->alias_strings.num_strings) {
    274 	    add_aliases(context, &princ, &e->alias_strings);
    275 	    mask |= KADM5_TL_DATA;
    276 	}
    277 	if (e->pkinit_acl_strings.num_strings) {
    278 	    add_pkinit_acl(context, &princ, &e->pkinit_acl_strings);
    279 	    mask |= KADM5_TL_DATA;
    280 	}
    281 	if (e->hist_kvno_diff_clnt_integer != -1) {
    282 	    add_kvno_diff(context, &princ, 0, e->hist_kvno_diff_clnt_integer);
    283 	    mask |= KADM5_TL_DATA;
    284 	}
    285 	if (e->hist_kvno_diff_svc_integer != -1) {
    286 	    add_kvno_diff(context, &princ, 1, e->hist_kvno_diff_svc_integer);
    287 	    mask |= KADM5_TL_DATA;
    288 	}
    289     } else
    290 	ret = edit_entry(&princ, &mask, NULL, 0);
    291     if(ret == 0) {
    292 	ret = kadm5_modify_principal(kadm_handle, &princ, mask);
    293 	if(ret)
    294 	    krb5_warn(context, ret, "kadm5_modify_principal");
    295     }
    296 
    297     kadm5_free_principal_ent(kadm_handle, &princ);
    298     return ret;
    299 }
    300 
    301 int
    302 mod_entry(struct modify_options *opt, int argc, char **argv)
    303 {
    304     krb5_error_code ret = 0;
    305     int i;
    306 
    307     for(i = 0; i < argc; i++) {
    308 	ret = foreach_principal(argv[i], do_mod_entry, "mod", opt);
    309 	if (ret)
    310 	    break;
    311     }
    312     return ret != 0;
    313 }
    314 
    315