diff options
author | Andrew Bartlett <abartlet@samba.org> | 2011-04-16 15:41:50 +1000 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2011-04-27 11:56:48 +1000 |
commit | 6ec4306f8c3fed7ec5b5bd164c5829b2661589b7 (patch) | |
tree | 5384aed4fe934eb82f7487cfc12f9c220ba5184d /auth/kerberos | |
parent | e130dec97bb4e08b11f39c1c1382f0c8ad36ef67 (diff) | |
download | samba-6ec4306f8c3fed7ec5b5bd164c5829b2661589b7.tar.gz samba-6ec4306f8c3fed7ec5b5bd164c5829b2661589b7.tar.bz2 samba-6ec4306f8c3fed7ec5b5bd164c5829b2661589b7.zip |
auth/kerberos: Create common helper to get the verified PAC from GSSAPI
This only works for Heimdal and MIT Krb5 1.8, other versions will get
an ACCESS_DEINED error.
We no longer manually verify any details of the PAC in Samba for
GSSAPI logins, as we never had the information to do it properly, and
it is better to have the GSSAPI library handle it.
Andrew Bartlett
Diffstat (limited to 'auth/kerberos')
-rw-r--r-- | auth/kerberos/gssapi_pac.c | 123 | ||||
-rw-r--r-- | auth/kerberos/wscript_build | 3 |
2 files changed, 126 insertions, 0 deletions
diff --git a/auth/kerberos/gssapi_pac.c b/auth/kerberos/gssapi_pac.c new file mode 100644 index 0000000000..dd2fb7e0a7 --- /dev/null +++ b/auth/kerberos/gssapi_pac.c @@ -0,0 +1,123 @@ +/* + Unix SMB/CIFS implementation. + kerberos authorization data (PAC) utility library + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2011 + Copyright (C) Simo Sorce 2010. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#ifdef HAVE_KRB5 + +#include "libcli/auth/krb5_wrap.h" + +/* The Heimdal OID for getting the PAC */ +#define EXTRACT_PAC_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH 8 +/* EXTRACTION OID AUTHZ ID */ +#define EXTRACT_PAC_AUTHZ_DATA_FROM_SEC_CONTEXT_OID "\x2a\x85\x70\x2b\x0d\x03" "\x81\x00" + +static gss_OID_desc pac_data_oid = { + EXTRACT_PAC_AUTHZ_DATA_FROM_SEC_CONTEXT_OID_LENGTH, + (void *)EXTRACT_PAC_AUTHZ_DATA_FROM_SEC_CONTEXT_OID +}; + +NTSTATUS gssapi_obtain_pac_blob(TALLOC_CTX *mem_ctx, + gss_ctx_id_t gssapi_context, + gss_name_t gss_client_name, + DATA_BLOB *pac_blob) +{ + OM_uint32 gss_maj, gss_min; + gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; + gss_buffer_desc pac_buffer; + gss_buffer_desc pac_display_buffer; + gss_buffer_desc pac_name = { + .value = "urn:mspac:", + .length = sizeof("urn:mspac:")-1 + }; + NTSTATUS status; + int more = -1; + int authenticated = false; + int complete = false; + +#ifdef HAVE_GSS_GET_NAME_ATTRIBUTE + gss_maj = gss_get_name_attribute( + &gss_min, gss_client_name, &pac_name, + &authenticated, &complete, + &pac_buffer, &pac_display_buffer, &more); + + if (gss_maj != 0) { + DEBUG(0, ("obtaining PAC via GSSAPI gss_get_name_attribute failed: %s\n", + gssapi_error_string(mem_ctx, gss_maj, gss_min, gss_mech_krb5))); + return NT_STATUS_ACCESS_DENIED; + } else if (authenticated && complete) { + /* The PAC blob is returned directly */ + *pac_blob = data_blob_talloc(mem_ctx, pac_buffer.value, + pac_buffer.length); + + if (!pac_blob->data) { + status = NT_STATUS_NO_MEMORY; + } else { + status = NT_STATUS_OK; + } + + gss_maj = gss_release_buffer(&gss_min, &pac_buffer); + gss_maj = gss_release_buffer(&gss_min, &pac_display_buffer); + return status; + } else { + DEBUG(0, ("obtaining PAC via GSSAPI failed: authenticated: %s, complete: %s, more: %s\n", + authenticated ? "true" : "false", + complete ? "true" : "false", + more ? "true" : "false")); + return NT_STATUS_ACCESS_DENIED; + } + +#endif + /* If we didn't have the routine to get a verified, validated + * PAC (supplied only by MIT at the time of writing), then try + * with the Heimdal OID (fetches the PAC directly and always + * validates) */ + gss_maj = gss_inquire_sec_context_by_oid( + &gss_min, gssapi_context, + &pac_data_oid, &set); + + /* First check for the error MIT gives for an unknown OID */ + if (gss_maj == GSS_S_UNAVAILABLE) { + DEBUG(1, ("unable to obtain a PAC against this GSSAPI library. " + "GSSAPI secured connections are available only with Heimdal or MIT Kerberos >= 1.8\n")); + } else if (gss_maj != 0) { + DEBUG(2, ("obtaining PAC via GSSAPI gss_inqiure_sec_context_by_oid (Heimdal OID) failed: %s\n", + gssapi_error_string(mem_ctx, gss_maj, gss_min, gss_mech_krb5))); + } else { + if (set == GSS_C_NO_BUFFER_SET) { + DEBUG(0, ("gss_inquire_sec_context_by_oid returned unknown " + "data in results.\n")); + return NT_STATUS_INTERNAL_ERROR; + } + + /* The PAC blob is returned directly */ + *pac_blob = data_blob_talloc(mem_ctx, set->elements[0].value, + set->elements[0].length); + if (!pac_blob->data) { + status = NT_STATUS_NO_MEMORY; + } else { + status = NT_STATUS_OK; + } + + gss_maj = gss_release_buffer_set(&gss_min, &set); + return status; + } + return NT_STATUS_ACCESS_DENIED; +} +#endif diff --git a/auth/kerberos/wscript_build b/auth/kerberos/wscript_build new file mode 100644 index 0000000000..c289aab839 --- /dev/null +++ b/auth/kerberos/wscript_build @@ -0,0 +1,3 @@ +bld.SAMBA_SUBSYSTEM('KRB5_PAC', + source='gssapi_pac.c', + deps='gssapi_krb5 krb5 ndr-krb5pac') |