1 /* 2 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 7 /* 8 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 9 * 10 * Openvision retains the copyright to derivative works of 11 * this source code. Do *NOT* create a derivative of this 12 * source code before consulting with your legal department. 13 * Do *NOT* integrate *ANY* of this source code into another 14 * product before consulting with your legal department. 15 * 16 * For further information, read the top-level Openvision 17 * copyright which is contained in the top-level MIT Kerberos 18 * copyright. 19 * 20 * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING 21 * 22 */ 23 24 25 /* 26 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved 27 * 28 */ 29 30 #include <k5-int.h> 31 #include <krb5/kdb.h> 32 #include <kadm5/server_internal.h> 33 #include "misc.h" 34 35 /* 36 * Function: chpass_principal_wrapper_3 37 * 38 * Purpose: wrapper to kadm5_chpass_principal that checks to see if 39 * pw_min_life has been reached. if not it returns an error. 40 * otherwise it calls kadm5_chpass_principal 41 * 42 * Arguments: 43 * principal (input) krb5_principals whose password we are 44 * changing 45 * keepold (input) whether to preserve old keys 46 * n_ks_tuple (input) the number of key-salt tuples in ks_tuple 47 * ks_tuple (input) array of tuples indicating the caller's 48 * requested enctypes/salttypes 49 * password (input) password we are going to change to. 50 * <return value> 0 on success error code on failure. 51 * 52 * Requires: 53 * kadm5_init to have been run. 54 * 55 * Effects: 56 * calls kadm5_chpass_principal which changes the kdb and the 57 * the admin db. 58 * 59 */ 60 kadm5_ret_t 61 chpass_principal_wrapper_3(void *server_handle, 62 krb5_principal principal, 63 krb5_boolean keepold, 64 int n_ks_tuple, 65 krb5_key_salt_tuple *ks_tuple, 66 char *password) 67 { 68 kadm5_ret_t ret; 69 70 ret = check_min_life(server_handle, principal, NULL, 0); 71 if (ret) 72 return ret; 73 74 return kadm5_chpass_principal_3(server_handle, principal, 75 keepold, n_ks_tuple, ks_tuple, 76 password); 77 } 78 79 80 /* 81 * Function: randkey_principal_wrapper_3 82 * 83 * Purpose: wrapper to kadm5_randkey_principal which checks the 84 * password's min. life. 85 * 86 * Arguments: 87 * principal (input) krb5_principal whose password we are 88 * changing 89 * keepold (input) whether to preserve old keys 90 * n_ks_tuple (input) the number of key-salt tuples in ks_tuple 91 * ks_tuple (input) array of tuples indicating the caller's 92 * requested enctypes/salttypes 93 * key (output) new random key 94 * <return value> 0, error code on error. 95 * 96 * Requires: 97 * kadm5_init needs to be run 98 * 99 * Effects: 100 * calls kadm5_randkey_principal 101 * 102 */ 103 kadm5_ret_t 104 randkey_principal_wrapper_3(void *server_handle, 105 krb5_principal principal, 106 krb5_boolean keepold, 107 int n_ks_tuple, 108 krb5_key_salt_tuple *ks_tuple, 109 krb5_keyblock **keys, int *n_keys) 110 { 111 kadm5_ret_t ret; 112 113 ret = check_min_life(server_handle, principal, NULL, 0); 114 if (ret) 115 return ret; 116 return kadm5_randkey_principal_3(server_handle, principal, 117 keepold, n_ks_tuple, ks_tuple, 118 keys, n_keys); 119 } 120 121 kadm5_ret_t 122 schpw_util_wrapper(void *server_handle, krb5_principal princ, 123 char *new_pw, char **ret_pw, 124 char *msg_ret, unsigned int msg_len) 125 { 126 kadm5_ret_t ret; 127 128 ret = check_min_life(server_handle, princ, msg_ret, msg_len); 129 if (ret) 130 return ret; 131 132 return kadm5_chpass_principal_util(server_handle, princ, 133 new_pw, ret_pw, 134 msg_ret, msg_len); 135 } 136 137 kadm5_ret_t 138 randkey_principal_wrapper(void *server_handle, krb5_principal princ, 139 krb5_keyblock ** keys, int *n_keys) 140 { 141 kadm5_ret_t ret; 142 143 ret = check_min_life(server_handle, princ, NULL, 0); 144 if (ret) 145 return ret; 146 147 return kadm5_randkey_principal(server_handle, princ, keys, n_keys); 148 } 149 150 kadm5_ret_t 151 check_min_life(void *server_handle, krb5_principal principal, 152 char *msg_ret, unsigned int msg_len) 153 { 154 krb5_int32 now; 155 kadm5_ret_t ret; 156 kadm5_policy_ent_rec pol; 157 kadm5_principal_ent_rec princ; 158 kadm5_server_handle_t handle = server_handle; 159 160 if (msg_ret != NULL) 161 *msg_ret = '\0'; 162 163 ret = krb5_timeofday(handle->context, &now); 164 if (ret) 165 return ret; 166 167 ret = kadm5_get_principal(handle->lhandle, principal, 168 &princ, KADM5_PRINCIPAL_NORMAL_MASK); 169 if(ret) 170 return ret; 171 if(princ.aux_attributes & KADM5_POLICY) { 172 if((ret=kadm5_get_policy(handle->lhandle, 173 princ.policy, &pol)) != KADM5_OK) { 174 (void) kadm5_free_principal_ent(handle->lhandle, &princ); 175 return ret; 176 } 177 if((now - princ.last_pwd_change) < pol.pw_min_life && 178 !(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) { 179 if (msg_ret != NULL) { 180 time_t until; 181 char *time_string, *ptr, *errstr; 182 183 until = princ.last_pwd_change + pol.pw_min_life; 184 185 time_string = ctime(&until); 186 errstr = (char *)error_message(CHPASS_UTIL_PASSWORD_TOO_SOON); 187 188 if (strlen(errstr) + strlen(time_string) >= msg_len) { 189 *errstr = '\0'; 190 } else { 191 if (*(ptr = &time_string[strlen(time_string)-1]) == '\n') 192 *ptr = '\0'; 193 sprintf(msg_ret, errstr, time_string); 194 } 195 } 196 197 (void) kadm5_free_policy_ent(handle->lhandle, &pol); 198 (void) kadm5_free_principal_ent(handle->lhandle, &princ); 199 return KADM5_PASS_TOOSOON; 200 } 201 202 ret = kadm5_free_policy_ent(handle->lhandle, &pol); 203 if (ret) { 204 (void) kadm5_free_principal_ent(handle->lhandle, &princ); 205 return ret; 206 } 207 } 208 209 return kadm5_free_principal_ent(handle->lhandle, &princ); 210 } 211