]> git.ipfire.org Git - thirdparty/sarg.git/blobdiff - userinfo.c
Add support to decompress xz files
[thirdparty/sarg.git] / userinfo.c
index 37451b07b130f7afe2f4724907a2d39e6c945d9d..c502d89033139435368ab10635d5da6131b2e70e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * SARG Squid Analysis Report Generator      http://sarg.sourceforge.net
- *                                                            1998, 2013
+ *                                                            1998, 2015
  *
  * SARG donations:
  *      please look at http://sarg.sourceforge.net/donations.php
@@ -65,6 +65,11 @@ static StringBufferObject UserStrings=NULL;
 //! User aliases.
 static AliasObject UserAliases=NULL;
 
+extern struct ReadLogDataStruct ReadFilter;
+extern char StripUserSuffix[MAX_USER_LEN];
+extern int StripSuffixLen;
+extern char *userfile;
+
 struct userinfostruct *userinfo_create(const char *userid,const char *ip)
 {
        struct usergroupstruct *group, *last;
@@ -79,7 +84,7 @@ struct userinfostruct *userinfo_create(const char *userid,const char *ip)
        if (!UserStrings) {
                UserStrings=StringBuffer_Create();
                if (!UserStrings) {
-                       debuga(_("Not enough memory to store the user's strings\n"));
+                       debuga(__FILE__,__LINE__,_("Not enough memory to store the user's strings\n"));
                        exit(EXIT_FAILURE);
                }
        }
@@ -93,7 +98,7 @@ struct userinfostruct *userinfo_create(const char *userid,const char *ip)
        if (!group) {
                group=malloc(sizeof(*group));
                if (!group) {
-                       debuga(_("Not enough memory to store user \"%s\"\n"),userid);
+                       debuga(__FILE__,__LINE__,_("Not enough memory to store user \"%s\"\n"),userid);
                        exit(EXIT_FAILURE);
                }
                memset(group,0,sizeof(*group));
@@ -106,18 +111,24 @@ struct userinfostruct *userinfo_create(const char *userid,const char *ip)
 
        user->id=StringBuffer_Store(UserStrings,userid);
        if (!user->id) {
-               debuga(_("Not enough memory to store user ID \"%s\"\n"),userid);
+               debuga(__FILE__,__LINE__,_("Not enough memory to store user ID \"%s\"\n"),userid);
                exit(EXIT_FAILURE);
        }
        user->label=user->id; //assign a label to avoid a NULL pointer in case none is provided
        if (ip) {
-               user->id_is_ip=0;
+               /*
+                * IP address is not the same as the user's ID. A separate buffer
+                * must be allocated.
+                */
+               user->id_is_ip=false;
                user->ip=StringBuffer_Store(UserStrings,ip);
        } else {
-               user->id_is_ip=1;
+               /*
+                * User's IP address share the same buffer as the user's ID.
+                */
+               user->id_is_ip=true;
                user->ip=user->id;
        }
-       user->user_limit=0;
 
        if (AnonymousOutputFiles) {
                snprintf(filename,sizeof(filename),"%d",AnonymousCounter++);
@@ -156,7 +167,7 @@ struct userinfostruct *userinfo_create(const char *userid,const char *ip)
        user->filename=StringBuffer_Store(UserStrings,filename);
        if (!user->filename)
        {
-               debuga(_("Not enough memory to store the file name for user \"%s\"\n"),user->id);
+               debuga(__FILE__,__LINE__,_("Not enough memory to store the file name for user \"%s\"\n"),user->id);
                exit(EXIT_FAILURE);
        }
 
@@ -186,7 +197,7 @@ void userinfo_label(struct userinfostruct *uinfo,const char *label)
        if (!UserStrings) return;
        uinfo->label=StringBuffer_Store(UserStrings,label);
        if (!uinfo->label) {
-               debuga(_("Not enough memory to store label \"%s\" of user \"%s\"\n"),label,uinfo->id);
+               debuga(__FILE__,__LINE__,_("Not enough memory to store label \"%s\" of user \"%s\"\n"),label,uinfo->id);
                exit(EXIT_FAILURE);
        }
 }
@@ -217,6 +228,19 @@ struct userinfostruct *userinfo_find_from_id(const char *id)
        return(NULL);
 }
 
+struct userinfostruct *userinfo_find_from_ip(const char *ip)
+{
+       struct usergroupstruct *group;
+       int i;
+
+       for (group=first_user_group ; group ; group=group->next) {
+               for (i=0 ; i<group->nusers ; i++)
+                       if (strcmp(ip,group->list[i].ip)==0)
+                               return(group->list+i);
+       }
+       return(NULL);
+}
+
 /*!
 Start the scanning of the user list.
 
@@ -292,41 +316,44 @@ Read the file containing the user names to alias in the report.
 */
 void read_useralias(const char *Filename)
 {
-       FILE *fi;
+       FileObject *fi;
        longline line;
        char *buf;
 
-       if (debug) debuga(_("Reading user alias file \"%s\"\n"),Filename);
+       if (debug) debuga(__FILE__,__LINE__,_("Reading user alias file \"%s\"\n"),Filename);
 
        UserAliases=Alias_Create();
        if (!UserAliases) {
-               debuga(_("Cannot store user's aliases\n"));
+               debuga(__FILE__,__LINE__,_("Cannot store user's aliases\n"));
                exit(EXIT_FAILURE);
        }
 
-       fi=fopen(Filename,"rt");
+       fi=FileObject_Open(Filename);
        if (!fi) {
-               debuga(_("Cannot read user name alias file \"%s\" - %s\n"),Filename,strerror(errno));
+               debuga(__FILE__,__LINE__,_("Cannot read user name alias file \"%s\": %s\n"),Filename,FileObject_GetLastOpenError());
                exit(EXIT_FAILURE);
        }
 
        if ((line=longline_create())==NULL) {
-               debuga(_("Not enough memory to read the user name aliases\n"));
+               debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),Filename);
                exit(EXIT_FAILURE);
        }
 
        while ((buf=longline_read(fi,line)) != NULL) {
                if (Alias_Store(UserAliases,buf)<0) {
-                       debuga(_("While reading \"%s\"\n"),Filename);
+                       debuga(__FILE__,__LINE__,_("While reading \"%s\"\n"),Filename);
                        exit(EXIT_FAILURE);
                }
        }
 
        longline_destroy(&line);
-       fclose(fi);
+       if (FileObject_Close(fi)) {
+               debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),Filename,FileObject_GetLastCloseError());
+               exit(EXIT_FAILURE);
+       }
 
        if (debug) {
-               debuga(_("List of user names to alias:\n"));
+               debuga(__FILE__,__LINE__,_("List of user names to alias:\n"));
                Alias_PrintList(UserAliases);
        }
 }
@@ -343,9 +370,99 @@ void free_useralias(void)
 Replace the user's name or ID by an alias if one is defined.
 
 \param user The user's name or ID as extracted from the report.
+
+\retval USERERR_NoError No error.
+\retval USERERR_NameTooLong User name too long.
 */
-const char *process_user(const char *user)
+enum UserProcessError process_user(const char **UserPtr,const char *IpAddress,bool *IsIp)
 {
-       user=Alias_Replace(UserAliases,user);
-       return(user);
+       const char *user=*UserPtr;
+       static char UserBuffer[MAX_USER_LEN];
+       const char *auser;
+
+       if (UserIp) {
+               user=IpAddress;
+               *IsIp=true;
+       } else {
+               *IsIp=false;
+
+               if (StripSuffixLen>0)
+               {
+                       int x=strlen(user);
+                       if (x>StripSuffixLen && strcasecmp(user+(x-StripSuffixLen),StripUserSuffix)==0)
+                       {
+                               if (x-StripSuffixLen>=sizeof(UserBuffer))
+                                       return(USERERR_NameTooLong);
+                               safe_strcpy(UserBuffer,user,x-StripSuffixLen+1);
+                               user=UserBuffer;
+                       }
+               }
+               if (strlen(user)>MAX_USER_LEN)
+                       return(USERERR_NameTooLong);
+
+               if (testvaliduserchar(user))
+                       return(USERERR_InvalidChar);
+
+               if ((user[0]=='\0') || (user[1]=='\0' && (user[0]=='-' || user[0]==' '))) {
+                       if(RecordsWithoutUser == RECORDWITHOUTUSER_IP) {
+                               user=IpAddress;
+                               *IsIp=true;
+                       }
+                       if (RecordsWithoutUser == RECORDWITHOUTUSER_IGNORE)
+                               return(USERERR_EmptyUser);
+                       if (RecordsWithoutUser == RECORDWITHOUTUSER_EVERYBODY)
+                               user="everybody";
+               } else {
+                       if (NtlmUserFormat == NTLMUSERFORMAT_USER) {
+                               const char *str;
+                               if ((str=strchr(user,'+'))!=NULL || (str=strchr(user,'\\'))!=NULL || (str=strchr(user,'_'))!=NULL) {
+                                       user=str+1;
+                               }
+                       }
+               }
+       }
+
+       if (us[0]!='\0' && strcmp(user,us)!=0)
+               return(USERERR_Untracked);
+
+       if (ReadFilter.SysUsers) {
+               char wuser[MAX_USER_LEN+2]=":";
+
+               strcat(wuser,user);
+               strcat(wuser,":");
+               if (strstr(userfile, wuser) == 0)
+                       return(USERERR_SysUser);
+       }
+
+       if (ReadFilter.UserFilter) {
+               if (!vuexclude(user)) {
+                       if (debugz>=LogLevel_Process) debuga(__FILE__,__LINE__,_("Excluded user: %s\n"),user);
+                       return(USERERR_Ignored);
+               }
+       }
+
+       auser=Alias_Replace(UserAliases,user);
+       if (auser!=user) {
+               if (*auser==ALIAS_PREFIX) auser++;//no need for that indicator for a user name
+               user=auser;
+               *IsIp=false;
+       }
+
+       // include_users
+       if (IncludeUsers[0] != '\0') {
+               char wuser[MAX_USER_LEN+2]=":";
+               char *str;
+
+               strcat(wuser,user);
+               strcat(wuser,":");
+               str=strstr(IncludeUsers,wuser);
+               if (!str)
+                       return(USERERR_Excluded);
+       }
+
+       if (user[0]=='\0' || (user[1]=='\0' && (user[0]=='-' || user[0]==' ' || user[0]==':')))
+               return(USERERR_EmptyUser);
+
+       *UserPtr=user;
+       return(USERERR_NoError);
 }