1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
3 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
9 #include <kadm5/server_internal.h>
12 #include "net-server.h"
14 schpw_util_wrapper(void *server_handle,
15 krb5_principal client,
16 krb5_principal target,
17 krb5_boolean initial_flag,
18 char *new_pw, char **ret_pw,
19 char *msg_ret, unsigned int msg_len)
22 kadm5_server_handle_t handle = server_handle;
25 * If no target is explicitly provided, then the target principal
26 * is the client principal.
31 /* If the client is changing its own password, require it to use an initial
32 * ticket, and enforce the policy min_life. */
33 if (krb5_principal_compare(handle->context, client, target)) {
35 strlcpy(msg_ret, "Ticket must be derived from a password",
37 return KADM5_AUTH_INITIAL;
40 ret = check_min_life(server_handle, target, msg_ret, msg_len);
45 if (auth(handle->context, OP_CPW, client, target,
46 NULL, NULL, NULL, NULL, 0)) {
47 ret = kadm5_chpass_principal_util(server_handle,
52 ret = KADM5_AUTH_CHANGEPW;
53 strlcpy(msg_ret, "Unauthorized request", msg_len);
60 check_min_life(void *server_handle, krb5_principal principal,
61 char *msg_ret, unsigned int msg_len)
65 kadm5_policy_ent_rec pol;
66 kadm5_principal_ent_rec princ;
67 kadm5_server_handle_t handle = server_handle;
72 ret = krb5_timeofday(handle->context, &now);
76 ret = kadm5_get_principal(handle->lhandle, principal,
77 &princ, KADM5_PRINCIPAL_NORMAL_MASK);
80 if(princ.aux_attributes & KADM5_POLICY) {
81 /* Look up the policy. If it doesn't exist, treat this principal as if
82 * it had no policy. */
83 if((ret=kadm5_get_policy(handle->lhandle,
84 princ.policy, &pol)) != KADM5_OK) {
85 (void) kadm5_free_principal_ent(handle->lhandle, &princ);
86 return (ret == KADM5_UNK_POLICY) ? 0 : ret;
88 if(ts_delta(now, princ.last_pwd_change) < pol.pw_min_life &&
89 !(princ.attributes & KRB5_KDB_REQUIRES_PWCHANGE)) {
90 if (msg_ret != NULL) {
92 char *time_string, *ptr;
95 until = princ.last_pwd_change + pol.pw_min_life;
97 time_string = ctime(&until);
98 if (time_string == NULL)
99 time_string = "(error)";
100 errstr = error_message(CHPASS_UTIL_PASSWORD_TOO_SOON);
102 if (strlen(errstr) + strlen(time_string) < msg_len) {
103 if (*(ptr = &time_string[strlen(time_string)-1]) == '\n')
105 snprintf(msg_ret, msg_len, errstr, time_string);
109 (void) kadm5_free_policy_ent(handle->lhandle, &pol);
110 (void) kadm5_free_principal_ent(handle->lhandle, &princ);
111 return KADM5_PASS_TOOSOON;
114 ret = kadm5_free_policy_ent(handle->lhandle, &pol);
116 (void) kadm5_free_principal_ent(handle->lhandle, &princ);
121 return kadm5_free_principal_ent(handle->lhandle, &princ);
124 #define MAXPRINCLEN 125
127 trunc_name(size_t *len, char **dots)
129 *dots = *len > MAXPRINCLEN ? "..." : "";
130 *len = *len > MAXPRINCLEN ? MAXPRINCLEN : *len;
134 make_toolong_error (void *handle, krb5_data **out)
137 krb5_error_code retval;
139 kadm5_server_handle_t server_handle = (kadm5_server_handle_t)handle;
141 retval = krb5_us_timeofday(server_handle->context, &errpkt.stime, &errpkt.susec);
144 errpkt.error = KRB_ERR_FIELD_TOOLONG;
145 retval = krb5_build_principal(server_handle->context, &errpkt.server,
146 strlen(server_handle->params.realm),
147 server_handle->params.realm,
148 "kadmin", "changepw", NULL);
151 errpkt.client = NULL;
154 errpkt.text.length = 0;
155 errpkt.text.data = 0;
156 errpkt.e_data.length = 0;
157 errpkt.e_data.data = 0;
158 scratch = malloc(sizeof(*scratch));
161 retval = krb5_mk_error(server_handle->context, &errpkt, scratch);
171 krb5_context get_context(void *handle)
173 kadm5_server_handle_t server_handle = (kadm5_server_handle_t)handle;
174 return server_handle->context;