summaryrefslogtreecommitdiff
path: root/daemon/ntlm.c
diff options
context:
space:
mode:
Diffstat (limited to 'daemon/ntlm.c')
-rw-r--r--daemon/ntlm.c138
1 files changed, 82 insertions, 56 deletions
diff --git a/daemon/ntlm.c b/daemon/ntlm.c
index ef889f1..bbbac5e 100644
--- a/daemon/ntlm.c
+++ b/daemon/ntlm.c
@@ -44,7 +44,6 @@ typedef struct ntlm_context
const char* backup; /* Backup server if primary is down */
int pending_max; /* Maximum number of connections at once */
int pending_timeout; /* Timeout for authentication (in seconds) */
- const char* basic_realm; /* The realm for basic authentication */
/* Context ----------------------------------------------------------- */
hash_t* pending; /* Pending connections */
@@ -57,7 +56,7 @@ ntlm_context_t;
static const ntlm_context_t ntlm_defaults =
{
NULL, NULL, NULL, DEFAULT_PENDING_MAX, DEFAULT_PENDING_TIMEOUT,
- NULL, NULL, NULL
+ NULL, NULL
};
@@ -94,12 +93,13 @@ static ntlm_connection_t* makeconnection(ntlm_context_t* ctx)
ctx->domain, conn->nonce);
if(!conn->handle)
{
- ha_messagex(LOG_ERR, "couldn't connect to the domain server %s (backup: %s)",
+ ha_messagex(LOG_ERR, "ntlm: couldn't connect to the domain server %s (backup: %s)",
ctx->server, ctx->backup ? ctx->backup : "none");
free(conn);
return NULL;
}
+ ha_messagex(LOG_INFO, "ntlm: established connection to server");
return conn;
}
@@ -109,6 +109,7 @@ static void freeconnection(ntlm_connection_t* conn)
if(conn->handle)
{
+ ha_messagex(LOG_DEBUG, "ntlm: disconnected from server");
ntlmssp_disconnect(conn->handle);
conn->handle = NULL;
}
@@ -183,7 +184,10 @@ int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header,
*/
conn = getpending(ctx, key);
if(conn)
+ {
+ ha_messagex(LOG_WARNING, "ntlm: basic auth killed a pending ntlm auth in progress");
freeconnection(conn);
+ }
if((r = basic_parse(header, buf, &basic)) < 0)
return r;
@@ -196,43 +200,53 @@ int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header,
ha_unlock(NULL);
+ if(found)
+ ha_messagex(LOG_NOTICE, "ntlm: validated basic user against cache: %s", basic.user);
- /* Try to find a domain in the user */
- if((t = strchr(basic.user, '\\')) != NULL ||
- (t = strchr(basic.user, '/')) != NULL)
+ else
{
- /* Break at the domain */
- domain = basic.user;
- basic.user = t + 1;
- *t = 0;
-
- /* Make sure this is our domain */
- if(strcasecmp(domain, ctx->domain) != 0)
- domain = NULL;
- }
+ /* Try to find a domain in the user */
+ if((t = strchr(basic.user, '\\')) != NULL ||
+ (t = strchr(basic.user, '/')) != NULL)
+ {
+ /* Break at the domain */
+ domain = basic.user;
+ basic.user = t + 1;
+ *t = 0;
+
+ /* Make sure this is our domain */
+ if(strcasecmp(domain, ctx->domain) != 0)
+ domain = NULL;
+ }
- if(!domain)
- {
- /* Use the default domain if none specified */
- domain = ctx->domain;
- }
+ if(!domain)
+ {
+ /* Use the default domain if none specified */
+ domain = ctx->domain;
+ }
- /* Make sure above did not fail */
- if(!found && basic.user && basic.user[0] && basic.password &&
- domain && domain[0])
- {
- /* We need to lock to go into smblib */
- ha_lock(&g_smblib_mutex);
+ /* Make sure above did not fail */
+ if(basic.user && basic.user[0] && basic.password &&
+ domain && domain[0])
+ {
+ ha_messagex(LOG_DEBUG, "ntlm: checking user against server: %s", basic.user);
- /* Found in smbval/valid.h */
- if(ntlmssp_validuser(basic.user, basic.password, ctx->server,
- ctx->backup, domain) == NTV_NO_ERROR)
- {
- /* If valid then we return */
- found = 1;
- }
+ /* We need to lock to go into smblib */
+ ha_lock(&g_smblib_mutex);
- ha_unlock(&g_smblib_mutex);
+ /* Found in smbval/valid.h */
+ if(ntlmssp_validuser(basic.user, basic.password, ctx->server,
+ ctx->backup, domain) == NTV_NO_ERROR)
+ {
+ /* If valid then we return */
+ found = 1;
+ }
+
+ ha_unlock(&g_smblib_mutex);
+ }
+
+ if(found)
+ ha_messagex(LOG_NOTICE, "ntlm: validated basic user against server: %s", basic.user);
}
if(found)
@@ -300,7 +314,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
r = ntlmssp_decode_msg(&ntlmssp, d, len, &flags);
if(r != 0)
{
- ha_messagex(LOG_ERR, "decoding NTLM message failed (error %d)", r);
+ ha_messagex(LOG_WARNING, "ntlm: decoding NTLMSSP message failed (error %d)", r);
resp->code = HA_SERVER_BADREQ;
goto finally;
}
@@ -340,7 +354,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
}
else
{
- ha_messagex(LOG_ERR, "received out of order NTLM request from client");
+ ha_messagex(LOG_ERR, "ntlm: received out of order NTLM request from client");
resp->code = HA_SERVER_BADREQ;
}
@@ -421,6 +435,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
}
else
{
+ ha_messagex(LOG_DEBUG, "ntlm: sending ntlm challenge");
ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
resp->code = HA_SERVER_DECLINE;
}
@@ -439,14 +454,14 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
*/
if(!conn || !conn->handle)
{
- ha_messagex(LOG_ERR, "received out of order NTLM response from client");
+ ha_messagex(LOG_WARNING, "ntlm: received out of order NTLM response from client");
resp->code = HA_SERVER_BADREQ;
goto finally;
}
if(!ntlmssp.user)
{
- ha_messagex(LOG_ERR, "received NTLM response without user name");
+ ha_messagex(LOG_WARNING, "ntlm: received NTLM response without user name");
resp->code = HA_SERVER_BADREQ;
goto finally;
}
@@ -468,7 +483,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
* Note that we don't set a code here. This causes our
* caller to put in all the proper headers for us.
*/
- ha_messagex(LOG_ERR, "failed NTLM logon for user '%s'", ntlmssp.user);
+ ha_messagex(LOG_WARNING, "ntlm: failed NTLM logon for user '%s'", ntlmssp.user);
ret = HA_FALSE;
}
@@ -477,6 +492,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
{
int r;
resp->detail = ntlmssp.user;
+ ha_messagex(LOG_NOTICE, "ntlm: validated ntlm user against server", ntlmssp.user);
ha_lock(NULL);
@@ -500,7 +516,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header,
}
default:
- ha_messagex(LOG_ERR, "received invalid NTLM message (type %d)", ntlmssp.msg_type);
+ ha_messagex(LOG_WARNING, "ntlm: received invalid NTLM message (type %d)", ntlmssp.msg_type);
resp->code = HA_SERVER_BADREQ;
goto finally;
};
@@ -555,12 +571,6 @@ int ntlm_config(ha_context_t* context, const char* name, const char* value)
return ha_confint(name, value, 1, 86400, &(ctx->pending_timeout));
}
- else if(strcmp(name, "realm") == 0)
- {
- ctx->basic_realm = value;
- return HA_OK;
- }
-
return HA_FALSE;
}
@@ -574,7 +584,7 @@ int ntlm_init(ha_context_t* context)
ASSERT(ctx);
/* Make sure there are some types of authentication we can do */
- if(!(context->types & (HA_TYPE_BASIC | HA_TYPE_NTLM)))
+ if(!(context->opts.types & (HA_TYPE_BASIC | HA_TYPE_NTLM)))
{
ha_messagex(LOG_ERR, "NTLM module configured, but does not implement any "
"configured authentication type.");
@@ -599,6 +609,8 @@ int ntlm_init(ha_context_t* context)
ha_messagex(LOG_CRIT, "out of memory");
return HA_CRITERROR;
}
+
+ ha_messagex(LOG_INFO, "ntlm: initialized handler");
}
/* Global Initialization */
@@ -630,6 +642,8 @@ void ntlm_destroy(ha_context_t* context)
if(ctx->established)
hash_free(ctx->established);
+
+ ha_messagex(LOG_INFO, "ntlm: uninitialized handler");
}
/* Global Destroy */
@@ -649,7 +663,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
unsigned char key[NTLM_HASH_KEY_LEN];
const char* header = NULL;
time_t t = time(NULL);
- int ret;
+ int ret, r;
ASSERT(context && req && resp && buf);
ASSERT(req->args[AUTH_ARG_CONN]);
@@ -667,14 +681,16 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
* authenticated connections which have expired as
* well as half open connections which expire.
*/
- hash_purge(ctx->pending, t - ctx->pending_timeout);
- hash_purge(ctx->established, t - context->cache_timeout);
+ r = hash_purge(ctx->pending, t - ctx->pending_timeout);
+ r += hash_purge(ctx->established, t - context->opts.cache_timeout);
ha_unlock(NULL);
+ if(r > 0)
+ ha_messagex(LOG_DEBUG, "ntlm: purged info from cache: %d", r);
/* Look for a NTLM header */
- if(context->types & HA_TYPE_NTLM)
+ if(context->opts.types & HA_TYPE_NTLM)
{
header = ha_getheader(req, "Authorization", HA_PREFIX_NTLM);
if(header)
@@ -683,6 +699,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
while(*header && isspace(*header))
header++;
+ ha_messagex(LOG_DEBUG, "ntlm: processing ntlm auth header");
ret = ntlm_auth_ntlm(ctx, key, header, resp, buf);
if(ret < 0)
return ret;
@@ -690,7 +707,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
}
/* If basic is enabled, and no NTLM */
- if(!header && context->types & HA_TYPE_BASIC)
+ if(!header && context->opts.types & HA_TYPE_BASIC)
{
/* Look for a Basic header */
header = ha_getheader(req, "Authorization", HA_PREFIX_BASIC);
@@ -700,6 +717,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
while(*header && isspace(*header))
header++;
+ ha_messagex(LOG_DEBUG, "ntlm: processing basic auth header");
ret = ntlm_auth_basic(ctx, key, header, resp, buf);
if(ret < 0)
return ret;
@@ -725,6 +743,11 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
}
ha_unlock(NULL);
+
+ if(resp->code == HA_SERVER_ACCEPT)
+ ha_messagex(LOG_NOTICE, "ntlm: validated user against connection cache");
+
+ /* TODO: We need to be able to retrieve the user here somehow */
}
@@ -734,18 +757,21 @@ int ntlm_process(ha_context_t* context, ha_request_t* req,
/* If authentication failed tell the browser about it */
resp->code = HA_SERVER_DECLINE;
- if(context->types & HA_TYPE_NTLM)
+ if(context->opts.types & HA_TYPE_NTLM)
+ {
ha_addheader(resp, "WWW-Authenticate", HA_PREFIX_NTLM);
+ ha_messagex(LOG_DEBUG, "ntlm: sent ntlm auth request");
+ }
- if(context->types & HA_TYPE_BASIC)
+ if(context->opts.types & HA_TYPE_BASIC)
{
- ha_bufmcat(buf, HA_PREFIX_BASIC, "realm=\"",
- ctx->basic_realm ? ctx->basic_realm : "", "\"", NULL);
+ ha_bufmcat(buf, HA_PREFIX_BASIC, "realm=\"", context->opts.realm, "\"", NULL);
if(ha_buferr(buf))
return HA_CRITERROR;
ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf));
+ ha_messagex(LOG_DEBUG, "ntlm: sent basic auth request");
}
}