"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "userinfo.c" between
sarg-2.3.11.tar.gz and sarg-2.4.0.tar.gz

About: SARG ia a Squid Analysis Report Generator.

userinfo.c  (sarg-2.3.11):userinfo.c  (sarg-2.4.0)
/* /*
* SARG Squid Analysis Report Generator http://sarg.sourceforge.net * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
* 1998, 2013 * 1998, 2015
* *
* SARG donations: * SARG donations:
* please look at http://sarg.sourceforge.net/donations.php * please look at http://sarg.sourceforge.net/donations.php
* Support: * Support:
* http://sourceforge.net/projects/sarg/forums/forum/363374 * http://sourceforge.net/projects/sarg/forums/forum/363374
* --------------------------------------------------------------------- * ---------------------------------------------------------------------
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
skipping to change at line 29 skipping to change at line 29
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
* *
*/ */
#include "include/conf.h" #include "include/conf.h"
#include "include/defs.h" #include "include/defs.h"
#include "include/stringbuffer.h"
#include "include/alias.h"
//! The number of users to group in one unit. //! The number of users to group in one unit.
#define USERS_PER_GROUP 50 #define USERS_PER_GROUP 50
/*! \brief Group the users in one allocation unit. /*! \brief Group the users in one allocation unit.
Structure to store a group of users and reduce the number of memory Structure to store a group of users and reduce the number of memory
allocations. allocations.
*/ */
struct usergroupstruct struct usergroupstruct
{ {
skipping to change at line 61 skipping to change at line 63
//! The group containing the user. //! The group containing the user.
struct usergroupstruct *group; struct usergroupstruct *group;
//! The index of the user in the group. //! The index of the user in the group.
int index; int index;
}; };
//! The first group of users. //! The first group of users.
static struct usergroupstruct *first_user_group=NULL; static struct usergroupstruct *first_user_group=NULL;
//! The counter to generate unique user number when ::AnonymousOutputFiles is se t. //! The counter to generate unique user number when ::AnonymousOutputFiles is se t.
static int AnonymousCounter=0; static int AnonymousCounter=0;
//! String buffer to store the user's related constants.
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 userinfostruct *userinfo_create(const char *userid,const char *ip)
{ {
struct usergroupstruct *group, *last; struct usergroupstruct *group, *last;
struct userinfostruct *user; struct userinfostruct *user;
int i, j, lastuser; int i, j, lastuser;
int skip; int skip;
int flen; int flen;
int count, clen; int count, clen;
char cstr[9]; char cstr[9];
char filename[MAX_USER_FNAME_LEN];
if (!UserStrings) {
UserStrings=StringBuffer_Create();
if (!UserStrings) {
debuga(__FILE__,__LINE__,_("Not enough memory to store th
e user's strings\n"));
exit(EXIT_FAILURE);
}
}
last=NULL; last=NULL;
for (group=first_user_group ; group ; group=group->next) { for (group=first_user_group ; group ; group=group->next) {
if (group->nusers<USERS_PER_GROUP) break; if (group->nusers<USERS_PER_GROUP) break;
last=group; last=group;
} }
if (!group) { if (!group) {
group=malloc(sizeof(*group)); group=malloc(sizeof(*group));
if (!group) { if (!group) {
debuga(_("Not enough memory to store the user\n")); debuga(__FILE__,__LINE__,_("Not enough memory to store us er \"%s\"\n"),userid);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
memset(group,0,sizeof(*group)); memset(group,0,sizeof(*group));
if (last) if (last)
last->next=group; last->next=group;
else else
first_user_group=group; first_user_group=group;
} }
user=group->list+group->nusers++; user=group->list+group->nusers++;
safe_strcpy(user->id,userid,sizeof(user->id)); user->id=StringBuffer_Store(UserStrings,userid);
if (!user->id) {
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 no
ne is provided
if (ip) {
/*
* 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's IP address share the same buffer as the user's ID.
*/
user->id_is_ip=true;
user->ip=user->id;
}
if (AnonymousOutputFiles) { if (AnonymousOutputFiles) {
snprintf(user->filename,sizeof(user->filename),"%d",AnonymousCoun ter++); snprintf(filename,sizeof(filename),"%d",AnonymousCounter++);
} else { } else {
skip=0; skip=0;
j=0; j=0;
for (i=0 ; userid[i] && j<MAX_USER_FNAME_LEN-1 ; i++) { for (i=0 ; userid[i] && j<MAX_USER_FNAME_LEN-1 ; i++) {
if (isalnum(userid[i]) || userid[i]=='-' || userid[i]=='_ ') { if (isalnum(userid[i]) || userid[i]=='-' || userid[i]=='_ ') {
user->filename[j++]=userid[i]; filename[j++]=userid[i];
skip=0; skip=0;
} else { } else {
if (!skip) { if (!skip) {
user->filename[j++]='_'; filename[j++]='_';
skip=1; skip=1;
} }
} }
} }
if (j==0) user->filename[j++]='_'; //don't leave a file name empt y if (j==0) filename[j++]='_'; //don't leave a file name empty
flen=j; flen=j;
user->filename[j]='\0'; filename[j]='\0';
strncpy(user->ip,ip,sizeof(user->ip)-1);
user->ip[sizeof(user->ip)-1]='\0';
count=0; count=0;
for (group=first_user_group ; group ; group=group->next) { for (group=first_user_group ; group ; group=group->next) {
lastuser=(group->next) ? group->nusers : group->nusers-1; lastuser=(group->next) ? group->nusers : group->nusers-1;
for (i=0 ; i<lastuser ; i++) { for (i=0 ; i<lastuser ; i++) {
if (strcasecmp(user->filename,group->list[i].file name)==0) { if (strcasecmp(filename,group->list[i].filename)= =0) {
clen=sprintf(cstr,"+%X",count++); clen=sprintf(cstr,"+%X",count++);
if (flen+clen<MAX_USER_FNAME_LEN) if (flen+clen<MAX_USER_FNAME_LEN)
strcpy(user->filename+flen,cstr); strcpy(filename+flen,cstr);
else else
strcpy(user->filename+MAX_USER_FN AME_LEN-clen,cstr); strcpy(filename+MAX_USER_FNAME_LE N-clen,cstr);
} }
} }
} }
} }
user->filename=StringBuffer_Store(UserStrings,filename);
if (!user->filename)
{
debuga(__FILE__,__LINE__,_("Not enough memory to store the file n
ame for user \"%s\"\n"),user->id);
exit(EXIT_FAILURE);
}
return(user); return(user);
} }
void userinfo_free(void) void userinfo_free(void)
{ {
struct usergroupstruct *group, *next; struct usergroupstruct *group, *next;
for (group=first_user_group ; group ; group=next) { for (group=first_user_group ; group ; group=next) {
next=group->next; next=group->next;
free(group); free(group);
} }
first_user_group=NULL; first_user_group=NULL;
StringBuffer_Destroy(&UserStrings);
}
/*!
* Store the user's label.
* \param uinfo The user info structure created by userinfo_create().
* \param label The string label to store.
*/
void userinfo_label(struct userinfostruct *uinfo,const char *label)
{
if (!uinfo) return;
if (!UserStrings) return;
uinfo->label=StringBuffer_Store(UserStrings,label);
if (!uinfo->label) {
debuga(__FILE__,__LINE__,_("Not enough memory to store label \"%s
\" of user \"%s\"\n"),label,uinfo->id);
exit(EXIT_FAILURE);
}
} }
struct userinfostruct *userinfo_find_from_file(const char *filename) struct userinfostruct *userinfo_find_from_file(const char *filename)
{ {
struct usergroupstruct *group; struct usergroupstruct *group;
int i; int i;
for (group=first_user_group ; group ; group=group->next) { for (group=first_user_group ; group ; group=group->next) {
for (i=0 ; i<group->nusers ; i++) for (i=0 ; i<group->nusers ; i++)
if (strcmp(filename,group->list[i].filename)==0) if (strcmp(filename,group->list[i].filename)==0)
skipping to change at line 171 skipping to change at line 231
int i; int i;
for (group=first_user_group ; group ; group=group->next) { for (group=first_user_group ; group ; group=group->next) {
for (i=0 ; i<group->nusers ; i++) for (i=0 ; i<group->nusers ; i++)
if (strcmp(id,group->list[i].id)==0) if (strcmp(id,group->list[i].id)==0)
return(group->list+i); return(group->list+i);
} }
return(NULL); 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. Start the scanning of the user list.
\return The object to pass to subsequent scanning functions or NULL \return The object to pass to subsequent scanning functions or NULL
if it failed. The object must be freed with a call to userinfo_stop(). if it failed. The object must be freed with a call to userinfo_stop().
*/ */
userscan userinfo_startscan(void) userscan userinfo_startscan(void)
{ {
userscan uscan; userscan uscan;
skipping to change at line 238 skipping to change at line 311
void userinfo_clearflag(void) void userinfo_clearflag(void)
{ {
struct usergroupstruct *group; struct usergroupstruct *group;
int i; int i;
for (group=first_user_group ; group ; group=group->next) { for (group=first_user_group ; group ; group=group->next) {
for (i=0 ; i<group->nusers ; i++) for (i=0 ; i<group->nusers ; i++)
group->list[i].flag=0; group->list[i].flag=0;
} }
} }
/*!
Read the file containing the user names to alias in the report.
\param Filename The name of the file.
*/
void read_useralias(const char *Filename)
{
FileObject *fi;
longline line;
char *buf;
if (debug) debuga(__FILE__,__LINE__,_("Reading user alias file \"%s\"\n")
,Filename);
UserAliases=Alias_Create();
if (!UserAliases) {
debuga(__FILE__,__LINE__,_("Cannot store user's aliases\n"));
exit(EXIT_FAILURE);
}
fi=FileObject_Open(Filename);
if (!fi) {
debuga(__FILE__,__LINE__,_("Cannot read user name alias file \"%s
\": %s\n"),Filename,FileObject_GetLastOpenError());
exit(EXIT_FAILURE);
}
if ((line=longline_create())==NULL) {
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(__FILE__,__LINE__,_("While reading \"%s\"\n"),File
name);
exit(EXIT_FAILURE);
}
}
longline_destroy(&line);
if (FileObject_Close(fi)) {
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),Filename
,FileObject_GetLastCloseError());
exit(EXIT_FAILURE);
}
if (debug) {
debuga(__FILE__,__LINE__,_("List of user names to alias:\n"));
Alias_PrintList(UserAliases);
}
}
/*!
Free the memory allocated by read_useralias().
*/
void free_useralias(void)
{
Alias_Destroy(&UserAliases);
}
/*!
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.
*/
enum UserProcessError process_user(const char **UserPtr,const char *IpAddress,bo
ol *IsIp)
{
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(u
ser,'\\'))!=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 fo
r 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]==' ' || u
ser[0]==':')))
return(USERERR_EmptyUser);
*UserPtr=user;
return(USERERR_NoError);
}
 End of changes. 18 change blocks. 
13 lines changed or deleted 91 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)