]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Author: Chad Naugle <chad.naugle@travimp.com>
authorAmos Jeffries <amosjeffries@squid-cache.org>
Mon, 9 Aug 2010 12:00:18 +0000 (06:00 -0600)
committerAmos Jeffries <amosjeffries@squid-cache.org>
Mon, 9 Aug 2010 12:00:18 +0000 (06:00 -0600)
Bug 2999: v1.5 of ext_edirectory_userip_acl

* Modified command-line arguments to closer resemble LDAP auth helper's.
* Added much-needed 'Persistent Connections' option, with timeout.
* Cleaned up some of the debugging statements, and to make debug messages
  more meaningful.

helpers/external_acl/eDirectory_userip/iplookup.c
helpers/external_acl/eDirectory_userip/iplookup.h
helpers/external_acl/eDirectory_userip/main.c
helpers/external_acl/eDirectory_userip/main.h

index bde9d1b71be73ba449c3a8471d9c0b8a4cd283cd..294b0cd4ec7f963987bc7b8819769c0bc45f6a12 100644 (file)
@@ -36,7 +36,7 @@
  */
 void InitLDAP(ldap_t *l)
 {
-    if (l == NULL) return;
+    if (l == NULL) return;                     /* Duh! */
 
     l->lp = NULL;
     if (l->lm != NULL)
@@ -57,7 +57,9 @@ void InitLDAP(ldap_t *l)
     l->port = 0;
     l->scope = -1;
     l->type = 0;
+    l->err = -1;                                       /* Set error to LDAP_SUCCESS by default */
     l->ver = 0;
+    l->idle_time = 0;
     l->num_ent = 0;                            /* Number of entries in l->lm */
     l->num_val = 0;                            /* Number of entries in l->val */
 
@@ -89,8 +91,10 @@ void InitLDAP(ldap_t *l)
  */
 int OpenLDAP(ldap_t *l, char *h, unsigned int p)
 {
-    if ((l == NULL) || (h == NULL)) return -1;
-    if (!(l->status & LDAP_INIT_S)) return -2;         /* Not initalized, or might be in use */
+    if ((l == NULL) || (h == NULL)) return LDAP_ERR_NULL;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized, or might be in use */
+    if (l->status & LDAP_OPEN_S) return LDAP_ERR_OPEN;         /* Already open */
+    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;         /* Already bound */
 
     strncpy(l->host, h, sizeof(l->host));
     if (p > 0)
@@ -108,12 +112,16 @@ int OpenLDAP(ldap_t *l, char *h, unsigned int p)
 #else
     l->lp = ldap_open(l->host, l->port);
 #endif
-    if (l->lp == NULL) return -3;                              /* Unable to connect */
-
-    /* set status */
-    l->status &= ~(LDAP_INIT_S);
-    l->status |= LDAP_OPEN_S;
-    return LDAP_SUCCESS;
+    if (l->lp == NULL) {
+        l->err = LDAP_CONNECT_ERROR;
+        return LDAP_ERR_CONNECT;                               /* Unable to connect */
+    } else {
+        /* set status */
+//    l->status &= ~(LDAP_INIT_S);
+        l->status |= LDAP_OPEN_S;
+        l->err = LDAP_SUCCESS;
+        return LDAP_ERR_SUCCESS;
+    }
 }
 
 /* CloseLDAP() - <ldap_t>
@@ -124,16 +132,15 @@ int OpenLDAP(ldap_t *l, char *h, unsigned int p)
 int CloseLDAP(ldap_t *l)
 {
     int s;
-    if (l == NULL) return -1;
-    if (l->lp == NULL) return -2;
-    if (!(l->status & LDAP_OPEN_S)) return -3;         /* Connection not open */
-    if (l->lp == NULL) return -4;                              /* Error */
+    if (l == NULL) return LDAP_ERR_NULL;
+    if (l->lp == NULL) return LDAP_ERR_NULL;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Connection not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;              /* Connection not open */
 
     if (l->lm != NULL) {
         ldap_msgfree(l->lm);
         l->lm = NULL;
     }
-
     if (l->val != NULL) {
         ldap_value_free_len(l->val);
         l->val = NULL;
@@ -141,9 +148,15 @@ int CloseLDAP(ldap_t *l)
 
     /* okay, so it's open, close it - No need to check other criteria */
     s = ldap_unbind(l->lp);
-    if (s == LDAP_SUCCESS)
+    if (s == LDAP_SUCCESS) {
         l->status &= ~(LDAP_OPEN_S | LDAP_BIND_S);
-    return s;                                          /* returns unbind result */
+        l->idle_time = 0;
+        l->err = s;                                                    /* Set LDAP error code */
+        return LDAP_ERR_SUCCESS;
+    } else {
+        l->err = s;                                                    /* Set LDAP error code */
+        return LDAP_ERR_FAILED;
+    }
 }
 
 /* SetVerLDAP() - <ldap_t> <version>
@@ -154,14 +167,23 @@ int CloseLDAP(ldap_t *l)
 int SetVerLDAP(ldap_t *l, int v)
 {
     int x;
-    if ((l == NULL) || (v > 3) || (v < 1)) return -1;
-    if (l->lp == NULL) return -2;
-    if (l->status & LDAP_BIND_S) return -3;            /* Already binded */
-    if (!(l->status & LDAP_OPEN_S)) return -4;         /* Not open */
+    if (l == NULL) return LDAP_ERR_NULL;
+    if ((v > 3) || (v < 1)) return LDAP_ERR_PARAM;
+    if (l->lp == NULL) return LDAP_ERR_POINTER;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;              /* Not open */
+    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;         /* Already bound */
 
     /* set version */
     x = ldap_set_option(l->lp, LDAP_OPT_PROTOCOL_VERSION, &v);
-    return x;                                          /* returns result code */
+    if (x == LDAP_SUCCESS) {
+        l->ver = v;
+        l->err = x;                                                    /* Set LDAP error code */
+        return LDAP_ERR_SUCCESS;
+    } else {
+        l->err = x;                                                    /* Set LDAP error code */
+        return LDAP_ERR_FAILED;
+    }
 }
 
 /* BindLDAP() - <ldap_t> <use-dn> <use-password> <type>
@@ -172,10 +194,11 @@ int SetVerLDAP(ldap_t *l, int v)
 int BindLDAP(ldap_t *l, char *dn, char *pw, unsigned int t)
 {
     int s;
-    if (l == NULL) return -1;
-    if (!(l->status & LDAP_OPEN_S)) return -2;         /* Not open */
-    if (l->status & LDAP_BIND_S) return -3;            /* Already binded */
-    if (l->lp == NULL) return -4;                              /* Error */
+    if (l == NULL) return LDAP_ERR_NULL;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;              /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;              /* Not open */
+    if (l->status & LDAP_BIND_S) return LDAP_ERR_BIND;         /* Already bound */
+    if (l->lp == NULL) return LDAP_ERR_POINTER;                        /* Error */
 
     /* Copy details - dn and pw CAN be NULL for anonymous and/or TLS */
     if (dn != NULL) {
@@ -227,9 +250,14 @@ int BindLDAP(ldap_t *l, char *dn, char *pw, unsigned int t)
     else
 #endif
         s = ldap_bind_s(l->lp, l->dn, l->passwd, l->type);
-    if (s == LDAP_SUCCESS)
+    if (s == LDAP_SUCCESS) {
         l->status |= LDAP_BIND_S;                              /* Success */
-    return s;                                          /* LDAP Error code */
+        l->err = s;                                            /* Set LDAP error code */
+        return LDAP_ERR_SUCCESS;
+    } else {
+        l->err = s;                                            /* Set LDAP error code */
+        return LDAP_ERR_FAILED;
+    }
 }
 
 /*
@@ -245,9 +273,12 @@ int ConvertIP(ldap_t *l, char *ip)
     char hexc[4], *p;
     size_t s;
     long x;
-    int i, j, t, swi;                                          /* IPv6 "::" cut over toggle */
-    if ((l == NULL) || (ip == NULL)) return -1;
-    if (!(l->status & LDAP_BIND_S)) return -2;                 /* Not binded */
+    int i, j, t, swi;                                                  /* IPv6 "::" cut over toggle */
+    if (l == NULL) return LDAP_ERR_NULL;
+    if (ip == NULL) return LDAP_ERR_PARAM;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
+    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not bound */
 
     s = strlen(ip);
     memset(bufa, '\0', sizeof(bufa));
@@ -255,12 +286,12 @@ int ConvertIP(ldap_t *l, char *ip)
     memset(obj, '\0', sizeof(obj));
     /* SplitString() will zero out bufa & obj at each call */
     memset(l->search_ip, '\0', sizeof(l->search_ip));
-    strncpy(bufa, ip, s);                                              /* To avoid segfaults, use bufa instead of ip */
+    strncpy(bufa, ip, s);                                                      /* To avoid segfaults, use bufa instead of ip */
     swi = 0;
 
     if ((conf.mode & MODE_IPV6) && (conf.mode & MODE_IPV4)) {
         if (strcasestr(bufa, ":FFFF:") == NULL)
-            return -3;                                         /* Unable to find IPv4-in-IPv6 notation */
+            return LDAP_ERR_INVALID;                                           /* Unable to find IPv4-in-IPv6 notation */
     }
     if (conf.mode & MODE_IPV6) {
         /* Search for :: in string */
@@ -268,13 +299,13 @@ int ConvertIP(ldap_t *l, char *ip)
             /* bufa starts with a ::, so just copy and clear */
             strncpy(bufb, bufa, sizeof(bufa));
             memset(bufa, '\0', strlen(bufa));
-            swi++;                                                     /* Indicates that there is a bufb */
+            swi++;                                                             /* Indicates that there is a bufb */
         } else if ((bufa[0] == ':') && (bufa[1] != ':')) {
             /* bufa starts with a :, a typo so just fill in a ':', cat and clear */
             bufb[0] = ':';
             strncat(bufb, bufa, sizeof(bufa));
             memset(bufa, '\0', strlen(bufa));
-            swi++;                                                     /* Indicates that there is a bufb */
+            swi++;                                                             /* Indicates that there is a bufb */
         } else {
             p = strstr(bufa, "::");
             if (p != NULL) {
@@ -284,7 +315,7 @@ int ConvertIP(ldap_t *l, char *ip)
                 memcpy(bufb, p, i);
                 *p = '\0';
                 bufb[i] = '\0';
-                swi++;                                                 /* Indicates that there is a bufb */
+                swi++;                                                         /* Indicates that there is a bufb */
             }
         }
     }
@@ -300,7 +331,7 @@ int ConvertIP(ldap_t *l, char *ip)
                     strcpy(hexc, "FFFF");
                     strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 } else
-                    break;                                             /* reached end */
+                    break;                                                     /* reached end */
             } else {
                 /* Break down IPv4 address nested in the IPv6 address */
                 t = SplitString(bufb, s, '.', obj, sizeof(obj));
@@ -308,12 +339,12 @@ int ConvertIP(ldap_t *l, char *ip)
                     errno = 0;
                     x = strtol(obj, (char **)NULL, 10);
                     if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0)))
-                        return -4;                                             /* Out of bounds -- Invalid address */
+                        return LDAP_ERR_OOB;                                   /* Out of bounds -- Invalid address */
                     memset(hexc, '\0', sizeof(hexc));
                     snprintf(hexc, sizeof(hexc), "%.2X", (int)x);
                     strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 } else
-                    break;                                             /* reached end of octet */
+                    break;                                                     /* reached end of octet */
             }
         } else if ((conf.mode & MODE_IPV4) && (swi == 0)) {
             /* Break down IPv4 address  */
@@ -322,39 +353,39 @@ int ConvertIP(ldap_t *l, char *ip)
                 errno = 0;
                 x = strtol(obj, (char **)NULL, 10);
                 if (((x < 0) || (x > 255)) || ((errno != 0) && (x == 0)) || ((obj[0] != '0') && (x == 0)))
-                    return -4;                                         /* Out of bounds -- Invalid address */
+                    return LDAP_ERR_OOB;                                               /* Out of bounds -- Invalid address */
                 memset(hexc, '\0', sizeof(hexc));
                 snprintf(hexc, sizeof(hexc), "%.2X", (int)x);
                 strncat(l->search_ip, hexc, sizeof(l->search_ip));
             } else
-                break;                                                 /* reached end of octet */
+                break;                                                         /* reached end of octet */
         } else if (conf.mode & MODE_IPV6) {
             /* Break down IPv6 address */
             if (swi > 1)
-                t = SplitString(bufb, s, ':', obj, sizeof(obj));       /* After "::" */
+                t = SplitString(bufb, s, ':', obj, sizeof(obj));               /* After "::" */
             else
-                t = SplitString(bufa, s, ':', obj, sizeof(obj));       /* Before "::" */
+                t = SplitString(bufa, s, ':', obj, sizeof(obj));               /* Before "::" */
             /* Convert octet by size (t) - and fill 0's */
-            switch (t) {                                               /* IPv6 is already in HEX, copy contents */
+            switch (t) {                                                       /* IPv6 is already in HEX, copy contents */
             case 4:
                 hexc[0] = (char) toupper((int)obj[0]);
                 i = (int)hexc[0];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[1] = (char) toupper((int)obj[1]);
                 i = (int)hexc[1];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[2] = '\0';
                 strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 hexc[0] = (char) toupper((int)obj[2]);
                 i = (int)hexc[0];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[1] = (char) toupper((int)obj[3]);
                 i = (int)hexc[1];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[2] = '\0';
                 strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 break;
@@ -363,17 +394,17 @@ int ConvertIP(ldap_t *l, char *ip)
                 hexc[1] = (char) toupper((int)obj[0]);
                 i = (int)hexc[1];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[2] = '\0';
                 strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 hexc[0] = (char) toupper((int)obj[1]);
                 i = (int)hexc[0];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[1] = (char) toupper((int)obj[2]);
                 i = (int)hexc[1];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[2] = '\0';
                 strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 break;
@@ -382,11 +413,11 @@ int ConvertIP(ldap_t *l, char *ip)
                 hexc[0] = (char) toupper((int)obj[0]);
                 i = (int)hexc[0];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[1] = (char) toupper((int)obj[1]);
                 i = (int)hexc[1];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[2] = '\0';
                 strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 break;
@@ -396,13 +427,13 @@ int ConvertIP(ldap_t *l, char *ip)
                 hexc[1] = (char) toupper((int)obj[0]);
                 i = (int)hexc[1];
                 if (!isxdigit(i))
-                    return -5;                                         /* Out of bounds */
+                    return LDAP_ERR_OOB;                                       /* Out of bounds */
                 hexc[2] = '\0';
                 strncat(l->search_ip, hexc, sizeof(l->search_ip));
                 break;
             default:
                 if (t > 4)
-                    return -5;
+                    return LDAP_ERR_OOB;
                 break;
             }
             /* Code to pad the address with 0's between a '::' */
@@ -472,9 +503,12 @@ int SearchFilterLDAP(ldap_t *l, char *group)
     size_t i, j, s;
     int swi;
     char bufa[MAXLEN], bufb[MAXLEN], bufc[MAXLEN], bufd[MAXLEN], bufg[MAXLEN];
-    if (l == NULL) return -1;
-    if (!(l->status & LDAP_BIND_S)) return -2;                 /* Must be Bound first */
-    if (l->search_ip[0] == '\0') return -3;                    /* Search IP is required */
+    if (l == NULL) return LDAP_ERR_NULL;
+//  if (group == NULL) return LDAP_ERR_PARAM;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
+    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not Bound */
+    if (l->search_ip[0] == '\0') return LDAP_ERR_DATA;                 /* Search IP is required */
 
     /* Zero out if not already */
     memset(bufa, '\0', strlen(bufa));
@@ -514,7 +548,7 @@ int SearchFilterLDAP(ldap_t *l, char *group)
             strncat(bufb, bufd, sizeof(bufb));
         } else
             strncat(bufb, ")", sizeof(bufb));
-        debug("SearchFilterLDAP", "bufb: %s\n", bufb);
+//    debug("SearchFilterLDAP", "bufb: %s\n", bufb);
         strncat(bufa, bufb, sizeof(bufa));
         strncat(bufa, ")", sizeof(bufa));
     } else {
@@ -528,7 +562,7 @@ int SearchFilterLDAP(ldap_t *l, char *group)
             strncat(bufg, l->basedn, sizeof(bufg));
         }
         strncat(bufg, ")", sizeof(bufg));
-        debug("SearchFilterLDAP", "bufg: %s\n", bufg);
+//    debug("SearchFilterLDAP", "bufg: %s\n", bufg);
         strncat(bufa, bufg, sizeof(bufa));
         /* networkAddress */
         snprintf(bufb, sizeof(bufb), "(|(networkAddress=1\\23%s)(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", \
@@ -539,7 +573,7 @@ int SearchFilterLDAP(ldap_t *l, char *group)
             strncat(bufb, bufd, sizeof(bufb));
         } else
             strncat(bufb, ")", sizeof(bufb));
-        debug("SearchFilterLDAP", "bufb: %s\n", bufb);
+//    debug("SearchFilterLDAP", "bufb: %s\n", bufb);
         strncat(bufa, bufb, sizeof(bufa));
         strncat(bufa, "))", sizeof(bufa));
     }
@@ -559,18 +593,18 @@ int SearchLDAP(ldap_t *l, int scope, char *filter, char **attrs)
 {
     int s;
     char ft[MAXLEN];
-    if ((l == NULL) || (filter == NULL)) return -1;    /* If attrs is NULL, then all attrs will return */
-    if (scope < 0) return -2;                          /* We require a scope */
-    if (l->lp == NULL) return -3;
-    if (!(l->status & LDAP_BIND_S)) return -4;         /* Must be bound */
-    if (l->status & LDAP_SEARCH_S) return -5;          /* Must not already be searching */
-    if (l->basedn[0] == '\0') return -6;                       /* We require a basedn */
+    if (l == NULL) return LDAP_ERR_NULL;
+    if ((scope < 0) || (filter == NULL)) return LDAP_ERR_PARAM;                /* If attrs is NULL, then all attrs will return */
+    if (l->lp == NULL) return LDAP_ERR_POINTER;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
+    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not bound */
+    if (l->status & LDAP_SEARCH_S) return LDAP_ERR_SEARCHED;           /* Already searching */
+    if (l->basedn[0] == '\0') return LDAP_ERR_DATA;                    /* We require a basedn */
     if (l->lm != NULL)
-        ldap_msgfree(l->lm);                           /* Make sure l->lm is empty */
+        ldap_msgfree(l->lm);                                           /* Make sure l->lm is empty */
 
-    /* FIX IT -- ?? Narrow results to include the IP Address ?? */
-
-    if (filter == NULL)                                        /* if filter is NULL, then return ALL networkAddress */
+    if (filter == NULL)                                                        /* if filter is NULL, then return ALL networkAddress */
         strcpy(ft, "(&(objectClass=User)(networkAddress=*))");
     else
         strncpy(ft, filter, sizeof(ft));
@@ -591,15 +625,17 @@ int SearchLDAP(ldap_t *l, int scope, char *filter, char **attrs)
         s = ldap_search_s(l->lp, l->basedn, LDAP_SCOPE_BASE, ft, attrs, 0, &(l->lm));
         break;
     }
-
-    /* FIX IT -- ?? Narrow results to include the IP Address ?? */
-
     if (s == LDAP_SUCCESS) {
-        l->status |= (LDAP_SEARCH_S);                  /* Mark as searched */
-        l->num_ent = ldap_count_entries(l->lp, l->lm); /* Counted */
-    } else
+        l->status |= (LDAP_SEARCH_S);                                  /* Mark as searched */
+        l->err = s;
+        l->idle_time = 0;                                                      /* Connection in use, reset idle timer */
+        l->num_ent = ldap_count_entries(l->lp, l->lm);                 /* Counted */
+        return LDAP_ERR_SUCCESS;
+    } else {
+        l->err = s;
         l->num_ent = (-1);
-    return s;                                          /* Return search value */
+        return LDAP_ERR_FAILED;
+    }
 }
 
 /*
@@ -610,39 +646,47 @@ int SearchLDAP(ldap_t *l, int scope, char *filter, char **attrs)
  */
 int GetValLDAP(ldap_t *l, char *attr)
 {
-    ber_len_t i, j;
     ber_len_t x;
-    int c;
+    /*
+      ber_len_t i, j;
+      int c;
+    */
     LDAPMessage *ent;
-    if ((l == NULL) || (attr == NULL)) return -1;
-    if (l->lp == NULL) return -2;
-    if (!(l->status & LDAP_SEARCH_S)) return -3;               /* Not searched */
-    if (l->num_ent <= 0) return -4;                    /* No entries found */
+    if (l == NULL) return LDAP_ERR_NULL;
+    if (attr == NULL) return LDAP_ERR_PARAM;
+    if (l->lp == NULL) return LDAP_ERR_POINTER;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
+    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not bound */
+    if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED;    /* Not searched */
+    if (l->num_ent <= 0) return LDAP_ERR_DATA;                         /* No entries found */
     if (l->val != NULL)
-        ldap_value_free_len(l->val);                   /* Clear data before populating */
+        ldap_value_free_len(l->val);                                   /* Clear data before populating */
     l->num_val = 0;
     if (l->status & LDAP_VAL_S)
-        l->status &= ~(LDAP_VAL_S);                            /* Clear VAL bit */
+        l->status &= ~(LDAP_VAL_S);                                            /* Clear VAL bit */
 
     /* Sift through entries -- Look for matches */
     for (ent = ldap_first_entry(l->lp, l->lm); ent != NULL; ent = ldap_next_entry(l->lp, ent)) {
         l->val = ldap_get_values_len(l->lp, ent, attr);
         if (l->val != NULL) {
-            x = ldap_count_values_len(l->val);         /* We got x values ... */
+            x = ldap_count_values_len(l->val);                         /* We got x values ... */
             l->num_val = x;
             if (x > 0) {
                 /* Display all values */
-                for (i = 0; i < x; i++) {
-                    debug("GetValLDAP", "value[%zd]: \"%s\"\n", i, l->val[i]->bv_val);
-                    debug("GetValLDAP", "value[%zd]: ", i);
-                    for (j = 0; j < (l->val[i]->bv_len); j++) {
-                        c = (int) l->val[i]->bv_val[j];
-                        if (c < 0)
-                            c = c + 256;
-                        debugx("%.2X", c);
-                    }
-                    debugx("\n");
-                }
+                /*
+                       for (i = 0; i < x; i++) {
+                         debug("GetValLDAP", "value[%zd]: \"%s\"\n", i, l->val[i]->bv_val);
+                         debug("GetValLDAP", "value[%zd]: ", i);
+                         for (j = 0; j < (l->val[i]->bv_len); j++) {
+                           c = (int) l->val[i]->bv_val[j];
+                           if (c < 0)
+                             c = c + 256;
+                           debugx("%.2X", c);
+                         }
+                         debugx("\n");
+                       }
+                */
                 /*     CRASHES?!?!
                        if (ent != NULL)
                          ldap_msgfree(ent);
@@ -654,7 +698,8 @@ int GetValLDAP(ldap_t *l, char *attr)
                 l->num_ent = 0;
                 l->status &= ~(LDAP_SEARCH_S);
                 l->status |= LDAP_VAL_S;
-                return LDAP_SUCCESS;                                   /* Found it */
+                l->err = LDAP_SUCCESS;
+                return LDAP_ERR_SUCCESS;                                       /* Found it */
             }
         }
         /* Attr not found, continue */
@@ -672,8 +717,9 @@ int GetValLDAP(ldap_t *l, char *attr)
     }
     l->num_ent = 0;
     l->num_val = 0;
+    l->err = LDAP_NO_SUCH_OBJECT;
     l->status &= ~(LDAP_SEARCH_S);
-    return -5;                                         /* Not found */
+    return LDAP_ERR_NOTFOUND;                                          /* Not found */
 }
 
 /*
@@ -692,22 +738,26 @@ int SearchIPLDAP(ldap_t *l, char *uid)
     char bufa[MAXLEN], bufb[MAXLEN], hexc[4];
     LDAPMessage *ent;
     struct berval **ber;
-    if ((l == NULL) || (uid == NULL)) return -1;
-    if (l->lp == NULL) return -2;
-    if (!(l->status & LDAP_SEARCH_S)) return -3;               /* Not searched */
-    if (l->num_ent <= 0) return -4;                    /* No entries found */
+    if (l == NULL) return LDAP_ERR_NULL;
+    if (uid == NULL) return LDAP_ERR_PARAM;
+    if (l->lp == NULL) return LDAP_ERR_POINTER;
+    if (!(l->status & LDAP_INIT_S)) return LDAP_ERR_INIT;                      /* Not initalized */
+    if (!(l->status & LDAP_OPEN_S)) return LDAP_ERR_OPEN;                      /* Not open */
+    if (!(l->status & LDAP_BIND_S)) return LDAP_ERR_BIND;                      /* Not bound */
+    if (!(l->status & LDAP_SEARCH_S)) return LDAP_ERR_NOT_SEARCHED;    /* Not searched */
+    if (l->num_ent <= 0) return LDAP_ERR_DATA;                         /* No entries found */
     if (l->val != NULL)
-        ldap_value_free_len(l->val);                   /* Clear data before populating */
+        ldap_value_free_len(l->val);                                   /* Clear data before populating */
     l->num_val = 0;
     if (l->status & LDAP_VAL_S)
-        l->status &= ~(LDAP_VAL_S);                            /* Clear VAL bit */
+        l->status &= ~(LDAP_VAL_S);                                            /* Clear VAL bit */
 
     /* Sift through entries */
     for (ent = ldap_first_entry(l->lp, l->lm); ent != NULL; ent = ldap_next_entry(l->lp, ent)) {
         l->val = ldap_get_values_len(l->lp, ent, "networkAddress");
-        ber = ldap_get_values_len(l->lp, ent, "cn");
+        ber = ldap_get_values_len(l->lp, ent, conf.attrib);                    /* conf.attrib is the <userid> mapping */
         if (l->val != NULL) {
-            x = ldap_count_values_len(l->val);         /* We got x values ... */
+            x = ldap_count_values_len(l->val);                         /* We got x values ... */
             l->num_val = x;
             if (x > 0) {
                 /* Display all values */
@@ -715,30 +765,32 @@ int SearchIPLDAP(ldap_t *l, char *uid)
                     j = l->val[i]->bv_len;
                     memcpy(bufa, l->val[i]->bv_val, j);
                     z = SplitString(bufa, j, '#', bufb, sizeof(bufb));
-                    debug("SearchIPLDAP", "value[%zd]: SplitString(", i);
-                    for (k = 0; k < z; k++) {
-                        c = (int) bufb[k];
-                        if (c < 0)
-                            c = c + 256;
-                        debugx("%.2X", c);
-                    }
-                    debugx(", ");
-                    for (k = 0; k < (j - z - 1); k++) {
-                        c = (int) bufa[k];
-                        if (c < 0)
-                            c = c + 256;
-                        debugx("%.2X", c);
-                    }
-                    debugx("): %zd\n", z);
+                    /*
+                         debug("SearchIPLDAP", "value[%zd]: SplitString(", i);
+                         for (k = 0; k < z; k++) {
+                           c = (int) bufb[k];
+                           if (c < 0)
+                             c = c + 256;
+                           debugx("%.2X", c);
+                         }
+                         debugx(", ");
+                         for (k = 0; k < (j - z - 1); k++) {
+                           c = (int) bufa[k];
+                           if (c < 0)
+                             c = c + 256;
+                           debugx("%.2X", c);
+                         }
+                         debugx("): %zd\n", z);
+                    */
                     z = j - z - 1;
                     j = atoi(bufb);
                     switch (j) {
-                    case 0:                                            /* IPX address (We don't support these right now) */
+                    case 0:                                                    /* IPX address (We don't support these right now) */
                         break;
-                    case 1:                                            /* IPv4 address (eDirectory 8.7 and below) */
+                    case 1:                                                    /* IPv4 address (eDirectory 8.7 and below) */
                         /* bufa is the address, just compare it */
                         if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
-                            break;                                             /* Not looking for IPv4 */
+                            break;                                                     /* Not looking for IPv4 */
                         for (k = 0; k < z; k++) {
                             c = (int) bufa[k];
                             if (c < 0)
@@ -761,15 +813,16 @@ int SearchIPLDAP(ldap_t *l, char *uid)
                             ldap_value_free_len(ber);
                             ber = NULL;
                             l->num_val = 0;
+                            l->err = LDAP_SUCCESS;
                             l->status &= ~(LDAP_SEARCH_S);
-                            return LDAP_SUCCESS;                               /* We got our userid */
+                            return LDAP_ERR_SUCCESS;                           /* We got our userid */
                         }
                         /* Not matched, continue */
                         break;
-                    case 8:                                            /* IPv4 (UDP) address (eDirectory 8.8 and higher) */
+                    case 8:                                                    /* IPv4 (UDP) address (eDirectory 8.8 and higher) */
                         /* bufa + 2 is the address (skip 2 digit port) */
                         if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
-                            break;                                             /* Not looking for IPv4 */
+                            break;                                                     /* Not looking for IPv4 */
                         for (k = 2; k < z; k++) {
                             c = (int) bufa[k];
                             if (c < 0)
@@ -792,15 +845,16 @@ int SearchIPLDAP(ldap_t *l, char *uid)
                             ldap_value_free_len(ber);
                             ber = NULL;
                             l->num_val = 0;
+                            l->err = LDAP_SUCCESS;
                             l->status &= ~(LDAP_SEARCH_S);
-                            return LDAP_SUCCESS;                               /* We got our userid */
+                            return LDAP_ERR_SUCCESS;                           /* We got our userid */
                         }
                         /* Not matched, continue */
                         break;
-                    case 9:                                            /* IPv4 (TCP) address (eDirectory 8.8 and higher) */
+                    case 9:                                                    /* IPv4 (TCP) address (eDirectory 8.8 and higher) */
                         /* bufa + 2 is the address (skip 2 digit port) */
                         if (!(l->status & LDAP_IPV4_S) || (l->status & LDAP_IPV6_S))
-                            break;                                             /* Not looking for IPv4 */
+                            break;                                                     /* Not looking for IPv4 */
                         for (k = 2; k < z; k++) {
                             c = (int) bufa[k];
                             if (c < 0)
@@ -823,15 +877,16 @@ int SearchIPLDAP(ldap_t *l, char *uid)
                             ldap_value_free_len(ber);
                             ber = NULL;
                             l->num_val = 0;
+                            l->err = LDAP_SUCCESS;
                             l->status &= ~(LDAP_SEARCH_S);
-                            return LDAP_SUCCESS;                               /* We got our userid */
+                            return LDAP_ERR_SUCCESS;                           /* We got our userid */
                         }
                         /* Not matched, continue */
                         break;
-                    case 10:                                           /* IPv6 (UDP) address (eDirectory 8.8 and higher) */
+                    case 10:                                                   /* IPv6 (UDP) address (eDirectory 8.8 and higher) */
                         /* bufa + 2 is the address (skip 2 digit port) */
                         if (!(l->status & LDAP_IPV6_S))
-                            break;                                             /* Not looking for IPv6 */
+                            break;                                                     /* Not looking for IPv6 */
                         for (k = 2; k < z; k++) {
                             c = (int) bufa[k];
                             if (c < 0)
@@ -854,15 +909,16 @@ int SearchIPLDAP(ldap_t *l, char *uid)
                             ldap_value_free_len(ber);
                             ber = NULL;
                             l->num_val = 0;
+                            l->err = LDAP_SUCCESS;
                             l->status &= ~(LDAP_SEARCH_S);
-                            return LDAP_SUCCESS;                               /* We got our userid */
+                            return LDAP_ERR_SUCCESS;                           /* We got our userid */
                         }
                         /* Not matched, continue */
                         break;
-                    case 11:                                           /* IPv6 (TCP) address (eDirectory 8.8 and higher) */
+                    case 11:                                                   /* IPv6 (TCP) address (eDirectory 8.8 and higher) */
                         /* bufa + 2 is the address (skip 2 digit port) */
                         if (!(l->status & LDAP_IPV6_S))
-                            break;                                             /* Not looking for IPv6 */
+                            break;                                                     /* Not looking for IPv6 */
                         for (k = 2; k < z; k++) {
                             c = (int) bufa[k];
                             if (c < 0)
@@ -885,12 +941,13 @@ int SearchIPLDAP(ldap_t *l, char *uid)
                             ldap_value_free_len(ber);
                             ber = NULL;
                             l->num_val = 0;
+                            l->err = LDAP_SUCCESS;
                             l->status &= ~(LDAP_SEARCH_S);
-                            return LDAP_SUCCESS;                               /* We gout our userid */
+                            return LDAP_ERR_SUCCESS;                           /* We gout our userid */
                         }
                         /* Not matched, continue */
                         break;
-                    default:                                           /* Other, unsupported */
+                    default:                                                   /* Other, unsupported */
                         break;
                     }
                 }
@@ -927,6 +984,49 @@ int SearchIPLDAP(ldap_t *l, char *uid)
     }
     l->num_ent = 0;
     l->num_val = 0;
+    l->err = LDAP_NO_SUCH_OBJECT;
     l->status &= ~(LDAP_SEARCH_S);
-    return -5;                                         /* Not found ... Sorry :) */
+    return LDAP_ERR_NOTFOUND;                                          /* Not found ... Sorry :) */
+}
+
+char *ErrLDAP(int e)
+{
+    switch (e) {
+    case LDAP_ERR_NULL:
+        return "Null pointer provided";
+    case LDAP_ERR_POINTER:
+        return "Null LDAP pointer";
+    case LDAP_ERR_PARAM:
+        return "Null or Missing paremeter(s)";
+    case LDAP_ERR_INIT:
+        return "LDAP data not initalized";
+    case LDAP_ERR_OPEN:
+        return "LDAP connection is not active";
+    case LDAP_ERR_CONNECT:
+        return "Unable to connect to LDAP host";
+    case LDAP_ERR_BIND:
+        return "LDAP connection is not bound";
+    case LDAP_ERR_SEARCHED:
+        return "LDAP connection has already been searched";
+    case LDAP_ERR_NOT_SEARCHED:
+        return "LDAP connection has not been searched";
+    case LDAP_ERR_INVALID:
+        return "Invalid paremeters";
+    case LDAP_ERR_OOB:
+        return "Paremeter is out of bounds";
+    case LDAP_ERR_PERSIST:
+        return "Persistent mode is not active";
+    case LDAP_ERR_DATA:
+        return "Required data has not been found";
+    case LDAP_ERR_NOTFOUND:
+        return "Item or object has not been found";
+    case LDAP_ERR_OTHER:
+        return "An unknown error has occured";
+    case LDAP_ERR_FAILED:
+        return "Operation has failed";
+    case LDAP_ERR_SUCCESS:
+        return "Operation is successful";
+    default:
+        return "An unknown error has occured";
+    }
 }
index 6e942dfba13ddfe93129e33e828ff213d49b1058..c085715237c6b4610d3b05c26a32166c5d954844 100644 (file)
@@ -71,12 +71,14 @@ typedef struct {
     char passwd[MAXLEN];
     char search_filter[MAXLEN];                        /* search_group gets appended here by GroupLDAP */
     char search_ip[MAXLEN];                    /* Could be IPv4 or IPv6, set by ConvertIP */
-    char userid[MAXLEN];                               /* Resulting cn */
+    char userid[MAXLEN];                               /* Resulting userid */
     unsigned int status;
     unsigned int port;
     unsigned long type;                                /* Type of bind */
     int ver;
     int scope;
+    int err;                                   /* LDAP error code */
+    time_t idle_time;
     int num_ent;                                       /* Number of entry's found via search */
     int num_val;                                       /* Number of value's found via getval */
 } ldap_t;
index a807794dea30f000012de53e890716f88c886f31..ad757e1c5bf2447c61753317d60a939de407218e 100644 (file)
 char *search_attrib[] = { "cn", "uid", "networkAddress", "groupMembership", NULL };
 conf_t conf;
 ldap_t ldap;
+time_t now;
+time_t elap;
 
 /* Displays version information */
 void DisplayVersion()
 {
-    printfx("Squid eDirectory IP Lookup Helper v1.2.  Copyright (C) 2009, 2010 Chad E. Naugle\n");
+    printfx("Squid eDirectory IP Lookup Helper v1.5.  Copyright (C) 2009, 2010 Chad E. Naugle\n");
 }
 
 /* Displays program usage information */
@@ -45,8 +47,8 @@ void DisplayUsage()
     DisplayVersion();
     printfx("\n");
     printfx("Usage: %s\n", conf.program);
-    printfx("          -H <host> -p <port> [-Z] [-2/3] -b <basedn> -s <scope>\n");
-    printfx("          -D <binddn> -W <bindpass> -F <search-filter> -G \n\n");
+    printfx("          -H <host> -p <port> [-Z] [-P] [-v 3] -b <basedn> -s <scope>\n");
+    printfx("          -D <binddn> -W <bindpass> -F <search-filter> [-G] \n\n");
     printfx("  -d          : Debug Mode.\n");
     printfx("  -4          : Address is IPv4 (127.0.0.1 format).\n");
     printfx("  -6          : Address is IPv6 (::1 format).\n");
@@ -54,16 +56,17 @@ void DisplayUsage()
     printfx("  -H <host>   : Specify hostname/ip of server.\n");
     printfx("  -p <port>   : Specify port number. (Range 1-65535)\n");
     printfx("  -Z          : Enable TLS security.\n");
-    printfx("  -1          : Set LDAP version 1.\n");
-    printfx("  -2          : Set LDAP version 2.\n");
-    printfx("  -3          : Set LDAP version 3.\n");
-    printfx("  -b <base>   : Specify Base DN. (ie. o=ORG)\n");
+    printfx("  -P          : Use persistent connections.\n");
+    printfx("  -t <sec>    : Timeout factor for persistent connections.  (Default is 60 sec, set to 0 for never timeout)\n");
+    printfx("  -v <1,2,3>  : Set LDAP version to 1, 2, or 3.\n");
+    printfx("  -b <base>   : Specify Base DN. (ie. \"o=ORG\")\n");
     printfx("  -s <scope>  : Specify LDAP Search Scope (base, one, sub; defaults to 'base').\n");
     printfx("  -D <dn>     : Specify Binding DN. (ie. cn=squid,o=ORG)\n");
     printfx("  -W <pass>   : Specify Binding password.\n");
+    printfx("  -u <attrib> : Set userid attribute (Defaults to \"cn\").\n");
     printfx("  -F <filter> : Specify LDAP search filter. (ie. \"(objectClass=User)\")\n");
-    printfx("  -G          : Specify if LDAP search group is required.\n");
-    printfx("  -v          : Display version & exit.\n");
+    printfx("  -G          : Specify if LDAP search group is required. (ie. \"groupMembership=\")\n");
+    printfx("  -V          : Display version & exit.\n");
     printfx("  -h          : This screen & exit.\n");
     printfx("\n");
 }
@@ -74,12 +77,14 @@ void InitConf()
     memset(conf.program, '\0', sizeof(conf.program));
     memset(conf.basedn, '\0', sizeof(conf.basedn));
     memset(conf.host, '\0', sizeof(conf.host));
+    memset(conf.attrib, '\0', sizeof(conf.attrib));
     memset(conf.dn, '\0', sizeof(conf.dn));
     memset(conf.passwd, '\0', sizeof(conf.passwd));
     memset(conf.search_filter, '\0', sizeof(conf.search_filter));
     conf.scope = -1;
     conf.ver = -1;
     conf.port = -1;
+    conf.persist_timeout = -1;
     conf.mode = 0;
     conf.mode |= MODE_INIT;
 
@@ -96,11 +101,21 @@ void InitConf()
 #ifdef DEFAULT_BIND_PASS
     strcpy(conf.passwd, DEFAULT_BIND_PASS);
 #endif
+#ifdef DEFAULT_USER_ATTRIB
+    strcpy(conf.attrib, DEFAULT_USER_ATTRIB);
+#endif
 #ifdef DEFAULT_SEARCH_FILTER
     strcpy(conf.search_filter, DEFAULT_SEARCH_FILTER);
 #endif
 #ifdef DEFAULT_SEARCH_SCOPE
-    conf.scope = DEFAULT_SEARCH_SCOPE;
+    if (!strcmp(DEFAULT_SEARCH_SCOPE, "base"))
+        conf.scope = 0;
+    else if (!strcmp(DEFAULT_SEARCH_SCOPE, "one"))
+        conf.scope = 1;
+    else if (!strcmp(DEFAULT_SEARCH_SCOPE, "sub"))
+        conf.scope = 2;
+    else
+        conf.scope = 0;
 #endif
 #ifdef DEFAULT_LDAP_VERSION
     conf.ver = DEFAULT_LDAP_VERSION;
@@ -117,12 +132,18 @@ void InitConf()
 #ifdef DEFAULT_USE_TLS
     conf.mode |= MODE_TLS;
 #endif
-#ifdef DEFAULT_DEBUG
-    conf.mode |= MODE_DEBUG;
+#ifdef DEFAULT_USE_PERSIST
+    conf.mode |= MODE_PERSIST;
+#endif
+#ifdef DEFAULT_PERSIST_TIMEOUT
+    conf.persist_timeout = DEFAULT_PERSIST_TIMEOUT;
 #endif
 #ifdef DEFAULT_GROUP_REQUIRED
     conf.mode |= MODE_GROUP;
 #endif
+#ifdef DEFAULT_DEBUG
+    conf.mode |= MODE_DEBUG;
+#endif
 }
 
 /* Displays running configuration */
@@ -155,6 +176,14 @@ void DisplayConf()
         printfx("      TLS mode: ON\n");
     else
         printfx("      TLS mode: OFF\n");
+    if (conf.mode & MODE_PERSIST) {
+        printfx("      Persistent mode: ON\n");
+        if (conf.persist_timeout > 0)
+            printfx("  Persistent mode idle timeout: %d\n", conf.persist_timeout);
+        else
+            printfx("  Persistent mode idle timeout: OFF\n");
+    } else
+        printfx("      Persistent mode: OFF\n");
     printfx("  LDAP Version: %d\n", conf.ver);
     if (conf.basedn[0] != '\0')
         printfx("      Base DN: %s\n", conf.basedn);
@@ -215,6 +244,7 @@ int main(int argc, char **argv)
     char sfmod[MAXLEN];
     int x;
     size_t i, j, s, k;
+    time_t t;
     struct sigaction sv;
 
     /* Init */
@@ -225,6 +255,8 @@ int main(int argc, char **argv)
     memset(sfmod, '\0', sizeof(sfmod));
     InitConf(&conf);
     strncpy(conf.program, argv[0], sizeof(conf.program));
+    now = -1;
+    t = -1;
     debug("main", "InitConf() done.\n");
 
     /* Scan args */
@@ -244,8 +276,8 @@ int main(int argc, char **argv)
                 s = strlen(argv[i]);
                 for (j = 1; j < s; j++) {
                     switch (argv[i][j]) {
-                    case 'v':
-                        DisplayVersion();
+                    case 'h':
+                        DisplayUsage();
                         return 1;
                     case 'V':
                         DisplayVersion();
@@ -266,21 +298,42 @@ int main(int argc, char **argv)
                         if (!(conf.mode & MODE_TLS))
                             conf.mode |= MODE_TLS;                     /* Don't set mode more than once */
                         break;
-                    case '1':
-                        conf.ver = 1;
+                    case 'P':
+                        if (!(conf.mode & MODE_PERSIST))
+                            conf.mode |= MODE_PERSIST;                 /* Don't set mode more than once */
                         break;
-                    case '2':
-                        conf.ver = 2;
+                    case 'v':
+                        i++;
+                        if (argv[i] != NULL) {
+                            conf.ver = atoi(argv[i]);
+                            if (conf.ver < 1)
+                                conf.ver = 1;
+                            else if (conf.ver > 3)
+                                conf.ver = 3;
+                        } else {
+                            printfx("No parameters given for 'v'.\n");
+                            DisplayUsage();
+                            return 1;
+                        }
                         break;
-                    case '3':
-                        conf.ver = 3;
+                    case 't':
+                        i++;
+                        if (argv[i] != NULL) {
+                            conf.persist_timeout = atoi(argv[i]);
+                            if (conf.persist_timeout < 0)
+                                conf.persist_timeout = 0;
+                        } else {
+                            printfx("No parameters given for 't'.\n");
+                            DisplayUsage();
+                            return 1;
+                        }
                         break;
                     case 'b':
                         i++;                                   /* Set Base DN */
                         if (argv[i] != NULL)
                             strncpy(conf.basedn, argv[i], sizeof(conf.basedn));
                         else {
-                            printfx("No parameters given to 'b'.\n");
+                            printfx("No parameters given for 'b'.\n");
                             DisplayUsage();
                             return 1;
                         }
@@ -290,7 +343,7 @@ int main(int argc, char **argv)
                         if (argv[i] != NULL)
                             strncpy(conf.host, argv[i], sizeof(conf.host));
                         else {
-                            printfx("No parameters given to 'H'.\n");
+                            printfx("No parameters given for 'H'.\n");
                             DisplayUsage();
                             return 1;
                         }
@@ -300,7 +353,7 @@ int main(int argc, char **argv)
                         if (argv[i] != NULL)
                             conf.port = atoi(argv[i]);
                         else {
-                            printfx("No parameters given to 'p'.\n");
+                            printfx("No parameters given for 'p'.\n");
                             DisplayUsage();
                             return 1;
                         }
@@ -310,7 +363,7 @@ int main(int argc, char **argv)
                         if (argv[i] != NULL)
                             strncpy(conf.dn, argv[i], sizeof(conf.dn));
                         else {
-                            printfx("No parameters given to 'D'.\n");
+                            printfx("No parameters given for 'D'.\n");
                             DisplayUsage();
                             return 1;
                         }
@@ -320,7 +373,7 @@ int main(int argc, char **argv)
                         if (argv[i] != NULL)
                             strncpy(conf.passwd, argv[i], sizeof(conf.passwd));
                         else {
-                            printfx("No parameters given to 'W'.\n");
+                            printfx("No parameters given for 'W'.\n");
                             DisplayUsage();
                             return 1;
                         }
@@ -330,7 +383,7 @@ int main(int argc, char **argv)
                         if (argv[i] != NULL)
                             strncpy(conf.search_filter, argv[i], sizeof(conf.search_filter));
                         else {
-                            printfx("No parameters given to 'F'.\n");
+                            printfx("No parameters given for 'F'.\n");
                             DisplayUsage();
                             return 1;
                         }
@@ -342,24 +395,20 @@ int main(int argc, char **argv)
                     case 's':
                         i++;                                   /* Set Scope Level */
                         if (argv[i] != NULL) {
-                            strncpy(bufa, argv[i], sizeof(bufa));
-                            if (!strcmp(bufa, "base"))
+                            if (!strncmp(argv[i], "base", 4))
                                 conf.scope = 0;
-                            else if (!strcmp(bufa, "one"))
+                            else if (!strncmp(argv[i], "one", 4))
                                 conf.scope = 1;
-                            else if (!strcmp(bufa, "sub"))
+                            else if (!strncmp(argv[i], "sub", 4))
                                 conf.scope = 2;
                             else
-                                conf.scope = 0;
+                                conf.scope = 0;                        /* Default is 'base' */
                         } else {
-                            printfx("No parameters given to 's'.\n");
+                            printfx("No parameters given for 's'.\n");
                             DisplayUsage();
                             return 1;
                         }
                         break;
-                    case 'h':
-                        DisplayUsage();
-                        return 1;
                     case '-':                                  /* We got a second '-' ... ignore */
                         break;
                     default:
@@ -386,6 +435,8 @@ int main(int argc, char **argv)
         conf.ver = 2;
     if ((conf.mode & MODE_TLS) && (conf.ver < 3))
         conf.ver = 3;                                  /* TLS requires version 3 */
+    if (conf.persist_timeout < 0)
+        conf.persist_timeout = 600;                            /* Default: 600 seconds (10 minutes) */
     if (conf.scope < 0)
         conf.scope = 0;                                        /* Default: base */
     if (conf.search_filter[0] == '\0')
@@ -409,16 +460,30 @@ int main(int argc, char **argv)
     sigaction(SIGSEGV, &sv, NULL);
     debug("main", "Signals trapped.\n");
 
+    /* Set elap timer */
+    time(&now);
+    t = now;
+
     /* Main loop -- Waits for stdin input before action */
     while (fgets(bufa, sizeof(bufa), stdin) != NULL) {
         if (conf.mode & MODE_KILL)
             break;
+        time(&now);
+        if (t < now) {
+            /* Elapse seconds */
+            elap = now - t;
+//      debug("main", "while() -> %d seconds elapsed.\n", elap);
+            t = now;
+        } else
+            elap = 0;
         k = strlen(bufa);
-        debug("main", "while() bufa[%zd]: %s", k, bufa);
-        debug("main", "while() bufa[%zd]: ");
-        for (i = 0; i < k; i++)
-            debugx("%.2X", bufa[i]);
-        debugx("\n");
+        /*
+            debug("main", "while() -> bufa[%zd]: %s", k, bufa);
+            debug("main", "while() -> bufa[%zd]: ");
+            for (i = 0; i < k; i++)
+              debugx("%.2X", bufa[i]);
+            debugx("\n");
+        */
         /* Check for CRLF */
         p = strchr(bufa, '\n');
         if (p != NULL)
@@ -430,144 +495,180 @@ int main(int argc, char **argv)
 
         /* No space given, but group string is required --> ERR */
         if ((conf.mode & MODE_GROUP) && (p == NULL)) {
+            debug("main", "while() -> Search group is required.\n");
             printfx("ERR\n");
             continue;
         }
+        x = 0;
 
         /* Open LDAP connection */
-        InitLDAP(&ldap);
-        debug("main", "InitLDAP() done.\n");
-        x = OpenLDAP(&ldap, conf.host, conf.port);
-        if (x != LDAP_SUCCESS) {
-            /* Failed to connect */
-            debug("main", "Failed to connect.  Error: %d (%s)\n", x, ldap_err2string(x));
-        } else {
-            debug("main", "OpenLDAP(-, %s, %d) done. Result: %d\n", conf.host, conf.port, x);
-            x = SetVerLDAP(&ldap, conf.ver);
-            if (x != LDAP_SUCCESS) {
-                /* Failed to set version */
-                debug("main", "Failed to set version.  Error: %d (%s)\n", x, ldap_err2string(x));
+        if (!(ldap.status & LDAP_INIT_S)) {
+            InitLDAP(&ldap);
+            debug("main", "InitLDAP() -> %s\n", ErrLDAP(LDAP_ERR_SUCCESS));
+            if (conf.mode & MODE_PERSIST)                                      /* Setup persistant mode */
+                ldap.status |= LDAP_PERSIST_S;
+        }
+        if ((ldap.status & LDAP_IDLE_S) && (elap > 0)) {
+            ldap.idle_time = ldap.idle_time + elap;
+        }
+        if ((ldap.status & LDAP_PERSIST_S) && (ldap.status & LDAP_IDLE_S) && (ldap.idle_time > conf.persist_timeout)) {
+            debug("main", "while() -> Connection timed out after %u seconds\n", ldap.idle_time);
+            x = CloseLDAP(&ldap);
+            debug("main", "CloseLDAP(-) -> %s\n", ErrLDAP(x));
+        }
+        ldap.err = -1;
+        if (!(ldap.status & LDAP_OPEN_S)) {
+            x = OpenLDAP(&ldap, conf.host, conf.port);
+            if (x != LDAP_ERR_SUCCESS) {
+                /* Failed to connect */
+                debug("main", "OpenLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
             } else {
-                debug("main", "SetVerLDAP(-, %d) done. Result: %d\n", conf.ver, x);
-                if (conf.mode & MODE_TLS) {
-                    /* TLS binding */
-                    x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_TLS);
-                    if (x != LDAP_SUCCESS) {
-                        /* Unable to bind */
-                        debug("main", "Failed to bind.  Error: %d (%s)\n", x, ldap_err2string(x));
-                    } else
-                        debug("main", "BindLDAP(-, %s, %s, %ul) done. Result: %d\n", conf.dn, conf.passwd, LDAP_AUTH_TLS, x);
-                } else if (conf.dn[0] != '\0') {
-                    /* Simple binding - using dn / passwd for authorization */
-                    x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_SIMPLE);
-                    if (x != LDAP_SUCCESS) {
-                        /* Unable to bind */
-                        debug("main", "Failed to bind.  Error: %d (%s)\n", x, ldap_err2string(x));
-                    } else
-                        debug("main", "BindLDAP(-, %s, %s, %ul) done. Result: %d\n", conf.dn, conf.passwd, LDAP_AUTH_SIMPLE, x);
-                } else {
-                    /* Anonymous binding */
-                    x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_NONE);
-                    if (x != LDAP_SUCCESS) {
-                        /* Unable to bind */
-                        debug("main", "Failed to bind.  Error: %d (%s)\n", x, ldap_err2string(x));
-                    } else
-                        debug("main", "BindLDAP(-, -, -, %ul) done. Result: %d\n", LDAP_AUTH_NONE, x);
-                }
+                debug("main", "OpenLDAP(-, %s, %d) -> %s\n", conf.host, conf.port, ErrLDAP(x));
+                x = SetVerLDAP(&ldap, conf.ver);
+                if (x != LDAP_ERR_SUCCESS) {
+                    /* Failed to set version */
+                    debug("main", "SetVerLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
+                } else
+                    debug("main", "SetVerLDAP(-, %d) -> %s\n", conf.ver, ErrLDAP(x));
             }
         }
-        /* Everything failed --> ERR */
-        if (x != LDAP_SUCCESS) {
-            printfx("ERR\n");
-            memset(bufa, '\0', strlen(bufa));
+        ldap.err = -1;
+        if (!(ldap.status & LDAP_BIND_S) && (conf.mode & MODE_TLS)) {
+            /* TLS binding */
+            x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_TLS);
+            if (x != LDAP_ERR_SUCCESS) {
+                /* Unable to bind */
+                debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
+            } else
+                debug("main", "BindLDAP(-, %s, %s, %ul) -> %s\n", conf.dn, conf.passwd, LDAP_AUTH_TLS, ErrLDAP(x));
+        } else if (!(ldap.status & LDAP_BIND_S)) {
+            if (conf.dn[0] != '\0') {
+                /* Simple binding - using dn / passwd for authorization */
+                x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_SIMPLE);
+                if (x != LDAP_ERR_SUCCESS) {
+                    /* Unable to bind */
+                    debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
+                } else
+                    debug("main", "BindLDAP(-, %s, %s, %ul) -> %s\n", conf.dn, conf.passwd, LDAP_AUTH_SIMPLE, ErrLDAP(x));
+            } else {
+                /* Anonymous binding */
+                x = BindLDAP(&ldap, conf.dn, conf.passwd, LDAP_AUTH_NONE);
+                if (x != LDAP_ERR_SUCCESS) {
+                    /* Unable to bind */
+                    debug("main", "BindLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
+                } else
+                    debug("main", "BindLDAP(-, -, -, %ul) -> %s\n", LDAP_AUTH_NONE, ErrLDAP(x));
+            }
+        }
+        ldap.err = -1;
+        if (ldap.status & LDAP_PERSIST_S) {
+            x = ResetLDAP(&ldap);
+            if (x != LDAP_ERR_SUCCESS) {
+                /* Unable to reset */
+                debug("main", "ResetLDAP() -> %s\n", ErrLDAP(x));
+            } else
+                debug("main", "ResetLDAP() -> %s\n", ErrLDAP(x));
+        }
+        if (x != LDAP_ERR_SUCCESS) {
+            /* Everything failed --> ERR */
+            debug("main", "while() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
             CloseLDAP(&ldap);
+            printfx("ERR\n");
             continue;
-        } else {
-            /* We got a group string -- split it */
-            if (p != NULL) {
-                /* Split string */
-                debug("main", "SplitString(%s, %zd, ' ', %s, %zd)\n", bufa, strlen(bufa), bufb, sizeof(bufb));
-                i = SplitString(bufa, strlen(bufa), ' ', bufb, sizeof(bufb));
-                if (i > 0) {
-                    debug("main", "SplitString(%s, %s) done.  Result: %zd\n", bufa, bufb, i);
-                    /* Got a group to match against */
-                    x = ConvertIP(&ldap, bufb);
+        }
+        ldap.err = -1;
+        /* If we got a group string, split it */
+        if (p != NULL) {
+            /* Split string */
+            debug("main", "SplitString(%s, %zd, ' ', %s, %zd)\n", bufa, strlen(bufa), bufb, sizeof(bufb));
+            i = SplitString(bufa, strlen(bufa), ' ', bufb, sizeof(bufb));
+            if (i > 0) {
+                debug("main", "SplitString(%s, %s) done.  Result: %zd\n", bufa, bufb, i);
+                /* Got a group to match against */
+                x = ConvertIP(&ldap, bufb);
+                if (x < 0) {
+                    debug("main", "ConvertIP() -> %s\n", ErrLDAP(x));
+                    printfx("ERR\n");
+                } else {
+                    ldap.err = -1;
+                    debug("main", "ConvertIP(-, %s) -> Result[%zd]: %s\n", bufb, x, ldap.search_ip);
+                    x = SearchFilterLDAP(&ldap, bufa);
                     if (x < 0) {
-                        debug("main", "Failed to ConvertIP().  Error: %d\n", x);
-                        printfx("ERR (ConvertIP %d)\n", x);
+                        debug("main", "SearchFilterLDAP() -> %s\n", ErrLDAP(x));
+                        printfx("ERR\n");
                     } else {
-                        debug("main", "ConvertIP(-, %s) done.  Result[%zd]: %s\n", bufb, x, ldap.search_ip);
-                        x = SearchFilterLDAP(&ldap, bufa);
-                        if (x < 0) {
-                            debug("main", "Failed to SearchFilterLDAP().  Error: %d\n", x);
+                        /* Do Search */
+                        ldap.err = -1;
+                        debug("main", "SearchFilterLDAP(-, %s) -> Length: %u\n", bufa, x);
+                        x = SearchLDAP(&ldap, ldap.scope, ldap.search_filter, search_attrib);
+                        if (x != LDAP_ERR_SUCCESS) {
+                            debug("main", "SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
                             printfx("ERR\n");
                         } else {
-                            /* Do Search */
-                            debug("main", "IP: %s, Search Filter: %s\n", ldap.search_ip, ldap.search_filter);
-                            x = SearchLDAP(&ldap, ldap.scope, ldap.search_filter, search_attrib);
-                            if (x != LDAP_SUCCESS) {
-                                debug("main", "Failed to SearchLDAP().  Error: %d (%s)\n", x, ldap_err2string(x));
+                            ldap.err = -1;
+                            debug("main", "SearchLDAP(-, %d, %s, -) -> %s\n", conf.scope, ldap.search_filter, ErrLDAP(x));
+                            x = SearchIPLDAP(&ldap, bufc);
+                            if (x != LDAP_ERR_SUCCESS) {
+                                debug("main", "SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
                                 printfx("ERR\n");
                             } else {
-                                debug("main", "SearchLDAP(-, %d, %s, -) done. Result: %d\n", conf.scope, ldap.search_filter, x);
-                                x = SearchIPLDAP(&ldap, bufc);
-                                if (x != LDAP_SUCCESS) {
-                                    debug("main", "Failed to SearchIPLDAP().  Error: %d\n", x);
-                                    printfx("ERR\n");
-                                } else {
-                                    debug("main", "SearchIPLDAP(-, %s) done. Result: %d\n", bufc, x);
-                                    printfx("OK user=%s\n", bufc);                     /* Got userid --> OK user=<userid> */
-                                }
+                                debug("main", "SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x));
+                                printfx("OK user=%s\n", bufc);                 /* Got userid --> OK user=<userid> */
                             }
-
-                            /* Clear for next query */
-                            memset(bufc, '\0', strlen(bufc));
                         }
+                        /* Clear for next query */
+                        memset(bufc, '\0', strlen(bufc));
                     }
-                } else {
-                    debug("main", "Failed to SplitString().  Error: %d\n", i);
-                    printfx("ERR\n");
                 }
             } else {
-                /* No group to match against, only an IP */
-                x = ConvertIP(&ldap, bufa);
+                debug("main", "SplitString() -> Error: %d\n", i);
+                printfx("ERR\n");
+            }
+        } else {
+            /* No group to match against, only an IP */
+            x = ConvertIP(&ldap, bufa);
+            if (x < 0) {
+                debug("main", "ConvertIP() -> %s\n", ErrLDAP(x));
+                printfx("ERR\n");
+            } else {
+                debug("main", "ConvertIP(-, %s) -> Result[%zd]: %s\n", bufa, x, ldap.search_ip);
+                /* Do search */
+                x = SearchFilterLDAP(&ldap, NULL);
                 if (x < 0) {
-                    debug("main", "Failed to ConvertIP().  Error: %d\n", x);
-                    printfx("ERR (ConvertIP %d)\n", x);
+                    debug("main", "SearchFilterLDAP() -> %s\n", ErrLDAP(x));
+                    printfx("ERR\n");
                 } else {
-                    debug("main", "ConvertIP(-, %s) done.  Result[%zd]: %s\n", bufa, x, ldap.search_ip);
-                    /* Do search */
-                    x = SearchFilterLDAP(&ldap, NULL);
-                    if (x < 0) {
-                        debug("main", "Failed to SearchFilterLDAP().  Error: %d\n", x);
+                    ldap.err = -1;
+                    debug("main", "SearchFilterLDAP(-, NULL) -> Length: %u\n", x);
+                    x = SearchLDAP(&ldap, ldap.scope, ldap.search_filter, search_attrib);
+                    if (x != LDAP_ERR_SUCCESS) {
+                        debug("main", "SearchLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(x));
                         printfx("ERR\n");
                     } else {
-                        debug("main", "IP: %s, Search Filter: %s\n", ldap.search_ip, ldap.search_filter);
-                        x = SearchLDAP(&ldap, ldap.scope, ldap.search_filter, search_attrib);
-                        if (x != LDAP_SUCCESS) {
-                            debug("main", "Failed to SearchLDAP().  Error: %d (%s)\n", x, ldap_err2string(x));
+                        ldap.err = -1;
+                        debug("main", "SearchLDAP(-, %d, %s, -) -> %s\n", conf.scope, ldap.search_filter, ErrLDAP(x));
+                        x = SearchIPLDAP(&ldap, bufc);
+                        if (x != LDAP_ERR_SUCCESS) {
+                            debug("main", "SearchIPLDAP() -> %s (LDAP: %s)\n", ErrLDAP(x), ldap_err2string(ldap.err));
                             printfx("ERR\n");
                         } else {
-                            debug("main", "SearchLDAP(-, %d, %s, -) done. Result: %d\n", conf.scope, ldap.search_filter, x);
-                            x = SearchIPLDAP(&ldap, bufc);
-                            if (x != LDAP_SUCCESS) {
-                                debug("main", "Failed to SearchIPLDAP().  Error: %d\n", x);
-                                printfx("ERR\n");
-                            } else {
-                                debug("main", "SearchIPLDAP(-, %s) done. Result: %d\n", bufc, x);
-                                printfx("OK user=%s\n", bufc);                         /* Got a userid --> OK user=<userid> */
-                            }
+                            debug("main", "SearchIPLDAP(-, %s) -> %s\n", bufc, ErrLDAP(x));
+                            printfx("OK user=%s\n", bufc);                             /* Got a userid --> OK user=<userid> */
                         }
                     }
-                    /* Clear for next query */
-                    memset(bufc, '\0', strlen(bufc));
                 }
+                /* Clear for next query */
+                memset(bufc, '\0', strlen(bufc));
             }
         }
 
-        /* Clear buffer and close for next data */
+        /* Clear buffer and close for next data, if not persistent */
+        ldap.err = -1;
         memset(bufa, '\0', strlen(bufa));
-        CloseLDAP(&ldap);
+        if (!(ldap.status & LDAP_PERSIST_S)) {
+            x = CloseLDAP(&ldap);
+            debug("main", "CloseLDAP(-) -> %s\n", ErrLDAP(x));
+        }
     }
 
     debug("main", "Terminating.\n");
index b8e74d4f00027b039390da2a4d734426a66ff46d..9e11d71ec868143a0bcc467f6ff93cf0ec32b518 100644 (file)
 #define MODE_TLS       0x04
 #define MODE_IPV4      0x08
 #define MODE_IPV6      0x10
-#define MODE_KILL      0x20
-#define MODE_GROUP     0x40                            /* Group is REQUIRED */
+#define MODE_GROUP     0x20                            /* Group is REQUIRED */
+#define MODE_PERSIST   0x40                            /* Persistent LDAP connections */
+#define MODE_KILL      0x80
 
 /* conf_t - Program configuration struct typedef */
 typedef struct {
     char program[MAXLEN];
     char basedn[MAXLEN];
     char host[MAXLEN];
+    char attrib[MAXLEN];
     char dn[MAXLEN];
     char passwd[MAXLEN];
     char search_filter[MAXLEN];                                /* Base search_filter that gets copied to ldap_t */
     int ver;
     int scope;
     int port;
+    time_t persist_timeout;
     unsigned int mode;
 } conf_t;
 
 /* extern the struct */
 extern conf_t conf;                                    /* Main configuration struct */
+extern time_t now;                                     /* Now's time, according to time() */
+extern time_t elap;                                    /* Time elapsed since 'now' */
 #endif