]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - helpers/external_acl/kerberos_ldap_group/support_group.cc
Boilerplate: update copyright blurbs on Squid helpers
[thirdparty/squid.git] / helpers / external_acl / kerberos_ldap_group / support_group.cc
index 5f528c2ec7e8e729b64b7035c311ea58986b6bd6..137bde529db140dddd00e515f3dca9069c4d13c1 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
 
 /*
  * -----------------------------------------------------------------------------
 #include "squid.h"
 #include "util.h"
 
-#ifdef HAVE_LDAP
+#if HAVE_LDAP
 
 #include "support.h"
 
 struct gdstruct *init_gd(void);
+void free_gd(struct gdstruct *gdsp);
 
 struct gdstruct *
 init_gd(void) {
@@ -42,15 +50,27 @@ init_gd(void) {
     return gdsp;
 }
 
+void
+free_gd(struct gdstruct *gdsp)
+{
+    while (gdsp) {
+        struct gdstruct *gdspn = gdsp->next;
+        xfree(gdsp->group);
+        xfree(gdsp->domain);
+        xfree(gdsp);
+        gdsp = gdspn;
+    }
+}
+
 char *utf8dup(struct main_args *margs);
 
 char *
 utf8dup(struct main_args *margs)
 {
-    int c = 0, s;
+    size_t c = 0;
     size_t n;
     char *src;
-    unsigned char *p, *dupp;
+    unsigned char *p;
 
     src = margs->glist;
     if (!src)
@@ -59,15 +79,17 @@ utf8dup(struct main_args *margs)
         if ((unsigned char) src[n] > 127)
             ++c;
     if (c != 0) {
+        unsigned char *dupp;
         p = (unsigned char *) xmalloc(strlen(src) + c);
         dupp = p;
         for (n = 0; n < strlen(src); ++n) {
+            unsigned char s;
             s = (unsigned char) src[n];
             if (s > 127 && s < 192) {
                 *p = 194;
                 ++p;
                 *p = s;
-            } else if (s > 191 && s < 256) {
+            } else if (s > 191) {
                 *p = 195;
                 ++p;
                 *p = s - 64;
@@ -101,35 +123,24 @@ char *hex_utf_char(struct main_args *margs, int flag);
 char *
 hex_utf_char(struct main_args *margs, int flag)
 {
-    char *up;
-    char *upd;
-    char *ul;
-    int a, n, nl, ival, ichar;
+    int ival, ichar;
     int iUTF2, iUTF3, iUTF4;
 
-    if (flag) {
-        up = margs->ulist;
-    } else {
-        up = margs->tlist;
-    }
-
+    char *up = (flag ? margs->ulist : margs->tlist);
     if (!up)
         return NULL;
 
-    upd = strrchr(up, '@');
-    if (upd)
-        a = upd - up;
-    else
-        a = strlen(up);
+    char *upd = strrchr(up, '@');
+    size_t a = (upd ? (size_t)(upd - up) : strlen(up) );
 
-    ul = (char *) xmalloc(strlen(up));
-    n = 0;
-    nl = 0;
+    char *ul = (char *) xmalloc(strlen(up)+1);
+    size_t n = 0;
+    int nl = 0;
     iUTF2 = 0;
     iUTF3 = 0;
     iUTF4 = 0;
 
-    while (n < (int) strlen(up)) {
+    while (n < strlen(up)) {
         if (flag && n == a)
             break;
         if (up[n] == '@') {
@@ -147,16 +158,13 @@ hex_utf_char(struct main_args *margs, int flag)
             ichar = (ival - 48) * 16;
         else {
             debug((char *) "%s| %s: WARNING: Invalid Hex value %c\n", LogTime(), PROGRAM, ival);
-            if (ul)
-                xfree(ul);
+            xfree(ul);
             return NULL;
         }
 
-
         if (n == a - 1) {
             debug((char *) "%s| %s: WARNING: Invalid Hex UTF-8 string %s\n", LogTime(), PROGRAM, up);
-            if (ul)
-                xfree(ul);
+            xfree(ul);
             return NULL;
         }
         ++n;
@@ -169,115 +177,110 @@ hex_utf_char(struct main_args *margs, int flag)
             ichar = ichar + ival - 48;
         else {
             debug((char *) "%s| %s: WARNING: Invalid Hex value %c\n", LogTime(), PROGRAM, ival);
-            if (ul)
-                xfree(ul);
+            xfree(ul);
             return NULL;
         }
 
         if (iUTF2) {
             if (iUTF2 == 0xC2 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF2 = 0;
-                ul[nl - 1] = ichar;
+                ul[nl - 1] = (char)ichar;
             } else if (iUTF2 == 0xC3 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF2 = 0;
-                ul[nl - 1] = ichar + 64;
+                ul[nl - 1] = (char)(ichar + 64);
             } else if (iUTF2 > 0xC3 && iUTF2 < 0xE0 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF2 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else {
                 iUTF2 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ul[nl + 1] = '\0';
                 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
-                if (ul)
-                    xfree(ul);
+                xfree(ul);
                 return NULL;
             }
         } else if (iUTF3) {
             if (iUTF3 == 0xE0 && ichar > 0x9F && ichar < 0xC0) {
                 iUTF3 = 1;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 > 0xE0 && iUTF3 < 0xED && ichar > 0x7F && ichar < 0xC0) {
                 iUTF3 = 2;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 == 0xED && ichar > 0x7F && ichar < 0xA0) {
                 iUTF3 = 3;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 > 0xED && iUTF3 < 0xF0 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF3 = 4;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF3 > 0 && iUTF3 < 5 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF3 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else {
                 iUTF3 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ul[nl + 1] = '\0';
                 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
-                if (ul)
-                    xfree(ul);
+                xfree(ul);
                 return NULL;
             }
         } else if (iUTF4) {
             if (iUTF4 == 0xF0 && ichar > 0x8F && ichar < 0xC0) {
                 iUTF4 = 1;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF4 > 0xF0 && iUTF3 < 0xF4 && ichar > 0x7F && ichar < 0xC0) {
                 iUTF4 = 2;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF4 == 0xF4 && ichar > 0x7F && ichar < 0x90) {
                 iUTF4 = 3;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else if (iUTF4 > 0 && iUTF4 < 5 && ichar > 0x7F && ichar < 0xC0) {
                 if (iUTF4 == 4)
                     iUTF4 = 0;
                 else
                     iUTF4 = 4;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ++nl;
             } else {
                 iUTF4 = 0;
-                ul[nl] = ichar;
+                ul[nl] = (char)ichar;
                 ul[nl + 1] = '\0';
                 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
-                if (ul)
-                    xfree(ul);
+                xfree(ul);
                 return NULL;
             }
         } else if (ichar < 0x80) {
             /* UTF1 */
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else if (ichar > 0xC1 && ichar < 0xE0) {
             /* UTF2 (Latin) */
             iUTF2 = ichar;
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else if (ichar > 0xDF && ichar < 0xF0) {
             /* UTF3 */
             iUTF3 = ichar;
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else if (ichar > 0xEF && ichar < 0xF5) {
             /* UTF4 */
             iUTF4 = ichar;
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ++nl;
         } else {
-            ul[nl] = ichar;
+            ul[nl] = (char)ichar;
             ul[nl + 1] = '\0';
             debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
-            if (ul)
-                xfree(ul);
+            xfree(ul);
             return NULL;
         }
         ++n;
@@ -287,8 +290,7 @@ hex_utf_char(struct main_args *margs, int flag)
     if (iUTF2 || iUTF3 || iUTF4) {
         debug((char *) "%s| %s: INFO: iUTF2: %d iUTF3: %d iUTF4: %d\n", LogTime(), PROGRAM, iUTF2, iUTF3, iUTF4);
         debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
-        if (ul)
-            xfree(ul);
+        xfree(ul);
         return NULL;
     }
     if (flag && upd)
@@ -296,12 +298,10 @@ hex_utf_char(struct main_args *margs, int flag)
     return ul;
 }
 
-
 int
 create_gd(struct main_args *margs)
 {
     char *gp, *dp;
-    char *hp1, *hp2, *up;
     char *p;
     struct gdstruct *gdsp = NULL, *gdspn = NULL;
     /*
@@ -323,28 +323,43 @@ create_gd(struct main_args *margs)
      *
      *
      */
-    hp1 = hex_utf_char(margs, 0);
-    hp2 = hex_utf_char(margs, 1);
-    up = utf8dup(margs);
+    char *hp1 = hex_utf_char(margs, 0);
+    char *hp2 = hex_utf_char(margs, 1);
+    char *up = utf8dup(margs);
+
+    // NP: will point to the start of a temporary assembly buffer used by 'p' and 'gp'
+    //     for catenation of the hp1, hp2, and up buffer contents from above.
+    //     necessary for xfree() because both p and gp move over the assembly area
+    char *gpbuf = NULL;
+
+    // release the allocated UTF decoding buffers
+#define cleanup() { \
+    xfree(gpbuf); \
+    xfree(hp1); \
+    xfree(hp2); \
+    xfree(up); \
+    free_gd(gdsp); \
+ }
+
     p = up;
     if (hp1) {
         if (hp2) {
             if (up) {
-                p = (char *) xmalloc(strlen(up) + strlen(hp1) + strlen(hp2) + 2);
+                gpbuf = p = (char *) xmalloc(strlen(up) + strlen(hp1) + strlen(hp2) + 2);
                 strcpy(p, up);
                 strcat(p, ":");
                 strcat(p, hp1);
                 strcat(p, ":");
                 strcat(p, hp2);
             } else {
-                p = (char *) xmalloc(strlen(hp1) + strlen(hp2) + 1);
+                gpbuf = p = (char *) xmalloc(strlen(hp1) + strlen(hp2) + 1);
                 strcpy(p, hp1);
                 strcat(p, ":");
                 strcat(p, hp2);
             }
         } else {
             if (up) {
-                p = (char *) xmalloc(strlen(up) + strlen(hp1) + 1);
+                gpbuf = p = (char *) xmalloc(strlen(up) + strlen(hp1) + 1);
                 strcpy(p, up);
                 strcat(p, ":");
                 strcat(p, hp1);
@@ -354,7 +369,7 @@ create_gd(struct main_args *margs)
     } else {
         if (hp2) {
             if (up) {
-                p = (char *) xmalloc(strlen(up) + strlen(hp2) + 1);
+                gpbuf = p = (char *) xmalloc(strlen(up) + strlen(hp2) + 1);
                 strcpy(p, up);
                 strcat(p, ":");
                 strcat(p, hp2);
@@ -369,6 +384,7 @@ create_gd(struct main_args *margs)
 
     if (!p) {
         debug((char *) "%s| %s: ERROR: No groups defined.\n", LogTime(), PROGRAM);
+        cleanup();
         return (1);
     }
     while (*p) {               /* loop over group list */
@@ -379,18 +395,24 @@ create_gd(struct main_args *margs)
         if (*p == '@') {       /* end of group name - start of domain name */
             if (p == gp) {     /* empty group name not allowed */
                 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
+                cleanup();
                 return (1);
             }
+            if (dp) {  /* end of domain name - twice */
+                debug((char *) "%s| %s: @ is not allowed in group name %s@%s\n",LogTime(), PROGRAM,gp,dp);
+                cleanup();
+                return(1);
+            }
             *p = '\0';
             ++p;
             gdsp = init_gd();
-            gdsp->group = gp;
-            if (gdspn)         /* Have already an existing structure */
-                gdsp->next = gdspn;
+            gdsp->group = xstrdup(gp);
+            gdsp->next = gdspn;
             dp = p;            /* after @ starts new domain name */
         } else if (*p == ':') {        /* end of group name or end of domain name */
             if (p == gp) {     /* empty group name not allowed */
                 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
+                cleanup();
                 return (1);
             }
             *p = '\0';
@@ -400,9 +422,8 @@ create_gd(struct main_args *margs)
                 dp = NULL;
             } else {           /* end of group name and no domain name */
                 gdsp = init_gd();
-                gdsp->group = gp;
-                if (gdspn)     /* Have already an existing structure */
-                    gdsp->next = gdspn;
+                gdsp->group = xstrdup(gp);
+                gdsp->next = gdspn;
             }
             gdspn = gdsp;
             gp = p;            /* after : starts new group name */
@@ -412,19 +433,22 @@ create_gd(struct main_args *margs)
     }
     if (p == gp) {             /* empty group name not allowed */
         debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
+        cleanup();
         return (1);
     }
     if (dp) {                  /* end of domain name */
         gdsp->domain = xstrdup(dp);
     } else {                   /* end of group name and no domain name */
         gdsp = init_gd();
-        gdsp->group = gp;
+        gdsp->group = xstrdup(gp);
         if (gdspn)             /* Have already an existing structure */
             gdsp->next = gdspn;
     }
     debug((char *) "%s| %s: INFO: Group %s  Domain %s\n", LogTime(), PROGRAM, gdsp->group, gdsp->domain ? gdsp->domain : "NULL");
 
     margs->groups = gdsp;
+    gdsp = NULL; // prevent the cleanup() deallocating it.
+    cleanup();
     return (0);
 }
 #endif