1 /* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
3 * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
8 #include <gssrpc/rpc.h>
9 #include <gssapi/gssapi_krb5.h> /* for gss_nt_krb5_name */
16 #include <kadm5/kadm_rpc.h>
18 #include <kadm5/admin.h>
19 #include <adm_proto.h>
20 #ifdef HAVE_ARPA_INET_H
21 #include <arpa/inet.h>
24 #include "kadm5/server_internal.h"
26 extern void *global_server_handle;
28 static int check_rpcsec_auth(struct svc_req *);
33 * Purpose: RPC proccessing procedure.
34 * originally generated from rpcgen
37 * rqstp (input) rpc request structure
38 * transp (input) rpc transport structure
47 void kadm_1(rqstp, transp)
48 struct svc_req *rqstp;
49 register SVCXPRT *transp;
52 cprinc_arg create_principal_2_arg;
53 dprinc_arg delete_principal_2_arg;
54 mprinc_arg modify_principal_2_arg;
55 rprinc_arg rename_principal_2_arg;
56 gprinc_arg get_principal_2_arg;
57 chpass_arg chpass_principal_2_arg;
58 chrand_arg chrand_principal_2_arg;
59 cpol_arg create_policy_2_arg;
60 dpol_arg delete_policy_2_arg;
61 mpol_arg modify_policy_2_arg;
62 gpol_arg get_policy_2_arg;
63 setkey_arg setkey_principal_2_arg;
64 setv4key_arg setv4key_principal_2_arg;
65 cprinc3_arg create_principal3_2_arg;
66 chpass3_arg chpass_principal3_2_arg;
67 chrand3_arg chrand_principal3_2_arg;
68 setkey3_arg setkey_principal3_2_arg;
71 bool_t (*xdr_argument)(), (*xdr_result)();
74 if (rqstp->rq_cred.oa_flavor != AUTH_GSSAPI &&
75 !check_rpcsec_auth(rqstp)) {
76 krb5_klog_syslog(LOG_ERR, "Authentication attempt failed: %s, "
77 "RPC authentication flavor %d",
78 inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),
79 rqstp->rq_cred.oa_flavor);
80 svcerr_weakauth(transp);
84 switch (rqstp->rq_proc) {
86 (void) svc_sendreply(transp, xdr_void, (char *)NULL);
89 case CREATE_PRINCIPAL:
90 xdr_argument = xdr_cprinc_arg;
91 xdr_result = xdr_generic_ret;
92 local = (char *(*)()) create_principal_2_svc;
95 case DELETE_PRINCIPAL:
96 xdr_argument = xdr_dprinc_arg;
97 xdr_result = xdr_generic_ret;
98 local = (char *(*)()) delete_principal_2_svc;
101 case MODIFY_PRINCIPAL:
102 xdr_argument = xdr_mprinc_arg;
103 xdr_result = xdr_generic_ret;
104 local = (char *(*)()) modify_principal_2_svc;
107 case RENAME_PRINCIPAL:
108 xdr_argument = xdr_rprinc_arg;
109 xdr_result = xdr_generic_ret;
110 local = (char *(*)()) rename_principal_2_svc;
114 xdr_argument = xdr_gprinc_arg;
115 xdr_result = xdr_gprinc_ret;
116 local = (char *(*)()) get_principal_2_svc;
120 xdr_argument = xdr_gprincs_arg;
121 xdr_result = xdr_gprincs_ret;
122 local = (char *(*)()) get_princs_2_svc;
125 case CHPASS_PRINCIPAL:
126 xdr_argument = xdr_chpass_arg;
127 xdr_result = xdr_generic_ret;
128 local = (char *(*)()) chpass_principal_2_svc;
131 case SETV4KEY_PRINCIPAL:
132 xdr_argument = xdr_setv4key_arg;
133 xdr_result = xdr_generic_ret;
134 local = (char *(*)()) setv4key_principal_2_svc;
137 case SETKEY_PRINCIPAL:
138 xdr_argument = xdr_setkey_arg;
139 xdr_result = xdr_generic_ret;
140 local = (char *(*)()) setkey_principal_2_svc;
143 case CHRAND_PRINCIPAL:
144 xdr_argument = xdr_chrand_arg;
145 xdr_result = xdr_chrand_ret;
146 local = (char *(*)()) chrand_principal_2_svc;
150 xdr_argument = xdr_cpol_arg;
151 xdr_result = xdr_generic_ret;
152 local = (char *(*)()) create_policy_2_svc;
156 xdr_argument = xdr_dpol_arg;
157 xdr_result = xdr_generic_ret;
158 local = (char *(*)()) delete_policy_2_svc;
162 xdr_argument = xdr_mpol_arg;
163 xdr_result = xdr_generic_ret;
164 local = (char *(*)()) modify_policy_2_svc;
168 xdr_argument = xdr_gpol_arg;
169 xdr_result = xdr_gpol_ret;
170 local = (char *(*)()) get_policy_2_svc;
174 xdr_argument = xdr_gpols_arg;
175 xdr_result = xdr_gpols_ret;
176 local = (char *(*)()) get_pols_2_svc;
180 xdr_argument = xdr_u_int32;
181 xdr_result = xdr_getprivs_ret;
182 local = (char *(*)()) get_privs_2_svc;
186 xdr_argument = xdr_u_int32;
187 xdr_result = xdr_generic_ret;
188 local = (char *(*)()) init_2_svc;
191 case CREATE_PRINCIPAL3:
192 xdr_argument = xdr_cprinc3_arg;
193 xdr_result = xdr_generic_ret;
194 local = (char *(*)()) create_principal3_2_svc;
197 case CHPASS_PRINCIPAL3:
198 xdr_argument = xdr_chpass3_arg;
199 xdr_result = xdr_generic_ret;
200 local = (char *(*)()) chpass_principal3_2_svc;
203 case CHRAND_PRINCIPAL3:
204 xdr_argument = xdr_chrand3_arg;
205 xdr_result = xdr_chrand_ret;
206 local = (char *(*)()) chrand_principal3_2_svc;
209 case SETKEY_PRINCIPAL3:
210 xdr_argument = xdr_setkey3_arg;
211 xdr_result = xdr_generic_ret;
212 local = (char *(*)()) setkey_principal3_2_svc;
216 krb5_klog_syslog(LOG_ERR, "Invalid KADM5 procedure number: %s, %d",
217 inet_ntoa(rqstp->rq_xprt->xp_raddr.sin_addr),
219 svcerr_noproc(transp);
222 memset(&argument, 0, sizeof(argument));
223 if (!svc_getargs(transp, xdr_argument, &argument)) {
224 svcerr_decode(transp);
227 result = (*local)(&argument, rqstp);
228 if (result != NULL && !svc_sendreply(transp, xdr_result, result)) {
229 krb5_klog_syslog(LOG_ERR, "WARNING! Unable to send function results, "
231 svcerr_systemerr(transp);
233 if (!svc_freeargs(transp, xdr_argument, &argument)) {
234 krb5_klog_syslog(LOG_ERR, "WARNING! Unable to free arguments, "
241 check_rpcsec_auth(struct svc_req *rqstp)
245 OM_uint32 maj_stat, min_stat;
247 krb5_principal princ;
249 krb5_data *c1, *c2, *realm;
250 gss_buffer_desc gss_str;
251 kadm5_server_handle_t handle;
256 handle = (kadm5_server_handle_t)global_server_handle;
258 if (rqstp->rq_cred.oa_flavor != RPCSEC_GSS)
261 ctx = rqstp->rq_svccred;
263 maj_stat = gss_inquire_context(&min_stat, ctx, NULL, &name,
264 NULL, NULL, NULL, NULL, NULL);
265 if (maj_stat != GSS_S_COMPLETE) {
266 krb5_klog_syslog(LOG_ERR, "check_rpcsec_auth: "
267 "failed inquire_context, stat=%u", maj_stat);
268 log_badauth(maj_stat, min_stat,
269 &rqstp->rq_xprt->xp_raddr, NULL);
273 kctx = handle->context;
274 ret = gss_to_krb5_name_1(rqstp, kctx, name, &princ, &gss_str);
278 slen = gss_str.length;
279 trunc_name(&slen, &sdots);
281 * Since we accept with GSS_C_NO_NAME, the client can authenticate
282 * against the entire kdb. Therefore, ensure that the service
283 * name is something reasonable.
285 if (krb5_princ_size(kctx, princ) != 2)
288 c1 = krb5_princ_component(kctx, princ, 0);
289 c2 = krb5_princ_component(kctx, princ, 1);
290 realm = krb5_princ_realm(kctx, princ);
291 if (strncmp(handle->params.realm, realm->data, realm->length) == 0
292 && strncmp("kadmin", c1->data, c1->length) == 0) {
294 if (strncmp("history", c2->data, c2->length) == 0)
302 krb5_klog_syslog(LOG_ERR, "bad service principal %.*s%s",
303 (int) slen, (char *) gss_str.value, sdots);
305 gss_release_buffer(&min_stat, &gss_str);
306 krb5_free_principal(kctx, princ);
308 gss_release_name(&min_stat, &name);
313 gss_to_krb5_name_1(struct svc_req *rqstp, krb5_context ctx, gss_name_t gss_name,
314 krb5_principal *princ, gss_buffer_t gss_str)
316 OM_uint32 status, minor_stat;
321 status = gss_display_name(&minor_stat, gss_name, gss_str, &gss_type);
322 if ((status != GSS_S_COMPLETE) || (gss_type != gss_nt_krb5_name)) {
323 krb5_klog_syslog(LOG_ERR,
325 "failed display_name status %d", status);
326 log_badauth(status, minor_stat,
327 &rqstp->rq_xprt->xp_raddr, NULL);
330 str = malloc(gss_str->length +1);
335 strncat(str, gss_str->value, gss_str->length);
336 success = (krb5_parse_name(ctx, str, princ) == 0);