diff options
Diffstat (limited to 'daemon/ntlm.c')
-rw-r--r-- | daemon/ntlm.c | 138 |
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"); } } |