xref: /illumos-gate/usr/src/cmd/krb5/kadmin/server/misc.c (revision 257873cfc1dd3337766407f80397db60a56f2f5a)
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