155682Smarkm/* 2233294Sstas * Copyright (c) 1997-2001 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 "kadm5_locl.h" 3555682Smarkm 36233294SstasRCSID("$Id$"); 3755682Smarkm 3855682Smarkmstatic kadm5_ret_t 39233294Sstasget_default(kadm5_server_context *context, krb5_principal princ, 4055682Smarkm kadm5_principal_ent_t def) 4155682Smarkm{ 4255682Smarkm kadm5_ret_t ret; 4355682Smarkm krb5_principal def_principal; 44233294Sstas krb5_const_realm realm = krb5_principal_get_realm(context->context, princ); 4555682Smarkm 46233294Sstas ret = krb5_make_principal(context->context, &def_principal, 47233294Sstas realm, "default", NULL); 4855682Smarkm if (ret) 4955682Smarkm return ret; 50233294Sstas ret = kadm5_s_get_principal(context, def_principal, def, 5155682Smarkm KADM5_PRINCIPAL_NORMAL_MASK); 5255682Smarkm krb5_free_principal (context->context, def_principal); 5355682Smarkm return ret; 5455682Smarkm} 5555682Smarkm 5655682Smarkmstatic kadm5_ret_t 5755682Smarkmcreate_principal(kadm5_server_context *context, 5855682Smarkm kadm5_principal_ent_t princ, 59178825Sdfr uint32_t mask, 60178825Sdfr hdb_entry_ex *ent, 61178825Sdfr uint32_t required_mask, 62178825Sdfr uint32_t forbidden_mask) 6355682Smarkm{ 6455682Smarkm kadm5_ret_t ret; 6555682Smarkm kadm5_principal_ent_rec defrec, *defent; 66178825Sdfr uint32_t def_mask; 67233294Sstas 6855682Smarkm if((mask & required_mask) != required_mask) 6955682Smarkm return KADM5_BAD_MASK; 7055682Smarkm if((mask & forbidden_mask)) 7155682Smarkm return KADM5_BAD_MASK; 7255682Smarkm if((mask & KADM5_POLICY) && strcmp(princ->policy, "default")) 7355682Smarkm /* XXX no real policies for now */ 7455682Smarkm return KADM5_UNK_POLICY; 7555682Smarkm memset(ent, 0, sizeof(*ent)); 76233294Sstas ret = krb5_copy_principal(context->context, princ->principal, 77178825Sdfr &ent->entry.principal); 7855682Smarkm if(ret) 7955682Smarkm return ret; 80233294Sstas 8155682Smarkm defent = &defrec; 8255682Smarkm ret = get_default(context, princ->principal, defent); 8355682Smarkm if(ret) { 8455682Smarkm defent = NULL; 8555682Smarkm def_mask = 0; 8655682Smarkm } else { 8755682Smarkm def_mask = KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE; 8855682Smarkm } 8955682Smarkm 9072445Sassar ret = _kadm5_setup_entry(context, 9172445Sassar ent, mask | def_mask, 9255682Smarkm princ, mask, 9355682Smarkm defent, def_mask); 9455682Smarkm if(defent) 9555682Smarkm kadm5_free_principal_ent(context, defent); 96233294Sstas if (ret) 97233294Sstas return ret; 98233294Sstas 99178825Sdfr ent->entry.created_by.time = time(NULL); 10055682Smarkm 101233294Sstas return krb5_copy_principal(context->context, context->caller, 102233294Sstas &ent->entry.created_by.principal); 10355682Smarkm} 10455682Smarkm 10555682Smarkmkadm5_ret_t 10655682Smarkmkadm5_s_create_principal_with_key(void *server_handle, 10755682Smarkm kadm5_principal_ent_t princ, 108178825Sdfr uint32_t mask) 10955682Smarkm{ 11055682Smarkm kadm5_ret_t ret; 111178825Sdfr hdb_entry_ex ent; 11255682Smarkm kadm5_server_context *context = server_handle; 11355682Smarkm 11455682Smarkm ret = create_principal(context, princ, mask, &ent, 11555682Smarkm KADM5_PRINCIPAL | KADM5_KEY_DATA, 116233294Sstas KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME 117233294Sstas | KADM5_MOD_NAME | KADM5_MKVNO 118233294Sstas | KADM5_AUX_ATTRIBUTES 119233294Sstas | KADM5_POLICY_CLR | KADM5_LAST_SUCCESS 12055682Smarkm | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT); 12155682Smarkm if(ret) 12255682Smarkm goto out; 12355682Smarkm 124178825Sdfr if ((mask & KADM5_KVNO) == 0) 125178825Sdfr ent.entry.kvno = 1; 126178825Sdfr 127178825Sdfr ret = hdb_seal_keys(context->context, context->db, &ent.entry); 128178825Sdfr if (ret) 129178825Sdfr goto out; 130233294Sstas 131178825Sdfr ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); 13255682Smarkm if(ret) 13355682Smarkm goto out; 134178825Sdfr ret = context->db->hdb_store(context->context, context->db, 0, &ent); 135178825Sdfr context->db->hdb_close(context->context, context->db); 13672445Sassar if (ret) 13772445Sassar goto out; 138178825Sdfr kadm5_log_create (context, &ent.entry); 13955682Smarkm 14055682Smarkmout: 14155682Smarkm hdb_free_entry(context->context, &ent); 14255682Smarkm return _kadm5_error_code(ret); 14355682Smarkm} 14455682Smarkm 145233294Sstas 14655682Smarkmkadm5_ret_t 14755682Smarkmkadm5_s_create_principal(void *server_handle, 148233294Sstas kadm5_principal_ent_t princ, 149178825Sdfr uint32_t mask, 150178825Sdfr const char *password) 15155682Smarkm{ 15255682Smarkm kadm5_ret_t ret; 153178825Sdfr hdb_entry_ex ent; 15455682Smarkm kadm5_server_context *context = server_handle; 15555682Smarkm 15655682Smarkm ret = create_principal(context, princ, mask, &ent, 15755682Smarkm KADM5_PRINCIPAL, 158233294Sstas KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME 159233294Sstas | KADM5_MOD_NAME | KADM5_MKVNO 16055682Smarkm | KADM5_AUX_ATTRIBUTES | KADM5_KEY_DATA 161233294Sstas | KADM5_POLICY_CLR | KADM5_LAST_SUCCESS 16255682Smarkm | KADM5_LAST_FAILED | KADM5_FAIL_AUTH_COUNT); 16355682Smarkm if(ret) 16455682Smarkm goto out; 16555682Smarkm 166178825Sdfr if ((mask & KADM5_KVNO) == 0) 167178825Sdfr ent.entry.kvno = 1; 168178825Sdfr 169178825Sdfr ent.entry.keys.len = 0; 170178825Sdfr ent.entry.keys.val = NULL; 171178825Sdfr 172178825Sdfr ret = _kadm5_set_keys(context, &ent.entry, password); 17372445Sassar if (ret) 17472445Sassar goto out; 17555682Smarkm 176178825Sdfr ret = hdb_seal_keys(context->context, context->db, &ent.entry); 17772445Sassar if (ret) 17872445Sassar goto out; 179233294Sstas 180178825Sdfr ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); 18155682Smarkm if(ret) 18255682Smarkm goto out; 183178825Sdfr ret = context->db->hdb_store(context->context, context->db, 0, &ent); 184178825Sdfr context->db->hdb_close(context->context, context->db); 185178825Sdfr if (ret) 186178825Sdfr goto out; 187178825Sdfr 188178825Sdfr kadm5_log_create (context, &ent.entry); 189178825Sdfr 190178825Sdfr out: 19155682Smarkm hdb_free_entry(context->context, &ent); 19255682Smarkm return _kadm5_error_code(ret); 19355682Smarkm} 19455682Smarkm 195