4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include <sys/errno.h>
37 #define RPCSEC "rpcsec.so.1"
40 AUTH
*(*rpc_gss_seccreate
)();
41 bool_t (*rpc_gss_set_defaults
)();
42 bool_t (*rpc_gss_get_principal_name
)();
43 char **(*rpc_gss_get_mechanisms
)();
44 char **(*rpc_gss_get_mech_info
)();
45 bool_t (*rpc_gss_get_versions
)();
46 bool_t (*rpc_gss_is_installed
)();
47 bool_t (*rpc_gss_set_svc_name
)();
48 bool_t (*rpc_gss_set_callback
)();
49 bool_t (*rpc_gss_getcred
)();
50 bool_t (*rpc_gss_mech_to_oid
)();
51 bool_t (*rpc_gss_qop_to_num
)();
52 enum auth_stat (*__svcrpcsec_gss
)();
53 bool_t (*__rpc_gss_wrap
)();
54 bool_t (*__rpc_gss_unwrap
)();
55 int (*rpc_gss_max_data_length
)();
56 int (*rpc_gss_svc_max_data_length
)();
57 void (*rpc_gss_get_error
)();
60 static rpcgss_calls_t calls
;
61 static mutex_t rpcgss_calls_mutex
= DEFAULTMUTEX
;
62 static bool_t initialized
= FALSE
;
65 rpcgss_calls_init(void)
74 (void) mutex_lock(&rpcgss_calls_mutex
);
76 (void) mutex_unlock(&rpcgss_calls_mutex
);
81 if ((handle
= dlopen(RPCSEC
, RTLD_LAZY
)) == NULL
)
84 if ((calls
.rpc_gss_seccreate
= (AUTH
*(*)()) dlsym(handle
,
85 "__rpc_gss_seccreate")) == NULL
)
87 if ((calls
.rpc_gss_set_defaults
= (bool_t (*)()) dlsym(handle
,
88 "__rpc_gss_set_defaults")) == NULL
)
90 if ((calls
.rpc_gss_get_principal_name
= (bool_t (*)()) dlsym(handle
,
91 "__rpc_gss_get_principal_name")) == NULL
)
93 if ((calls
.rpc_gss_get_mechanisms
= (char **(*)()) dlsym(handle
,
94 "__rpc_gss_get_mechanisms")) == NULL
)
96 if ((calls
.rpc_gss_get_mech_info
= (char **(*)()) dlsym(handle
,
97 "__rpc_gss_get_mech_info")) == NULL
)
99 if ((calls
.rpc_gss_get_versions
= (bool_t (*)()) dlsym(handle
,
100 "__rpc_gss_get_versions")) == NULL
)
102 if ((calls
.rpc_gss_is_installed
= (bool_t (*)()) dlsym(handle
,
103 "__rpc_gss_is_installed")) == NULL
)
105 if ((calls
.rpc_gss_set_svc_name
= (bool_t (*)()) dlsym(handle
,
106 "__rpc_gss_set_svc_name")) == NULL
)
108 if ((calls
.rpc_gss_set_callback
= (bool_t (*)()) dlsym(handle
,
109 "__rpc_gss_set_callback")) == NULL
)
111 if ((calls
.rpc_gss_getcred
= (bool_t (*)()) dlsym(handle
,
112 "__rpc_gss_getcred")) == NULL
)
114 if ((calls
.rpc_gss_mech_to_oid
= (bool_t (*)()) dlsym(handle
,
115 "__rpc_gss_mech_to_oid")) == NULL
)
118 if ((calls
.rpc_gss_qop_to_num
= (bool_t (*)()) dlsym(handle
,
119 "__rpc_gss_qop_to_num")) == NULL
)
121 if ((calls
.__svcrpcsec_gss
= (enum auth_stat (*)()) dlsym(handle
,
122 "__svcrpcsec_gss")) == NULL
)
124 if ((calls
.__rpc_gss_wrap
= (bool_t (*)()) dlsym(handle
,
125 "__rpc_gss_wrap")) == NULL
)
127 if ((calls
.__rpc_gss_unwrap
= (bool_t (*)()) dlsym(handle
,
128 "__rpc_gss_unwrap")) == NULL
)
130 if ((calls
.rpc_gss_max_data_length
= (int (*)()) dlsym(handle
,
131 "__rpc_gss_max_data_length")) == NULL
)
133 if ((calls
.rpc_gss_svc_max_data_length
= (int (*)()) dlsym(handle
,
134 "__rpc_gss_svc_max_data_length")) == NULL
)
136 if ((calls
.rpc_gss_get_error
= (void (*)()) dlsym(handle
,
137 "__rpc_gss_get_error")) == NULL
)
143 (void) dlclose(handle
);
147 (void) mutex_unlock(&rpcgss_calls_mutex
);
153 CLIENT
*clnt
, /* associated client handle */
154 char *principal
, /* server service principal */
155 char *mechanism
, /* security mechanism */
156 rpc_gss_service_t service_type
, /* security service */
157 char *qop
, /* requested QOP */
158 rpc_gss_options_req_t
*options_req
, /* requested options */
159 rpc_gss_options_ret_t
*options_ret
) /* returned options */
161 if (!rpcgss_calls_init())
163 return ((*calls
.rpc_gss_seccreate
)(clnt
, principal
, mechanism
,
164 service_type
, qop
, options_req
, options_ret
));
168 rpc_gss_set_defaults(AUTH
*auth
, rpc_gss_service_t service
, char *qop
)
170 if (!rpcgss_calls_init())
172 return ((*calls
.rpc_gss_set_defaults
)(auth
, service
, qop
));
176 rpc_gss_get_principal_name(
177 rpc_gss_principal_t
*principal
,
183 if (!rpcgss_calls_init())
185 return ((*calls
.rpc_gss_get_principal_name
)(principal
, mechanism
,
186 user_name
, node
, secdomain
));
190 rpc_gss_get_mechanisms(void)
192 if (!rpcgss_calls_init())
194 return ((*calls
.rpc_gss_get_mechanisms
)());
198 rpc_gss_get_mech_info(char *mechanism
, rpc_gss_service_t
*service
)
200 if (!rpcgss_calls_init())
202 return ((*calls
.rpc_gss_get_mech_info
)(mechanism
, service
));
206 rpc_gss_get_versions(uint_t
*vers_hi
, uint_t
*vers_lo
)
208 if (!rpcgss_calls_init())
210 return ((*calls
.rpc_gss_get_versions
)(vers_hi
, vers_lo
));
214 rpc_gss_is_installed(char *mechanism
)
216 if (!rpcgss_calls_init())
218 return ((*calls
.rpc_gss_is_installed
)(mechanism
));
222 rpc_gss_set_svc_name(
223 char *principal
, /* server service principal name */
229 if (!rpcgss_calls_init())
231 return ((*calls
.rpc_gss_set_svc_name
)(principal
, mechanism
, req_time
,
236 rpc_gss_set_callback(rpc_gss_callback_t
*cb
)
238 if (!rpcgss_calls_init())
240 return ((*calls
.rpc_gss_set_callback
)(cb
));
244 rpc_gss_getcred(struct svc_req
*req
, rpc_gss_rawcred_t
**rcred
,
245 rpc_gss_ucred_t
**ucred
, void **cookie
)
247 if (!rpcgss_calls_init())
249 return ((*calls
.rpc_gss_getcred
)(req
, rcred
, ucred
, cookie
));
253 rpc_gss_mech_to_oid(char *mech
, rpc_gss_OID
*oid
)
255 if (!rpcgss_calls_init())
257 return ((*calls
.rpc_gss_mech_to_oid
)(mech
, oid
));
261 rpc_gss_qop_to_num(char *qop
, char *mech
, uint_t
*num
)
263 if (!rpcgss_calls_init())
265 return ((*calls
.rpc_gss_qop_to_num
)(qop
, mech
, num
));
269 __svcrpcsec_gss(struct svc_req
*rqst
, struct rpc_msg
*msg
, bool_t
*no_dispatch
)
271 if (!rpcgss_calls_init())
272 return (AUTH_FAILED
);
273 return ((*calls
.__svcrpcsec_gss
)(rqst
, msg
, no_dispatch
));
277 __rpc_gss_wrap(AUTH
*auth
, char *buf
, uint_t buflen
, XDR
*out_xdrs
,
278 bool_t (*xdr_func
)(), caddr_t xdr_ptr
)
280 if (!rpcgss_calls_init())
282 return ((*calls
.__rpc_gss_wrap
)(auth
, buf
, buflen
, out_xdrs
,
287 __rpc_gss_unwrap(AUTH
*auth
, XDR
*in_xdrs
, bool_t (*xdr_func
)(),
290 if (!rpcgss_calls_init())
292 return ((*calls
.__rpc_gss_unwrap
)(auth
, in_xdrs
, xdr_func
, xdr_ptr
));
296 rpc_gss_max_data_length(AUTH
*rpcgss_handle
, int max_tp_unit_len
)
298 if (!rpcgss_calls_init())
300 return ((*calls
.rpc_gss_max_data_length
)(rpcgss_handle
,
305 rpc_gss_svc_max_data_length(struct svc_req
*req
, int max_tp_unit_len
)
307 if (!rpcgss_calls_init())
309 return ((*calls
.rpc_gss_svc_max_data_length
)(req
, max_tp_unit_len
));
313 rpc_gss_get_error(rpc_gss_error_t
*error
)
315 if (!rpcgss_calls_init()) {
316 error
->rpc_gss_error
= RPC_GSS_ER_SYSTEMERROR
;
317 error
->system_error
= ENOTSUP
;
320 (*calls
.rpc_gss_get_error
)(error
);