Rename mit-krb5-1.4.4 to stanford-krb5-1.4.4 because it only applies
cleanly to a source tree already patched for krb5-strength. Update
the documentation and prepare for a new clean krb5-1.4.4 patch.
Russ Allbery
16 years ago
2 | 2 | committed to the KDC database and after a change is made to the attributes |
3 | 3 | of a principal (specifically, a change to DISALLOW_ALL_TIX). |
4 | 4 | |
5 | Currently, there is only one patch available: | |
5 | Currently, there are two patches available: | |
6 | 6 | |
7 | mit-krb5-1.4.4 Built against Stanford-patched MIT Kerberos 1.4.4 | |
7 | mit-krb5-1.4.4 Built against stock MIT Kerberos 1.4.4 | |
8 | stanford-krb5-1.4.4 Built against Stanford-patched MIT Kerberos 1.4.4 | |
8 | 9 | |
9 | More patches against other, or cleaner, source trees may be provided in | |
10 | the future. Please let me know if there is a specific version you wish to | |
11 | see a patch for (and even better, let me know if you have a tested patch | |
12 | for a different version). | |
10 | If you're also applying the patch from the krb5-strength package, apply | |
11 | that patch first and then use the stanford-krb5-1.4.4 patch. More patches | |
12 | against other source trees may be provided in the future. Please let me | |
13 | know if there is a specific version you wish to see a patch for (and even | |
14 | better, let me know if you have a tested patch for a different version). | |
13 | 15 | |
14 | 16 | This patch adds to kadmind a configuration option which should be set in |
15 | 17 | the local realm section of kdc.conf. That configuration option is in the |
0 | Patch built against MIT Kerberos 1.4.4. Note that this patch was | |
1 | generated with some other Stanford-local patches applied and therefore may | |
2 | not apply entirely cleanly. I will hopefully have a chance to regenerate | |
3 | a clean patch against a virgin source tarball for a later release. | |
4 | ||
5 | This patch may apply to earlier or later versions but may not and will | |
6 | require verification. | |
7 | ||
8 | Note that this patch modifies configure.in and hence will require running | |
9 | util/reconf from the src directory of the MIT Kerberos distribution before | |
10 | running configure and rebuilding. | |
11 | ||
12 | ||
13 | Index: krb5/src/lib/kadm5/server_internal.h | |
14 | =================================================================== | |
15 | --- krb5.orig/src/lib/kadm5/server_internal.h 2006-12-14 19:43:21.000000000 -0800 | |
16 | +++ krb5/src/lib/kadm5/server_internal.h 2006-12-14 19:43:21.000000000 -0800 | |
17 | @@ -62,6 +62,9 @@ int init_dict(kadm5_config_params * | |
18 | int find_word(const char *word, const char *princ); | |
19 | void destroy_dict(void); | |
20 | ||
21 | +int init_pwupdate(krb5_context, kadm5_config_params *); | |
22 | +void destroy_pwupdate(void); | |
23 | + | |
24 | /* XXX this ought to be in libkrb5.a, but isn't */ | |
25 | kadm5_ret_t krb5_copy_key_data_contents(krb5_context context, | |
26 | krb5_key_data *from, | |
27 | Index: krb5/src/lib/kadm5/srv/server_init.c | |
28 | =================================================================== | |
29 | --- krb5.orig/src/lib/kadm5/srv/server_init.c 2006-12-14 19:27:34.000000000 -0800 | |
30 | +++ krb5/src/lib/kadm5/srv/server_init.c 2006-12-14 19:43:21.000000000 -0800 | |
31 | @@ -272,6 +272,15 @@ kadm5_ret_t kadm5_init(char *client_name | |
32 | return ret; | |
33 | } | |
34 | ||
35 | + ret = init_pwupdate(handle->context, &handle->params); | |
36 | + if (ret) { | |
37 | + krb5_db_fini(handle->context); | |
38 | + krb5_free_principal(handle->context, handle->current_caller); | |
39 | + krb5_free_context(handle->context); | |
40 | + free(handle); | |
41 | + return ret; | |
42 | + } | |
43 | + | |
44 | ret = adb_policy_init(handle); | |
45 | if (ret) { | |
46 | krb5_db_fini(handle->context); | |
47 | @@ -294,6 +303,7 @@ kadm5_ret_t kadm5_destroy(void *server_h | |
48 | CHECK_HANDLE(server_handle); | |
49 | ||
50 | destroy_dict(); | |
51 | + destroy_pwupdate(); | |
52 | ||
53 | adb_policy_close(handle); | |
54 | krb5_db_fini(handle->context); | |
55 | Index: krb5/src/lib/kadm5/srv/svr_principal.c | |
56 | =================================================================== | |
57 | --- krb5.orig/src/lib/kadm5/srv/svr_principal.c 2006-12-14 19:43:21.000000000 -0800 | |
58 | +++ krb5/src/lib/kadm5/srv/svr_principal.c 2006-12-14 19:43:48.000000000 -0800 | |
59 | @@ -23,6 +23,9 @@ static char *rcsid = "$Header$"; | |
60 | #include <sys/wait.h> | |
61 | #endif | |
62 | ||
63 | +#include <dlfcn.h> | |
64 | +#include <syslog.h> | |
65 | + | |
66 | extern krb5_principal master_princ; | |
67 | extern krb5_principal hist_princ; | |
68 | extern krb5_keyblock master_keyblock; | |
69 | @@ -35,6 +38,17 @@ static int decrypt_key_data(krb5_context | |
70 | int n_key_data, krb5_key_data *key_data, | |
71 | krb5_keyblock **keyblocks, int *n_keys); | |
72 | ||
73 | +static void *update_handle = NULL; | |
74 | +static int (*d_pwupdate_init)(krb5_context, void **) = NULL; | |
75 | +static int (*d_pwupdate_precommit_password)(void *, krb5_principal, char *, | |
76 | + int, char *, int) = NULL; | |
77 | +static int (*d_pwupdate_postcommit_password)(void *, krb5_principal, char *, | |
78 | + int, char *, int) = NULL; | |
79 | +static int (*d_pwupdate_postcommit_status)(void *, krb5_principal, int, | |
80 | + char *, int) = NULL; | |
81 | +static int (*d_pwupdate_close)(void *) = NULL; | |
82 | +static void *pwupdate_context = NULL; | |
83 | + | |
84 | /* | |
85 | * XXX Functions that ought to be in libkrb5.a, but aren't. | |
86 | */ | |
87 | @@ -238,6 +252,25 @@ kadm5_create_principal_3(void *server_ha | |
88 | return(ret); | |
89 | } | |
90 | ||
91 | + /* | |
92 | + * If we have a precommit password update entry point, call that now | |
93 | + * before any database modifications. | |
94 | + */ | |
95 | + | |
96 | + if (d_pwupdate_precommit_password) { | |
97 | + char errstr[256]; | |
98 | + | |
99 | + ret = (*d_pwupdate_precommit_password)(pwupdate_context, | |
100 | + entry->principal, password, | |
101 | + strlen(password), errstr, | |
102 | + sizeof(errstr)); | |
103 | + if (ret) { | |
104 | + krb5_klog_syslog(LOG_ERR, "External password update failed: " | |
105 | + "%s (%d)", errstr, ret); | |
106 | + return ret; | |
107 | + } | |
108 | + } | |
109 | + | |
110 | if ((ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now))) { | |
111 | krb5_dbe_free_contents(handle->context, &kdb); | |
112 | if (mask & KADM5_POLICY) | |
113 | @@ -328,6 +361,18 @@ kadm5_create_principal_3(void *server_ha | |
114 | return(ret); | |
115 | } | |
116 | ||
117 | + if (d_pwupdate_postcommit_password) { | |
118 | + char errstr[256]; | |
119 | + | |
120 | + ret = (*d_pwupdate_postcommit_password)(pwupdate_context, | |
121 | + entry->principal, password, | |
122 | + strlen(password), errstr, | |
123 | + sizeof(errstr)); | |
124 | + if (ret) | |
125 | + krb5_klog_syslog(LOG_ERR, "WARNING: External password update " | |
126 | + "failed: %s (%d)", errstr, ret); | |
127 | + } | |
128 | + | |
129 | if (mask & KADM5_POLICY) | |
130 | (void) kadm5_free_policy_ent(handle->lhandle, &polent); | |
131 | ||
132 | @@ -515,8 +560,22 @@ kadm5_modify_principal(void *server_hand | |
133 | KADM5_REF_COUNT))))) | |
134 | goto done; | |
135 | ||
136 | - if ((mask & KADM5_ATTRIBUTES)) | |
137 | + if ((mask & KADM5_ATTRIBUTES)) { | |
138 | + if (d_pwupdate_postcommit_status | |
139 | + && ((kdb.attributes & KRB5_KDB_DISALLOW_ALL_TIX) != | |
140 | + (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX))) { | |
141 | + char errstr[256]; | |
142 | + int enabled = (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX) == 0; | |
143 | + | |
144 | + ret = (*d_pwupdate_postcommit_status)(pwupdate_context, | |
145 | + entry->principal, enabled, | |
146 | + errstr, sizeof(errstr)); | |
147 | + if (ret) | |
148 | + krb5_klog_syslog(LOG_ERR, "External status update failed: " | |
149 | + "%s (%d)", errstr, ret); | |
150 | + } | |
151 | kdb.attributes = entry->attributes; | |
152 | + } | |
153 | if ((mask & KADM5_MAX_LIFE)) | |
154 | kdb.max_life = entry->max_life; | |
155 | if ((mask & KADM5_PRINC_EXPIRE_TIME)) | |
156 | @@ -1250,6 +1309,24 @@ kadm5_chpass_principal_3(void *server_ha | |
157 | KADM5_POLICY, &pol, principal))) | |
158 | goto done; | |
159 | ||
160 | + /* | |
161 | + * If we have a precommit password update entry point, call that now | |
162 | + * before any database modifications. | |
163 | + */ | |
164 | + | |
165 | + if (d_pwupdate_precommit_password) { | |
166 | + char errstr[256]; | |
167 | + | |
168 | + ret = (*d_pwupdate_precommit_password)(pwupdate_context, principal, | |
169 | + password, strlen(password), | |
170 | + errstr, sizeof(errstr)); | |
171 | + if (ret) { | |
172 | + krb5_klog_syslog(LOG_ERR, "External password update failed: " | |
173 | + "%s (%d)", errstr, ret); | |
174 | + return ret; | |
175 | + } | |
176 | + } | |
177 | + | |
178 | ret = krb5_dbe_cpw(handle->context, &master_keyblock, | |
179 | n_ks_tuple?ks_tuple:handle->params.keysalts, | |
180 | n_ks_tuple?n_ks_tuple:handle->params.num_keysalts, | |
181 | @@ -1367,6 +1444,17 @@ kadm5_chpass_principal_3(void *server_ha | |
182 | if ((ret = kdb_put_entry(handle, &kdb, &adb))) | |
183 | goto done; | |
184 | ||
185 | + if (d_pwupdate_postcommit_password) { | |
186 | + char errstr[256]; | |
187 | + | |
188 | + ret = (*d_pwupdate_postcommit_password)(pwupdate_context, principal, | |
189 | + password, strlen(password), | |
190 | + errstr, sizeof(errstr)); | |
191 | + if (ret) | |
192 | + krb5_klog_syslog(LOG_ERR, "WARNING: External password update " | |
193 | + "failed: %s (%d)", errstr, ret); | |
194 | + } | |
195 | + | |
196 | ret = KADM5_OK; | |
197 | done: | |
198 | if (!hist_added && hist.key_data) | |
199 | @@ -2001,3 +2089,71 @@ kadm5_ret_t kadm5_decrypt_key(void *serv | |
200 | ||
201 | return KADM5_OK; | |
202 | } | |
203 | + | |
204 | +/* | |
205 | + * Function: init_pwupdate | |
206 | + * | |
207 | + * Initialize the password update module (if we have one) | |
208 | + * | |
209 | + * Right now all we do is look for a module named "pwupdate.so" in the | |
210 | + * same directory as the database. Later on this should be cleaned up. | |
211 | + */ | |
212 | + | |
213 | +int | |
214 | +init_pwupdate(krb5_context context, kadm5_config_params *params) | |
215 | +{ | |
216 | + int ret; | |
217 | + | |
218 | + if (params->pwupdate_plugin) { | |
219 | + update_handle = dlopen(params->pwupdate_plugin, RTLD_NOW); | |
220 | + | |
221 | + if (! update_handle) { | |
222 | + krb5_klog_syslog(LOG_ERR, "ERROR: Unable to load plugin " | |
223 | + "\"%s\": %s", params->pwupdate_plugin, | |
224 | + dlerror()); | |
225 | + return KADM5_FAILURE; | |
226 | + } | |
227 | + | |
228 | + d_pwupdate_init = dlsym(update_handle, "pwupdate_init"); | |
229 | + d_pwupdate_precommit_password = dlsym(update_handle, | |
230 | + "pwupdate_precommit_password"); | |
231 | + d_pwupdate_postcommit_password = dlsym(update_handle, | |
232 | + "pwupdate_postcommit_password"); | |
233 | + d_pwupdate_postcommit_status = dlsym(update_handle, | |
234 | + "pwupdate_postcommit_status"); | |
235 | + d_pwupdate_close = dlsym(update_handle, "pwupdate_close"); | |
236 | + | |
237 | + if (d_pwupdate_init == NULL | |
238 | + || d_pwupdate_close == NULL | |
239 | + || (d_pwupdate_precommit_password == NULL && | |
240 | + d_pwupdate_postcommit_password == NULL && | |
241 | + d_pwupdate_postcommit_status == NULL)) { | |
242 | + krb5_klog_syslog(LOG_ERR, "ERROR: Needed symbols missing in " | |
243 | + "pwupdate plugin"); | |
244 | + dlclose(update_handle); | |
245 | + update_handle = NULL; | |
246 | + return KADM5_FAILURE; | |
247 | + } | |
248 | + | |
249 | + ret = (*d_pwupdate_init)(context, &pwupdate_context); | |
250 | + | |
251 | + if (ret != 0) { | |
252 | + krb5_klog_syslog(LOG_ERR, "ERROR: Password update plugin " | |
253 | + "initialization failed with code %d", ret); | |
254 | + dlclose(update_handle); | |
255 | + update_handle = NULL; | |
256 | + return KADM5_FAILURE; | |
257 | + } | |
258 | + | |
259 | + krb5_klog_syslog(LOG_INFO, "Password update plugin \"%s\" initialized", | |
260 | + params->pwupdate_plugin); | |
261 | + } | |
262 | + return KADM5_OK; | |
263 | +} | |
264 | + | |
265 | +void | |
266 | +destroy_pwupdate(void) | |
267 | +{ | |
268 | + if (d_pwupdate_close) | |
269 | + (*d_pwupdate_close)(pwupdate_context); | |
270 | +} | |
271 | Index: krb5/src/lib/kadm5/configure.in | |
272 | =================================================================== | |
273 | --- krb5.orig/src/lib/kadm5/configure.in 2006-12-14 19:27:34.000000000 -0800 | |
274 | +++ krb5/src/lib/kadm5/configure.in 2006-12-14 19:43:21.000000000 -0800 | |
275 | @@ -10,10 +10,12 @@ dnl The following are tests for the pres | |
276 | AC_CHECK_PROG(RUNTEST,runtest,runtest) | |
277 | AC_CHECK_PROG(PERL,perl,perl) | |
278 | AC_CHECK_FUNCS(srand48 srand srandom) | |
279 | +AC_CHECK_LIB(dl, dlopen, DL_LIB=-ldl) | |
280 | AC_KRB5_TCL | |
281 | if test "$PERL" = perl -a "$RUNTEST" = runtest -a "$TCL_LIBS" != ""; then | |
282 | DO_TEST=ok | |
283 | fi | |
284 | +AC_SUBST(DL_LIB) | |
285 | AC_SUBST(DO_TEST) | |
286 | dnl | |
287 | KRB5_BUILD_LIBOBJS | |
288 | Index: krb5/src/lib/kadm5/srv/Makefile.in | |
289 | =================================================================== | |
290 | --- krb5.orig/src/lib/kadm5/srv/Makefile.in 2006-12-14 19:27:34.000000000 -0800 | |
291 | +++ krb5/src/lib/kadm5/srv/Makefile.in 2006-12-14 19:43:21.000000000 -0800 | |
292 | @@ -21,7 +21,7 @@ SHLIB_EXPDEPS=\ | |
293 | $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ | |
294 | $(COM_ERR_DEPLIB) | |
295 | SHLIB_EXPLIBS = -lgssrpc -lgssapi_krb5 -lkdb5 $(KDB5_DB_LIB) \ | |
296 | - -lkrb5 -lk5crypto -lcom_err @GEN_LIB@ | |
297 | + -lkrb5 -lk5crypto -lcom_err @GEN_LIB@ @DL_LIB@ | |
298 | SHLIB_DIRS=-L$(TOPLIBD) | |
299 | SHLIB_RDIRS=$(KRB5_LIBDIR) | |
300 | RELDIR=kadm5/srv | |
301 | Index: krb5/src/lib/kadm5/admin.h | |
302 | =================================================================== | |
303 | --- krb5.orig/src/lib/kadm5/admin.h 2006-12-14 19:43:21.000000000 -0800 | |
304 | +++ krb5/src/lib/kadm5/admin.h 2006-12-14 19:43:21.000000000 -0800 | |
305 | @@ -228,6 +228,7 @@ typedef struct _kadm5_config_params { | |
306 | char * acl_file; | |
307 | char * dict_file; | |
308 | char * pwcheck_plugin; | |
309 | + char * pwupdate_plugin; | |
310 | ||
311 | int mkey_from_kbd; | |
312 | char * stash_file; | |
313 | Index: krb5/src/lib/kadm5/alt_prof.c | |
314 | =================================================================== | |
315 | --- krb5.orig/src/lib/kadm5/alt_prof.c 2006-12-14 19:43:21.000000000 -0800 | |
316 | +++ krb5/src/lib/kadm5/alt_prof.c 2006-12-14 19:43:21.000000000 -0800 | |
317 | @@ -523,6 +523,16 @@ krb5_error_code kadm5_get_config_params( | |
318 | params.pwcheck_plugin = NULL; | |
319 | } | |
320 | ||
321 | + /* Get the value for the pwsync plugin */ | |
322 | + hierarchy[2] = "pwupdate_plugin"; | |
323 | + if (aprofile && | |
324 | + !krb5_aprof_get_string(aprofile, hierarchy, TRUE, | |
325 | + &svalue)) { | |
326 | + params.pwupdate_plugin = svalue; | |
327 | + } else { | |
328 | + params.pwupdate_plugin = NULL; | |
329 | + } | |
330 | + | |
331 | /* Get the value for the kadmind port */ | |
332 | if (! (params.mask & KADM5_CONFIG_KADMIND_PORT)) { | |
333 | hierarchy[2] = "kadmind_port"; |
0 | Patch built against MIT Kerberos 1.4.4. Note that this patch was | |
1 | generated with some other Stanford-local patches applied and therefore may | |
2 | not apply entirely cleanly. I will hopefully have a chance to regenerate | |
3 | a clean patch against a virgin source tarball for a later release. | |
4 | ||
5 | This patch may apply to earlier or later versions but may not and will | |
6 | require verification. | |
7 | ||
8 | Note that this patch modifies configure.in and hence will require running | |
9 | util/reconf from the src directory of the MIT Kerberos distribution before | |
10 | running configure and rebuilding. | |
11 | ||
12 | ||
13 | Index: krb5/src/lib/kadm5/server_internal.h | |
14 | =================================================================== | |
15 | --- krb5.orig/src/lib/kadm5/server_internal.h 2006-12-14 19:43:21.000000000 -0800 | |
16 | +++ krb5/src/lib/kadm5/server_internal.h 2006-12-14 19:43:21.000000000 -0800 | |
17 | @@ -62,6 +62,9 @@ int init_dict(kadm5_config_params * | |
18 | int find_word(const char *word, const char *princ); | |
19 | void destroy_dict(void); | |
20 | ||
21 | +int init_pwupdate(krb5_context, kadm5_config_params *); | |
22 | +void destroy_pwupdate(void); | |
23 | + | |
24 | /* XXX this ought to be in libkrb5.a, but isn't */ | |
25 | kadm5_ret_t krb5_copy_key_data_contents(krb5_context context, | |
26 | krb5_key_data *from, | |
27 | Index: krb5/src/lib/kadm5/srv/server_init.c | |
28 | =================================================================== | |
29 | --- krb5.orig/src/lib/kadm5/srv/server_init.c 2006-12-14 19:27:34.000000000 -0800 | |
30 | +++ krb5/src/lib/kadm5/srv/server_init.c 2006-12-14 19:43:21.000000000 -0800 | |
31 | @@ -272,6 +272,15 @@ kadm5_ret_t kadm5_init(char *client_name | |
32 | return ret; | |
33 | } | |
34 | ||
35 | + ret = init_pwupdate(handle->context, &handle->params); | |
36 | + if (ret) { | |
37 | + krb5_db_fini(handle->context); | |
38 | + krb5_free_principal(handle->context, handle->current_caller); | |
39 | + krb5_free_context(handle->context); | |
40 | + free(handle); | |
41 | + return ret; | |
42 | + } | |
43 | + | |
44 | ret = adb_policy_init(handle); | |
45 | if (ret) { | |
46 | krb5_db_fini(handle->context); | |
47 | @@ -294,6 +303,7 @@ kadm5_ret_t kadm5_destroy(void *server_h | |
48 | CHECK_HANDLE(server_handle); | |
49 | ||
50 | destroy_dict(); | |
51 | + destroy_pwupdate(); | |
52 | ||
53 | adb_policy_close(handle); | |
54 | krb5_db_fini(handle->context); | |
55 | Index: krb5/src/lib/kadm5/srv/svr_principal.c | |
56 | =================================================================== | |
57 | --- krb5.orig/src/lib/kadm5/srv/svr_principal.c 2006-12-14 19:43:21.000000000 -0800 | |
58 | +++ krb5/src/lib/kadm5/srv/svr_principal.c 2006-12-14 19:43:48.000000000 -0800 | |
59 | @@ -23,6 +23,9 @@ static char *rcsid = "$Header$"; | |
60 | #include <sys/wait.h> | |
61 | #endif | |
62 | ||
63 | +#include <dlfcn.h> | |
64 | +#include <syslog.h> | |
65 | + | |
66 | extern krb5_principal master_princ; | |
67 | extern krb5_principal hist_princ; | |
68 | extern krb5_keyblock master_keyblock; | |
69 | @@ -35,6 +38,17 @@ static int decrypt_key_data(krb5_context | |
70 | int n_key_data, krb5_key_data *key_data, | |
71 | krb5_keyblock **keyblocks, int *n_keys); | |
72 | ||
73 | +static void *update_handle = NULL; | |
74 | +static int (*d_pwupdate_init)(krb5_context, void **) = NULL; | |
75 | +static int (*d_pwupdate_precommit_password)(void *, krb5_principal, char *, | |
76 | + int, char *, int) = NULL; | |
77 | +static int (*d_pwupdate_postcommit_password)(void *, krb5_principal, char *, | |
78 | + int, char *, int) = NULL; | |
79 | +static int (*d_pwupdate_postcommit_status)(void *, krb5_principal, int, | |
80 | + char *, int) = NULL; | |
81 | +static int (*d_pwupdate_close)(void *) = NULL; | |
82 | +static void *pwupdate_context = NULL; | |
83 | + | |
84 | /* | |
85 | * XXX Functions that ought to be in libkrb5.a, but aren't. | |
86 | */ | |
87 | @@ -238,6 +252,25 @@ kadm5_create_principal_3(void *server_ha | |
88 | return(ret); | |
89 | } | |
90 | ||
91 | + /* | |
92 | + * If we have a precommit password update entry point, call that now | |
93 | + * before any database modifications. | |
94 | + */ | |
95 | + | |
96 | + if (d_pwupdate_precommit_password) { | |
97 | + char errstr[256]; | |
98 | + | |
99 | + ret = (*d_pwupdate_precommit_password)(pwupdate_context, | |
100 | + entry->principal, password, | |
101 | + strlen(password), errstr, | |
102 | + sizeof(errstr)); | |
103 | + if (ret) { | |
104 | + krb5_klog_syslog(LOG_ERR, "External password update failed: " | |
105 | + "%s (%d)", errstr, ret); | |
106 | + return ret; | |
107 | + } | |
108 | + } | |
109 | + | |
110 | if ((ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now))) { | |
111 | krb5_dbe_free_contents(handle->context, &kdb); | |
112 | if (mask & KADM5_POLICY) | |
113 | @@ -328,6 +361,18 @@ kadm5_create_principal_3(void *server_ha | |
114 | return(ret); | |
115 | } | |
116 | ||
117 | + if (d_pwupdate_postcommit_password) { | |
118 | + char errstr[256]; | |
119 | + | |
120 | + ret = (*d_pwupdate_postcommit_password)(pwupdate_context, | |
121 | + entry->principal, password, | |
122 | + strlen(password), errstr, | |
123 | + sizeof(errstr)); | |
124 | + if (ret) | |
125 | + krb5_klog_syslog(LOG_ERR, "WARNING: External password update " | |
126 | + "failed: %s (%d)", errstr, ret); | |
127 | + } | |
128 | + | |
129 | if (mask & KADM5_POLICY) | |
130 | (void) kadm5_free_policy_ent(handle->lhandle, &polent); | |
131 | ||
132 | @@ -515,8 +560,22 @@ kadm5_modify_principal(void *server_hand | |
133 | KADM5_REF_COUNT))))) | |
134 | goto done; | |
135 | ||
136 | - if ((mask & KADM5_ATTRIBUTES)) | |
137 | + if ((mask & KADM5_ATTRIBUTES)) { | |
138 | + if (d_pwupdate_postcommit_status | |
139 | + && ((kdb.attributes & KRB5_KDB_DISALLOW_ALL_TIX) != | |
140 | + (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX))) { | |
141 | + char errstr[256]; | |
142 | + int enabled = (entry->attributes & KRB5_KDB_DISALLOW_ALL_TIX) == 0; | |
143 | + | |
144 | + ret = (*d_pwupdate_postcommit_status)(pwupdate_context, | |
145 | + entry->principal, enabled, | |
146 | + errstr, sizeof(errstr)); | |
147 | + if (ret) | |
148 | + krb5_klog_syslog(LOG_ERR, "External status update failed: " | |
149 | + "%s (%d)", errstr, ret); | |
150 | + } | |
151 | kdb.attributes = entry->attributes; | |
152 | + } | |
153 | if ((mask & KADM5_MAX_LIFE)) | |
154 | kdb.max_life = entry->max_life; | |
155 | if ((mask & KADM5_PRINC_EXPIRE_TIME)) | |
156 | @@ -1250,6 +1309,24 @@ kadm5_chpass_principal_3(void *server_ha | |
157 | KADM5_POLICY, &pol, principal))) | |
158 | goto done; | |
159 | ||
160 | + /* | |
161 | + * If we have a precommit password update entry point, call that now | |
162 | + * before any database modifications. | |
163 | + */ | |
164 | + | |
165 | + if (d_pwupdate_precommit_password) { | |
166 | + char errstr[256]; | |
167 | + | |
168 | + ret = (*d_pwupdate_precommit_password)(pwupdate_context, principal, | |
169 | + password, strlen(password), | |
170 | + errstr, sizeof(errstr)); | |
171 | + if (ret) { | |
172 | + krb5_klog_syslog(LOG_ERR, "External password update failed: " | |
173 | + "%s (%d)", errstr, ret); | |
174 | + return ret; | |
175 | + } | |
176 | + } | |
177 | + | |
178 | ret = krb5_dbe_cpw(handle->context, &master_keyblock, | |
179 | n_ks_tuple?ks_tuple:handle->params.keysalts, | |
180 | n_ks_tuple?n_ks_tuple:handle->params.num_keysalts, | |
181 | @@ -1367,6 +1444,17 @@ kadm5_chpass_principal_3(void *server_ha | |
182 | if ((ret = kdb_put_entry(handle, &kdb, &adb))) | |
183 | goto done; | |
184 | ||
185 | + if (d_pwupdate_postcommit_password) { | |
186 | + char errstr[256]; | |
187 | + | |
188 | + ret = (*d_pwupdate_postcommit_password)(pwupdate_context, principal, | |
189 | + password, strlen(password), | |
190 | + errstr, sizeof(errstr)); | |
191 | + if (ret) | |
192 | + krb5_klog_syslog(LOG_ERR, "WARNING: External password update " | |
193 | + "failed: %s (%d)", errstr, ret); | |
194 | + } | |
195 | + | |
196 | ret = KADM5_OK; | |
197 | done: | |
198 | if (!hist_added && hist.key_data) | |
199 | @@ -2001,3 +2089,71 @@ kadm5_ret_t kadm5_decrypt_key(void *serv | |
200 | ||
201 | return KADM5_OK; | |
202 | } | |
203 | + | |
204 | +/* | |
205 | + * Function: init_pwupdate | |
206 | + * | |
207 | + * Initialize the password update module (if we have one) | |
208 | + * | |
209 | + * Right now all we do is look for a module named "pwupdate.so" in the | |
210 | + * same directory as the database. Later on this should be cleaned up. | |
211 | + */ | |
212 | + | |
213 | +int | |
214 | +init_pwupdate(krb5_context context, kadm5_config_params *params) | |
215 | +{ | |
216 | + int ret; | |
217 | + | |
218 | + if (params->pwupdate_plugin) { | |
219 | + update_handle = dlopen(params->pwupdate_plugin, RTLD_NOW); | |
220 | + | |
221 | + if (! update_handle) { | |
222 | + krb5_klog_syslog(LOG_ERR, "ERROR: Unable to load plugin " | |
223 | + "\"%s\": %s", params->pwupdate_plugin, | |
224 | + dlerror()); | |
225 | + return KADM5_FAILURE; | |
226 | + } | |
227 | + | |
228 | + d_pwupdate_init = dlsym(update_handle, "pwupdate_init"); | |
229 | + d_pwupdate_precommit_password = dlsym(update_handle, | |
230 | + "pwupdate_precommit_password"); | |
231 | + d_pwupdate_postcommit_password = dlsym(update_handle, | |
232 | + "pwupdate_postcommit_password"); | |
233 | + d_pwupdate_postcommit_status = dlsym(update_handle, | |
234 | + "pwupdate_postcommit_status"); | |
235 | + d_pwupdate_close = dlsym(update_handle, "pwupdate_close"); | |
236 | + | |
237 | + if (d_pwupdate_init == NULL | |
238 | + || d_pwupdate_close == NULL | |
239 | + || (d_pwupdate_precommit_password == NULL && | |
240 | + d_pwupdate_postcommit_password == NULL && | |
241 | + d_pwupdate_postcommit_status == NULL)) { | |
242 | + krb5_klog_syslog(LOG_ERR, "ERROR: Needed symbols missing in " | |
243 | + "pwupdate plugin"); | |
244 | + dlclose(update_handle); | |
245 | + update_handle = NULL; | |
246 | + return KADM5_FAILURE; | |
247 | + } | |
248 | + | |
249 | + ret = (*d_pwupdate_init)(context, &pwupdate_context); | |
250 | + | |
251 | + if (ret != 0) { | |
252 | + krb5_klog_syslog(LOG_ERR, "ERROR: Password update plugin " | |
253 | + "initialization failed with code %d", ret); | |
254 | + dlclose(update_handle); | |
255 | + update_handle = NULL; | |
256 | + return KADM5_FAILURE; | |
257 | + } | |
258 | + | |
259 | + krb5_klog_syslog(LOG_INFO, "Password update plugin \"%s\" initialized", | |
260 | + params->pwupdate_plugin); | |
261 | + } | |
262 | + return KADM5_OK; | |
263 | +} | |
264 | + | |
265 | +void | |
266 | +destroy_pwupdate(void) | |
267 | +{ | |
268 | + if (d_pwupdate_close) | |
269 | + (*d_pwupdate_close)(pwupdate_context); | |
270 | +} | |
271 | Index: krb5/src/lib/kadm5/configure.in | |
272 | =================================================================== | |
273 | --- krb5.orig/src/lib/kadm5/configure.in 2006-12-14 19:27:34.000000000 -0800 | |
274 | +++ krb5/src/lib/kadm5/configure.in 2006-12-14 19:43:21.000000000 -0800 | |
275 | @@ -10,10 +10,12 @@ dnl The following are tests for the pres | |
276 | AC_CHECK_PROG(RUNTEST,runtest,runtest) | |
277 | AC_CHECK_PROG(PERL,perl,perl) | |
278 | AC_CHECK_FUNCS(srand48 srand srandom) | |
279 | +AC_CHECK_LIB(dl, dlopen, DL_LIB=-ldl) | |
280 | AC_KRB5_TCL | |
281 | if test "$PERL" = perl -a "$RUNTEST" = runtest -a "$TCL_LIBS" != ""; then | |
282 | DO_TEST=ok | |
283 | fi | |
284 | +AC_SUBST(DL_LIB) | |
285 | AC_SUBST(DO_TEST) | |
286 | dnl | |
287 | KRB5_BUILD_LIBOBJS | |
288 | Index: krb5/src/lib/kadm5/srv/Makefile.in | |
289 | =================================================================== | |
290 | --- krb5.orig/src/lib/kadm5/srv/Makefile.in 2006-12-14 19:27:34.000000000 -0800 | |
291 | +++ krb5/src/lib/kadm5/srv/Makefile.in 2006-12-14 19:43:21.000000000 -0800 | |
292 | @@ -21,7 +21,7 @@ SHLIB_EXPDEPS=\ | |
293 | $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ | |
294 | $(COM_ERR_DEPLIB) | |
295 | SHLIB_EXPLIBS = -lgssrpc -lgssapi_krb5 -lkdb5 $(KDB5_DB_LIB) \ | |
296 | - -lkrb5 -lk5crypto -lcom_err @GEN_LIB@ | |
297 | + -lkrb5 -lk5crypto -lcom_err @GEN_LIB@ @DL_LIB@ | |
298 | SHLIB_DIRS=-L$(TOPLIBD) | |
299 | SHLIB_RDIRS=$(KRB5_LIBDIR) | |
300 | RELDIR=kadm5/srv | |
301 | Index: krb5/src/lib/kadm5/admin.h | |
302 | =================================================================== | |
303 | --- krb5.orig/src/lib/kadm5/admin.h 2006-12-14 19:43:21.000000000 -0800 | |
304 | +++ krb5/src/lib/kadm5/admin.h 2006-12-14 19:43:21.000000000 -0800 | |
305 | @@ -228,6 +228,7 @@ typedef struct _kadm5_config_params { | |
306 | char * acl_file; | |
307 | char * dict_file; | |
308 | char * pwcheck_plugin; | |
309 | + char * pwupdate_plugin; | |
310 | ||
311 | int mkey_from_kbd; | |
312 | char * stash_file; | |
313 | Index: krb5/src/lib/kadm5/alt_prof.c | |
314 | =================================================================== | |
315 | --- krb5.orig/src/lib/kadm5/alt_prof.c 2006-12-14 19:43:21.000000000 -0800 | |
316 | +++ krb5/src/lib/kadm5/alt_prof.c 2006-12-14 19:43:21.000000000 -0800 | |
317 | @@ -523,6 +523,16 @@ krb5_error_code kadm5_get_config_params( | |
318 | params.pwcheck_plugin = NULL; | |
319 | } | |
320 | ||
321 | + /* Get the value for the pwsync plugin */ | |
322 | + hierarchy[2] = "pwupdate_plugin"; | |
323 | + if (aprofile && | |
324 | + !krb5_aprof_get_string(aprofile, hierarchy, TRUE, | |
325 | + &svalue)) { | |
326 | + params.pwupdate_plugin = svalue; | |
327 | + } else { | |
328 | + params.pwupdate_plugin = NULL; | |
329 | + } | |
330 | + | |
331 | /* Get the value for the kadmind port */ | |
332 | if (! (params.mask & KADM5_CONFIG_KADMIND_PORT)) { | |
333 | hierarchy[2] = "kadmind_port"; |