r25026: Move param/param.h out of includes.h
[kai/samba.git] / source4 / utils / ntlm_auth.c
index fc864fd50ee5216292cfe1a15035930b100b7331..8775bab2db3b04a0795aec9b18e2bcd373eab845 100644 (file)
 #include "lib/messaging/messaging.h"
 #include "lib/messaging/irpc.h"
 #include "auth/ntlmssp/ntlmssp.h"
+#include "param/param.h"
 
-#define SQUID_BUFFER_SIZE 2010
+#define INITIAL_BUFFER_SIZE 300
+#define MAX_BUFFER_SIZE 63000
 
 enum stdio_helper_mode {
        SQUID_2_4_BASIC,
@@ -119,7 +121,7 @@ static void mux_printf(unsigned int mux_id, const char *format, ...)
 /* Copy of parse_domain_user from winbindd_util.c.  Parse a string of the
    form DOMAIN/user into a domain and a user */
 
-static BOOL parse_ntlm_auth_domain_user(const char *domuser, fstring domain, 
+static bool parse_ntlm_auth_domain_user(const char *domuser, fstring domain, 
                                        fstring user)
 {
 
@@ -243,7 +245,7 @@ static void manage_squid_basic_request(enum stdio_helper_mode stdio_helper_mode,
        char *user, *pass;      
        user=buf;
        
-       pass=memchr(buf,' ',length);
+       pass = memchr(buf, ' ', length);
        if (!pass) {
                DEBUG(2, ("Password not found. Denying access\n"));
                mux_printf(mux_id, "ERR\n");
@@ -323,6 +325,24 @@ static const char *get_password(struct cli_credentials *credentials)
        return password;
 }
 
+/**
+ Check if a string is part of a list.
+**/
+static bool in_list(const char *s, const char *list, bool casesensitive)
+{
+       pstring tok;
+       const char *p=list;
+
+       if (!list)
+               return false;
+
+       while (next_token(&p, tok, LIST_SEP, sizeof(tok))) {
+               if ((casesensitive?strcmp:strcasecmp_m)(tok,s) == 0)
+                       return true;
+       }
+       return false;
+}
+
 static void gensec_want_feature_list(struct gensec_security *state, char* feature_list)
 {
        if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) {
@@ -366,7 +386,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
        TALLOC_CTX *mem_ctx;
 
        if (*private) {
-               state = *private;
+               state = (struct gensec_ntlm_state *)*private;
        } else {
                state = talloc_zero(NULL, struct gensec_ntlm_state);
                if (!state) {
@@ -868,51 +888,66 @@ static void manage_ntlm_server_1_request(enum stdio_helper_mode stdio_helper_mod
 static void manage_squid_request(enum stdio_helper_mode helper_mode, 
                                 stdio_helper_function fn, void **private2) 
 {
-       char buf[SQUID_BUFFER_SIZE+1];
+       char *buf;
+       char tmp[INITIAL_BUFFER_SIZE+1];
        unsigned int mux_id = 0;
-       int length;
+       int length, buf_size = 0;
        char *c;
-       static BOOL err;
        struct mux_private {
                unsigned int max_mux;
                void **private_pointers;
        };
-       
+
        static struct mux_private *mux_private;
        static void *normal_private;
        void **private;
 
-       /* this is not a typo - x_fgets doesn't work too well under squid */
-       if (fgets(buf, sizeof(buf)-1, stdin) == NULL) {
-               if (ferror(stdin)) {
-                       DEBUG(1, ("fgets() failed! dying..... errno=%d (%s)\n", ferror(stdin),
-                                 strerror(ferror(stdin))));
-                       
-                       exit(1);    /* BIIG buffer */
-               }
-               exit(0);
-       }
-    
-       c=memchr(buf,'\n',sizeof(buf)-1);
-       if (c) {
-               *c = '\0';
-               length = c-buf;
-       } else {
-               err = 1;
-               return;
-       }
-       if (err) {
-               DEBUG(0, ("Oversized message\n"));
+       buf = talloc(NULL, char);
+       buf[0] = '\0';
+
+       if (buf == NULL) {
+               DEBUG(0, ("Failed to allocate memory for reading the input "
+                         "buffer.\n"));
                x_fprintf(x_stdout, "ERR\n");
-               err = 0;
                return;
        }
 
+       do {
+               /* this is not a typo - x_fgets doesn't work too well under
+                * squid */
+               if (fgets(tmp, INITIAL_BUFFER_SIZE, stdin) == NULL) {
+                       if (ferror(stdin)) {
+                               DEBUG(1, ("fgets() failed! dying..... errno=%d "
+                                         "(%s)\n", ferror(stdin),
+                                         strerror(ferror(stdin))));
+
+                               exit(1);    /* BIIG buffer */
+                       }
+                       exit(0);
+               }
+
+               buf = talloc_append_string(buf, buf, tmp);
+               buf_size += INITIAL_BUFFER_SIZE;
+
+               if (buf_size > MAX_BUFFER_SIZE) {
+                       DEBUG(0, ("Invalid Request (too large)\n"));
+                       x_fprintf(x_stdout, "ERR\n");
+                       talloc_free(buf);
+                       return;
+               }
+
+               c = strchr(buf, '\n');
+       } while (c == NULL);
+
+       *c = '\0';
+       length = c-buf;
+
        DEBUG(10, ("Got '%s' from squid (length: %d).\n",buf,length));
 
        if (buf[0] == '\0') {
                DEBUG(0, ("Invalid Request (empty)\n"));
                x_fprintf(x_stdout, "ERR\n");
+               talloc_free(buf);
                return;
        }
 
@@ -920,6 +955,7 @@ static void manage_squid_request(enum stdio_helper_mode helper_mode,
                if (sscanf(buf, "%u ", &mux_id) != 1) {
                        DEBUG(0, ("Invalid Request - no multiplex id\n"));
                        x_fprintf(x_stdout, "ERR\n");
+                       talloc_free(buf);
                        return;
                }
                if (!mux_private) {
@@ -932,6 +968,7 @@ static void manage_squid_request(enum stdio_helper_mode helper_mode,
                if (!c) {
                        DEBUG(0, ("Invalid Request - no data after multiplex id\n"));
                        x_fprintf(x_stdout, "ERR\n");
+                       talloc_free(buf);
                        return;
                }
                c++;
@@ -951,8 +988,9 @@ static void manage_squid_request(enum stdio_helper_mode helper_mode,
                c = buf;
                private = &normal_private;
        }
-       
+
        fn(helper_mode, c, length, private, mux_id, private2);
+       talloc_free(buf);
 }
 
 static void squid_stream(enum stdio_helper_mode stdio_mode,