sarg  2.4.0
About: SARG ia a Squid Analysis Report Generator.
  Fossies Dox: sarg-2.4.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

userinfo.c
Go to the documentation of this file.
1 /*
2  * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3  * 1998, 2015
4  *
5  * SARG donations:
6  * please look at http://sarg.sourceforge.net/donations.php
7  * Support:
8  * http://sourceforge.net/projects/sarg/forums/forum/363374
9  * ---------------------------------------------------------------------
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24  *
25  */
26 
27 #include "include/conf.h"
28 #include "include/defs.h"
29 #include "include/stringbuffer.h"
30 #include "include/alias.h"
31 
33 #define USERS_PER_GROUP 50
34 
40 {
46  int nusers;
47 };
48 
52 {
56  int index;
57 };
58 
60 static struct usergroupstruct *first_user_group=NULL;
62 static int AnonymousCounter=0;
67 
68 extern struct ReadLogDataStruct ReadFilter;
69 extern char StripUserSuffix[MAX_USER_LEN];
70 extern int StripSuffixLen;
71 extern char *userfile;
72 
73 struct userinfostruct *userinfo_create(const char *userid,const char *ip)
74 {
75  struct usergroupstruct *group, *last;
76  struct userinfostruct *user;
77  int i, j, lastuser;
78  int skip;
79  int flen;
80  int count, clen;
81  char cstr[9];
83 
84  if (!UserStrings) {
86  if (!UserStrings) {
87  debuga(__FILE__,__LINE__,_("Not enough memory to store the user's strings\n"));
88  exit(EXIT_FAILURE);
89  }
90  }
91 
92  last=NULL;
93  for (group=first_user_group ; group ; group=group->next) {
94  if (group->nusers<USERS_PER_GROUP) break;
95  last=group;
96  }
97 
98  if (!group) {
99  group=malloc(sizeof(*group));
100  if (!group) {
101  debuga(__FILE__,__LINE__,_("Not enough memory to store user \"%s\"\n"),userid);
102  exit(EXIT_FAILURE);
103  }
104  memset(group,0,sizeof(*group));
105  if (last)
106  last->next=group;
107  else
108  first_user_group=group;
109  }
110  user=group->list+group->nusers++;
111 
112  user->id=StringBuffer_Store(UserStrings,userid);
113  if (!user->id) {
114  debuga(__FILE__,__LINE__,_("Not enough memory to store user ID \"%s\"\n"),userid);
115  exit(EXIT_FAILURE);
116  }
117  user->label=user->id; //assign a label to avoid a NULL pointer in case none is provided
118  if (ip) {
119  /*
120  * IP address is not the same as the user's ID. A separate buffer
121  * must be allocated.
122  */
123  user->id_is_ip=false;
125  } else {
126  /*
127  * User's IP address share the same buffer as the user's ID.
128  */
129  user->id_is_ip=true;
130  user->ip=user->id;
131  }
132 
133  if (AnonymousOutputFiles) {
134  snprintf(filename,sizeof(filename),"%d",AnonymousCounter++);
135  } else {
136  skip=0;
137  j=0;
138  for (i=0 ; userid[i] && j<MAX_USER_FNAME_LEN-1 ; i++) {
139  if (isalnum(userid[i]) || userid[i]=='-' || userid[i]=='_') {
140  filename[j++]=userid[i];
141  skip=0;
142  } else {
143  if (!skip) {
144  filename[j++]='_';
145  skip=1;
146  }
147  }
148  }
149  if (j==0) filename[j++]='_'; //don't leave a file name empty
150  flen=j;
151  filename[j]='\0';
152 
153  count=0;
154  for (group=first_user_group ; group ; group=group->next) {
155  lastuser=(group->next) ? group->nusers : group->nusers-1;
156  for (i=0 ; i<lastuser ; i++) {
157  if (strcasecmp(filename,group->list[i].filename)==0) {
158  clen=sprintf(cstr,"+%X",count++);
159  if (flen+clen<MAX_USER_FNAME_LEN)
160  strcpy(filename+flen,cstr);
161  else
162  strcpy(filename+MAX_USER_FNAME_LEN-clen,cstr);
163  }
164  }
165  }
166  }
168  if (!user->filename)
169  {
170  debuga(__FILE__,__LINE__,_("Not enough memory to store the file name for user \"%s\"\n"),user->id);
171  exit(EXIT_FAILURE);
172  }
173 
174  return(user);
175 }
176 
177 void userinfo_free(void)
178 {
179  struct usergroupstruct *group, *next;
180 
181  for (group=first_user_group ; group ; group=next) {
182  next=group->next;
183  free(group);
184  }
185  first_user_group=NULL;
187 }
188 
194 void userinfo_label(struct userinfostruct *uinfo,const char *label)
195 {
196  if (!uinfo) return;
197  if (!UserStrings) return;
198  uinfo->label=StringBuffer_Store(UserStrings,label);
199  if (!uinfo->label) {
200  debuga(__FILE__,__LINE__,_("Not enough memory to store label \"%s\" of user \"%s\"\n"),label,uinfo->id);
201  exit(EXIT_FAILURE);
202  }
203 }
204 
206 {
207  struct usergroupstruct *group;
208  int i;
209 
210  for (group=first_user_group ; group ; group=group->next) {
211  for (i=0 ; i<group->nusers ; i++)
212  if (strcmp(filename,group->list[i].filename)==0)
213  return(group->list+i);
214  }
215  return(NULL);
216 }
217 
218 struct userinfostruct *userinfo_find_from_id(const char *id)
219 {
220  struct usergroupstruct *group;
221  int i;
222 
223  for (group=first_user_group ; group ; group=group->next) {
224  for (i=0 ; i<group->nusers ; i++)
225  if (strcmp(id,group->list[i].id)==0)
226  return(group->list+i);
227  }
228  return(NULL);
229 }
230 
232 {
233  struct usergroupstruct *group;
234  int i;
235 
236  for (group=first_user_group ; group ; group=group->next) {
237  for (i=0 ; i<group->nusers ; i++)
238  if (strcmp(ip,group->list[i].ip)==0)
239  return(group->list+i);
240  }
241  return(NULL);
242 }
243 
251 {
252  userscan uscan;
253 
254  uscan=malloc(sizeof(*uscan));
255  if (!uscan) return(NULL);
256  uscan->group=first_user_group;
257  uscan->index=0;
258  return(uscan);
259 }
260 
267 {
268  free(uscan);
269 }
270 
281 {
282  struct userinfostruct *uinfo;
283 
284  if (!uscan) return(NULL);
285  if (!uscan->group) return(NULL);
286  if (uscan->index<0 || uscan->index>=uscan->group->nusers) return(NULL);
287 
288  uinfo=uscan->group->list+uscan->index;
289 
290  ++uscan->index;
291  if (uscan->index>=uscan->group->nusers) {
292  uscan->group=uscan->group->next;
293  uscan->index=0;
294  }
295  return(uinfo);
296 }
297 
302 {
303  struct usergroupstruct *group;
304  int i;
305 
306  for (group=first_user_group ; group ; group=group->next) {
307  for (i=0 ; i<group->nusers ; i++)
308  group->list[i].flag=0;
309  }
310 }
311 
317 void read_useralias(const char *Filename)
318 {
319  FileObject *fi;
320  longline line;
321  char *buf;
322 
323  if (debug) debuga(__FILE__,__LINE__,_("Reading user alias file \"%s\"\n"),Filename);
324 
326  if (!UserAliases) {
327  debuga(__FILE__,__LINE__,_("Cannot store user's aliases\n"));
328  exit(EXIT_FAILURE);
329  }
330 
331  fi=FileObject_Open(Filename);
332  if (!fi) {
333  debuga(__FILE__,__LINE__,_("Cannot read user name alias file \"%s\": %s\n"),Filename,FileObject_GetLastOpenError());
334  exit(EXIT_FAILURE);
335  }
336 
337  if ((line=longline_create())==NULL) {
338  debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\"\n"),Filename);
339  exit(EXIT_FAILURE);
340  }
341 
342  while ((buf=longline_read(fi,line)) != NULL) {
343  if (Alias_Store(UserAliases,buf)<0) {
344  debuga(__FILE__,__LINE__,_("While reading \"%s\"\n"),Filename);
345  exit(EXIT_FAILURE);
346  }
347  }
348 
349  longline_destroy(&line);
350  if (FileObject_Close(fi)) {
351  debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),Filename,FileObject_GetLastCloseError());
352  exit(EXIT_FAILURE);
353  }
354 
355  if (debug) {
356  debuga(__FILE__,__LINE__,_("List of user names to alias:\n"));
358  }
359 }
360 
364 void free_useralias(void)
365 {
367 }
368 
377 enum UserProcessError process_user(const char **UserPtr,const char *IpAddress,bool *IsIp)
378 {
379  const char *user=*UserPtr;
380  static char UserBuffer[MAX_USER_LEN];
381  const char *auser;
382 
383  if (UserIp) {
384  user=IpAddress;
385  *IsIp=true;
386  } else {
387  *IsIp=false;
388 
389  if (StripSuffixLen>0)
390  {
391  int x=strlen(user);
392  if (x>StripSuffixLen && strcasecmp(user+(x-StripSuffixLen),StripUserSuffix)==0)
393  {
394  if (x-StripSuffixLen>=sizeof(UserBuffer))
395  return(USERERR_NameTooLong);
396  safe_strcpy(UserBuffer,user,x-StripSuffixLen+1);
397  user=UserBuffer;
398  }
399  }
400  if (strlen(user)>MAX_USER_LEN)
401  return(USERERR_NameTooLong);
402 
403  if (testvaliduserchar(user))
404  return(USERERR_InvalidChar);
405 
406  if ((user[0]=='\0') || (user[1]=='\0' && (user[0]=='-' || user[0]==' '))) {
408  user=IpAddress;
409  *IsIp=true;
410  }
412  return(USERERR_EmptyUser);
414  user="everybody";
415  } else {
417  const char *str;
418  if ((str=strchr(user,'+'))!=NULL || (str=strchr(user,'\\'))!=NULL || (str=strchr(user,'_'))!=NULL) {
419  user=str+1;
420  }
421  }
422  }
423  }
424 
425  if (us[0]!='\0' && strcmp(user,us)!=0)
426  return(USERERR_Untracked);
427 
428  if (ReadFilter.SysUsers) {
429  char wuser[MAX_USER_LEN+2]=":";
430 
431  strcat(wuser,user);
432  strcat(wuser,":");
433  if (strstr(userfile, wuser) == 0)
434  return(USERERR_SysUser);
435  }
436 
437  if (ReadFilter.UserFilter) {
438  if (!vuexclude(user)) {
439  if (debugz>=LogLevel_Process) debuga(__FILE__,__LINE__,_("Excluded user: %s\n"),user);
440  return(USERERR_Ignored);
441  }
442  }
443 
444  auser=Alias_Replace(UserAliases,user);
445  if (auser!=user) {
446  if (*auser==ALIAS_PREFIX) auser++;//no need for that indicator for a user name
447  user=auser;
448  *IsIp=false;
449  }
450 
451  // include_users
452  if (IncludeUsers[0] != '\0') {
453  char wuser[MAX_USER_LEN+2]=":";
454  char *str;
455 
456  strcat(wuser,user);
457  strcat(wuser,":");
458  str=strstr(IncludeUsers,wuser);
459  if (!str)
460  return(USERERR_Excluded);
461  }
462 
463  if (user[0]=='\0' || (user[1]=='\0' && (user[0]=='-' || user[0]==' ' || user[0]==':')))
464  return(USERERR_EmptyUser);
465 
466  *UserPtr=user;
467  return(USERERR_NoError);
468 }
StringBuffer_Destroy
void StringBuffer_Destroy(StringBufferObject *SPtr)
Definition: stringbuffer.c:78
ReadLogDataStruct::UserFilter
bool UserFilter
True to filter on users.
Definition: defs.h:142
RECORDWITHOUTUSER_IGNORE
#define RECORDWITHOUTUSER_IGNORE
Definition: conf.h:249
first_user_group
static struct usergroupstruct * first_user_group
The first group of users.
Definition: userinfo.c:60
AnonymousOutputFiles
bool AnonymousOutputFiles
True to use anonymous file and directory names in the report.
Definition: conf.h:422
ReadLogDataStruct::SysUsers
bool SysUsers
True to restrict the log to the system users.
Definition: defs.h:146
userinfo_free
void userinfo_free(void)
Definition: userinfo.c:177
debuga
void debuga(const char *File, int Line, const char *msg,...)
Definition: util.c:601
read_useralias
void read_useralias(const char *Filename)
Definition: userinfo.c:317
usergroupstruct
Group the users in one allocation unit. Structure to store a group of users and reduce the number of ...
Definition: userinfo.c:39
UserStrings
static StringBufferObject UserStrings
String buffer to store the user's related constants.
Definition: userinfo.c:64
StringBuffer_Create
StringBufferObject StringBuffer_Create(void)
Definition: stringbuffer.c:60
userinfo_advancescan
struct userinfostruct * userinfo_advancescan(userscan uscan)
Definition: userinfo.c:280
userinfostruct
What is known about a user.
Definition: defs.h:78
userscanstruct::group
struct usergroupstruct * group
The group containing the user.
Definition: userinfo.c:54
longline_read
char * longline_read(FileObject *fp_in, longline line)
Definition: longline.c:97
FileObject_GetLastCloseError
const char * FileObject_GetLastCloseError(void)
Definition: fileobject.c:263
USERERR_Untracked
@ USERERR_Untracked
Definition: defs.h:73
longlinestruct
Definition: longline.c:56
FileObject_GetLastOpenError
const char * FileObject_GetLastOpenError(void)
Definition: fileobject.c:236
userinfo_create
struct userinfostruct * userinfo_create(const char *userid, const char *ip)
Definition: userinfo.c:73
userinfostruct::id
const char * id
The ID of the user as found in the input file.
Definition: defs.h:81
_
#define _(String)
Definition: conf.h:155
USERERR_Excluded
@ USERERR_Excluded
Definition: defs.h:68
Alias_Destroy
void Alias_Destroy(AliasObject *AliasPtr)
Definition: alias.c:161
userinfo_clearflag
void userinfo_clearflag(void)
Definition: userinfo.c:301
userinfo_find_from_file
struct userinfostruct * userinfo_find_from_file(const char *filename)
Definition: userinfo.c:205
userscanstruct
Hold pointer to scan through the user list.
Definition: userinfo.c:51
MAX_USER_LEN
#define MAX_USER_LEN
Definition: conf.h:179
ReadFilter
struct ReadLogDataStruct ReadFilter
The log file filtering.
Definition: log.c:37
userinfostruct::id_is_ip
bool id_is_ip
True if the ID is in fact the IP address from which the user connected.
Definition: defs.h:85
stringbuffer.h
alias.h
StripSuffixLen
int StripSuffixLen
Length of the suffix to strip from the user name.
Definition: readlog.c:95
process_user
enum UserProcessError process_user(const char **UserPtr, const char *IpAddress, bool *IsIp)
Definition: userinfo.c:377
userinfostruct::label
const char * label
The name of the user to display in the report.
Definition: defs.h:89
StringBufferStruct
String storage data.
Definition: stringbuffer.c:45
userscanstruct::index
int index
The index of the user in the group.
Definition: userinfo.c:56
usergroupstruct::next
struct usergroupstruct * next
The next group of users.
Definition: userinfo.c:42
UserAliases
static AliasObject UserAliases
User aliases.
Definition: userinfo.c:66
Alias_PrintList
void Alias_PrintList(struct AliasStruct *AliasData)
Definition: alias.c:638
userinfo_startscan
userscan userinfo_startscan(void)
Definition: userinfo.c:250
UserProcessError
UserProcessError
Error codes returned by process_user.
Definition: defs.h:64
userfile
char * userfile
The list of the system users.
Definition: log.c:40
userinfo_label
void userinfo_label(struct userinfostruct *uinfo, const char *label)
Definition: userinfo.c:194
Alias_Store
int Alias_Store(struct AliasStruct *AliasData, char *String)
Definition: alias.c:594
FileObject_Open
FileObject * FileObject_Open(const char *FileName)
Definition: fileobject.c:104
AliasStruct
Object to group items together.
Definition: alias.c:121
USERERR_EmptyUser
@ USERERR_EmptyUser
Definition: defs.h:70
conf.h
Include headers and define global variables. */.
ALIAS_PREFIX
#define ALIAS_PREFIX
The character prefixed in front of the host names that are aliased.
Definition: conf.h:290
USERERR_NameTooLong
@ USERERR_NameTooLong
Definition: defs.h:67
userinfo_stopscan
void userinfo_stopscan(userscan uscan)
Definition: userinfo.c:266
ReadLogDataStruct
Log filtering criterion.
Definition: defs.h:131
longline_create
longline longline_create(void)
Definition: longline.c:70
userinfostruct::filename
const char * filename
The mangled name to use in file names of that user.
Definition: defs.h:91
vuexclude
int vuexclude(const char *user)
Definition: exclude.c:364
AnonymousCounter
static int AnonymousCounter
The counter to generate unique user number when AnonymousOutputFiles is set.
Definition: userinfo.c:62
NTLMUSERFORMAT_USER
#define NTLMUSERFORMAT_USER
Definition: conf.h:245
NtlmUserFormat
unsigned long int NtlmUserFormat
Definition: conf.h:414
testvaliduserchar
int testvaliduserchar(const char *user)
Definition: util.c:1933
IncludeUsers
char IncludeUsers[20000]
Definition: conf.h:375
MAX_USER_FNAME_LEN
#define MAX_USER_FNAME_LEN
Definition: conf.h:180
userinfo_find_from_id
struct userinfostruct * userinfo_find_from_id(const char *id)
Definition: userinfo.c:218
longline_destroy
void longline_destroy(longline *line_ptr)
Definition: longline.c:168
StringBuffer_Store
char * StringBuffer_Store(StringBufferObject SObj, const char *String)
Definition: stringbuffer.c:179
StripUserSuffix
char StripUserSuffix[256]
Domain suffix to strip from the user name.
Definition: readlog.c:93
userinfostruct::flag
int flag
A general purpose flag that can be set when scanning the user's list.
Definition: defs.h:95
USERERR_Ignored
@ USERERR_Ignored
Definition: defs.h:72
userinfostruct::ip
const char * ip
The user's IP address.
Definition: defs.h:83
us
char us[50]
Definition: conf.h:434
USERS_PER_GROUP
#define USERS_PER_GROUP
The number of users to group in one unit.
Definition: userinfo.c:33
safe_strcpy
void safe_strcpy(char *dest, const char *src, int length)
Definition: util.c:1550
userinfo_find_from_ip
struct userinfostruct * userinfo_find_from_ip(const char *ip)
Definition: userinfo.c:231
USERERR_InvalidChar
@ USERERR_InvalidChar
Definition: defs.h:69
Alias_Replace
const char * Alias_Replace(struct AliasStruct *AliasData, const char *Name)
Definition: alias.c:819
defs.h
Declaration of the structures and functions.
RecordsWithoutUser
unsigned long int RecordsWithoutUser
Definition: conf.h:325
usergroupstruct::nusers
int nusers
The number of users stored in the list.
Definition: userinfo.c:46
debugz
int debugz
Definition: conf.h:490
free_useralias
void free_useralias(void)
Definition: userinfo.c:364
USERERR_NoError
@ USERERR_NoError
Definition: defs.h:66
RECORDWITHOUTUSER_IP
#define RECORDWITHOUTUSER_IP
Definition: conf.h:248
Alias_Create
AliasObject Alias_Create(void)
Definition: alias.c:137
UserIp
bool UserIp
Definition: conf.h:365
FileObject_Close
int FileObject_Close(FileObject *File)
Definition: fileobject.c:206
debug
int debug
Definition: conf.h:489
FileObjectStruct
Definition: fileobject.h:4
USERERR_SysUser
@ USERERR_SysUser
Definition: defs.h:71
RECORDWITHOUTUSER_EVERYBODY
#define RECORDWITHOUTUSER_EVERYBODY
Definition: conf.h:250
usergroupstruct::list
struct userinfostruct list[50]
A group of users.
Definition: userinfo.c:44
LogLevel_Process
@ LogLevel_Process
Process informational messages.
Definition: defs.h:15