Home | History | Annotate | Line # | Download | only in kadm5
      1 /*	$NetBSD: create_s.c,v 1.2 2017/01/28 21:31:49 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997-2001 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 "kadm5_locl.h"
     37 
     38 __RCSID("$NetBSD: create_s.c,v 1.2 2017/01/28 21:31:49 christos Exp $");
     39 
     40 static kadm5_ret_t
     41 get_default(kadm5_server_context *context, krb5_principal princ,
     42 	    kadm5_principal_ent_t def)
     43 {
     44     kadm5_ret_t ret;
     45     krb5_principal def_principal;
     46     krb5_const_realm realm = krb5_principal_get_realm(context->context, princ);
     47 
     48     ret = krb5_make_principal(context->context, &def_principal,
     49 			      realm, "default", NULL);
     50     if (ret)
     51 	return ret;
     52     ret = kadm5_s_get_principal(context, def_principal, def,
     53 				KADM5_PRINCIPAL_NORMAL_MASK);
     54     krb5_free_principal (context->context, def_principal);
     55     return ret;
     56 }
     57 
     58 static kadm5_ret_t
     59 create_principal(kadm5_server_context *context,
     60 		 kadm5_principal_ent_t princ,
     61 		 uint32_t mask,
     62 		 hdb_entry_ex *ent,
     63 		 uint32_t required_mask,
     64 		 uint32_t forbidden_mask)
     65 {
     66     kadm5_ret_t ret;
     67     kadm5_principal_ent_rec defrec, *defent;
     68     uint32_t def_mask;
     69 
     70     memset(ent, 0, sizeof(*ent));
     71     if((mask & required_mask) != required_mask)
     72 	return KADM5_BAD_MASK;
     73     if((mask & forbidden_mask))
     74 	return KADM5_BAD_MASK;
     75     if((mask & KADM5_POLICY) && strcmp(princ->policy, "default"))
     76 	/* XXX no real policies for now */
     77 	return KADM5_UNK_POLICY;
     78     ret  = krb5_copy_principal(context->context, princ->principal,
     79 			       &ent->entry.principal);
     80     if(ret)
     81 	return ret;
     82 
     83     defent = &defrec;
     84     ret = get_default(context, princ->principal, defent);
     85     if(ret) {
     86 	defent   = NULL;
     87 	def_mask = 0;
     88     } else {
     89 	def_mask = KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE;
     90     }
     91 
     92     ret = _kadm5_setup_entry(context,
     93 			     ent, mask | def_mask,
     94 			     princ, mask,
     95 			     defent, def_mask);
     96     if(defent)
     97 	kadm5_free_principal_ent(context, defent);
     98     if (ret)
     99 	return ret;
    100 
    101     ent->entry.created_by.time = time(NULL);
    102 
    103     return krb5_copy_principal(context->context, context->caller,
    104 			       &ent->entry.created_by.principal);
    105 }
    106 
    107 kadm5_ret_t
    108 kadm5_s_create_principal_with_key(void *server_handle,
    109 				  kadm5_principal_ent_t princ,
    110 				  uint32_t mask)
    111 {
    112     kadm5_ret_t ret;
    113     hdb_entry_ex ent;
    114     kadm5_server_context *context = server_handle;
    115 
    116     if ((mask & KADM5_KVNO) == 0) {
    117 	/* create_principal() through _kadm5_setup_entry(), will need this */
    118 	princ->kvno = 1;
    119 	mask |= KADM5_KVNO;
    120     }
    121 
    122     ret = create_principal(context, princ, mask, &ent,
    123 			   KADM5_PRINCIPAL | KADM5_KEY_DATA,
    124 			   KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME
    125 			   | KADM5_MOD_NAME | KADM5_MKVNO
    126 			   | KADM5_AUX_ATTRIBUTES
    127 			   | KADM5_POLICY_CLR | KADM5_LAST_SUCCESS
    128 			   | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT);
    129     if (ret)
    130         return ret;
    131 
    132     if (!context->keep_open) {
    133         ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0);
    134         if (ret) {
    135             hdb_free_entry(context->context, &ent);
    136             return ret;
    137         }
    138     }
    139 
    140     ret = kadm5_log_init(context);
    141     if (ret)
    142         goto out;
    143 
    144     ret = hdb_seal_keys(context->context, context->db, &ent.entry);
    145     if (ret)
    146 	goto out2;
    147 
    148     /* This logs the change for iprop and writes to the HDB */
    149     ret = kadm5_log_create(context, &ent.entry);
    150 
    151  out2:
    152     (void) kadm5_log_end(context);
    153  out:
    154     if (!context->keep_open) {
    155         kadm5_ret_t ret2;
    156         ret2 = context->db->hdb_close(context->context, context->db);
    157         if (ret == 0 && ret2 != 0)
    158             ret = ret2;
    159     }
    160     hdb_free_entry(context->context, &ent);
    161     return _kadm5_error_code(ret);
    162 }
    163 
    164 
    165 kadm5_ret_t
    166 kadm5_s_create_principal(void *server_handle,
    167 			 kadm5_principal_ent_t princ,
    168 			 uint32_t mask,
    169 			 int n_ks_tuple,
    170 			 krb5_key_salt_tuple *ks_tuple,
    171 			 const char *password)
    172 {
    173     kadm5_ret_t ret;
    174     hdb_entry_ex ent;
    175     kadm5_server_context *context = server_handle;
    176 
    177     if ((mask & KADM5_KVNO) == 0) {
    178 	/* create_principal() through _kadm5_setup_entry(), will need this */
    179 	princ->kvno = 1;
    180 	mask |= KADM5_KVNO;
    181     }
    182 
    183     ret = create_principal(context, princ, mask, &ent,
    184 			   KADM5_PRINCIPAL,
    185 			   KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME
    186 			   | KADM5_MOD_NAME | KADM5_MKVNO
    187 			   | KADM5_AUX_ATTRIBUTES | KADM5_KEY_DATA
    188 			   | KADM5_POLICY_CLR | KADM5_LAST_SUCCESS
    189 			   | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT);
    190     if (ret)
    191         return ret;
    192 
    193     if (!context->keep_open) {
    194         ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0);
    195         if (ret) {
    196             hdb_free_entry(context->context, &ent);
    197             return ret;
    198         }
    199     }
    200 
    201     ret = kadm5_log_init(context);
    202     if (ret)
    203         goto out;
    204 
    205     ent.entry.keys.len = 0;
    206     ent.entry.keys.val = NULL;
    207 
    208     ret = _kadm5_set_keys(context, &ent.entry, n_ks_tuple, ks_tuple, password);
    209     if (ret)
    210 	goto out2;
    211 
    212     ret = hdb_seal_keys(context->context, context->db, &ent.entry);
    213     if (ret)
    214 	goto out2;
    215 
    216     /* This logs the change for iprop and writes to the HDB */
    217     ret = kadm5_log_create(context, &ent.entry);
    218 
    219  out2:
    220     (void) kadm5_log_end(context);
    221  out:
    222     if (!context->keep_open) {
    223         kadm5_ret_t ret2;
    224         ret2 = context->db->hdb_close(context->context, context->db);
    225         if (ret == 0 && ret2 != 0)
    226             ret = ret2;
    227     }
    228     hdb_free_entry(context->context, &ent);
    229     return _kadm5_error_code(ret);
    230 }
    231 
    232