SERVER_MANS = rpc_svc_calls.3t rpc_svc_create.3t rpc_svc_err.3t \
rpc_svc_reg.3t
GENERIC_MANS = rpc.3t rpc_xdr.3t
-RPCSEC_MANS = rpcsec_gss.3t
+RPCSEC_MANS = rpcsec_gss.3t rpc_gss_get_error.3t \
+ rpc_gss_get_mechanisms.3t rpc_gss_get_mech_info.3t \
+ rpc_gss_get_versions.3t rpc_gss_is_installed.3t \
+ rpc_gss_mech_to_oid.3t rpc_gss_qop_to_num.3t
dist_man5_MANS = netconfig.5
dist_man3_MANS = $(LOOKUP_MANS) $(NETCONFIG_MANS) \
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_GET_ERROR 3
+.Os
+.Sh NAME
+.Nm rpc_gss_get_error
+.Nd "Get error details"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft void
+.Fn rpc_gss_get_error "rpc_gss_error_t *error"
+.Sh DESCRIPTION
+Get details of the last RPCSEC_GSS error.
+.Sh PARAMETERS
+.Bl -tag -width ".It error"
+.It error
+A pointer to a structure where the error details will be returned
+.El
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_get_error
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_GET_MECH_INFO 3
+.Os
+.Sh NAME
+.Nm rpc_gss_get_mech_info
+.Nd "Get extra information about a security mechanism"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft const char **
+.Fn rpc_gss_get_mech_info "const char *mech" "rpc_gss_service_t *service"
+.Sh DESCRIPTION
+This function looks up a mechanism by name by reading the file
+/etc/gss/mech and queries it for its capabilities.
+.Sh PARAMETERS
+.Bl -tag -width ".It service"
+.It mech
+The mechanism to search for
+.It service
+If the mechanism is found, the maximum supported service type is
+returned in
+.Fa *service
+.El
+.Sh RETURN VALUES
+If the mechanism is found,
+a list of the supported qualities of protection is returned,
+otherwise
+.Dv NULL .
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_get_mech_info
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_GET_MECHANISMS 3
+.Os
+.Sh NAME
+.Nm rpc_gss_get_mechanisms
+.Nd "Get installed mechanisms"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft const char **
+.Fn rpc_gss_get_mechanisms "void"
+.Sh DESCRIPTION
+Return a
+.Dv NULL
+terminated list of installed security mechanisms.
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_get_mechanisms
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_GET_VERSIONS 3
+.Os
+.Sh NAME
+.Nm rpc_gss_get_versions
+.Nd "Get supported protocol version"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft bool_t
+.Fn rpc_gss_get_versions "u_int *vers_hi" "u_int *vers_lo"
+.Sh DESCRIPTION
+Return the highest and lowest supported versions of the RPCSEC_GSS protocol.
+.Sh PARAMETERS
+.Bl -tag -width ".It vers_lo"
+.It vers_hi
+The value of
+.Fa *vers_hi
+is set to the highest supported protocol version
+.It vers_lo
+The value of
+.Fa *vers_lo
+is set to the lowest supported protocol version
+.El
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_get_versions
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_IS_INSTALLED 3
+.Os
+.Sh NAME
+.Nm rpc_gss_is_installed
+.Nd "Query for the presence os a security mechanism"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft bool_t
+.Fn rpc_gss_is_installed "const char *mech"
+.Sh DESCRIPTION
+This function looks up a mechanism by name by reading the file
+/etc/gss/mech.
+.Sh PARAMETERS
+.Bl -tag -width ".It mech"
+.It mech
+The mechanism to search for
+.El
+.Sh RETURN VALUES
+Returns
+.Dv TRUE
+if the mechanism is installed,
+.Dv FALSE
+otherwise.
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_is_installed
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_MECH_TO_OID 3
+.Os
+.Sh NAME
+.Nm rpc_gss_mech_to_oid
+.Nd "Convert a mechanism name to a GSS-API oid"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft bool_t
+.Fn rpc_gss_mech_to_oid "const char *mech" "gss_OID *oid_ret"
+.Sh DESCRIPTION
+This function looks up a mechanism by name by reading the file
+/etc/gss/mech.
+.Sh PARAMETERS
+.Bl -tag -width ".It oid_ret"
+.It mech
+The mechanism name to search for
+.It oid_ret
+If the mechanism is found, the corresponding GSS-API oid is returned
+in
+.Fa *oid_ret
+.El
+.Sh RETURN VALUES
+If the mechanism is found,
+.Dv TRUE
+is returned, otherwise
+.Dv FALSE .
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_mech_to_oid
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
--- /dev/null
+.\" Copyright (c) 2008 Isilon Inc http://www.isilon.com/
+.\" Authors: Doug Rabson <dfr@rabson.org>
+.\" Developed with Red Inc: Alfred Perlstein <alfred@FreeBSD.org>
+.\"
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+.\"
+.\" $FreeBSD$
+.Dd January 26, 2010
+.Dt RPC_GSS_QOP_TO_NUM 3
+.Os
+.Sh NAME
+.Nm rpc_gss_qop_to_num
+.Nd "Convert a quality of protection name to number"
+.Sh SYNOPSIS
+.In rpc/rpcsec_gss.h
+.Ft bool_t
+.Fn rpc_gss_qop_to_num "const char *qop" "const char *mech" "u_int *num_ret"
+.Sh DESCRIPTION
+This function looks up a quality of protection by name by reading the file
+/etc/gss/qop.
+.Sh PARAMETERS
+.Bl -tag -width ".It number_ret"
+.It qop
+The quality of protection to search for
+.It mech
+The mechanism name to search for
+.It number_ret
+If the quality of protection is found, the corresponding number is
+returned in
+.Fa *num_ret
+.El
+.Sh RETURN VALUES
+If the value is found,
+.Dv TRUE
+is returned, otherwise
+.Dv FALSE .
+.Sh AVAILABILITY
+The
+.Fn rpc_gss_qop_to_num
+function is part of libtirpc.
+.Sh SEE ALSO
+.Xr rpc 3 ,
+.Xr gssapi 3 ,
+.Xr rpcsec_gss 3
+.Sh AUTHORS
+This
+manual page was written by
+.An Doug Rabson Aq dfr@FreeBSD.org .
## Secure-RPC
if GSS
- libtirpc_la_SOURCES += auth_gss.c authgss_prot.c svc_auth_gss.c
+ libtirpc_la_SOURCES += auth_gss.c authgss_prot.c svc_auth_gss.c \
+ rpc_gss_utils.c
libtirpc_la_LDFLAGS += $(GSSAPI_LIBS)
libtirpc_la_CFLAGS += -DHAVE_RPCSEC_GSS $(GSSAPI_CFLAGS)
endif
thread_key_t udp_key = KEY_INITIALIZER;
thread_key_t nc_key = KEY_INITIALIZER;
thread_key_t rce_key = KEY_INITIALIZER;
+thread_key_t rg_key = KEY_INITIALIZER;
/* xprtlist (svc_generic.c) */
pthread_mutex_t xprtlist_lock = PTHREAD_MUTEX_INITIALIZER;
pthread_key_delete(nc_key);
if (rce_key != KEY_INITIALIZER)
pthread_key_delete(rce_key);
+ if (rg_key != KEY_INITIALIZER)
+ pthread_key_delete(rce_key);
return;
}
--- /dev/null
+/*
+ * Copyright (c) 2013, Oracle America, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * - Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * - 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.
+ * - Neither the name of "Oracle America, Inc." nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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.
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <reentrant.h>
+
+#include <rpc/auth_gss.h>
+#include <rpc/rpcsec_gss.h>
+
+#include <gssapi/gssapi_krb5.h>
+
+/* Internal only */
+void rpc_gss_set_error(int);
+void rpc_gss_clear_error(void);
+bool_t rpc_gss_oid_to_mech(rpc_gss_OID, char **);
+
+/*
+ * Return the static "_rpc_gss_error" if we are the main thread
+ * (including non-threaded programs), or if an allocation fails.
+ */
+static rpc_gss_error_t *
+__rpc_gss_error(void)
+{
+ static rpc_gss_error_t _rpc_gss_error = { 0, 0 };
+ extern thread_key_t rg_key;
+ rpc_gss_error_t *result;
+
+ if (rg_key == KEY_INITIALIZER) {
+ static mutex_t _rpc_gss_error_lock = MUTEX_INITIALIZER;
+ int err = 0;
+
+ mutex_lock(&_rpc_gss_error_lock);
+ if (rg_key == KEY_INITIALIZER)
+ err = thr_keycreate(&rg_key, free);
+ mutex_unlock(&_rpc_gss_error_lock);
+
+ if (err != 0)
+ return &_rpc_gss_error;
+ }
+
+ result = thr_getspecific(rg_key);
+ if (result == NULL) {
+ result = calloc(1, sizeof(*result));
+ if (result == NULL)
+ return &_rpc_gss_error;
+
+ if (thr_setspecific(rg_key, result) != 0) {
+ free(result);
+ return &_rpc_gss_error;
+ }
+ }
+
+ return result;
+}
+
+/*
+ * External API: Retrieve thread-specific error values
+ *
+ * error: address of rpc_gss_error_t structure to fill in
+ */
+void
+rpc_gss_get_error(rpc_gss_error_t *result)
+{
+ rpc_gss_error_t *error = __rpc_gss_error();
+
+ result->rpc_gss_error = error->rpc_gss_error;
+ result->system_error = error->system_error;
+}
+
+/*
+ * Internal only: Set thread-specific error value
+ *
+ * system_error: new value for thread's .system_error field.
+ * .rpc_gss_error is always set to RPC_GSS_ER_SYSTEMERROR.
+ */
+void
+rpc_gss_set_error(int system_error)
+{
+ rpc_gss_error_t *error = __rpc_gss_error();
+
+ error->rpc_gss_error = RPC_GSS_ER_SYSTEMERROR;
+ error->system_error = system_error;
+}
+
+/*
+ * Internal only: Clear thread-specific error values
+ */
+void
+rpc_gss_clear_error(void)
+{
+ rpc_gss_error_t *error = __rpc_gss_error();
+
+ error->rpc_gss_error = RPC_GSS_ER_SUCCESS;
+ error->system_error = 0;
+}
+
+/*
+ * On Solaris, the GSS-API implementation consults the files
+ * /etc/gss/mech and /etc/gss/qop for a mapping of mechanism
+ * names to OIDs, and QOP names to numbers.
+ *
+ * GNU's GSS-API has no such database. We emulate it here
+ * with a built-in table of supported mechanisms and qops,
+ * since the set of supported mechanisms is unlikely to
+ * change often.
+ */
+
+struct _rpc_gss_qop {
+ char *qi_name;
+ unsigned int qi_num;
+};
+
+struct _rpc_gss_mechanism {
+ char *mi_name;
+ rpc_gss_OID_desc mi_oid;
+ char **mi_qop_names;
+ struct _rpc_gss_qop **mi_qops;
+};
+
+
+static struct _rpc_gss_qop _rpc_gss_qop_default = {
+ .qi_name = "GSS_C_QOP_DEFAULT",
+ .qi_num = GSS_C_QOP_DEFAULT,
+};
+
+static struct _rpc_gss_qop *_rpc_gss_krb5_qops[] = {
+ &_rpc_gss_qop_default,
+ NULL,
+};
+
+static char *_rpc_gss_krb5_qop_names[] = {
+ "GSS_C_QOP_DEFAULT",
+ NULL,
+};
+
+static struct _rpc_gss_mechanism _rpc_gss_mech_kerberos_v5 = {
+ .mi_name = "kerberos_v5",
+ .mi_oid = { 9, "\052\206\110\206\367\022\001\002\002" },
+ .mi_qop_names = _rpc_gss_krb5_qop_names,
+ .mi_qops = _rpc_gss_krb5_qops,
+};
+
+static struct _rpc_gss_mechanism *_rpc_gss_mechanisms[] = {
+ &_rpc_gss_mech_kerberos_v5,
+ NULL,
+};
+
+static char *_rpc_gss_mechanism_names[] = {
+ "kerberos_v5",
+ NULL,
+};
+
+static struct _rpc_gss_mechanism *
+_rpc_gss_find_mechanism(char *mechanism)
+{
+ unsigned int i;
+
+ for (i = 0; _rpc_gss_mechanisms[i] != NULL; i++)
+ if (strcmp(mechanism, _rpc_gss_mechanisms[i]->mi_name) == 0)
+ return _rpc_gss_mechanisms[i];
+ return NULL;
+}
+
+static struct _rpc_gss_mechanism *
+_rpc_gss_find_oid(rpc_gss_OID oid)
+{
+ unsigned int i;
+
+ for (i = 0; _rpc_gss_mechanisms[i] != NULL; i++)
+ if (g_OID_equal(oid, &_rpc_gss_mechanisms[i]->mi_oid))
+ return _rpc_gss_mechanisms[i];
+ return NULL;
+}
+
+static struct _rpc_gss_qop *
+_rpc_gss_find_qop_by_name(struct _rpc_gss_mechanism *m, char *qop)
+{
+ unsigned int i;
+
+ for (i = 0; m->mi_qops[i] != NULL; i++)
+ if (strcmp(qop, m->mi_qops[i]->qi_name) == 0)
+ return m->mi_qops[i];
+ return NULL;
+}
+
+static struct _rpc_gss_qop *
+_rpc_gss_find_qop_by_num(struct _rpc_gss_mechanism *m, u_int num)
+{
+ unsigned int i;
+
+ for (i = 0; m->mi_qops[i] != NULL; i++)
+ if (num == m->mi_qops[i]->qi_num)
+ return m->mi_qops[i];
+ return NULL;
+}
+
+/*
+ * External API: Return array of security mechanism names
+ *
+ * Returns NULL-terminated array of pointers to NUL-terminated C
+ * strings, each containing a mechanism name. This is statically
+ * allocated memory. Caller must not free this array.
+ */
+char **
+rpc_gss_get_mechanisms(void)
+{
+ rpc_gss_clear_error();
+ return (char **)_rpc_gss_mechanism_names;
+}
+
+/*
+ * External API: Return array of qop names for a security mechanism
+ *
+ * mechanism: NUL-terminated C string containing mechanism name
+ * dummy: address of a service enum
+ *
+ * Returns NULL-terminated array of pointers to NUL-terminated C
+ * strings, each containing a qop name. This is statically
+ * allocated memory. Caller must not free this array.
+ */
+char **
+rpc_gss_get_mech_info(char *mechanism, rpc_gss_service_t *dummy)
+{
+ struct _rpc_gss_mechanism *m;
+
+ if (mechanism == NULL || dummy == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return NULL;
+ }
+
+ m = _rpc_gss_find_mechanism(mechanism);
+ if (m == NULL) {
+ rpc_gss_set_error(ENOENT);
+ return NULL;
+ }
+
+ rpc_gss_clear_error();
+ *dummy = rpcsec_gss_svc_privacy;
+ return (char **)m->mi_qop_names;
+}
+
+/*
+ * External API: Return range of supported RPCSEC_GSS versions
+ *
+ * high: address of highest supported version to fill in
+ * low: address of lowest supported version to fill in
+ *
+ * Returns TRUE if successful, or FALSE if an error occurs.
+ */
+bool_t
+rpc_gss_get_versions(u_int *high, u_int *low)
+{
+ if (high == NULL || low == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ rpc_gss_clear_error();
+ *high = *low = RPCSEC_GSS_VERSION;
+ return TRUE;
+}
+
+/*
+ * External API: Check if a security mechanism is supported
+ *
+ * mechanism: NUL-terminated C string containing mechanism name
+ *
+ * Returns TRUE if the mechanism name is recognized and supported,
+ * otherwise FALSE is returned.
+ */
+bool_t
+rpc_gss_is_installed(char *mechanism)
+{
+ struct _rpc_gss_mechanism *m;
+
+ if (mechanism == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ rpc_gss_clear_error();
+ m = _rpc_gss_find_mechanism(mechanism);
+ if (m == NULL)
+ return FALSE;
+ return TRUE;
+}
+
+/*
+ * External API: Return the OID for a given security mechanism
+ *
+ * mechanism: NUL-terminated C string containing mechanism name
+ * oid: address of OID buffer to fill in
+ *
+ * Returns TRUE if the mechanism name is recognized and supported,
+ * otherwise FALSE is returned.
+ */
+bool_t
+rpc_gss_mech_to_oid(char *mechanism, rpc_gss_OID *result)
+{
+ struct _rpc_gss_mechanism *m;
+
+ if (mechanism == NULL || result == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ m = _rpc_gss_find_mechanism(mechanism);
+ if (m == NULL) {
+ rpc_gss_set_error(ENOENT);
+ return FALSE;
+ }
+
+ *result = &m->mi_oid;
+ rpc_gss_clear_error();
+ return TRUE;
+}
+
+/*
+ * Internal only: Return the mechanism name for a given OID
+ *
+ * oid: GSS mechanism OID
+ * mechanism: address of a char * to fill in. This is statically
+ * allocated memory. Caller must not free this memory.
+ *
+ * Returns TRUE if the OID is a recognized and supported mechanism,
+ * otherwise FALSE is returned.
+ */
+bool_t
+rpc_gss_oid_to_mech(rpc_gss_OID oid, char **mechanism)
+{
+ struct _rpc_gss_mechanism *m;
+
+ if (oid == NULL || mechanism == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ m = _rpc_gss_find_oid(oid);
+ if (m == NULL) {
+ rpc_gss_set_error(ENOENT);
+ return FALSE;
+ }
+
+ *mechanism = m->mi_name;
+ rpc_gss_clear_error();
+ return TRUE;
+}
+
+/*
+ * External API: Return the QOP number for a given QOP and mechanism name
+ *
+ * qop: NUL-terminated C string containing qop name
+ * mechanism: NUL-terminated C string containing mechanism name
+ * num: address of QOP buffer to fill in
+ *
+ * Returns TRUE if the qop and mechanism name are recognized and
+ * supported, otherwise FALSE is returned.
+ */
+bool_t
+rpc_gss_qop_to_num(char *qop, char *mechanism, u_int *num)
+{
+ struct _rpc_gss_mechanism *m;
+ struct _rpc_gss_qop *q;
+
+ if (qop == NULL || mechanism == NULL || num == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ m = _rpc_gss_find_mechanism(mechanism);
+ if (m == NULL)
+ goto out_err;
+
+ q = _rpc_gss_find_qop_by_name(m, qop);
+ if (q == NULL)
+ goto out_err;
+
+ *num = q->qi_num;
+ rpc_gss_clear_error();
+ return TRUE;
+
+out_err:
+ rpc_gss_set_error(ENOENT);
+ return FALSE;
+}
+
+/*
+ * Internal only: Return the QOP name for a given mechanism and QOP number
+ *
+ * mechanism: NUL-terminated C string containing security mechanism name
+ * num: QOP number
+ * qop: address of a char * to fill in. This is statically
+ * allocated memory. Caller must not free this memory.
+ *
+ * Returns TRUE if the QOP and mechanism are recognized and supported,
+ * otherwise FALSE is returned.
+ */
+bool_t
+rpc_gss_num_to_qop(char *mechanism, u_int num, char **qop)
+{
+ struct _rpc_gss_mechanism *m;
+ struct _rpc_gss_qop *q;
+
+ if (mechanism == NULL || qop == NULL) {
+ rpc_gss_set_error(EINVAL);
+ return FALSE;
+ }
+
+ m = _rpc_gss_find_mechanism(mechanism);
+ if (m == NULL)
+ goto out_err;
+
+ q = _rpc_gss_find_qop_by_num(m, num);
+ if (q == NULL)
+ goto out_err;
+
+ *qop = q->qi_name;
+ rpc_gss_clear_error();
+ return TRUE;
+
+out_err:
+ rpc_gss_set_error(ENOENT);
+ return FALSE;
+}