diff options
Diffstat (limited to 'daemon/ntlm.c')
-rw-r--r-- | daemon/ntlm.c | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/daemon/ntlm.c b/daemon/ntlm.c index 880ae9e..bdf2116 100644 --- a/daemon/ntlm.c +++ b/daemon/ntlm.c @@ -5,6 +5,8 @@ #include "httpauthd.h" #include "hash.h" #include "defaults.h" +#include "md5.h" +#include "basic.h" #include <syslog.h> @@ -15,8 +17,7 @@ * Defaults and Constants */ -/* This needs to be the same as an MD5 hash length */ -#define NTLM_HASH_KEY_LEN 16 +#define NTLM_HASH_KEY_LEN MD5_LEN #define NTLM_ESTABLISHED (void*)1 @@ -75,8 +76,7 @@ static ntlm_connection_t* getpending(ntlm_context_t* ctx, const void* key) ha_lock(NULL); - if(ret = (ntlm_connection_t*)hash_get(ctx->pending, key)) - hash_rem(ctx->pending, key); + ret = (ntlm_connection_t*)hash_rem(ctx->pending, key); ha_unlock(NULL); @@ -87,18 +87,18 @@ static int putpending(ntlm_context_t* ctx, const void* key, ntlm_connection_t* c { int r = 0; - ha_lock(NULL); + if(!hash_get(ctx->pending, key)) + { + ha_lock(NULL); - if(hash_get(ctx->pending, key)) - { if(!hash_set(ctx->pending, key, (void*)conn)) { ha_messagex(LOG_ERR, "out of memory"); r = -1; } - } - ha_unlock(NULL); + ha_unlock(NULL); + } return r; } @@ -132,7 +132,7 @@ static ntlm_connection_t* makeconnection(ntlm_context_t* ctx) } } -static void freeconnection(ntlm_context_t* ctx, ntlm_connection_t* conn) +static void freeconnection(ntlm_connection_t* conn) { if(conn->handle) { @@ -143,13 +143,20 @@ static void freeconnection(ntlm_context_t* ctx, ntlm_connection_t* conn) free(conn); } +static void free_hash_object(void* arg, void* val) +{ + if(val) + freeconnection((ntlm_connection_t*)val); +} + int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header, ha_response_t* resp, ha_buffer_t* buf) { ntlm_connection_t* conn; char* t; - ha_basic_header_t basic; + basic_header_t basic; const char* domain = NULL; + int found = 0; /* * We're doing basic authentication on the connection @@ -158,15 +165,15 @@ int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header, */ conn = getpending(ctx, key); if(conn) - freeconnection(ctx, conn); + freeconnection(conn); - if(ha_parsebasic(header, buf, &basic) == HA_ERROR) + if(basic_parse(header, buf, &basic) == HA_ERROR) return HA_ERROR; /* Check and see if this connection is in the cache */ ha_lock(NULL); - if(hash_get(ctx->established, basic.key) == BASIC_ESTABLISHED) + if(hash_get(ctx->established, basic.key) == NTLM_ESTABLISHED) found = 1; ha_unlock(NULL); @@ -204,18 +211,26 @@ int ntlm_auth_basic(ntlm_context_t* ctx, char* key, const char* header, ctx->backup, domain) == NTV_NO_ERROR) { /* If valid then we return */ - resp->code = HA_SERVER_ACCEPT; + found = 1; } ha_unlock(&g_smblib_mutex); } - if(resp->code = HA_SERVER_ACCEPT) + if(found) { + int r; + resp->code = HA_SERVER_ACCEPT; resp->detail = basic.user; - /* We put this connection into the successful connections */ - if(!hash_set(ctx->established, basic.key, BASIC_ESTABLISHED)) + ha_lock(NULL); + + /* We put this connection into the successful connections */ + r = hash_set(ctx->established, basic.key, NTLM_ESTABLISHED); + + ha_unlock(NULL); + + if(!r) { ha_messagex(LOG_CRIT, "out of memory"); return HA_ERROR; @@ -255,8 +270,7 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header, * is sending us. */ - ha_bufnext(buf); - ha_bufdec64(buf, header); + ha_bufdec64(buf, header, 0); header = ha_bufdata(buf); if(ha_buferr(buf)) @@ -312,14 +326,11 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header, if(ctx->pending_max != -1) { ha_lock(NULL); - r = (hash_count(ctx->pending) >= ctx->pending_max); - ha_unlock(NULL); - if(r) - { - resp->code = HA_SERVER_BUSY; - goto finally; - } + if(hash_count(ctx->pending) >= ctx->pending_max) + hash_bump(ctx->pending); + + ha_unlock(NULL); } @@ -340,19 +351,20 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header, conn->flags = flags; /* Start building the header */ - ha_bufnext(buf); - ha_bufcat(buf, NTLM_PREFIX); + ha_bufcpy(buf, HA_PREFIX_NTLM); if(win9x) { struct ntlm_msg2_win9x msg_win9x; ntlmssp_encode_msg2_win9x(conn->nonce, &msg_win9x, (char*)ctx->domain, flags); + ha_bufjoin(buf); ha_bufenc64(buf, (unsigned char*)&msg_win9x, sizeof(msg_win9x)); } else { struct ntlm_msg2 msg; ntlmssp_encode_msg2(conn->nonce, &msg); + ha_bufjoin(buf); ha_bufenc64(buf, (unsigned char*)&msg, sizeof(msg)); } @@ -431,14 +443,25 @@ int ntlm_auth_ntlm(ntlm_context_t* ctx, void* key, const char* header, /* A successful login ends here */ else { - resp->code = HA_SERVER_ACCEPT; + int r; + resp->detail = ntlmssp.user; + + ha_lock(NULL); - /* We put this connection into the successful connections */ - if(!hash_set(ctx->established, key, NTLM_ESTABLISHED)) + /* We put this connection into the successful connections */ + r = hash_set(ctx->established, key, NTLM_ESTABLISHED); + + ha_unlock(NULL); + + if(!r) { ha_messagex(LOG_CRIT, "out of memory"); ret = HA_ERROR; } + else + { + ret = HA_OK; + } } goto finally; @@ -456,7 +479,7 @@ finally: ret = HA_ERROR; if(conn) - freeconnection(ctx, conn); + freeconnection(conn); return ret; } @@ -531,8 +554,8 @@ int ntlm_init(ha_context_t* context) } /* Initialize our tables */ - if(!(ctx->pending = hash_create(NTLM_HASH_KEY_LEN)) || - !(ctx->established = hash_create(NTLM_HASH_KEY_LEN))) + if(!(ctx->pending = hash_create(NTLM_HASH_KEY_LEN, free_hash_object, NULL)) || + !(ctx->established = hash_create(NTLM_HASH_KEY_LEN, NULL, NULL))) { ha_messagex(LOG_CRIT, "out of memory"); return HA_ERROR; @@ -545,7 +568,7 @@ int ntlm_init(ha_context_t* context) /* Create the smblib mutex */ if(pthread_mutexattr_init(&g_smblib_mutexattr) != 0 || pthread_mutexattr_settype(&g_smblib_mutexattr, HA_MUTEX_TYPE) || - pthread_mutex_init(&g_mutex, &g_smblib_mutexattr) != 0) + pthread_mutex_init(&g_smblib_mutex, &g_smblib_mutexattr) != 0) { ha_messagex(LOG_CRIT, "threading problem. can't create mutex"); return HA_ERROR; @@ -589,13 +612,11 @@ int ntlm_process(ha_context_t* context, ha_request_t* req, resp->code = -1; /* Hash the unique key */ - ha_md5string(req->args[1], key); + md5_string(key, req->args[AUTH_ARG_CONN]); ha_lock(NULL); - XXX: These connections aren't being destroyed properly - /* * Purge out stale connection stuff. This includes * authenticated connections which have expired as @@ -608,9 +629,9 @@ int ntlm_process(ha_context_t* context, ha_request_t* req, /* Look for a NTLM header */ - if(context->types & HA_TYPES_NTLM) + if(context->types & HA_TYPE_NTLM) { - header = ha_getheader(req, "Authorization", NTLM_PREFIX); + header = ha_getheader(req, "Authorization", HA_PREFIX_NTLM); if(header) { /* Trim off for decoding */ @@ -627,7 +648,7 @@ int ntlm_process(ha_context_t* context, ha_request_t* req, if(!header && context->types & HA_TYPE_BASIC) { /* Look for a Basic header */ - header = ha_getheader(req, "Authorization", BASIC_PREFIX); + header = ha_getheader(req, "Authorization", HA_PREFIX_BASIC); if(header) { /* Trim off for decoding */ @@ -669,14 +690,16 @@ int ntlm_process(ha_context_t* context, ha_request_t* req, resp->code = HA_SERVER_DECLINE; if(context->types & HA_TYPE_NTLM) - ha_addheader(resp, "WWW-Authenticate", NTLM_PREFIX); + ha_addheader(resp, "WWW-Authenticate", HA_PREFIX_NTLM); if(context->types & HA_TYPE_BASIC) { - ha_bufnext(buf); - ha_bufcat(buf, BASIC_PREFIX, "realm=\"", + ha_bufmcat(buf, HA_PREFIX_BASIC, "realm=\"", ctx->basic_realm ? ctx->basic_realm : "", "\"", NULL); + if(ha_buferr(buf)) + return HA_ERROR; + ha_addheader(resp, "WWW-Authenticate", ha_bufdata(buf)); } } @@ -697,7 +720,7 @@ ha_handler_t ntlm_handler = ntlm_destroy, /* Uninitialization routine */ ntlm_config, /* Config routine */ ntlm_process, /* Processing routine */ - ntlm_defaults, /* Default settings */ + &ntlm_defaults, /* Default settings */ sizeof(ntlm_context_t) }; |