summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimo Sorce <simo@redhat.com>2014-08-08 09:47:19 -0400
committerSimo Sorce <simo@redhat.com>2014-08-08 10:11:05 -0400
commit83a16a65b5c1bb8435505fe7f3b0cc805048821c (patch)
treede24440ea5cb48cbd2bfac97722a37257495de64
parent77b7dd9436db7f1b3a2f2110a58e90341de420c9 (diff)
downloadgss-ntlmssp-83a16a65b5c1bb8435505fe7f3b0cc805048821c.tar.gz
gss-ntlmssp-83a16a65b5c1bb8435505fe7f3b0cc805048821c.tar.xz
gss-ntlmssp-83a16a65b5c1bb8435505fe7f3b0cc805048821c.zip
Improve role managementwinbind
A server can be standalone or domain member, improve role management so we can autodetct which role we should assume as a server.
-rw-r--r--src/gss_ntlmssp.c37
-rw-r--r--src/gss_ntlmssp.h9
-rw-r--r--src/gss_sec_ctx.c20
3 files changed, 49 insertions, 17 deletions
diff --git a/src/gss_ntlmssp.c b/src/gss_ntlmssp.c
index e4a6336..666508b 100644
--- a/src/gss_ntlmssp.c
+++ b/src/gss_ntlmssp.c
@@ -28,8 +28,7 @@ const gss_OID_desc gssntlm_oid = {
.elements = discard_const(GSS_NTLMSSP_OID_STRING)
};
-uint8_t gssntlm_required_security(int security_level,
- enum gssntlm_role role)
+uint8_t gssntlm_required_security(int security_level, struct gssntlm_ctx *ctx)
{
uint8_t resp;
@@ -51,10 +50,10 @@ uint8_t gssntlm_required_security(int security_level,
break;
case 4:
resp |= SEC_NTLM_OK | SEC_EXT_SEC_OK;
- if (role == GSSNTLM_DOMAIN_CONTROLLER) resp &= ~SEC_DC_LM_OK;
+ if (ctx->role == GSSNTLM_DOMAIN_CONTROLLER) resp &= ~SEC_DC_LM_OK;
break;
case 5:
- if (role == GSSNTLM_DOMAIN_CONTROLLER) resp = SEC_DC_V2_OK;
+ if (ctx->role == GSSNTLM_DOMAIN_CONTROLLER) resp = SEC_DC_V2_OK;
resp |= SEC_V2_ONLY | SEC_EXT_SEC_OK;
break;
default:
@@ -65,6 +64,36 @@ uint8_t gssntlm_required_security(int security_level,
return resp;
}
+void gssntlm_set_role(struct gssntlm_ctx *ctx,
+ int desired, char *nb_domain_name)
+{
+ if (desired == GSSNTLM_CLIENT) {
+ ctx->role = GSSNTLM_CLIENT;
+ } else if (nb_domain_name && *nb_domain_name) {
+ ctx->role = GSSNTLM_DOMAIN_SERVER;
+ } else {
+ ctx->role = GSSNTLM_SERVER;
+ }
+}
+
+bool gssntlm_role_is_client(struct gssntlm_ctx *ctx)
+{
+ return (ctx->role == GSSNTLM_CLIENT);
+}
+
+bool gssntlm_role_is_server(struct gssntlm_ctx *ctx)
+{
+ switch (ctx->role) {
+ case GSSNTLM_SERVER:
+ case GSSNTLM_DOMAIN_SERVER:
+ case GSSNTLM_DOMAIN_CONTROLLER:
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
+
bool gssntlm_sec_lm_ok(struct gssntlm_ctx *ctx)
{
switch (ctx->role) {
diff --git a/src/gss_ntlmssp.h b/src/gss_ntlmssp.h
index efae6c7..5777968 100644
--- a/src/gss_ntlmssp.h
+++ b/src/gss_ntlmssp.h
@@ -154,8 +154,13 @@ struct gssntlm_ctx {
time_t expiration_time;
};
-uint8_t gssntlm_required_security(int security_level,
- enum gssntlm_role role);
+uint8_t gssntlm_required_security(int security_level, struct gssntlm_ctx *ctx);
+
+void gssntlm_set_role(struct gssntlm_ctx *ctx,
+ int desired, char *nb_domain_name);
+bool gssntlm_role_is_client(struct gssntlm_ctx *ctx);
+bool gssntlm_role_is_server(struct gssntlm_ctx *ctx);
+
bool gssntlm_sec_lm_ok(struct gssntlm_ctx *ctx);
bool gssntlm_sec_ntlm_ok(struct gssntlm_ctx *ctx);
bool gssntlm_ext_sec_ok(struct gssntlm_ctx *ctx);
diff --git a/src/gss_sec_ctx.c b/src/gss_sec_ctx.c
index 40817b8..4802567 100644
--- a/src/gss_sec_ctx.c
+++ b/src/gss_sec_ctx.c
@@ -127,8 +127,6 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
ctx->gss_flags = req_flags;
- ctx->role = GSSNTLM_CLIENT;
-
ctx->neg_flags = NTLMSSP_DEFAULT_CLIENT_FLAGS;
/*
@@ -204,10 +202,12 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
goto done;
}
+ gssntlm_set_role(ctx, GSSNTLM_CLIENT, nb_domain_name);
+
ctx->neg_flags |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED;
lm_compat_lvl = gssntlm_get_lm_compatibility_level();
- ctx->sec_req = gssntlm_required_security(lm_compat_lvl, ctx->role);
+ ctx->sec_req = gssntlm_required_security(lm_compat_lvl, ctx);
if (ctx->sec_req == 0xff) {
retmaj = GSS_S_FAILURE;
goto done;
@@ -285,7 +285,7 @@ uint32_t gssntlm_init_sec_context(uint32_t *minor_status,
} else {
- if (ctx->role != GSSNTLM_CLIENT) {
+ if (!gssntlm_role_is_client(ctx)) {
retmaj = GSS_S_NO_CONTEXT;
goto done;
}
@@ -631,13 +631,10 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
goto done;
}
- /* FIXME: add call to determine if we are any other type of
- * server, including setting up callbacks to perform validation
- * against a remote DC */
- ctx->role = GSSNTLM_SERVER;
+ gssntlm_set_role(ctx, GSSNTLM_SERVER, nb_domain_name);
lm_compat_lvl = gssntlm_get_lm_compatibility_level();
- ctx->sec_req = gssntlm_required_security(lm_compat_lvl, ctx->role);
+ ctx->sec_req = gssntlm_required_security(lm_compat_lvl, ctx);
if (ctx->sec_req == 0xff) {
retmaj = GSS_S_FAILURE;
goto done;
@@ -779,7 +776,8 @@ uint32_t gssntlm_accept_sec_context(uint32_t *minor_status,
} else {
ctx = (struct gssntlm_ctx *)(*context_handle);
- if (ctx->role != GSSNTLM_SERVER) {
+ if (!gssntlm_role_is_server(ctx)) {
+ retmin = EINVAL;
retmaj = GSS_S_NO_CONTEXT;
goto done;
}
@@ -1060,7 +1058,7 @@ uint32_t gssntlm_inquire_context(uint32_t *minor_status,
}
if (locally_initiated) {
- if (ctx->role == GSSNTLM_CLIENT) {
+ if (gssntlm_role_is_client(ctx)) {
*locally_initiated = 1;
} else {
*locally_initiated = 0;