rpcsec_gss.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2008 Doug Rabson
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26. * SUCH DAMAGE.
  27. */
  28. #ifndef _RPCSEC_GSS_H
  29. #define _RPCSEC_GSS_H
  30. #include <kgssapi/gssapi.h>
  31. #ifndef MAX_GSS_MECH
  32. #define MAX_GSS_MECH 64
  33. #endif
  34. /*
  35. * Define the types of security service required for rpc_gss_seccreate().
  36. */
  37. typedef enum {
  38. rpc_gss_svc_default = 0,
  39. rpc_gss_svc_none = 1,
  40. rpc_gss_svc_integrity = 2,
  41. rpc_gss_svc_privacy = 3
  42. } rpc_gss_service_t;
  43. /*
  44. * Structure containing options for rpc_gss_seccreate().
  45. */
  46. typedef struct {
  47. int req_flags; /* GSS request bits */
  48. int time_req; /* requested credential lifetime */
  49. gss_cred_id_t my_cred; /* GSS credential */
  50. gss_channel_bindings_t input_channel_bindings;
  51. } rpc_gss_options_req_t;
  52. /*
  53. * Structure containing options returned by rpc_gss_seccreate().
  54. */
  55. typedef struct {
  56. int major_status;
  57. int minor_status;
  58. u_int rpcsec_version;
  59. int ret_flags;
  60. int time_req;
  61. gss_ctx_id_t gss_context;
  62. char actual_mechanism[MAX_GSS_MECH];
  63. } rpc_gss_options_ret_t;
  64. /*
  65. * Client principal type. Used as an argument to
  66. * rpc_gss_get_principal_name(). Also referenced by the
  67. * rpc_gss_rawcred_t structure.
  68. */
  69. typedef struct {
  70. int len;
  71. char name[1];
  72. } *rpc_gss_principal_t;
  73. /*
  74. * Structure for raw credentials used by rpc_gss_getcred() and
  75. * rpc_gss_set_callback().
  76. */
  77. typedef struct {
  78. u_int version; /* RPC version number */
  79. const char *mechanism; /* security mechanism */
  80. const char *qop; /* quality of protection */
  81. rpc_gss_principal_t client_principal; /* client name */
  82. const char *svc_principal; /* server name */
  83. rpc_gss_service_t service; /* service type */
  84. } rpc_gss_rawcred_t;
  85. /*
  86. * Unix credentials derived from raw credentials. Returned by
  87. * rpc_gss_getcred().
  88. */
  89. typedef struct {
  90. uid_t uid; /* user ID */
  91. gid_t gid; /* group ID */
  92. short gidlen;
  93. gid_t *gidlist; /* list of groups */
  94. } rpc_gss_ucred_t;
  95. /*
  96. * Structure used to enforce a particular QOP and service.
  97. */
  98. typedef struct {
  99. bool_t locked;
  100. rpc_gss_rawcred_t *raw_cred;
  101. } rpc_gss_lock_t;
  102. /*
  103. * Callback structure used by rpc_gss_set_callback().
  104. */
  105. typedef struct {
  106. u_int program; /* RPC program number */
  107. u_int version; /* RPC version number */
  108. /* user defined callback */
  109. bool_t (*callback)(struct svc_req *req,
  110. gss_cred_id_t deleg,
  111. gss_ctx_id_t gss_context,
  112. rpc_gss_lock_t *lock,
  113. void **cookie);
  114. } rpc_gss_callback_t;
  115. /*
  116. * Structure used to return error information by rpc_gss_get_error()
  117. */
  118. typedef struct {
  119. int rpc_gss_error;
  120. int system_error; /* same as errno */
  121. } rpc_gss_error_t;
  122. /*
  123. * Values for rpc_gss_error
  124. */
  125. #define RPC_GSS_ER_SUCCESS 0 /* no error */
  126. #define RPC_GSS_ER_SYSTEMERROR 1 /* system error */
  127. __BEGIN_DECLS
  128. #ifdef _KERNEL
  129. /*
  130. * Set up a structure of entry points for the kgssapi module and inline
  131. * functions named rpc_gss_XXX_call() to use them, so that the kgssapi
  132. * module doesn't need to be loaded for the NFS modules to work using
  133. * AUTH_SYS. The kgssapi modules will be loaded by the gssd(8) daemon
  134. * when it is started up and the entry points will then be filled in.
  135. */
  136. typedef AUTH *rpc_gss_secfind_ftype(CLIENT *clnt, struct ucred *cred,
  137. const char *principal, gss_OID mech_oid,
  138. rpc_gss_service_t service);
  139. typedef void rpc_gss_secpurge_ftype(CLIENT *clnt);
  140. typedef AUTH *rpc_gss_seccreate_ftype(CLIENT *clnt, struct ucred *cred,
  141. const char *clnt_principal, const char *principal,
  142. const char *mechanism, rpc_gss_service_t service,
  143. const char *qop, rpc_gss_options_req_t *options_req,
  144. rpc_gss_options_ret_t *options_ret);
  145. typedef bool_t rpc_gss_set_defaults_ftype(AUTH *auth,
  146. rpc_gss_service_t service, const char *qop);
  147. typedef int rpc_gss_max_data_length_ftype(AUTH *handle,
  148. int max_tp_unit_len);
  149. typedef void rpc_gss_get_error_ftype(rpc_gss_error_t *error);
  150. typedef bool_t rpc_gss_mech_to_oid_ftype(const char *mech, gss_OID *oid_ret);
  151. typedef bool_t rpc_gss_oid_to_mech_ftype(gss_OID oid, const char **mech_ret);
  152. typedef bool_t rpc_gss_qop_to_num_ftype(const char *qop, const char *mech,
  153. u_int *num_ret);
  154. typedef const char **rpc_gss_get_mechanisms_ftype(void);
  155. typedef bool_t rpc_gss_get_versions_ftype(u_int *vers_hi, u_int *vers_lo);
  156. typedef bool_t rpc_gss_is_installed_ftype(const char *mech);
  157. typedef bool_t rpc_gss_set_svc_name_ftype(const char *principal,
  158. const char *mechanism, u_int req_time, u_int program,
  159. u_int version);
  160. typedef void rpc_gss_clear_svc_name_ftype(u_int program, u_int version);
  161. typedef bool_t rpc_gss_getcred_ftype(struct svc_req *req,
  162. rpc_gss_rawcred_t **rcred,
  163. rpc_gss_ucred_t **ucred, void **cookie);
  164. typedef bool_t rpc_gss_set_callback_ftype(rpc_gss_callback_t *cb);
  165. typedef void rpc_gss_clear_callback_ftype(rpc_gss_callback_t *cb);
  166. typedef bool_t rpc_gss_get_principal_name_ftype(rpc_gss_principal_t *principal,
  167. const char *mech, const char *name, const char *node,
  168. const char *domain);
  169. typedef int rpc_gss_svc_max_data_length_ftype(struct svc_req *req,
  170. int max_tp_unit_len);
  171. typedef void rpc_gss_refresh_auth_ftype(AUTH *auth);
  172. typedef bool_t rpc_gss_ip_to_srv_principal_ftype(char *ip_addr,
  173. const char *srv_name, char *dns_name);
  174. struct rpc_gss_entries {
  175. rpc_gss_secfind_ftype *rpc_gss_secfind;
  176. rpc_gss_secpurge_ftype *rpc_gss_secpurge;
  177. rpc_gss_seccreate_ftype *rpc_gss_seccreate;
  178. rpc_gss_set_defaults_ftype *rpc_gss_set_defaults;
  179. rpc_gss_max_data_length_ftype *rpc_gss_max_data_length;
  180. rpc_gss_get_error_ftype *rpc_gss_get_error;
  181. rpc_gss_mech_to_oid_ftype *rpc_gss_mech_to_oid;
  182. rpc_gss_oid_to_mech_ftype *rpc_gss_oid_to_mech;
  183. rpc_gss_qop_to_num_ftype *rpc_gss_qop_to_num;
  184. rpc_gss_get_mechanisms_ftype *rpc_gss_get_mechanisms;
  185. rpc_gss_get_versions_ftype *rpc_gss_get_versions;
  186. rpc_gss_is_installed_ftype *rpc_gss_is_installed;
  187. rpc_gss_set_svc_name_ftype *rpc_gss_set_svc_name;
  188. rpc_gss_clear_svc_name_ftype *rpc_gss_clear_svc_name;
  189. rpc_gss_getcred_ftype *rpc_gss_getcred;
  190. rpc_gss_set_callback_ftype *rpc_gss_set_callback;
  191. rpc_gss_clear_callback_ftype *rpc_gss_clear_callback;
  192. rpc_gss_get_principal_name_ftype *rpc_gss_get_principal_name;
  193. rpc_gss_svc_max_data_length_ftype *rpc_gss_svc_max_data_length;
  194. rpc_gss_refresh_auth_ftype *rpc_gss_refresh_auth;
  195. rpc_gss_ip_to_srv_principal_ftype *rpc_gss_ip_to_srv_principal;
  196. };
  197. extern struct rpc_gss_entries rpc_gss_entries;
  198. /* Functions to access the entry points. */
  199. static __inline AUTH *
  200. rpc_gss_secfind_call(CLIENT *clnt, struct ucred *cred, const char *principal,
  201. gss_OID mech_oid, rpc_gss_service_t service)
  202. {
  203. AUTH *ret = NULL;
  204. if (rpc_gss_entries.rpc_gss_secfind != NULL)
  205. ret = (*rpc_gss_entries.rpc_gss_secfind)(clnt, cred, principal,
  206. mech_oid, service);
  207. return (ret);
  208. }
  209. static __inline void
  210. rpc_gss_secpurge_call(CLIENT *clnt)
  211. {
  212. if (rpc_gss_entries.rpc_gss_secpurge != NULL)
  213. (*rpc_gss_entries.rpc_gss_secpurge)(clnt);
  214. }
  215. static __inline AUTH *
  216. rpc_gss_seccreate_call(CLIENT *clnt, struct ucred *cred,
  217. const char *clnt_principal, const char *principal, const char *mechanism,
  218. rpc_gss_service_t service, const char *qop,
  219. rpc_gss_options_req_t *options_req, rpc_gss_options_ret_t *options_ret)
  220. {
  221. AUTH *ret = NULL;
  222. if (rpc_gss_entries.rpc_gss_seccreate != NULL)
  223. ret = (*rpc_gss_entries.rpc_gss_seccreate)(clnt, cred,
  224. clnt_principal, principal, mechanism, service, qop,
  225. options_req, options_ret);
  226. return (ret);
  227. }
  228. static __inline bool_t
  229. rpc_gss_set_defaults_call(AUTH *auth, rpc_gss_service_t service,
  230. const char *qop)
  231. {
  232. bool_t ret = 1;
  233. if (rpc_gss_entries.rpc_gss_set_defaults != NULL)
  234. ret = (*rpc_gss_entries.rpc_gss_set_defaults)(auth, service,
  235. qop);
  236. return (ret);
  237. }
  238. static __inline int
  239. rpc_gss_max_data_length_call(AUTH *handle, int max_tp_unit_len)
  240. {
  241. int ret = 0;
  242. if (rpc_gss_entries.rpc_gss_max_data_length != NULL)
  243. ret = (*rpc_gss_entries.rpc_gss_max_data_length)(handle,
  244. max_tp_unit_len);
  245. return (ret);
  246. }
  247. static __inline void
  248. rpc_gss_get_error_call(rpc_gss_error_t *error)
  249. {
  250. if (rpc_gss_entries.rpc_gss_get_error != NULL)
  251. (*rpc_gss_entries.rpc_gss_get_error)(error);
  252. }
  253. static __inline bool_t
  254. rpc_gss_mech_to_oid_call(const char *mech, gss_OID *oid_ret)
  255. {
  256. bool_t ret = 1;
  257. if (rpc_gss_entries.rpc_gss_mech_to_oid != NULL)
  258. ret = (*rpc_gss_entries.rpc_gss_mech_to_oid)(mech, oid_ret);
  259. return (ret);
  260. }
  261. static __inline bool_t
  262. rpc_gss_oid_to_mech_call(gss_OID oid, const char **mech_ret)
  263. {
  264. bool_t ret = 1;
  265. if (rpc_gss_entries.rpc_gss_oid_to_mech != NULL)
  266. ret = (*rpc_gss_entries.rpc_gss_oid_to_mech)(oid, mech_ret);
  267. return (ret);
  268. }
  269. static __inline bool_t
  270. rpc_gss_qop_to_num_call(const char *qop, const char *mech, u_int *num_ret)
  271. {
  272. bool_t ret = 1;
  273. if (rpc_gss_entries.rpc_gss_qop_to_num != NULL)
  274. ret = (*rpc_gss_entries.rpc_gss_qop_to_num)(qop, mech, num_ret);
  275. return (ret);
  276. }
  277. static __inline const char **
  278. rpc_gss_get_mechanisms_call(void)
  279. {
  280. const char **ret = NULL;
  281. if (rpc_gss_entries.rpc_gss_get_mechanisms != NULL)
  282. ret = (*rpc_gss_entries.rpc_gss_get_mechanisms)();
  283. return (ret);
  284. }
  285. static __inline bool_t
  286. rpc_gss_get_versions_call(u_int *vers_hi, u_int *vers_lo)
  287. {
  288. bool_t ret = 1;
  289. if (rpc_gss_entries.rpc_gss_get_versions != NULL)
  290. ret = (*rpc_gss_entries.rpc_gss_get_versions)(vers_hi, vers_lo);
  291. return (ret);
  292. }
  293. static __inline bool_t
  294. rpc_gss_is_installed_call(const char *mech)
  295. {
  296. bool_t ret = 1;
  297. if (rpc_gss_entries.rpc_gss_is_installed != NULL)
  298. ret = (*rpc_gss_entries.rpc_gss_is_installed)(mech);
  299. return (ret);
  300. }
  301. static __inline bool_t
  302. rpc_gss_set_svc_name_call(const char *principal, const char *mechanism,
  303. u_int req_time, u_int program, u_int version)
  304. {
  305. bool_t ret = 1;
  306. if (rpc_gss_entries.rpc_gss_set_svc_name != NULL)
  307. ret = (*rpc_gss_entries.rpc_gss_set_svc_name)(principal,
  308. mechanism, req_time, program, version);
  309. return (ret);
  310. }
  311. static __inline void
  312. rpc_gss_clear_svc_name_call(u_int program, u_int version)
  313. {
  314. if (rpc_gss_entries.rpc_gss_clear_svc_name != NULL)
  315. (*rpc_gss_entries.rpc_gss_clear_svc_name)(program, version);
  316. }
  317. static __inline bool_t
  318. rpc_gss_getcred_call(struct svc_req *req, rpc_gss_rawcred_t **rcred,
  319. rpc_gss_ucred_t **ucred, void **cookie)
  320. {
  321. bool_t ret = 1;
  322. if (rpc_gss_entries.rpc_gss_getcred != NULL)
  323. ret = (*rpc_gss_entries.rpc_gss_getcred)(req, rcred, ucred,
  324. cookie);
  325. return (ret);
  326. }
  327. static __inline bool_t
  328. rpc_gss_set_callback_call(rpc_gss_callback_t *cb)
  329. {
  330. bool_t ret = 1;
  331. if (rpc_gss_entries.rpc_gss_set_callback != NULL)
  332. ret = (*rpc_gss_entries.rpc_gss_set_callback)(cb);
  333. return (ret);
  334. }
  335. static __inline void
  336. rpc_gss_clear_callback_call(rpc_gss_callback_t *cb)
  337. {
  338. if (rpc_gss_entries.rpc_gss_clear_callback != NULL)
  339. (*rpc_gss_entries.rpc_gss_clear_callback)(cb);
  340. }
  341. static __inline bool_t
  342. rpc_gss_get_principal_name_call(rpc_gss_principal_t *principal,
  343. const char *mech, const char *name, const char *node, const char *domain)
  344. {
  345. bool_t ret = 1;
  346. if (rpc_gss_entries.rpc_gss_get_principal_name != NULL)
  347. ret = (*rpc_gss_entries.rpc_gss_get_principal_name)(principal,
  348. mech, name, node, domain);
  349. return (ret);
  350. }
  351. static __inline int
  352. rpc_gss_svc_max_data_length_call(struct svc_req *req, int max_tp_unit_len)
  353. {
  354. int ret = 0;
  355. if (rpc_gss_entries.rpc_gss_svc_max_data_length != NULL)
  356. ret = (*rpc_gss_entries.rpc_gss_svc_max_data_length)(req,
  357. max_tp_unit_len);
  358. return (ret);
  359. }
  360. static __inline void
  361. rpc_gss_refresh_auth_call(AUTH *auth)
  362. {
  363. if (rpc_gss_entries.rpc_gss_refresh_auth != NULL)
  364. (*rpc_gss_entries.rpc_gss_refresh_auth)(auth);
  365. }
  366. static __inline bool_t
  367. rpc_gss_ip_to_srv_principal_call(char *ip_addr, const char *srv_name,
  368. char *dns_name)
  369. {
  370. bool_t ret = FALSE;
  371. if (rpc_gss_entries.rpc_gss_ip_to_srv_principal != NULL)
  372. ret = (*rpc_gss_entries.rpc_gss_ip_to_srv_principal)(ip_addr,
  373. srv_name, dns_name);
  374. return (ret);
  375. }
  376. AUTH *rpc_gss_secfind(CLIENT *clnt, struct ucred *cred,
  377. const char *principal, gss_OID mech_oid, rpc_gss_service_t service);
  378. void rpc_gss_secpurge(CLIENT *clnt);
  379. void rpc_gss_refresh_auth(AUTH *auth);
  380. AUTH *rpc_gss_seccreate(CLIENT *clnt, struct ucred *cred,
  381. const char *clnt_principal, const char *principal,
  382. const char *mechanism, rpc_gss_service_t service,
  383. const char *qop, rpc_gss_options_req_t *options_req,
  384. rpc_gss_options_ret_t *options_ret);
  385. #else /* !_KERNEL */
  386. AUTH *rpc_gss_seccreate(CLIENT *clnt, struct ucred *cred,
  387. const char *principal, const char *mechanism, rpc_gss_service_t service,
  388. const char *qop, rpc_gss_options_req_t *options_req,
  389. rpc_gss_options_ret_t *options_ret);
  390. #endif /* _KERNEL */
  391. bool_t rpc_gss_set_defaults(AUTH *auth, rpc_gss_service_t service,
  392. const char *qop);
  393. int rpc_gss_max_data_length(AUTH *handle, int max_tp_unit_len);
  394. void rpc_gss_get_error(rpc_gss_error_t *error);
  395. bool_t rpc_gss_mech_to_oid(const char *mech, gss_OID *oid_ret);
  396. bool_t rpc_gss_oid_to_mech(gss_OID oid, const char **mech_ret);
  397. bool_t rpc_gss_qop_to_num(const char *qop, const char *mech, u_int *num_ret);
  398. const char **rpc_gss_get_mechanisms(void);
  399. const char **rpc_gss_get_mech_info(const char *mech, rpc_gss_service_t *service);
  400. bool_t rpc_gss_get_versions(u_int *vers_hi, u_int *vers_lo);
  401. bool_t rpc_gss_is_installed(const char *mech);
  402. bool_t rpc_gss_set_svc_name(const char *principal, const char *mechanism,
  403. u_int req_time, u_int program, u_int version);
  404. void rpc_gss_clear_svc_name(u_int program, u_int version);
  405. bool_t rpc_gss_getcred(struct svc_req *req, rpc_gss_rawcred_t **rcred,
  406. rpc_gss_ucred_t **ucred, void **cookie);
  407. bool_t rpc_gss_set_callback(rpc_gss_callback_t *cb);
  408. void rpc_gss_clear_callback(rpc_gss_callback_t *cb);
  409. bool_t rpc_gss_get_principal_name(rpc_gss_principal_t *principal,
  410. const char *mech, const char *name, const char *node, const char *domain);
  411. int rpc_gss_svc_max_data_length(struct svc_req *req, int max_tp_unit_len);
  412. bool_t rpc_gss_ip_to_srv_principal(char *ip_addr, const char *srv_name,
  413. char *dns_name);
  414. /*
  415. * Internal interface from the RPC implementation.
  416. */
  417. #ifndef _KERNEL
  418. bool_t __rpc_gss_wrap(AUTH *auth, void *header, size_t headerlen,
  419. XDR* xdrs, xdrproc_t xdr_args, void *args_ptr);
  420. bool_t __rpc_gss_unwrap(AUTH *auth, XDR* xdrs, xdrproc_t xdr_args,
  421. void *args_ptr);
  422. #endif
  423. bool_t __rpc_gss_set_error(int rpc_gss_error, int system_error);
  424. __END_DECLS
  425. #endif /* !_RPCSEC_GSS_H */