blob: 17d0039145a5c968c0ad93e161b50ccd546524c8 [file] [log] [blame]
/*
* Copyright (c) 2012 Linux Box Corporation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GSS_INTERNAL_H
#define GSS_INTERNAL_H
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <pthread.h>
#include <reentrant.h>
#include <sys/types.h>
#include <rpc/rpc.h>
#include <misc/rbtree_x.h>
#include <misc/queue.h>
#include <misc/abstract_atomic.h>
#include <intrinsic.h>
#ifdef HAVE_HEIMDAL
#include <gssapi.h>
#define gss_nt_service_name GSS_C_NT_HOSTBASED_SERVICE
#else
#include <gssapi/gssapi.h>
#include <gssapi/gssapi_generic.h>
#include <gssapi/gssapi_ext.h>
#endif
#include <rpc/auth_gss.h>
extern SVCAUTH svc_auth_none;
#define SVCAUTH_PRIVATE(auth) \
((struct svc_rpc_gss_data *)(auth)->svc_ah_private)
/*
* from mit-krb5-1.2.1 mechglue/mglueP.h:
* Array of context IDs typed by mechanism OID
*/
struct gss_union_ctx_id {
gss_OID mech_type;
gss_ctx_id_t internal_ctx_id;
};
typedef struct gss_union_ctx_id gss_union_ctx_id_desc;
typedef gss_union_ctx_id_desc *gss_union_ctx_id_t;
#define SVC_RPC_GSS_FLAG_NONE 0x0000
#define SVC_RPC_GSS_FLAG_MSPAC 0x0001
#define SVC_RPC_GSS_FLAG_LOCKED 0x0002
struct svc_rpc_gss_data {
struct opr_rbtree_node node_k;
TAILQ_ENTRY(svc_rpc_gss_data) lru_q;
mutex_t lock;
uint32_t flags;
uint32_t refcnt;
uint32_t gen;
struct {
uint32_t k;
} hk;
bool established;
gss_ctx_id_t ctx; /* context id */
struct rpc_gss_sec sec; /* security triple */
gss_buffer_desc cname; /* GSS client name */
u_int seq;
u_int win;
u_int seqlast;
uint32_t seqmask;
gss_name_t client_name;
gss_buffer_desc checksum;
struct {
/* extended krb5 ticket ("pac") data */
gss_buffer_desc ms_pac;
} pac;
SVCAUTH *auth;
uint32_t endtime;
};
bool svcauth_gss_destroy(SVCAUTH *auth);
static inline struct
svc_rpc_gss_data *alloc_svc_rpc_gss_data(void)
{
struct svc_rpc_gss_data *gd =
(struct svc_rpc_gss_data *)
mem_zalloc(sizeof(struct svc_rpc_gss_data));
mutex_init(&gd->lock, NULL);
TAILQ_INIT_ENTRY(gd, lru_q);
gd->refcnt = 1;
return (gd);
}
static inline void
unref_svc_rpc_gss_data(struct svc_rpc_gss_data *gd,
uint32_t flags)
{
u_int refcnt;
bool gd_locked = flags & SVC_RPC_GSS_FLAG_LOCKED;
refcnt = atomic_dec_uint32_t(&gd->refcnt);
/* if refcnt is 0, gd is not reachable */
if (unlikely(refcnt == 0)) {
if (!gd_locked) {
mutex_lock(&gd->lock);
gd_locked = true;
if (likely(refcnt == 0)) {
mutex_unlock(&gd->lock);
/* XXX disposes gd */
svcauth_gss_destroy(gd->auth);
return;
}
}
}
if (gd_locked)
mutex_unlock(&gd->lock);
}
struct svc_rpc_gss_data *authgss_ctx_hash_get(struct rpc_gss_cred *gc);
bool authgss_ctx_hash_set(struct svc_rpc_gss_data *gd);
bool authgss_ctx_hash_del(struct svc_rpc_gss_data *gd);
bool svcauth_gss_acquire_cred(void);
bool svcauth_gss_release_cred(void);
bool svcauth_gss_import_name(char *service);
bool svcauth_gss_set_svc_name(gss_name_t name);
#endif /* GSS_INTERNAL_H */