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 "kadm5_locl.h" 3555682Smarkm 36233294SstasRCSID("$Id$"); 3755682Smarkm 3872445Sassarstatic kadm5_ret_t 39233294Sstaschange(void *server_handle, 4072445Sassar krb5_principal princ, 41178825Sdfr const char *password, 4272445Sassar int cond) 4355682Smarkm{ 4455682Smarkm kadm5_server_context *context = server_handle; 45178825Sdfr hdb_entry_ex ent; 4655682Smarkm kadm5_ret_t ret; 4772445Sassar Key *keys; 4872445Sassar size_t num_keys; 49233294Sstas int existsp = 0; 5072445Sassar 51178825Sdfr memset(&ent, 0, sizeof(ent)); 52178825Sdfr ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); 5355682Smarkm if(ret) 5455682Smarkm return ret; 55233294Sstas 56233294Sstas ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, 57233294Sstas HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent); 58233294Sstas if(ret) 5955682Smarkm goto out; 6072445Sassar 61233294Sstas if (context->db->hdb_capability_flags & HDB_CAP_F_HANDLE_PASSWORDS) { 62233294Sstas ret = context->db->hdb_password(context->context, context->db, 63233294Sstas &ent, password, cond); 64233294Sstas if (ret) 65233294Sstas goto out2; 66233294Sstas } else { 6772445Sassar 68233294Sstas num_keys = ent.entry.keys.len; 69233294Sstas keys = ent.entry.keys.val; 7072445Sassar 71233294Sstas ent.entry.keys.len = 0; 72233294Sstas ent.entry.keys.val = NULL; 73233294Sstas 74233294Sstas ret = _kadm5_set_keys(context, &ent.entry, password); 75233294Sstas if(ret) { 76233294Sstas _kadm5_free_keys (context->context, num_keys, keys); 77233294Sstas goto out2; 78233294Sstas } 79233294Sstas 80233294Sstas if (cond) 81233294Sstas existsp = _kadm5_exists_keys (ent.entry.keys.val, 82233294Sstas ent.entry.keys.len, 83233294Sstas keys, num_keys); 84178825Sdfr _kadm5_free_keys (context->context, num_keys, keys); 85233294Sstas 86233294Sstas if (existsp) { 87233294Sstas ret = KADM5_PASS_REUSE; 88233294Sstas krb5_set_error_message(context->context, ret, 89233294Sstas "Password reuse forbidden"); 90233294Sstas goto out2; 91233294Sstas } 92233294Sstas 93233294Sstas ret = hdb_seal_keys(context->context, context->db, &ent.entry); 94233294Sstas if (ret) 95233294Sstas goto out2; 9672445Sassar } 97178825Sdfr ent.entry.kvno++; 9872445Sassar 99178825Sdfr ret = _kadm5_set_modifier(context, &ent.entry); 10055682Smarkm if(ret) 10155682Smarkm goto out2; 10255682Smarkm 103178825Sdfr ret = _kadm5_bump_pw_expire(context, &ent.entry); 10472445Sassar if (ret) 10572445Sassar goto out2; 10655682Smarkm 107233294Sstas ret = context->db->hdb_store(context->context, context->db, 108178825Sdfr HDB_F_REPLACE, &ent); 109178825Sdfr if (ret) 110178825Sdfr goto out2; 111178825Sdfr 11255682Smarkm kadm5_log_modify (context, 113178825Sdfr &ent.entry, 11455682Smarkm KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | 115178825Sdfr KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | 116178825Sdfr KADM5_TL_DATA); 117178825Sdfr 11855682Smarkmout2: 11955682Smarkm hdb_free_entry(context->context, &ent); 12055682Smarkmout: 121178825Sdfr context->db->hdb_close(context->context, context->db); 12255682Smarkm return _kadm5_error_code(ret); 12355682Smarkm} 12455682Smarkm 12572445Sassar 12672445Sassar 12772445Sassar/* 12872445Sassar * change the password of `princ' to `password' if it's not already that. 12972445Sassar */ 13072445Sassar 13155682Smarkmkadm5_ret_t 132233294Sstaskadm5_s_chpass_principal_cond(void *server_handle, 13372445Sassar krb5_principal princ, 134178825Sdfr const char *password) 13572445Sassar{ 13672445Sassar return change (server_handle, princ, password, 1); 13772445Sassar} 13872445Sassar 13972445Sassar/* 14072445Sassar * change the password of `princ' to `password' 14172445Sassar */ 14272445Sassar 14372445Sassarkadm5_ret_t 144233294Sstaskadm5_s_chpass_principal(void *server_handle, 14572445Sassar krb5_principal princ, 146178825Sdfr const char *password) 14772445Sassar{ 14872445Sassar return change (server_handle, princ, password, 0); 14972445Sassar} 15072445Sassar 15172445Sassar/* 15272445Sassar * change keys for `princ' to `keys' 15372445Sassar */ 15472445Sassar 15572445Sassarkadm5_ret_t 156233294Sstaskadm5_s_chpass_principal_with_key(void *server_handle, 15755682Smarkm krb5_principal princ, 15855682Smarkm int n_key_data, 15955682Smarkm krb5_key_data *key_data) 16055682Smarkm{ 16155682Smarkm kadm5_server_context *context = server_handle; 162178825Sdfr hdb_entry_ex ent; 16355682Smarkm kadm5_ret_t ret; 164178825Sdfr 165178825Sdfr memset(&ent, 0, sizeof(ent)); 166178825Sdfr ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); 16755682Smarkm if(ret) 16855682Smarkm return ret; 169233294Sstas ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, 0, 170233294Sstas HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); 17155682Smarkm if(ret == HDB_ERR_NOENTRY) 17255682Smarkm goto out; 173178825Sdfr ret = _kadm5_set_keys2(context, &ent.entry, n_key_data, key_data); 17455682Smarkm if(ret) 17555682Smarkm goto out2; 176178825Sdfr ent.entry.kvno++; 177178825Sdfr ret = _kadm5_set_modifier(context, &ent.entry); 17855682Smarkm if(ret) 17955682Smarkm goto out2; 180178825Sdfr ret = _kadm5_bump_pw_expire(context, &ent.entry); 18172445Sassar if (ret) 18272445Sassar goto out2; 18355682Smarkm 184178825Sdfr ret = hdb_seal_keys(context->context, context->db, &ent.entry); 18572445Sassar if (ret) 18672445Sassar goto out2; 18755682Smarkm 188233294Sstas ret = context->db->hdb_store(context->context, context->db, 189178825Sdfr HDB_F_REPLACE, &ent); 190178825Sdfr if (ret) 191178825Sdfr goto out2; 192178825Sdfr 19355682Smarkm kadm5_log_modify (context, 194178825Sdfr &ent.entry, 19555682Smarkm KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | 196178825Sdfr KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | 197178825Sdfr KADM5_TL_DATA); 198178825Sdfr 19955682Smarkmout2: 20055682Smarkm hdb_free_entry(context->context, &ent); 20155682Smarkmout: 202178825Sdfr context->db->hdb_close(context->context, context->db); 20355682Smarkm return _kadm5_error_code(ret); 20455682Smarkm} 205