1 /* $NetBSD: chpass_s.c,v 1.1.1.2 2014/04/24 12:45:48 pettai Exp $ */ 2 3 /* 4 * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan 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"); 39 40 static kadm5_ret_t 41 change(void *server_handle, 42 krb5_principal princ, 43 const char *password, 44 int cond) 45 { 46 kadm5_server_context *context = server_handle; 47 hdb_entry_ex ent; 48 kadm5_ret_t ret; 49 Key *keys; 50 size_t num_keys; 51 int existsp = 0; 52 53 memset(&ent, 0, sizeof(ent)); 54 ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); 55 if(ret) 56 return ret; 57 58 ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, 59 HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent); 60 if(ret) 61 goto out; 62 63 if (context->db->hdb_capability_flags & HDB_CAP_F_HANDLE_PASSWORDS) { 64 ret = context->db->hdb_password(context->context, context->db, 65 &ent, password, cond); 66 if (ret) 67 goto out2; 68 } else { 69 70 num_keys = ent.entry.keys.len; 71 keys = ent.entry.keys.val; 72 73 ent.entry.keys.len = 0; 74 ent.entry.keys.val = NULL; 75 76 ret = _kadm5_set_keys(context, &ent.entry, password); 77 if(ret) { 78 _kadm5_free_keys (context->context, num_keys, keys); 79 goto out2; 80 } 81 82 if (cond) 83 existsp = _kadm5_exists_keys (ent.entry.keys.val, 84 ent.entry.keys.len, 85 keys, num_keys); 86 _kadm5_free_keys (context->context, num_keys, keys); 87 88 if (existsp) { 89 ret = KADM5_PASS_REUSE; 90 krb5_set_error_message(context->context, ret, 91 "Password reuse forbidden"); 92 goto out2; 93 } 94 95 ret = hdb_seal_keys(context->context, context->db, &ent.entry); 96 if (ret) 97 goto out2; 98 } 99 ent.entry.kvno++; 100 101 ret = _kadm5_set_modifier(context, &ent.entry); 102 if(ret) 103 goto out2; 104 105 ret = _kadm5_bump_pw_expire(context, &ent.entry); 106 if (ret) 107 goto out2; 108 109 ret = context->db->hdb_store(context->context, context->db, 110 HDB_F_REPLACE, &ent); 111 if (ret) 112 goto out2; 113 114 kadm5_log_modify (context, 115 &ent.entry, 116 KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | 117 KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | 118 KADM5_TL_DATA); 119 120 out2: 121 hdb_free_entry(context->context, &ent); 122 out: 123 context->db->hdb_close(context->context, context->db); 124 return _kadm5_error_code(ret); 125 } 126 127 128 129 /* 130 * change the password of `princ' to `password' if it's not already that. 131 */ 132 133 kadm5_ret_t 134 kadm5_s_chpass_principal_cond(void *server_handle, 135 krb5_principal princ, 136 const char *password) 137 { 138 return change (server_handle, princ, password, 1); 139 } 140 141 /* 142 * change the password of `princ' to `password' 143 */ 144 145 kadm5_ret_t 146 kadm5_s_chpass_principal(void *server_handle, 147 krb5_principal princ, 148 const char *password) 149 { 150 return change (server_handle, princ, password, 0); 151 } 152 153 /* 154 * change keys for `princ' to `keys' 155 */ 156 157 kadm5_ret_t 158 kadm5_s_chpass_principal_with_key(void *server_handle, 159 krb5_principal princ, 160 int n_key_data, 161 krb5_key_data *key_data) 162 { 163 kadm5_server_context *context = server_handle; 164 hdb_entry_ex ent; 165 kadm5_ret_t ret; 166 167 memset(&ent, 0, sizeof(ent)); 168 ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0); 169 if(ret) 170 return ret; 171 ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, 0, 172 HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); 173 if(ret == HDB_ERR_NOENTRY) 174 goto out; 175 ret = _kadm5_set_keys2(context, &ent.entry, n_key_data, key_data); 176 if(ret) 177 goto out2; 178 ent.entry.kvno++; 179 ret = _kadm5_set_modifier(context, &ent.entry); 180 if(ret) 181 goto out2; 182 ret = _kadm5_bump_pw_expire(context, &ent.entry); 183 if (ret) 184 goto out2; 185 186 ret = hdb_seal_keys(context->context, context->db, &ent.entry); 187 if (ret) 188 goto out2; 189 190 ret = context->db->hdb_store(context->context, context->db, 191 HDB_F_REPLACE, &ent); 192 if (ret) 193 goto out2; 194 195 kadm5_log_modify (context, 196 &ent.entry, 197 KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME | 198 KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION | 199 KADM5_TL_DATA); 200 201 out2: 202 hdb_free_entry(context->context, &ent); 203 out: 204 context->db->hdb_close(context->context, context->db); 205 return _kadm5_error_code(ret); 206 } 207