xref: /freebsd/crypto/heimdal/lib/kadm5/chpass_s.c (revision 671f5582)
1b528cefcSMark Murray /*
2ae771770SStanislav Sedov  * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
3b528cefcSMark Murray  * (Royal Institute of Technology, Stockholm, Sweden).
4b528cefcSMark Murray  * All rights reserved.
5b528cefcSMark Murray  *
6b528cefcSMark Murray  * Redistribution and use in source and binary forms, with or without
7b528cefcSMark Murray  * modification, are permitted provided that the following conditions
8b528cefcSMark Murray  * are met:
9b528cefcSMark Murray  *
10b528cefcSMark Murray  * 1. Redistributions of source code must retain the above copyright
11b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer.
12b528cefcSMark Murray  *
13b528cefcSMark Murray  * 2. Redistributions in binary form must reproduce the above copyright
14b528cefcSMark Murray  *    notice, this list of conditions and the following disclaimer in the
15b528cefcSMark Murray  *    documentation and/or other materials provided with the distribution.
16b528cefcSMark Murray  *
17b528cefcSMark Murray  * 3. Neither the name of the Institute nor the names of its contributors
18b528cefcSMark Murray  *    may be used to endorse or promote products derived from this software
19b528cefcSMark Murray  *    without specific prior written permission.
20b528cefcSMark Murray  *
21b528cefcSMark Murray  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22b528cefcSMark Murray  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23b528cefcSMark Murray  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24b528cefcSMark Murray  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25b528cefcSMark Murray  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26b528cefcSMark Murray  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27b528cefcSMark Murray  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28b528cefcSMark Murray  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29b528cefcSMark Murray  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30b528cefcSMark Murray  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31b528cefcSMark Murray  * SUCH DAMAGE.
32b528cefcSMark Murray  */
33b528cefcSMark Murray 
34b528cefcSMark Murray #include "kadm5_locl.h"
35b528cefcSMark Murray 
36ae771770SStanislav Sedov RCSID("$Id$");
37b528cefcSMark Murray 
385e9cd1aeSAssar Westerlund static kadm5_ret_t
change(void * server_handle,krb5_principal princ,const char * password,int cond)395e9cd1aeSAssar Westerlund change(void *server_handle,
40b528cefcSMark Murray        krb5_principal princ,
41c19800e8SDoug Rabson        const char *password,
425e9cd1aeSAssar Westerlund        int cond)
43b528cefcSMark Murray {
44b528cefcSMark Murray     kadm5_server_context *context = server_handle;
45c19800e8SDoug Rabson     hdb_entry_ex ent;
46b528cefcSMark Murray     kadm5_ret_t ret;
475e9cd1aeSAssar Westerlund     Key *keys;
485e9cd1aeSAssar Westerlund     size_t num_keys;
49ae771770SStanislav Sedov     int existsp = 0;
505e9cd1aeSAssar Westerlund 
51c19800e8SDoug Rabson     memset(&ent, 0, sizeof(ent));
52c19800e8SDoug Rabson     ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0);
53b528cefcSMark Murray     if(ret)
54b528cefcSMark Murray 	return ret;
55ae771770SStanislav Sedov 
56ae771770SStanislav Sedov     ret = context->db->hdb_fetch_kvno(context->context, context->db, princ,
57ae771770SStanislav Sedov 				      HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, 0, &ent);
58ae771770SStanislav Sedov     if(ret)
59b528cefcSMark Murray 	goto out;
605e9cd1aeSAssar Westerlund 
61ae771770SStanislav Sedov     if (context->db->hdb_capability_flags & HDB_CAP_F_HANDLE_PASSWORDS) {
62ae771770SStanislav Sedov 	ret = context->db->hdb_password(context->context, context->db,
63ae771770SStanislav Sedov 					&ent, password, cond);
64ae771770SStanislav Sedov 	if (ret)
65ae771770SStanislav Sedov 	    goto out2;
66ae771770SStanislav Sedov     } else {
67ae771770SStanislav Sedov 
68c19800e8SDoug Rabson 	num_keys = ent.entry.keys.len;
69c19800e8SDoug Rabson 	keys     = ent.entry.keys.val;
705e9cd1aeSAssar Westerlund 
71c19800e8SDoug Rabson 	ent.entry.keys.len = 0;
72c19800e8SDoug Rabson 	ent.entry.keys.val = NULL;
735e9cd1aeSAssar Westerlund 
74c19800e8SDoug Rabson 	ret = _kadm5_set_keys(context, &ent.entry, password);
755e9cd1aeSAssar Westerlund 	if(ret) {
76c19800e8SDoug Rabson 	    _kadm5_free_keys (context->context, num_keys, keys);
77b528cefcSMark Murray 	    goto out2;
785e9cd1aeSAssar Westerlund 	}
79ae771770SStanislav Sedov 
805e9cd1aeSAssar Westerlund 	if (cond)
81ae771770SStanislav Sedov 	    existsp = _kadm5_exists_keys (ent.entry.keys.val,
82ae771770SStanislav Sedov 					  ent.entry.keys.len,
835e9cd1aeSAssar Westerlund 					  keys, num_keys);
84c19800e8SDoug Rabson 	_kadm5_free_keys (context->context, num_keys, keys);
855e9cd1aeSAssar Westerlund 
86ae771770SStanislav Sedov 	if (existsp) {
871c43270aSJacques Vidrine 	    ret = KADM5_PASS_REUSE;
88ae771770SStanislav Sedov 	    krb5_set_error_message(context->context, ret,
89ae771770SStanislav Sedov 				   "Password reuse forbidden");
905e9cd1aeSAssar Westerlund 	    goto out2;
911c43270aSJacques Vidrine 	}
92c19800e8SDoug Rabson 
93ae771770SStanislav Sedov 	ret = hdb_seal_keys(context->context, context->db, &ent.entry);
94ae771770SStanislav Sedov 	if (ret)
95ae771770SStanislav Sedov 	    goto out2;
96ae771770SStanislav Sedov     }
97ae771770SStanislav Sedov     ent.entry.kvno++;
98ae771770SStanislav Sedov 
99c19800e8SDoug Rabson     ret = _kadm5_set_modifier(context, &ent.entry);
100b528cefcSMark Murray     if(ret)
101b528cefcSMark Murray 	goto out2;
102b528cefcSMark Murray 
103c19800e8SDoug Rabson     ret = _kadm5_bump_pw_expire(context, &ent.entry);
1045e9cd1aeSAssar Westerlund     if (ret)
1055e9cd1aeSAssar Westerlund 	goto out2;
1065e9cd1aeSAssar Westerlund 
107c19800e8SDoug Rabson     ret = context->db->hdb_store(context->context, context->db,
108c19800e8SDoug Rabson 				 HDB_F_REPLACE, &ent);
1095e9cd1aeSAssar Westerlund     if (ret)
1105e9cd1aeSAssar Westerlund 	goto out2;
111b528cefcSMark Murray 
112b528cefcSMark Murray     kadm5_log_modify (context,
113c19800e8SDoug Rabson 		      &ent.entry,
114b528cefcSMark Murray 		      KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME |
115c19800e8SDoug Rabson 		      KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION |
116c19800e8SDoug Rabson 		      KADM5_TL_DATA);
117b528cefcSMark Murray 
118b528cefcSMark Murray out2:
119b528cefcSMark Murray     hdb_free_entry(context->context, &ent);
120b528cefcSMark Murray out:
121c19800e8SDoug Rabson     context->db->hdb_close(context->context, context->db);
122b528cefcSMark Murray     return _kadm5_error_code(ret);
123b528cefcSMark Murray }
124b528cefcSMark Murray 
1255e9cd1aeSAssar Westerlund 
1265e9cd1aeSAssar Westerlund 
1275e9cd1aeSAssar Westerlund /*
1285e9cd1aeSAssar Westerlund  * change the password of `princ' to `password' if it's not already that.
1295e9cd1aeSAssar Westerlund  */
1305e9cd1aeSAssar Westerlund 
1315e9cd1aeSAssar Westerlund kadm5_ret_t
kadm5_s_chpass_principal_cond(void * server_handle,krb5_principal princ,const char * password)1325e9cd1aeSAssar Westerlund kadm5_s_chpass_principal_cond(void *server_handle,
1335e9cd1aeSAssar Westerlund 			      krb5_principal princ,
134c19800e8SDoug Rabson 			      const char *password)
1355e9cd1aeSAssar Westerlund {
1365e9cd1aeSAssar Westerlund     return change (server_handle, princ, password, 1);
1375e9cd1aeSAssar Westerlund }
1385e9cd1aeSAssar Westerlund 
1395e9cd1aeSAssar Westerlund /*
1405e9cd1aeSAssar Westerlund  * change the password of `princ' to `password'
1415e9cd1aeSAssar Westerlund  */
1425e9cd1aeSAssar Westerlund 
1435e9cd1aeSAssar Westerlund kadm5_ret_t
kadm5_s_chpass_principal(void * server_handle,krb5_principal princ,const char * password)1445e9cd1aeSAssar Westerlund kadm5_s_chpass_principal(void *server_handle,
1455e9cd1aeSAssar Westerlund 			 krb5_principal princ,
146c19800e8SDoug Rabson 			 const char *password)
1475e9cd1aeSAssar Westerlund {
1485e9cd1aeSAssar Westerlund     return change (server_handle, princ, password, 0);
1495e9cd1aeSAssar Westerlund }
1505e9cd1aeSAssar Westerlund 
1515e9cd1aeSAssar Westerlund /*
1525e9cd1aeSAssar Westerlund  * change keys for `princ' to `keys'
1535e9cd1aeSAssar Westerlund  */
1545e9cd1aeSAssar Westerlund 
155b528cefcSMark Murray kadm5_ret_t
kadm5_s_chpass_principal_with_key(void * server_handle,krb5_principal princ,int n_key_data,krb5_key_data * key_data)156b528cefcSMark Murray kadm5_s_chpass_principal_with_key(void *server_handle,
157b528cefcSMark Murray 				  krb5_principal princ,
158b528cefcSMark Murray 				  int n_key_data,
159b528cefcSMark Murray 				  krb5_key_data *key_data)
160b528cefcSMark Murray {
161b528cefcSMark Murray     kadm5_server_context *context = server_handle;
162c19800e8SDoug Rabson     hdb_entry_ex ent;
163b528cefcSMark Murray     kadm5_ret_t ret;
164c19800e8SDoug Rabson 
165c19800e8SDoug Rabson     memset(&ent, 0, sizeof(ent));
166c19800e8SDoug Rabson     ret = context->db->hdb_open(context->context, context->db, O_RDWR, 0);
167b528cefcSMark Murray     if(ret)
168b528cefcSMark Murray 	return ret;
169ae771770SStanislav Sedov     ret = context->db->hdb_fetch_kvno(context->context, context->db, princ, 0,
170ae771770SStanislav Sedov 				      HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent);
171671f5582SCy Schubert     if(ret)
172b528cefcSMark Murray 	goto out;
173c19800e8SDoug Rabson     ret = _kadm5_set_keys2(context, &ent.entry, n_key_data, key_data);
174b528cefcSMark Murray     if(ret)
175b528cefcSMark Murray 	goto out2;
176c19800e8SDoug Rabson     ent.entry.kvno++;
177c19800e8SDoug Rabson     ret = _kadm5_set_modifier(context, &ent.entry);
178b528cefcSMark Murray     if(ret)
179b528cefcSMark Murray 	goto out2;
180c19800e8SDoug Rabson     ret = _kadm5_bump_pw_expire(context, &ent.entry);
1815e9cd1aeSAssar Westerlund     if (ret)
1825e9cd1aeSAssar Westerlund 	goto out2;
183b528cefcSMark Murray 
184c19800e8SDoug Rabson     ret = hdb_seal_keys(context->context, context->db, &ent.entry);
185c19800e8SDoug Rabson     if (ret)
186c19800e8SDoug Rabson 	goto out2;
187c19800e8SDoug Rabson 
188c19800e8SDoug Rabson     ret = context->db->hdb_store(context->context, context->db,
189c19800e8SDoug Rabson 				 HDB_F_REPLACE, &ent);
1905e9cd1aeSAssar Westerlund     if (ret)
1915e9cd1aeSAssar Westerlund 	goto out2;
192b528cefcSMark Murray 
193b528cefcSMark Murray     kadm5_log_modify (context,
194c19800e8SDoug Rabson 		      &ent.entry,
195b528cefcSMark Murray 		      KADM5_PRINCIPAL | KADM5_MOD_NAME | KADM5_MOD_TIME |
196c19800e8SDoug Rabson 		      KADM5_KEY_DATA | KADM5_KVNO | KADM5_PW_EXPIRATION |
197c19800e8SDoug Rabson 		      KADM5_TL_DATA);
198b528cefcSMark Murray 
199b528cefcSMark Murray out2:
200b528cefcSMark Murray     hdb_free_entry(context->context, &ent);
201b528cefcSMark Murray out:
202c19800e8SDoug Rabson     context->db->hdb_close(context->context, context->db);
203b528cefcSMark Murray     return _kadm5_error_code(ret);
204b528cefcSMark Murray }
205