From: Pedro Orso Date: Fri, 11 Dec 2009 13:30:34 +0000 (+0000) Subject: LDAP usertab feature added X-Git-Tag: v2.3-pre2~115 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7179962ad1756f864971dedf50208eea56ef4273;p=thirdparty%2Fsarg.git LDAP usertab feature added --- diff --git a/btree_cache.c b/btree_cache.c new file mode 100644 index 0000000..f04bb55 --- /dev/null +++ b/btree_cache.c @@ -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 index 0000000..675bd27 --- /dev/null +++ b/samples/ldap/README @@ -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 index 0000000..29bd0d5 --- /dev/null +++ b/samples/ldap/base.ldif @@ -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 index 0000000..f15d0ea --- /dev/null +++ b/samples/ldap/create_usertab @@ -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 index 0000000..02b78a7 --- /dev/null +++ b/samples/ldap/group.ldif @@ -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 index 0000000..2ca9dc5 --- /dev/null +++ b/samples/ldap/users.ldif @@ -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 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 +#include +#include + +#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); + } +} +