summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-08-04 11:49:23 -0400
committerSimo Sorce <simo@redhat.com>2014-08-07 12:44:46 -0400
commitc0ab9d46730db8196ce46fa3e346009d30cee029 (patch)
tree79b1a2bfeac04cf853547770286de6a2f341055c
parent90dac37d9d15004dd425b3139ab8141113c245e1 (diff)
downloadgss-ntlmssp-c0ab9d46730db8196ce46fa3e346009d30cee029.tar.gz
gss-ntlmssp-c0ab9d46730db8196ce46fa3e346009d30cee029.tar.xz
gss-ntlmssp-c0ab9d46730db8196ce46fa3e346009d30cee029.zip
Add external server auth support via Winbind
If wbclient support is available we can now check domain credentials against a Domain Controller. Requires a configured Winbind (or cmpatible) service on the host.
-rw-r--r--Makefile.am4
-rw-r--r--src/external.c10
-rw-r--r--src/gss_ntlmssp_winbind.h7
-rw-r--r--src/gss_sec_ctx.c3
-rw-r--r--src/winbind.c55
5 files changed, 77 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 373da29..f2bdbb5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -80,13 +80,15 @@ GN_MECHGLUE_OBJ = \
src/gss_serialize.c \
src/external.c \
src/gss_auth.c \
+ src/winbind.c \
src/gss_ntlmssp.c
dist_noinst_HEADERS = \
src/crypto.h \
src/ntlm_common.h \
src/ntlm.h \
- src/gss_ntlmssp.h
+ src/gss_ntlmssp.h \
+ src/gss_ntlmssp_winbind.h
gssapidir = $(includedir)/gssapi
dist_gssapi_HEADERS = \
diff --git a/src/external.c b/src/external.c
index 07bbaab..a8c41f8 100644
--- a/src/external.c
+++ b/src/external.c
@@ -1,8 +1,13 @@
/* Copyright (C) 2014 GSS-NTLMSSP contributors, see COPYING for License */
+#include "config.h"
#include <errno.h>
#include "gss_ntlmssp.h"
+#if HAVE_WBCLIENT
+#include "gss_ntlmssp_winbind.h"
+#endif
+
uint32_t external_netbios_get_names(char **computer, char **domain)
{
return ENOSYS;
@@ -20,5 +25,10 @@ uint32_t external_srv_auth(char *user, char *domain,
struct ntlm_buffer *lm_chal_resp,
struct ntlm_key *ntlmv2_key)
{
+#if HAVE_WBCLIENT
+ return winbind_srv_auth(user, domain, workstation, challenge,
+ nt_chal_resp, lm_chal_resp, ntlmv2_key);
+#else
return ENOSYS;
+#endif
}
diff --git a/src/gss_ntlmssp_winbind.h b/src/gss_ntlmssp_winbind.h
new file mode 100644
index 0000000..6d57680
--- /dev/null
+++ b/src/gss_ntlmssp_winbind.h
@@ -0,0 +1,7 @@
+/* Copyright (C) 2014 GSS-NTLMSSP contributors, see COPYING for License */
+
+uint32_t winbind_srv_auth(char *user, char *domain,
+ char *workstation, uint8_t *challenge,
+ struct ntlm_buffer *nt_chal_resp,
+ struct ntlm_buffer *lm_chal_resp,
+ struct ntlm_key *ntlmv2_key);
diff --git a/src/gss_sec_ctx.c b/src/gss_sec_ctx.c
index 3f8d569..33e6aa0 100644
--- a/src/gss_sec_ctx.c
+++ b/src/gss_sec_ctx.c
@@ -907,7 +907,8 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
NULL, NULL);
if (retmaj) goto done;
/* We can't handle winbind credentials yet */
- if (usr_cred->type != GSSNTLM_CRED_USER) {
+ if (usr_cred->type != GSSNTLM_CRED_USER &&
+ usr_cred->type != GSSNTLM_CRED_EXTERNAL) {
retmin = EINVAL;
retmaj = GSS_S_CRED_UNAVAIL;
goto done;
diff --git a/src/winbind.c b/src/winbind.c
new file mode 100644
index 0000000..58114fe
--- /dev/null
+++ b/src/winbind.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 2014 GSS-NTLMSSP contributors, see COPYING for License */
+
+#include "config.h"
+
+#if HAVE_WBCLIENT
+#include <errno.h>
+#include <string.h>
+#include "gss_ntlmssp.h"
+#include "gss_ntlmssp_winbind.h"
+
+#include <wbclient.h>
+
+uint32_t winbind_srv_auth(char *user, char *domain,
+ char *workstation, uint8_t *challenge,
+ struct ntlm_buffer *nt_chal_resp,
+ struct ntlm_buffer *lm_chal_resp,
+ struct ntlm_key *ntlmv2_key)
+{
+ struct wbcAuthUserParams wbc_params = { 0 };
+ struct wbcAuthUserInfo *wbc_info = NULL;
+ struct wbcAuthErrorInfo *wbc_err = NULL;
+ wbcErr wbc_status;
+
+ if (ntlmv2_key->length != 16) {
+ return EINVAL;
+ }
+
+ wbc_params.account_name = user;
+ wbc_params.domain_name = domain;
+ wbc_params.workstation_name = workstation;
+ wbc_params.flags = 0;
+ wbc_params.parameter_control =
+ WBC_MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT |
+ WBC_MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
+ wbc_params.level = WBC_AUTH_USER_LEVEL_RESPONSE;
+ memcpy(wbc_params.password.response.challenge, challenge, 8);
+ wbc_params.password.response.nt_length = nt_chal_resp->length;
+ wbc_params.password.response.nt_data = nt_chal_resp->data;
+ wbc_params.password.response.lm_length = lm_chal_resp->length;
+ wbc_params.password.response.lm_data = lm_chal_resp->data;
+
+ wbc_status = wbcAuthenticateUserEx(&wbc_params, &wbc_info, &wbc_err);
+
+ if (!WBC_ERROR_IS_OK(wbc_status)) {
+ /* TODO: use wbcErrorString, to save error message */
+ wbcFreeMemory(wbc_err);
+ return EACCES;
+ }
+
+ memcpy(ntlmv2_key->data, wbc_info->user_session_key, ntlmv2_key->length);
+
+ wbcFreeMemory(wbc_info);
+ return 0;
+}
+#endif