]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - usertab.c
Merge messages about IP addresses.
[thirdparty/sarg.git] / usertab.c
index f5a3eeab0c981192b6a9d08a39f138b43f23a715..03934e3671bd1ee9e1b3d006de61586a89d65f41 100644 (file)
--- a/usertab.c
+++ b/usertab.c
@@ -1,6 +1,6 @@
 /*
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
- *                                                            1998, 2011
+ *                                                            1998, 2015
  *
  * SARG donations:
  *      please look at http://sarg.sourceforge.net/donations.php
 #include <ldap.h>
 #include <ldap_cdefs.h>
 #include <ldap_features.h>
+
+#if defined(HAVE_ICONV_H)
+#include <iconv.h>
+#define USE_ICONV 1
+#endif //HAVE_ICONV_H
+
 #endif //HAVE_LDAP_H
 
 enum UserTabEnum
@@ -53,6 +59,15 @@ static char *userfile=NULL;
 static LDAP *ldap_handle=NULL;
 #endif //HAVE_LDAP_H
 
+#ifdef USE_ICONV
+//! iconv conversion descriptor to convert the string returned by LDAP.
+static iconv_t ldapiconv=(iconv_t)-1;
+//! Buffer to store the converted string.
+static char *ldapconvbuffer=NULL;
+//! Size of the converted string buffer.
+static int ldapconvbuffersize=0;
+#endif
+
 static void init_file_usertab(const char *UserTabFile)
 {
        FILE *fp_usr;
@@ -61,25 +76,25 @@ static void init_file_usertab(const char *UserTabFile)
        int z1, z2;
 
        if((fp_usr=fopen(UserTabFile,"r"))==NULL) {
-               debuga(_("(usertab) Cannot open file %s - %s\n"),UserTabFile,strerror(errno));
+               debuga(_("Cannot open file \"%s\": %s\n"),UserTabFile,strerror(errno));
                exit(EXIT_FAILURE);
        }
        if (fseek(fp_usr, 0, SEEK_END)==-1) {
-               debuga(_("Failed to move till the end of the usertab file %s: %s\n"),UserTabFile,strerror(errno));
+               debuga(_("Failed to move till the end of file \"%s\": %s\n"),UserTabFile,strerror(errno));
                exit(EXIT_FAILURE);
        }
        nreg = ftell(fp_usr);
        if (nreg<0) {
-               debuga(_("Cannot get the size of file %s"),UserTabFile);
+               debuga(_("Cannot get the size of file %s\n"),UserTabFile);
                exit(EXIT_FAILURE);
        }
        nreg += 100;
        if (fseek(fp_usr, 0, SEEK_SET)==-1) {
-               debuga(_("Failed to rewind the usertab file %s: %s\n"),UserTabFile,strerror(errno));
+               debuga(_("Failed to rewind file \"%s\": %s\n"),UserTabFile,strerror(errno));
                exit(EXIT_FAILURE);
        }
        if((userfile=(char *) malloc(nreg))==NULL){
-               debuga(_("ERROR: Cannot load. Memory fault"));
+               debuga(_("ERROR: Cannot load. Memory fault\n"));
                exit(EXIT_FAILURE);
        }
        userfile[0]='\t';
@@ -108,7 +123,10 @@ static void init_file_usertab(const char *UserTabFile)
                userfile[z2++]='\t';
        }
        userfile[z2]='\0';
-       fclose(fp_usr);
+       if (fclose(fp_usr)==EOF) {
+               debuga(_("Read error in \"%s\": %s\n"),UserTabFile,strerror(errno));
+               exit(EXIT_FAILURE);
+       }
 }
 
 static void get_usertab_name(const char *user,char *name,int namelen)
@@ -116,18 +134,17 @@ static void get_usertab_name(const char *user,char *name,int namelen)
        char warea[MAXLEN];
        char *str;
 
-       namelen--;
        sprintf(warea,"\t%s\n",user);
        if((str=(char *) strstr(userfile,warea)) == (char *) NULL ) {
-               strncpy(name,user,namelen);
-               name[namelen]=0;
+               safe_strcpy(name,user,namelen);
        } else {
                str=strchr(str+1,'\n');
                str++;
+               namelen--;
                for(z1=0; *str != '\t' && z1<namelen ; z1++) {
                        name[z1]=*str++;
                }
-               name[z1]=0;
+               name[z1]='\0';
        }
 }
 
@@ -158,6 +175,10 @@ static void init_ldap_usertab(void) {
        }
        ldap_memfree(ldapuri);
 
+       if (ldap_set_option(ldap_handle, LDAP_OPT_REFERRALS, LDAP_OPT_OFF) != LDAP_OPT_SUCCESS) {
+               debuga(_("Could not disable LDAP_OPT_REFERRALS\n"));
+               exit(EXIT_FAILURE);
+       }
        int ldap_protocol_version = LDAPProtocolVersion;
        if (ldap_set_option(ldap_handle, LDAP_OPT_PROTOCOL_VERSION, &ldap_protocol_version) != LDAP_SUCCESS) {
                debuga(_("Could not set LDAP protocol version %d\n"), ldap_protocol_version);
@@ -171,11 +192,73 @@ static void init_ldap_usertab(void) {
                exit(EXIT_FAILURE);
        }
 
+#ifdef USE_ICONV
+       // prepare for the string conversion
+       if (LDAPNativeCharset[0]!='\0') {
+               ldapiconv = iconv_open( LDAPNativeCharset, "UTF-8" );
+               if (ldapiconv==(iconv_t)-1) {
+                       debuga(_("iconv cannot convert from UTF-8 to %s: %s\n"),LDAPNativeCharset,strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
+       }
+       ldapconvbuffer=NULL;
+       ldapconvbuffersize=0;
+#endif
+
        /* Initializing cache */
 
        init_cache();
 }
 
+const char * charset_convert( const char * str_in, const char * charset_to )
+{
+#ifdef USE_ICONV
+       size_t return_value;
+       const char * str_in_orig;
+       char * str_out;
+       size_t str_in_len;
+       size_t str_out_len;
+
+       str_in_len = strlen( str_in ) + 1;//process the terminating NUL too
+       str_out_len = ( 2 * str_in_len );
+       if (ldapconvbuffer==NULL || ldapconvbuffersize<str_out_len) {
+               ldapconvbuffersize=str_out_len;
+               str_out = realloc(ldapconvbuffer,ldapconvbuffersize);
+               if (!str_out) {
+                       debuga(_("Not enough memory to convert a LDAP returned string: %lu bytes required\n"),(unsigned long int)str_out_len);
+                       exit(EXIT_FAILURE);
+               }
+               ldapconvbuffer = str_out;
+       } else {
+               str_out = ldapconvbuffer;
+               str_out_len = ldapconvbuffersize;
+       }
+       str_in_orig = str_in;
+       return_value = iconv(ldapiconv, (ICONV_CONST char **)&str_in, &str_in_len, &str_out, &str_out_len );
+       if ( return_value == ( size_t ) -1 ) {
+               debuga(_("iconv failed in string \"%s\":\n"),str_in_orig);
+               switch ( errno ) {
+                       /* See "man 3 iconv" for an explanation. */
+                       case EILSEQ:
+                               debuga(_("Invalid multibyte sequence.\n"));
+                               break;
+                       case EINVAL:
+                               debuga(_("Incomplete multibyte sequence.\n"));
+                               break;
+                       case E2BIG:
+                               debuga(_("No more room.\n"));
+                               break;
+                       default:
+                               debuga(_("Error: %s.\n"),strerror( errno ));
+               }
+               exit(EXIT_FAILURE);
+       }
+       return(ldapconvbuffer);
+#else //USE_ICONV
+       return(str_in);
+#endif //USE_ICONV
+}
+
 static void get_ldap_name(const char *userlogin,char *mappedname,int namelen)
 {
        /* Start searching username in cache */
@@ -184,18 +267,18 @@ static void get_ldap_name(const char *userlogin,char *mappedname,int namelen)
        char filtersearch[256], *searched_in_cache;
        char searchloginname[3*MAX_USER_LEN];
        char *attr, **vals;
+       const char *attr_out;
        const char *ptr;
        LDAPMessage *result, *e;
        BerElement *ber;
        int i;
        int slen;
        int rc;
-       char *attrs[1];
+       char *attrs[2];
 
        searched_in_cache = search_in_cache(userlogin);
        if (searched_in_cache!=NULL) {
-               strncpy(mappedname, searched_in_cache,namelen-1);
-               mappedname[namelen-1]='\0';
+               safe_strcpy(mappedname, searched_in_cache,namelen);
                return;
        }
 
@@ -203,7 +286,7 @@ static void get_ldap_name(const char *userlogin,char *mappedname,int namelen)
        for (slen=0 , ptr=userlogin ; slen<sizeof(searchloginname)-1 && *ptr ; ptr++) {
                if (strchr(strictchars,*ptr)) {
                        if (slen+3>=sizeof(searchloginname)-1) break;
-                       slen+=sprintf(searchloginname+i,"\\%02X",*ptr);
+                       slen+=sprintf(searchloginname+slen,"\\%02X",*ptr);
                } else {
                        searchloginname[slen++]=*ptr;
                }
@@ -226,28 +309,27 @@ static void get_ldap_name(const char *userlogin,char *mappedname,int namelen)
 
        /* Search record(s) in LDAP base */
        attrs[0]=LDAPTargetAttr;
+       attrs[1]=NULL;
        rc= ldap_search_ext_s(ldap_handle, LDAPBaseSearch, LDAP_SCOPE_SUBTREE, filtersearch, attrs, 0, NULL, NULL, NULL, -1, &result);
        if (rc != LDAP_SUCCESS) {
                debuga(_("LDAP search failed: %s\n"), ldap_err2string(rc));
                debuga(_("looking for \"%s\" at or below \"%s\"\n"),filtersearch,LDAPBaseSearch);
-               strncpy(mappedname,userlogin,namelen-1);
-               mappedname[namelen-1]='\0';
+               safe_strcpy(mappedname,userlogin,namelen);
                return;
        }
 
        if (!(e = ldap_first_entry(ldap_handle, result))) {
                insert_to_cache(userlogin, userlogin);
-               strncpy(mappedname, userlogin,namelen-1);
-               mappedname[namelen-1]='\0';
+               safe_strcpy(mappedname, userlogin,namelen);
                return;
        }
 
        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]);
-                               strncpy(mappedname, vals[0],namelen-1);
-                               mappedname[namelen-1]='\0';
+                               attr_out = charset_convert( vals[0], LDAPNativeCharset );
+                               insert_to_cache(userlogin, attr_out);
+                               safe_strcpy(mappedname, attr_out, namelen);
                                ldap_memfree(vals);
                        }
                        ldap_memfree(attr);
@@ -292,8 +374,7 @@ void user_find(char *mappedname, int namelen, const char *userlogin)
        }
 #endif //HAVE_LDAP_H
        else {
-               strncpy(mappedname,userlogin,namelen-1);
-               mappedname[namelen-1]='\0';
+               safe_strcpy(mappedname,userlogin,namelen);
        }
 }
 
@@ -306,6 +387,16 @@ void close_usertab(void)
                ldap_handle=NULL;
        }
 #endif //HAVE_LDAP_H
+#ifdef USE_ICONV
+       if (ldapiconv!=(iconv_t)-1) {
+               iconv_close (ldapiconv);
+               ldapiconv=(iconv_t)-1;
+       }
+       if (ldapconvbuffer) {
+               free(ldapconvbuffer);
+               ldapconvbuffer=NULL;
+       }
+#endif // USE_ICONV
        if(userfile) {
                free(userfile);
                userfile=NULL;