|
1 # |
|
2 # This patch provides an authorization scheme for kadmind when used to |
|
3 # auto-migrate UNIX based users to Kerberos. This is required to support |
|
4 # the auto-migrate module, pam_krb5_migrate(5). |
|
5 # |
|
6 # Note: MIT will unlikely want the pam_krb5_migrate kadmind authorization |
|
7 # functionality as this is specific to a 3rd party migration design. |
|
8 # Patch source: in-house |
|
9 # |
|
10 diff -pur old/src/kadmin/server/Makefile.in new/src/kadmin/server/Makefile.in |
|
11 --- old/src/kadmin/server/Makefile.in 2015-04-30 01:12:10.540747993 -0600 |
|
12 +++ new/src/kadmin/server/Makefile.in 2015-05-20 21:20:31.285698636 -0600 |
|
13 @@ -13,7 +13,7 @@ SRCS = kadm_rpc_svc.c server_stubs.c ovs |
|
14 all:: $(PROG) |
|
15 |
|
16 $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(APPUTILS_DEPLIB) $(VERTO_DEPLIB) |
|
17 - $(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) $(VERTO_LIBS) |
|
18 + $(CC_LINK) -o $(PROG) $(OBJS) $(APPUTILS_LIB) $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) $(VERTO_LIBS) -lpam |
|
19 |
|
20 install:: |
|
21 $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(SERVER_BINDIR)/$(PROG) |
|
22 diff -pur old/src/kadmin/server/server_stubs.c new/src/kadmin/server/server_stubs.c |
|
23 --- old/src/kadmin/server/server_stubs.c 2015-04-30 01:12:10.540973547 -0600 |
|
24 +++ new/src/kadmin/server/server_stubs.c 2015-05-20 21:16:21.635418741 -0600 |
|
25 @@ -16,6 +16,7 @@ |
|
26 #include <syslog.h> |
|
27 #include <adm_proto.h> /* krb5_klog_syslog */ |
|
28 #include "misc.h" |
|
29 +#include <security/pam_appl.h> |
|
30 |
|
31 extern gss_name_t gss_changepw_name; |
|
32 extern gss_name_t gss_oldchangepw_name; |
|
33 @@ -352,6 +353,80 @@ log_done( |
|
34 client_addr(rqstp->rq_xprt)); |
|
35 } |
|
36 |
|
37 +/* |
|
38 + * This routine primarily validates the username and password |
|
39 + * of the principal to be created, if a prior acl check for |
|
40 + * the 'u' privilege succeeds. Validation is done using |
|
41 + * the PAM `k5migrate' service. k5migrate normally stacks |
|
42 + * pam_unix_auth.so and pam_unix_account.so in its auth and |
|
43 + * account stacks respectively. |
|
44 + * |
|
45 + * Returns 1 (true), if validation is successful, |
|
46 + * else returns 0 (false). |
|
47 + */ |
|
48 +int |
|
49 +verify_pam_pw(char *userdata, char *pwd) |
|
50 +{ |
|
51 + pam_handle_t *pamh; |
|
52 + int err = 0; |
|
53 + int result = 1; |
|
54 + char *user = NULL; |
|
55 + char *ptr = NULL; |
|
56 + |
|
57 + ptr = strchr(userdata, '@'); |
|
58 + if (ptr != NULL) { |
|
59 + user = (char *)malloc(ptr - userdata + 1); |
|
60 + if (user == NULL) |
|
61 + return (0); |
|
62 + (void) strlcpy(user, userdata, (ptr - userdata) + 1); |
|
63 + } else { |
|
64 + user = (char *)strdup(userdata); |
|
65 + if (user == NULL) |
|
66 + return (0); |
|
67 + } |
|
68 + |
|
69 + err = pam_start("k5migrate", user, NULL, &pamh); |
|
70 + if (err != PAM_SUCCESS) { |
|
71 + syslog(LOG_ERR, "verify_pam_pw: pam_start() failed, %s\n", |
|
72 + pam_strerror(pamh, err)); |
|
73 + free(user); |
|
74 + return (0); |
|
75 + } |
|
76 + |
|
77 + err = pam_set_item(pamh, PAM_AUTHTOK, (void *)pwd); |
|
78 + if (err != PAM_SUCCESS) { |
|
79 + syslog(LOG_ERR, "verify_pam_pw: pam_set_item() failed, %s\n", |
|
80 + pam_strerror(pamh, err)); |
|
81 + free(user); |
|
82 + (void) pam_end(pamh, err); |
|
83 + return (0); |
|
84 + } |
|
85 + |
|
86 + err = pam_authenticate(pamh, PAM_SILENT); |
|
87 + if (err != PAM_SUCCESS) { |
|
88 + syslog(LOG_ERR, "verify_pam_pw: pam_authenticate() failed for " |
|
89 + "user=%s, %s\n", user, |
|
90 + pam_strerror(pamh, err)); |
|
91 + free(user); |
|
92 + (void) pam_end(pamh, err); |
|
93 + return (0); |
|
94 + } |
|
95 + |
|
96 + err = pam_acct_mgmt(pamh, PAM_SILENT); |
|
97 + if (err != PAM_SUCCESS) { |
|
98 + syslog(LOG_ERR, "verify_pam_pw: pam_acct_mgmt() failed for " |
|
99 + "user=%s, %s\n", user, |
|
100 + pam_strerror(pamh, err)); |
|
101 + free(user); |
|
102 + (void) pam_end(pamh, err); |
|
103 + return (0); |
|
104 + } |
|
105 + |
|
106 + free(user); |
|
107 + (void) pam_end(pamh, PAM_SUCCESS); |
|
108 + return (result); |
|
109 +} |
|
110 + |
|
111 generic_ret * |
|
112 create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp) |
|
113 { |
|
114 @@ -363,6 +438,8 @@ create_principal_2_svc(cprinc_arg *arg, |
|
115 restriction_t *rp; |
|
116 const char *errmsg = NULL; |
|
117 gss_name_t name = NULL; |
|
118 + int policy_migrate = 0; |
|
119 + kadm5_ret_t retval; |
|
120 |
|
121 xdr_free(xdr_generic_ret, (char *) &ret); |
|
122 |
|
123 @@ -387,9 +464,17 @@ create_principal_2_svc(cprinc_arg *arg, |
|
124 ret.code = KADM5_FAILURE; |
|
125 goto exit_func; |
|
126 } |
|
127 + |
|
128 + if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE, |
|
129 + arg->rec.principal, &rp) && |
|
130 + verify_pam_pw(prime_arg, arg->passwd)) { |
|
131 + policy_migrate = 1; |
|
132 + } |
|
133 + |
|
134 if (CHANGEPW_SERVICE(rqstp) |
|
135 - || !kadm5int_acl_check(handle->context, name, ACL_ADD, |
|
136 - arg->rec.principal, &rp) |
|
137 + || (!kadm5int_acl_check(handle->context, name, ACL_ADD, |
|
138 + arg->rec.principal, &rp) && |
|
139 + !(policy_migrate)) |
|
140 || kadm5int_acl_impose_restrictions(handle->context, |
|
141 &arg->rec, &arg->mask, rp)) { |
|
142 ret.code = KADM5_AUTH_ADD; |
|
143 @@ -408,6 +493,25 @@ create_principal_2_svc(cprinc_arg *arg, |
|
144 |
|
145 if (errmsg != NULL) |
|
146 krb5_free_error_message(handle->context, errmsg); |
|
147 + |
|
148 + if (policy_migrate && (ret.code == 0)) { |
|
149 + arg->rec.policy = strdup("default"); |
|
150 + if ((arg->mask & KADM5_PW_EXPIRATION)) { |
|
151 + arg->mask = 0; |
|
152 + arg->mask |= KADM5_POLICY; |
|
153 + arg->mask |= KADM5_PW_EXPIRATION; |
|
154 + } else { |
|
155 + arg->mask = 0; |
|
156 + arg->mask |= KADM5_POLICY; |
|
157 + } |
|
158 + |
|
159 + retval = kadm5_modify_principal((void *)handle, |
|
160 + &arg->rec, arg->mask); |
|
161 + log_done("kadm5_modify_principal", |
|
162 + prime_arg, ((retval == 0) ? "success" : |
|
163 + error_message(retval)), &client_name, |
|
164 + &service_name, rqstp); |
|
165 + } |
|
166 } |
|
167 free(prime_arg); |
|
168 gss_release_buffer(&minor_stat, &client_name); |
|
169 @@ -431,6 +535,8 @@ create_principal3_2_svc(cprinc3_arg *arg |
|
170 restriction_t *rp; |
|
171 const char *errmsg = NULL; |
|
172 gss_name_t name = NULL; |
|
173 + int policy_migrate = 0; |
|
174 + kadm5_ret_t retval; |
|
175 |
|
176 xdr_free(xdr_generic_ret, (char *) &ret); |
|
177 |
|
178 @@ -455,9 +561,17 @@ create_principal3_2_svc(cprinc3_arg *arg |
|
179 ret.code = KADM5_FAILURE; |
|
180 goto exit_func; |
|
181 } |
|
182 + |
|
183 + if (kadm5int_acl_check(handle->context, name, ACL_MIGRATE, |
|
184 + arg->rec.principal, &rp) && |
|
185 + verify_pam_pw(prime_arg, arg->passwd)) { |
|
186 + policy_migrate = 1; |
|
187 + } |
|
188 + |
|
189 if (CHANGEPW_SERVICE(rqstp) |
|
190 - || !kadm5int_acl_check(handle->context, name, ACL_ADD, |
|
191 - arg->rec.principal, &rp) |
|
192 + || (!kadm5int_acl_check(handle->context, name, ACL_ADD, |
|
193 + arg->rec.principal, &rp) && |
|
194 + !(policy_migrate)) |
|
195 || kadm5int_acl_impose_restrictions(handle->context, |
|
196 &arg->rec, &arg->mask, rp)) { |
|
197 ret.code = KADM5_AUTH_ADD; |
|
198 @@ -477,6 +591,24 @@ create_principal3_2_svc(cprinc3_arg *arg |
|
199 |
|
200 if (errmsg != NULL) |
|
201 krb5_free_error_message(handle->context, errmsg); |
|
202 + |
|
203 + if (policy_migrate && (ret.code == 0)) { |
|
204 + arg->rec.policy = strdup("default"); |
|
205 + if ((arg->mask & KADM5_PW_EXPIRATION)) { |
|
206 + arg->mask = 0; |
|
207 + arg->mask |= KADM5_POLICY; |
|
208 + arg->mask |= KADM5_PW_EXPIRATION; |
|
209 + } else { |
|
210 + arg->mask = 0; |
|
211 + arg->mask |= KADM5_POLICY; |
|
212 + } |
|
213 + |
|
214 + retval = kadm5_modify_principal((void *)handle, |
|
215 + &arg->rec, arg->mask); |
|
216 + log_done("kadm5_modify_principal", prime_arg, |
|
217 + ((retval == 0) ? "success" : error_message(retval)), |
|
218 + &client_name, &service_name, rqstp); |
|
219 + } |
|
220 } |
|
221 free(prime_arg); |
|
222 gss_release_buffer(&minor_stat, &client_name); |
|
223 diff -pur old/src/lib/kadm5/srv/server_acl.c new/src/lib/kadm5/srv/server_acl.c |
|
224 --- old/src/lib/kadm5/srv/server_acl.c 2015-04-30 01:12:10.576699515 -0600 |
|
225 +++ new/src/lib/kadm5/srv/server_acl.c 2015-05-20 21:00:21.476861745 -0600 |
|
226 @@ -24,6 +24,10 @@ |
|
227 * or implied warranty. |
|
228 */ |
|
229 |
|
230 +/* |
|
231 + * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved. |
|
232 + */ |
|
233 + |
|
234 #include "k5-int.h" |
|
235 #include <syslog.h> |
|
236 #include <sys/param.h> |
|
237 @@ -63,6 +67,7 @@ static const aop_t acl_op_table[] = { |
|
238 { 'l', ACL_LIST }, |
|
239 { 'p', ACL_IPROP }, |
|
240 { 's', ACL_SETKEY }, |
|
241 + { 'u', ACL_MIGRATE }, |
|
242 { 'x', ACL_ALL_MASK }, |
|
243 { '*', ACL_ALL_MASK }, |
|
244 { '\0', 0 } |
|
245 diff -pur old/src/lib/kadm5/srv/server_acl.h new/src/lib/kadm5/srv/server_acl.h |
|
246 --- old/src/lib/kadm5/srv/server_acl.h 2015-04-30 01:12:10.575948391 -0600 |
|
247 +++ new/src/lib/kadm5/srv/server_acl.h 2015-05-20 21:00:26.742448675 -0600 |
|
248 @@ -24,6 +24,10 @@ |
|
249 * or implied warranty. |
|
250 */ |
|
251 |
|
252 +/* |
|
253 + * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. |
|
254 + */ |
|
255 + |
|
256 #ifndef SERVER_ACL_H__ |
|
257 #define SERVER_ACL_H__ |
|
258 |
|
259 @@ -59,6 +63,7 @@ |
|
260 #define ACL_SETKEY 256 |
|
261 #define ACL_IPROP 512 |
|
262 #define ACL_RENAME (ACL_ADD+ACL_DELETE) |
|
263 +#define ACL_MIGRATE 1024 |
|
264 |
|
265 #define ACL_ALL_MASK (ACL_ADD | \ |
|
266 ACL_DELETE | \ |
|
267 @@ -67,7 +72,8 @@ |
|
268 ACL_INQUIRE | \ |
|
269 ACL_LIST | \ |
|
270 ACL_IPROP | \ |
|
271 - ACL_SETKEY) |
|
272 + ACL_SETKEY | \ |
|
273 + ACL_MIGRATE) |
|
274 |
|
275 typedef struct _restriction { |
|
276 long mask; |