1 1.1 elric /* $NetBSD: modify_s.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */ 2 1.1 elric 3 1.1 elric /* 4 1.1 elric * Copyright (c) 1997-2001, 2003, 2005-2006 Kungliga Tekniska Hgskolan 5 1.1 elric * (Royal Institute of Technology, Stockholm, Sweden). 6 1.1 elric * All rights reserved. 7 1.1 elric * 8 1.1 elric * Redistribution and use in source and binary forms, with or without 9 1.1 elric * modification, are permitted provided that the following conditions 10 1.1 elric * are met: 11 1.1 elric * 12 1.1 elric * 1. Redistributions of source code must retain the above copyright 13 1.1 elric * notice, this list of conditions and the following disclaimer. 14 1.1 elric * 15 1.1 elric * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 elric * notice, this list of conditions and the following disclaimer in the 17 1.1 elric * documentation and/or other materials provided with the distribution. 18 1.1 elric * 19 1.1 elric * 3. Neither the name of the Institute nor the names of its contributors 20 1.1 elric * may be used to endorse or promote products derived from this software 21 1.1 elric * without specific prior written permission. 22 1.1 elric * 23 1.1 elric * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 1.1 elric * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 1.1 elric * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 1.1 elric * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 1.1 elric * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 1.1 elric * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 1.1 elric * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 1.1 elric * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 1.1 elric * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 1.1 elric * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 1.1 elric * SUCH DAMAGE. 34 1.1 elric */ 35 1.1 elric 36 1.1 elric #include "kadm5_locl.h" 37 1.1 elric 38 1.1 elric __RCSID("$NetBSD: modify_s.c,v 1.2 2017/01/28 21:31:49 christos Exp $"); 39 1.1 elric 40 1.1 elric static kadm5_ret_t 41 1.1 elric modify_principal(void *server_handle, 42 1.1 elric kadm5_principal_ent_t princ, 43 1.1 elric uint32_t mask, 44 1.1 elric uint32_t forbidden_mask) 45 1.1 elric { 46 1.1 elric kadm5_server_context *context = server_handle; 47 1.1 elric hdb_entry_ex ent; 48 1.1 elric kadm5_ret_t ret; 49 1.2 christos 50 1.2 christos memset(&ent, 0, sizeof(ent)); 51 1.2 christos 52 1.1 elric if((mask & forbidden_mask)) 53 1.1 elric return KADM5_BAD_MASK; 54 1.1 elric if((mask & KADM5_POLICY) && strcmp(princ->policy, "default")) 55 1.1 elric return KADM5_UNK_POLICY; 56 1.1 elric 57 1.2 christos if (!context->keep_open) { 58 1.2 christos ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); 59 1.2 christos if(ret) 60 1.2 christos return ret; 61 1.2 christos } 62 1.2 christos 63 1.2 christos ret = kadm5_log_init(context); 64 1.2 christos if (ret) 65 1.2 christos goto out; 66 1.2 christos 67 1.1 elric ret = context->db->hdb_fetch_kvno(context->context, context->db, 68 1.1 elric princ->principal, HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent); 69 1.2 christos if (ret) 70 1.2 christos goto out2; 71 1.1 elric ret = _kadm5_setup_entry(context, &ent, mask, princ, mask, NULL, 0); 72 1.2 christos if (ret) 73 1.2 christos goto out3; 74 1.1 elric ret = _kadm5_set_modifier(context, &ent.entry); 75 1.2 christos if (ret) 76 1.2 christos goto out3; 77 1.2 christos 78 1.2 christos /* 79 1.2 christos * If any keys are bogus, disallow the modify. If the keys were 80 1.2 christos * bogus as stored in the HDB we could allow those through, but 81 1.2 christos * distinguishing that case from a pre-1.6 client using add_enctype 82 1.2 christos * without the get-keys privilege requires more work (mainly: checking that 83 1.2 christos * the bogus keys in princ->key_data[] have corresponding bogus keys in ent 84 1.2 christos * before calling _kadm5_setup_entry()). 85 1.2 christos */ 86 1.2 christos if ((mask & KADM5_KEY_DATA) && 87 1.2 christos kadm5_some_keys_are_bogus(princ->n_key_data, princ->key_data)) { 88 1.2 christos ret = KADM5_AUTH_GET_KEYS; /* Not quite appropriate, but it'll do */ 89 1.2 christos goto out3; 90 1.2 christos } 91 1.1 elric 92 1.1 elric ret = hdb_seal_keys(context->context, context->db, &ent.entry); 93 1.1 elric if (ret) 94 1.2 christos goto out3; 95 1.1 elric 96 1.2 christos if ((mask & KADM5_POLICY)) { 97 1.2 christos HDB_extension ext; 98 1.1 elric 99 1.2 christos memset(&ext, 0, sizeof(ext)); 100 1.2 christos /* XXX should be TRUE, but we don't yet support policies */ 101 1.2 christos ext.mandatory = FALSE; 102 1.2 christos ext.data.element = choice_HDB_extension_data_policy; 103 1.2 christos ext.data.u.policy = strdup(princ->policy); 104 1.2 christos if (ext.data.u.policy == NULL) { 105 1.2 christos ret = ENOMEM; 106 1.2 christos goto out3; 107 1.2 christos } 108 1.2 christos /* This calls free_HDB_extension(), freeing ext.data.u.policy */ 109 1.2 christos ret = hdb_replace_extension(context->context, &ent.entry, &ext); 110 1.2 christos free(ext.data.u.policy); 111 1.2 christos if (ret) 112 1.2 christos goto out3; 113 1.2 christos } 114 1.2 christos 115 1.2 christos /* This logs the change for iprop and writes to the HDB */ 116 1.2 christos ret = kadm5_log_modify(context, &ent.entry, 117 1.2 christos mask | KADM5_MOD_NAME | KADM5_MOD_TIME); 118 1.1 elric 119 1.2 christos out3: 120 1.1 elric hdb_free_entry(context->context, &ent); 121 1.2 christos out2: 122 1.2 christos (void) kadm5_log_end(context); 123 1.2 christos out: 124 1.2 christos if (!context->keep_open) { 125 1.2 christos kadm5_ret_t ret2; 126 1.2 christos ret2 = context->db->hdb_close(context->context, context->db); 127 1.2 christos if (ret == 0 && ret2 != 0) 128 1.2 christos ret = ret2; 129 1.2 christos } 130 1.1 elric return _kadm5_error_code(ret); 131 1.1 elric } 132 1.1 elric 133 1.1 elric 134 1.1 elric kadm5_ret_t 135 1.1 elric kadm5_s_modify_principal(void *server_handle, 136 1.1 elric kadm5_principal_ent_t princ, 137 1.1 elric uint32_t mask) 138 1.1 elric { 139 1.1 elric return modify_principal(server_handle, princ, mask, 140 1.1 elric KADM5_LAST_PWD_CHANGE | KADM5_MOD_TIME 141 1.1 elric | KADM5_MOD_NAME | KADM5_MKVNO 142 1.1 elric | KADM5_AUX_ATTRIBUTES | KADM5_LAST_SUCCESS 143 1.1 elric | KADM5_LAST_FAILED); 144 1.1 elric } 145