]> git.ipfire.org Git - thirdparty/sarg.git/commitdiff
Apply patch 36 submitted by Dayel Zabin
authorFrederic Marchal <fmarchal@users.sourceforge.net>
Sun, 26 May 2013 18:36:57 +0000 (20:36 +0200)
committerFrederic Marchal <fmarchal@users.sourceforge.net>
Sun, 26 May 2013 18:36:57 +0000 (20:36 +0200)
The patch converts the string returned by a LDAP search into a user
selected character set.

The patch has been slightly modified to avoid memory leaks and report
errors the sarg's way.

getconf.c
include/conf.h
log.c
sarg.conf
usertab.c

index f034e7c5647f878694f4bdccacf47ef680e2e724..6722a2b25d6e4d30d16ba1116323f1816635fb51 100644 (file)
--- a/getconf.c
+++ b/getconf.c
@@ -773,6 +773,8 @@ static void parmtest(char *buf)
 
        if (getparam_string("LDAPTargetAttr",buf,LDAPTargetAttr,sizeof(LDAPTargetAttr))>0) return;
 
+       if (getparam_string("LDAPNativeCharset",buf,LDAPNativeCharset,sizeof(LDAPNativeCharset))>0) return;
+
        if (getparam_string("graph_font",buf,GraphFont,sizeof(GraphFont))>0) return;
 
        if (getparam_string("sorttable",buf,SortTableJs,sizeof(SortTableJs))>0) return;
index 3de0631ca5bc1b6e9ddfe9409a236a929ee78604..61736ccf53d502072728e1f212438d2fdade4711 100755 (executable)
@@ -436,6 +436,8 @@ int LDAPProtocolVersion;
 char LDAPBaseSearch[255];
 char LDAPFilterSearch[512];
 char LDAPTargetAttr[64];
+//! Character set to convert the LDAP returned string to.
+char LDAPNativeCharset[20];
 char GraphFont[MAXLEN];
 //! The full path to sorttable.js if the table in the reports must be dynamicaly sorted.
 char SortTableJs[256];
diff --git a/log.c b/log.c
index 92e10a12fc2a439aab08b675918fb77aae4dda41..46e8cae710785a1c9b5ed632c1b2fc3efaa603b3 100644 (file)
--- a/log.c
+++ b/log.c
@@ -216,6 +216,7 @@ int main(int argc,char *argv[])
        LDAPBaseSearch[0]='\0';
        strcpy(LDAPFilterSearch, "(uid=%s)");
        strcpy(LDAPTargetAttr, "cn");
+       LDAPNativeCharset[0]='\0';
        SortTableJs[0]='\0';
 
        tmp[0]='\0';
index 881fda8fe7fc5ceec26c135cc01b783661205c11..5a078d4f48a45a5246a2c7f72629b65c6eca538a 100644 (file)
--- a/sarg.conf
+++ b/sarg.conf
 #      default value is 'cn'
 #LDAPTargetAttr cn
 
+# TAG: LDAPNativeCharset charset-iconv-style
+#      Character set to convert the LDAP string to.
+#      For the list of some available charsets use: "iconv -l".
+#      This option requires libiconv and sarg must have been built with --with-iconv.
+#      default is empty line (UTF-8)
+#LDAPNativeCharset ISO-8859-1
+
 # TAG: long_url yes|no
 #      If yes, the full url is showed in report.
 #      If no, only the site will be showed
index 583030d8fbbfeb7404e7931cfaaf842b30d7767c..780c2006df7df4f4b4d6aecf889f5b712ca22d5c 100644 (file)
--- a/usertab.c
+++ b/usertab.c
 #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;
@@ -174,11 +189,72 @@ 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 );
+       str_out_len = ( 2 * str_in_len );
+       if (ldapconvbuffer==NULL || ldapconvbuffersize<str_out_len) {
+               ldapconvbuffersize=str_out_len;
+               str_out = realloc(ldapconvbuffer,str_out_len);
+               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_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 */
@@ -187,6 +263,7 @@ 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;
@@ -246,8 +323,9 @@ static void get_ldap_name(const char *userlogin,char *mappedname,int namelen)
        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]);
-                               safe_strcpy(mappedname, vals[0],namelen);
+                               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);
@@ -305,6 +383,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;