/* SAMS (Squid Account Management System * Author: Dmitry Chemerik chemerik@mail.ru * * 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 * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include #include #include #include #include #include #include "pcre.h" #include "config.h" #include "define.h" #include "tools.h" struct samsusers { char user[25]; char domain[25]; int ip[6]; int ipmask[6]; char shablon[25]; int enabled; char id[16]; int stime; int etime; int days[7]; int ipauth; int ntlmauth; int ncsaauth; int adldauth; int alldenied; }; struct samsshablons { char name[25]; char list[25]; long sm; long len; }; struct samsurls { char url[90]; char list[25]; char type[25]; int regex; double count; pcre *cexpr; }; sig_atomic_t child_exit_status; struct samsusers *users; struct samsurls *urls; struct samsshablons *shablons; int samsshablonscount,samsurlscount,samslistcount, samsuserscount,smcount,rflag; char samsuser[256]; char samsdomain[256]; int DEBUG,NCSA,IP,NTLM,NCSA,NTLMDOMAIN,USERNUMBER; int REDIRECT,DENIED,USERDENIED,ALLOW,URLALLOW,TIMEDENIED; char userid[16]; char LANG[16]; MYSQL *conn; MYSQL_RES *res, *res2; MYSQL_ROW row, row2; /* int LocalIPAddr(char *url, int *od, int *om) { int i=0,ocount=0,slashe=0,length=0; int t1=0,j=0; int bit,bit2; char octet[50]; for(i=0;i<6;i++) { od[i]=0; om[i]=0; } length=strlen(url); i=0; while(slashe<1&&i255) return(0); else od[ocount]=atoi(&octet[0]); t1=i+1; ocount++; } else if(url[i]=='/') { slashe++; strncpy(&octet[0],url+t1,i-t1); strcpy(&octet[i-t1],"\0"); if(atof(&octet[0])>255) return(0); else od[ocount]=atoi(&octet[0]); t1=i+1; } i++; } if(slashe==0) { strncpy(&octet[0],url+t1,i-t1); strcpy(&octet[i-t1],"\0"); if(atof(&octet[0])>255) return(0); else od[ocount]=atoi(&octet[0]); t1=i+1; } slashe=0; // **** Маска t1=i; ocount=0; if(length-i<=2&&length-i>0) { // * если маска задана количеством битов strncpy(&octet[0],url+i,length-i); strcpy(&octet[length-i],"\0"); if(atof(&octet[0])>48) return(0); else bit=atoi(&octet[0]); bit2=abs((32-bit)/8); for(j=0;j0) { while(slashe<1&&i255) return(0); else om[ocount]=atoi(&octet[0]); t1=i+1; ocount++; } else if(url[i]=='/') { slashe++; strncpy(&octet[0],url+t1,i-t1); strcpy(&octet[i-t1],"\0"); if(atof(&octet[0])>255) return(0); else om[ocount]=atoi(&octet[0]); //printf("%ld \n",om[ocount]); t1=i+1; } i++; } if(slashe==0) { strncpy(&octet[0],url+t1,i-t1); strcpy(&octet[i-t1],"\0"); if(atof(&octet[0])>255) return(0); else om[ocount]=atoi(&octet[0]); //printf("%ld\n",om[ocount]); t1=i+1; } } else { om[0]=om[1]=om[2]=om[3]=om[4]=om[5]=255; } return(1); } */ void clean_up_child_process(int signal_number) { int status; wait(&status); child_exit_status = status; } void convertplus(char* p) { char* buffer; int strCount = 0; int sourceCount = 0; while(1) { buffer = strstr(p,"%5c"); if(buffer) { sourceCount = strlen(p); strCount = strlen(buffer); p[sourceCount - strCount] = '+'; strcpy(&p[sourceCount - strCount+1],buffer+3); if(DEBUG==1) printf(" Found NTLN separator: %s \n","%5c"); } else break; } } void ReturnFullDomainName(char *domainname,char *url) { int i=0,count=0,slashe=0,t1=0,t2=0,j=0; for(i=0,count=0,t2=0;i=3) { count=i-1; break; } slashe=i; } } if(t1=3) { count=i-1; break; } slashe=i; } } if(t10) return(i+1); } } if((users[i].ntlmauth!=0||users[i].adldauth!=0)&&NTLMDOMAIN!=0) { strncpy(&samsuser[0],users[i].user,255); strncpy(&samsdomain[0],users[i].domain,255); strcat(&samsuser[0],"\0"); strcat(&samsdomain[0],"\0"); if(strstr(str1,"+")!=0) { sprintf(&str3[0],"%s+%s",users[i].domain,users[i].user); } else if(strstr(str1,"\\")!=0) { sprintf(&str3[0],"%s\\%s",users[i].domain,users[i].user); } else if(strstr(str1," ")!=0) { sprintf(&str3[0],"%s %s",users[i].domain,users[i].user); } else { sprintf(&str3[0],"%s%s",users[i].domain,users[i].user); } if(strcmp(str2lower(str1),&str3[0])==0) { strcpy(&userid[0],users[i].id); } if(strcmp(str2lower(str1),&str3[0])==0&&users[i].enabled>0) { return(i+1); } strcpy(&samsuser[0],"\0"); strcpy(&samsdomain[0],"\0"); } if(users[i].ncsaauth!=0||(users[i].ntlmauth!=0&&NTLMDOMAIN==0)||(users[i].adldauth!=0&&NTLMDOMAIN==0)) { if(strcmp(str2lower(str1),users[i].user)==0) { strcpy(&userid[0],users[i].id); } if(strcmp(str2lower(str1),users[i].user)==0&&users[i].enabled>0) { return(i+1); } } } return(0); } int main (int argc, char *argv[]) { int i=0,j=0,k=0,flag=0; static char domainname[BUFFER_SIZE]; static char str[BUFFER_SIZE]; static char str1[BUFFER_SIZE]; static char str1_[BUFFER_SIZE]; static char str2[BUFFER_SIZE]; static char str2_[BUFFER_SIZE]; static char str3[BUFFER_SIZE]; static char str4[BUFFER_SIZE]; static char redir_to[120]; static char denied_to[120]; char *user=NULL,*domain=NULL; char separator; unsigned int pid; struct sigaction sigchld_action; time_t tt; struct tm *t; char week[8]; int erroffset; const char *error; int ovector[30]; sprintf(&week[0],"SMTWHFA"); pid = getpid(); NCSA=0; REQUEST=0; for(i=0;i0) users[i].alldenied=1; if(DEBUG==1) { printf("%3d: ",i); printf("%15s ",users[i].user); printf("%15s ",users[i].domain); printf("%3d.%3d.%3d.%3d ",users[i].ip[0],users[i].ip[1],users[i].ip[2],users[i].ip[3]); printf("%2d ",users[i].enabled); printf("%16s ",users[i].shablon); printf("%d%d%d%d%d%d%d ",users[i].days[0],users[i].days[1],users[i].days[2],users[i].days[3],users[i].days[4],users[i].days[5],users[i].days[6]); printf("%d - %d ",users[i].stime,users[i].etime); printf("%d %d %d %d\n",users[i].ipauth,users[i].ntlmauth,users[i].ncsaauth,users[i].adldauth); } } /* Получаем количество Списков */ samsshablonscount=0; sprintf(&str[0],"SELECT count(sname) FROM %s.sconfig",conf.samsdb); flag=send_mysql_query(conn,&str[0]); res=mysql_store_result(conn); row=mysql_fetch_row(res); samsshablonscount=atoi(row[0]); if(DEBUG==1) { printf("\nSearch URL lists in the users templates: found %d URL lists\n",samsshablonscount); } /* Выделяем память под список шаблонов */ if((shablons=(struct samsshablons *)malloc(sizeof(struct samsshablons)*samsshablonscount))==NULL) { printf("Not enought memory to allocate buffer\n"); exit(1); } /* Загружаем списки и шаблоны в массив */ sprintf(&str[0],"SELECT * FROM %s.sconfig",conf.samsdb); flag=send_mysql_query(conn,&str[0]); res=mysql_store_result(conn); for(i=0;i0) { strncpy(&str1[0],strtok(&str[0]," "),BUFFER_SIZE-1); sprintf(&str1_[0],"%s",&str1[0]); strncpy(&str2_[0],strtok(NULL," "),254); strncpy(&str3[0],strtok(NULL," "),254); if(NTLM!=0||NCSA!=0) { url_decode(&str3[0]); } convertplus(&str3[0]); strncpy(&str4[0],strtok(NULL," "),254); strncpy(&str2[0],strtok(&str2_[0],"/"),254); ReturnFullDomainName(&str[0],&str1[0]); if(DEBUG==1) printf(" decode data: URL=%s IP=%s USER=%s TYPE=%s\n",&str1[0],&str2[0],&str3[0],&str4[0]); if(DEBUG==1&&NCSA!=0) printf(" authentication: ncsa \n"); if(DEBUG==1&&NTLM!=0&&NTLMDOMAIN!=0) printf(" authentication: ntlm (domain+username) \n"); if(DEBUG==1&&NTLM!=0&&NTLMDOMAIN==0) printf(" authentication: ntlm (username) \n"); if(DEBUG==1&&IP!=0) printf(" authentication: ip \n"); if(DEBUG==1) printf(" Search SAMS user... "); if(NTLM!=0||NCSA!=0) USERNUMBER=UserAccess(&str2[0],&str3[0],&str4[0]); if(IP!=0) USERNUMBER=UserAccess(&str2[0],&str3[0],&str4[0]); if(USERNUMBER==0) { if(DEBUG==1) printf(" NOT FOUND\n"); USERDENIED=1; } else { if(DEBUG==1&&(NCSA!=0||(NTLM!=0&&NTLMDOMAIN==0))) printf(" %s template: %s\n",users[USERNUMBER-1].user,users[USERNUMBER-1].shablon); if(DEBUG==1&&NTLM!=0&&NTLMDOMAIN!=0) printf(" %s+%s template: %s\n",users[USERNUMBER-1].domain,users[USERNUMBER-1].user,users[USERNUMBER-1].shablon); if(DEBUG==1&&IP!=0) printf(" %s, ip: %d.%d.%d.%d, template: %s\n",users[USERNUMBER-1].user,users[USERNUMBER-1].ip[0],users[USERNUMBER-1].ip[1],users[USERNUMBER-1].ip[2],users[USERNUMBER-1].ip[3],users[USERNUMBER-1].shablon); tt=time(NULL); t=localtime(&tt); TIMEDENIED=1; if(users[USERNUMBER-1].days[t->tm_wday]==1) { if( (users[USERNUMBER-1].stime>users[USERNUMBER-1].etime)) { if(users[USERNUMBER-1].stime < (t->tm_hour*60+t->tm_min) || (t->tm_hour*60+t->tm_min) tm_hour*60+t->tm_min)&& (t->tm_hour*60+t->tm_min) =0) { DENIED=1; if(DEBUG==1) printf(" REGEX: found rules: %s\n",urls[k].url); } } if(strcmp(urls[k].type,"redir")==0) { if(urls[k].cexpr!=NULL) if(pcre_exec(urls[k].cexpr,NULL,&str1[0],strlen(&str1[0]),0,0,ovector,30)>=0) { REDIRECT=1; urls[k].count+=1; rflag=1; if(DEBUG==1) printf(" REDIR: found URL %s\n",urls[k].url); } } //if(DEBUG==1) // printf(" %d %s %d URL: %s=%s \n",k,urls[k].type,j,&str1[0],urls[k].url); if(strstr(&str1[0],urls[k].url)!=0) { if(strcmp(urls[k].type,"allow")==0) { ALLOW=1; if(DEBUG==1) printf(" ALLOW: found URL %s\n",urls[k].url); } if(strcmp(urls[k].type,"denied")==0) { DENIED=1; if(DEBUG==1) printf(" DENIED: found URL %s\n",urls[k].url); } } } } } } else { //TIMEDENIED=1; if(DEBUG==1) printf("Data or time limit error %c=%d %d:%d \n",week[t->tm_wday],users[USERNUMBER-1].days[t->tm_wday],t->tm_hour,t->tm_min); } } if(DEBUG==1) printf("URLALLOW=%d ALLOW=%d USERDENIED=%d DENIED=%d REDIRECT=%d TIMEDENIED=%d\n",URLALLOW, ALLOW, USERDENIED, DENIED, REDIRECT, TIMEDENIED); //запрещено все и непопали в разрещенный список if(URLALLOW!=0&&ALLOW==0) { sprintf(&str1[0],"%s/blocked.php?action=urldenied&id=%s",&denied_to[0],&userid[0]); } if(USERDENIED!=0) { sprintf(&str1[0],"%s/blocked.php?action=userdisabled&id=%s",&denied_to[0],&userid[0]); } if(DENIED!=0&&ALLOW==0) { sprintf(&str1[0],"%s/blocked.php?action=urldenied&id=%s",&denied_to[0],&userid[0]); } if(REDIRECT!=0) { strncpy(&str1[0],&redir_to[0],254); } if(TIMEDENIED!=0) { sprintf(&str1[0],"%s/blocked.php?action=timedenied&id=%s",&denied_to[0],&userid[0]); } sprintf(&str[0],"%s %s/- %s %s",&str1[0],&str2[0],&str3[0],&str4[0]); fprintf(stdout,"%s\n",&str[0]); fflush(stdout); if(DEBUG==1) printf("\n"); if(REQUEST==1) { sprintf(&str[0],"INSERT INTO %s.redirect_test SET redirect_test.inp='%s',redirect_test.ip='%s',redirect_test.out='%s',redirect_test.user='%s',redirect_test.pid='%d'",conf.logdb,&str1_[0],&str2[0],&str1[0],&str3[0],pid); printf("%s\n",&str[0]); flag=send_mysql_query(conn,&str[0]); strcpy(&str[0],"\0"); printf("flag=%d\n",flag); } } } if(REQUEST==1) do_disconnect(conn); return(0); }