]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
LDAP usertab feature added
authorPedro Orso <orso@users.sourceforge.net>
Fri, 11 Dec 2009 13:30:34 +0000 (13:30 +0000)
committerPedro Orso <orso@users.sourceforge.net>
Fri, 11 Dec 2009 13:30:34 +0000 (13:30 +0000)
btree_cache.c [new file with mode: 0644]
samples/ldap/README [new file with mode: 0644]
samples/ldap/base.ldif [new file with mode: 0644]
samples/ldap/create_usertab [new file with mode: 0644]
samples/ldap/group.ldif [new file with mode: 0644]
samples/ldap/users.ldif [new file with mode: 0644]
usertab.c [new file with mode: 0644]

diff --git a/btree_cache.c b/btree_cache.c
new file mode 100644 (file)
index 0000000..f04bb55
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ * AUTHOR: Pedro Lineu Orso                         pedro.orso@gmail.com
+ *                                                            1998, 2009
+ * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
+ *
+ * SARG donations:
+ *      please look at http://sarg.sourceforge.net/donations.php
+ * ---------------------------------------------------------------------
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "include/conf.h"
+#include "include/defs.h"
+
+#define AVL_SINGLE_RIGHT_ROTATION 1
+#define AVL_SINGLE_LEFT_ROTATION  2
+#define AVL_DOUBLE_RIGHT_ROTATION 3
+#define AVL_DOUBLE_LEFT_ROTATION  4
+
+struct bt {
+           char value[64], targetattr[256];
+           struct bt *left, *right;
+           int balanceinfo;
+           // -1 - ÐÅÒÅ×ÅÛÉ×ÁÅÔ ×ÌÅ×Ï
+           // +1 - ÐÅÒÅ×ÅÛÉ×ÁÅÔ ×ÐÒÁ×Ï
+};
+
+struct bt *root_bt = NULL;
+int sizeof_bt;
+
+FILE *dbgfp = NULL;
+
+void set_balance_info(struct bt *node);
+struct bt *get_disbalanced_node(struct bt *node);
+void balance_node(struct bt *node);
+
+
+struct bt *insert_node(struct bt *root, char *item, char *value)
+{
+       struct bt *new_item_bt = NULL;
+       if (!root)
+       {
+               new_item_bt = malloc(sizeof_bt);
+               new_item_bt->left = NULL;
+               new_item_bt->right = NULL;
+               strncpy(new_item_bt->value, item, 64);
+               strncpy(new_item_bt->targetattr, value, 256);
+               new_item_bt->balanceinfo = 0;
+               return new_item_bt;
+       }
+       else
+       {
+               int result = strncmp(root->value, item, 64);
+               if ( result > 0 )
+               {
+                       new_item_bt = insert_node(root->left, item, value);
+                       if (!root->left)
+                               root->left = new_item_bt;
+               }
+               else
+                       if (result < 0)
+                       {
+                               new_item_bt = insert_node(root->right, item, value);
+                               if (!root->right)
+                                       root->right = new_item_bt;
+                       }
+                       else
+                               return NULL;
+
+       }
+       return new_item_bt;
+}
+
+
+
+
+void balance_tree(struct bt *node)
+{
+       struct bt *disbalanced_node = NULL;
+       do
+       {
+               set_balance_info(root_bt);
+               disbalanced_node = get_disbalanced_node(root_bt);
+               if (disbalanced_node)
+                       balance_node(disbalanced_node);
+       }
+       while (disbalanced_node);
+       set_balance_info(root_bt);
+}
+
+
+
+void delete_tree(struct bt *root)
+{
+       if (root)
+       {
+               delete_tree(root->left);
+               delete_tree(root->right);
+               free(root);
+               root = NULL;
+       }
+}
+
+struct bt *search_item(struct bt *root, char *item)
+{
+       int result;
+       while (root && (result = strncmp(root->value, item, 64)))
+       {
+               if (result > 0)
+                       root = root->left;
+               else
+                       root = root->right;
+       }
+       return root;
+}
+
+int get_length(struct bt *node, int d)
+{
+       int l_depth = d, r_depth = d;
+       if (node->left)
+               l_depth = get_length(node->left, d+1);
+       if (node->right)
+               r_depth = get_length(node->right, d+1);
+       // ÷ÏÚ×ÒÁÝÁÅÍ ÂÏÌØÛÅÅ ÉÚ ÚÎÁÞÅÎÉÊ
+       return( ( l_depth > r_depth ) ? l_depth : r_depth );
+}
+
+struct bt *get_parent(struct bt *node)
+{
+       if (node == root_bt)
+               return NULL;
+       else
+       {
+               int result;
+               struct bt *prev = root_bt, *tmp = root_bt;
+               while (tmp && (result = strncmp(node->value, tmp->value,64)))
+               {
+                       if (result < 0)
+                       {
+                               prev = tmp;
+                               tmp = tmp->left;
+                       }
+                       else
+                       {
+                               prev = tmp;
+                               tmp = tmp->right;
+                       }
+               }
+               if (tmp)
+                       return prev;
+               else
+                       return NULL;
+       }
+}
+
+void set_balance_info(struct bt *node)
+{
+       int l_depth = 0, r_depth = 0;
+       if (node->left)
+       {
+               l_depth = get_length(node->left, 1);
+               set_balance_info(node->left);
+       }
+       if (node->right)
+       {
+               r_depth = get_length(node->right, 1);
+               set_balance_info(node->right);
+       }
+       node->balanceinfo = r_depth - l_depth;
+}
+
+void rotate_right(struct bt *node)
+{
+       struct bt *left, *right, *tmp, *parent = get_parent(node);
+       left = node->left;
+       right = node->left->right;
+       tmp = node;
+       node = left;
+       tmp->left = right;
+       node->right = tmp;
+       
+       if (root_bt == tmp)
+               root_bt = node;
+       else
+       {
+               if (parent->left == tmp)
+                       parent->left = node;
+               else
+                       if (parent->right == tmp)
+                               parent->right = node;
+       }
+}
+
+void rotate_left(struct bt *node)
+{
+       struct bt *left, *right, *tmp, *parent = get_parent(node);
+       left = node->right->left;
+       right = node->right;
+       tmp = node;
+       node = right;
+       tmp->right = left;
+       node->left = tmp;
+
+       if (root_bt == tmp)
+               root_bt = node;
+       else
+       {
+               if (parent->left == tmp)
+                       parent->left = node;
+               else
+                       if (parent->right == tmp)
+                               parent->right = node;
+       }
+
+}
+
+int get_disbalance_type(struct bt *node)
+{
+       if (node->balanceinfo < 0)
+               if (node->left->balanceinfo > 0)
+                       return AVL_DOUBLE_RIGHT_ROTATION;
+               else
+                       return AVL_SINGLE_RIGHT_ROTATION;
+       else
+               if (node->right->balanceinfo < 0)
+                       return AVL_DOUBLE_LEFT_ROTATION;
+               else
+                       return AVL_SINGLE_LEFT_ROTATION;
+}
+
+void balance_node(struct bt *node)
+{
+       switch (get_disbalance_type(node))
+       {
+               case AVL_SINGLE_RIGHT_ROTATION:
+                       rotate_right(node);
+                       break;
+               case AVL_SINGLE_LEFT_ROTATION:
+                       rotate_left(node);
+                       break;
+               case AVL_DOUBLE_RIGHT_ROTATION:
+                       rotate_right(node);
+                       rotate_right(node);
+                       break;
+               case AVL_DOUBLE_LEFT_ROTATION:
+                       rotate_left(node);
+                       rotate_left(node);
+                       break;
+               default:
+                       exit(1);
+                       break;
+                       
+       }
+}
+
+struct bt *get_disbalanced_node(struct bt *node)
+{
+       struct bt *rdn;
+       if (fabs(node->balanceinfo) > 1)
+               return node;
+       else
+               if (node->left)
+               {
+                       rdn = get_disbalanced_node(node->left);
+                       if (rdn)
+                               return rdn;
+               }
+               if (node->right)
+               {
+                       rdn = get_disbalanced_node(node->right);
+                       if (rdn)
+                               return rdn;
+               }
+               return NULL;
+}
+
+void init_cache()
+{
+       root_bt = NULL;
+       sizeof_bt = sizeof(struct bt);
+}
+
+
+int insert_to_cache(char *key, char *value)
+{
+
+       struct bt *root = NULL;
+
+       char  strict_chars[] = " ~!@^&(){}|<>?:;\"\'\\[]`,\r\n\0", *strict_chars_ptr;
+       
+       strict_chars_ptr = strict_chars;
+       while (*strict_chars_ptr)
+       {
+               char *strict_chr_ptr = strchr(key, *strict_chars_ptr);
+               if (strict_chr_ptr)
+                       *strict_chr_ptr = '\0';
+               strict_chars_ptr++;
+       }
+       if ((root = (insert_node(root_bt, key, value))))
+       {
+               if (!root_bt)
+                       root_bt = root;
+               balance_tree(root_bt);
+               return 0;
+       }
+       else
+               return 1;
+
+}
+
+char *search_in_cache(char *key)
+{
+       struct bt *node;
+       if ((node = search_item(root_bt, key)))
+       {
+               return node->targetattr;
+       }
+       else
+               return NULL;
+}
+
+void destroy_cache()
+{
+       delete_tree(root_bt);
+       root_bt = NULL;
+}
diff --git a/samples/ldap/README b/samples/ldap/README
new file mode 100644 (file)
index 0000000..675bd27
--- /dev/null
@@ -0,0 +1 @@
+# Create a sample sarg usertab in LDAP server
diff --git a/samples/ldap/base.ldif b/samples/ldap/base.ldif
new file mode 100644 (file)
index 0000000..29bd0d5
--- /dev/null
@@ -0,0 +1,9 @@
+dn: dc=example,dc=com
+objectclass: dcObject
+objectclass: organization
+o: Example Company
+dc: example
+
+dn: cn=Manager,dc=example,dc=com
+objectclass: organizationalRole
+cn: Manager
diff --git a/samples/ldap/create_usertab b/samples/ldap/create_usertab
new file mode 100644 (file)
index 0000000..f15d0ea
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+#
+# Create a sarg usertab in ldap server
+# 2009, Pedro Orso
+#
+
+# Create the base
+ldapadd -W -x -D "cn=Manager,dc=example,dc=com" -W -f base.ldif
+# Create the group users
+ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f group.ldif
+# add some test users
+ldapadd -x -D "cn=Manager,dc=example,dc=com" -W -f users.ldif
diff --git a/samples/ldap/group.ldif b/samples/ldap/group.ldif
new file mode 100644 (file)
index 0000000..02b78a7
--- /dev/null
@@ -0,0 +1,6 @@
+dn: ou=users,dc=example,dc=com
+ou: users
+objectClass: top
+objectClass: organizationalUnit
+objectClass: dcObject
+dc: users
diff --git a/samples/ldap/users.ldif b/samples/ldap/users.ldif
new file mode 100644 (file)
index 0000000..2ca9dc5
--- /dev/null
@@ -0,0 +1,51 @@
+dn: cn=billy,ou=users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: posixAccount
+objectClass: inetOrgPerson
+cn: billy
+sn: Billy
+mail: billy@foo.com
+telephonenumber: 1234-5678
+uid: billy
+userPassword: 123456
+homeDirectory: /home/billy
+displayName: billy
+loginShell: /dev/null
+uidNumber:101
+gidNumber:201
+
+dn: cn=jane,ou=users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: posixAccount
+objectClass: inetOrgPerson
+cn: jane
+sn: Jane
+mail: jane@foo.com
+telephonenumber: 1234-0123
+uid: jane
+userPassword: 123456
+homeDirectory: /home/jane
+displayName: jane
+loginShell: /dev/null
+uidNumber:102
+gidNumber:202
+
+dn: cn=kevin,ou=users,dc=example,dc=com
+objectClass: top
+objectClass: person
+objectClass: posixAccount
+objectClass: inetOrgPerson
+cn: kevin
+sn: kevin
+mail: kevin@foo.com
+telephonenumber: 1234-0123
+uid: 167.10.11.63
+userPassword: 123456
+homeDirectory: /home/jane
+displayName: kevin
+loginShell: /dev/null
+uidNumber:103
+gidNumber:203
+
diff --git a/usertab.c b/usertab.c
new file mode 100644 (file)
index 0000000..30afc25
--- /dev/null
+++ b/usertab.c
@@ -0,0 +1,143 @@
+/*
+ * AUTHOR: Pedro Lineu Orso                         pedro.orso@gmail.com
+ *                                                            1998, 2009
+ * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
+ *
+ * SARG donations:
+ *      please look at http://sarg.sourceforge.net/donations.php
+ * ---------------------------------------------------------------------
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
+ *
+ */
+
+#include "include/conf.h"
+#include "include/defs.h"
+
+#include <ldap.h>
+#include <ldap_cdefs.h>
+#include <ldap_features.h>
+
+#define LDAP_DEPRECATED 1
+
+LDAP *ldap_handle;
+
+void init_ldap_usertab() {
+       /* Setting LDAP connection and initializing cache */
+       ldap_handle = NULL;
+       int ldap_port = atoi(LDAPPort);
+        if ((ldap_handle = (LDAP *)ldap_init(LDAPHost, ldap_port)) == NULL) {
+               sprintf(msg,"\nUnable to connect to LDAP server:%s port:%d\n", LDAPHost, ldap_port);
+               debuga(msg);
+               exit(1);
+        }
+
+        int ldap_protocol_version = atoi(LDAPProtocolVersion);
+        if (ldap_set_option(ldap_handle, LDAP_OPT_PROTOCOL_VERSION, &ldap_protocol_version) != LDAP_SUCCESS) {
+               sprintf(msg, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", ldap_protocol_version);
+               debuga(msg);
+               exit(1);
+        }
+
+       /* Bind to the LDAP server. */
+       int rc;
+       rc = ldap_simple_bind_s( ldap_handle, LDAPBindDN, LDAPBindPW ); 
+       if ( rc != LDAP_SUCCESS ) { 
+               sprintf(msg, "ldap_simple_bind_s: %s\n", ldap_err2string(rc)); 
+               debuga(msg);
+               exit(1); 
+       }
+       
+       /* Initializing cache */
+
+       init_cache();
+}
+
+void user_find(char *mappedname, char *userlogin) {
+   if(UserTabFile[0] != '\0') {
+      if (strcasecmp(UserTabFile, "ldap")) {
+         sprintf(warea,":%s:",userlogin);
+         if((str=(char *) strstr(userfile,warea)) != (char *) NULL ) {
+            z1=0;
+           str2=(char *) strstr(str+1,":");
+           str2++;
+           bzero(name, MAXLEN);
+           while(str2[z1] != ':') {
+              name[z1]=str2[z1];
+              z1++;
+           }
+        } else strcpy(mappedname,userlogin);
+      } else {
+
+      /* Start searching username in cache */
+       
+      char filtersearch[256], strictchars[] = " ~!@^&(){}|<>?:;\"\'\\[]`,\r\n\0", *strictptr = strictchars, *searched_in_cache;
+      char *attr, **vals;
+      LDAPMessage *result, *e;
+      BerElement *ber;
+
+      while (*strictptr) {
+         char *foundchr;
+         if ((foundchr = strchr(userlogin, *strictptr)))
+            *foundchr = '\0';
+         strictptr++;
+      }
+               
+      if (!(searched_in_cache = search_in_cache(userlogin))) {
+         snprintf(filtersearch, sizeof(filtersearch), LDAPFilterSearch, userlogin, userlogin, userlogin, userlogin, userlogin);
+                               
+         /* Search record(s) in LDAP base */
+                       
+         int rc= ldap_search_s(ldap_handle, LDAPBaseSearch, LDAP_SCOPE_SUBTREE, filtersearch, NULL, 0, &result);
+         if ( rc != LDAP_SUCCESS ) { 
+            sprintf(msg, "ldap_search_s: %s\n", ldap_err2string(rc));
+            debuga(msg);
+            strcpy(mappedname,userlogin);
+            return;
+         }
+                               
+         if (!(e = ldap_first_entry(ldap_handle, result)))
+            insert_to_cache(userlogin, userlogin);
+         else
+            for (attr = ldap_first_attribute(ldap_handle, e, &ber); attr != NULL; attr = ldap_next_attribute(ldap_handle, e, ber)) {
+               if (!strcasecmp(attr, LDAPTargetAttr)) {
+                  if ((vals = (char **)ldap_get_values(ldap_handle, e, attr))!=NULL) {
+                     insert_to_cache(userlogin, vals[0]);
+                     strcpy(mappedname, vals[0]);
+                     ldap_memfree(vals);
+                  }
+                  ldap_memfree(attr);
+                  break;
+               }
+               ldap_memfree(attr);
+            }
+            ldap_msgfree(result);
+         } else
+              strcpy(mappedname, searched_in_cache);
+      }
+   } else
+       strcpy(mappedname,userlogin);
+}
+
+void close_usertab() {
+   if (!strcasecmp(UserTabFile, "ldap")) {
+      destroy_cache();
+      ldap_unbind(ldap_handle);
+   } else {
+       if(userfile)
+           free(userfile);
+   }
+}
+