Back to index

wims  3.65+svn20090927
auth.c
Go to the documentation of this file.
00001 /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
00002  *
00003  *  This program is free software; you can redistribute it and/or modify
00004  *  it under the terms of the GNU General Public License as published by
00005  *  the Free Software Foundation; either version 2 of the License, or
00006  *  (at your option) any later version.
00007  *
00008  *  This program is distributed in the hope that it will be useful,
00009  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011  *  GNU General Public License for more details.
00012  *
00013  *  You should have received a copy of the GNU General Public License
00014  *  along with this program; if not, write to the Free Software
00015  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00016  */
00017 
00018        /* This file contains user authentification routines */
00019 
00020 void refuse_log(int th);
00021 void set_module_prefix(void);
00022 
00023        /* check machine load. 2-threshold system.
00024         * Threshold 1: anonymous new session refused.
00025         * Threshold 2: New session and anonymous request refused. */
00026 void check_load(int th)
00027 {
00028     int load, pload;
00029     char *p1, *p2, buf[64];
00030     char *pp;
00031     double dload;
00032     
00033     pload=0; pp=strchr(loadavg,'/'); if(pp) {
00034        for(;pp>loadavg && isdigit(pp[-1]); pp--);
00035        pload=atoi(pp);
00036        if(pload*12>threshold2+3) {
00037            pload_refuse:
00038            refuse_log(pload+100); user_error("threshold");
00039        }
00040     }
00041     if(ispriority) goto repcheck; /* priority connections will not be refused. */
00042     if(pload*20>threshold1+2) goto pload_refuse;
00043     if(th<0 || th>2) goto repcheck;
00044        /* Operating system load average facility */
00045     if(robot_access && loadavg[0]==0) goto refuse;
00046     if(loadavg[0]==0) goto repcheck;
00047     p1=find_word_start(loadavg); p2=find_word_end(p1);*p2=0;
00048     dload=atof(p1);
00049     if(robot_access && 
00050        (!finite(dload) || dload>1000 || dload<0 || dload*200>threshold1))
00051       goto refuse;
00052     if(!finite(dload) || dload<=0 || dload>1000) goto repcheck; /* unreasonable */
00053        /* very small 1 min load average */
00054     if(dload*200<threshold1) goto repcheck;
00055     if(dload*50>threshold2) goto refuse;
00056     p1=find_word_start(p2+1);      /* go to second average: 5 min. */
00057     *find_word_end(p1)=0;
00058     dload=atof(p1);
00059     if(!finite(dload) || dload<=0 || dload>1000) goto repcheck; /* unreasonable */
00060     load=dload*100;
00061     snprintf(buf,sizeof(buf),"%d",load);
00062     setvar("wims_server_load",buf);
00063        /* cut cpu allowance to 3/4 or half if load is high.
00064         * But alarm time is not changed */
00065     if(load*3>=threshold1*2) {
00066        struct rlimit rlim;
00067        rlimit_cpu=(3*rlimit_cpu+1)/4;
00068        if(load>=threshold1) rlimit_cpu=(3*rlimit_cpu+1)/4;
00069        rlim.rlim_cur=rlim.rlim_max=rlimit_cpu;
00070        setrlimit(RLIMIT_CPU,&rlim);
00071     }
00072     if((th==0 && load*2>threshold1) ||
00073        (th==1 && load>threshold1) || (th==2 && load>threshold2)) {
00074        refuse:
00075        if(new_session && *session_prefix!=0) {
00076            remove_tree(session_prefix); remove_tree(s2_prefix);
00077        }
00078        refuse_log(th);      user_error("threshold");
00079     }
00080     repcheck:
00081     if(robot_access) return;
00082     if(new_session && *session_prefix!=0 && *remote_addr
00083        && hostcquota && strcmp(remote_addr,"127.0.0.1")!=0
00084        && !ispriority) {
00085            /* overload: */
00086        remove_tree(session_prefix); remove_tree(s2_prefix);
00087        user_error("overload");
00088     }
00089 }
00090 
00091        /* User authentification routine, obsolete */
00092 void auth(void)
00093 {
00094     check_load(1); return;
00095 }
00096 
00097 #define rafinfono 10
00098 
00099        /* check rapidfire information */
00100 void checkrafale(void)
00101 {
00102     char *p, *p1, *p2, *sh, *u;
00103     char rbuf[MAX_LINELEN+1];
00104     time_t rr, rafinfo[rafinfono];
00105     int i, t, mm, rafinfocnt;
00106     double coef=0.23;
00107 
00108     if(rafalvl<=0) return;
00109     p=getvar("module_scoring"); if(p==NULL || strcasecmp(p,"yes")!=0) return;
00110     u=getvar("wims_user"); if(u!=NULL && strcmp(u,"supervisor")==0) return;
00111     p=getvar("wims_developer"); if(p!=NULL && *p!=0) return;
00112     p=getenv("REMOTE_ADDR");if(p!=NULL && strcmp(p,"127.0.0.1")==0) return;
00113     p=getvar("session"); if(p!=NULL && strstr(p,"_exam")!=NULL) return;
00114     sh=getvar("wims_sheet"); if(sh!=NULL && *sh>'0') coef*=3;
00115     p=getvar("wims_rafale"); if(p==NULL) p="";
00116     mm=0;
00117     for(p1=find_word_start(p),i=0;i<rafinfono && *p1;p1=find_word_start(p2)) {
00118        p2=find_word_end(p1); if(*p2) *p2++=0;
00119        rr=atol(p1); if(rr<=0 || rr>nowtime) continue;
00120        t=coef*rafalvl*pow(i,1+rafalvl*0.05)-(nowtime-rr); if(t>mm) mm=t;
00121        rafinfo[i++]=rr;
00122     }
00123     if(mm>0) {
00124        if(u!=NULL && *u!=0) user_log("rafale");
00125        user_error("rafale");
00126     }
00127     rafinfocnt=i;
00128     snprintf(rbuf,sizeof(rbuf),"%lu",nowtime);
00129     for(i=0;i<rafinfocnt;i++) {
00130        snprintf(rbuf+strlen(rbuf),sizeof(rbuf)-strlen(rbuf),
00131                " %lu",rafinfo[i]);
00132     }
00133     force_setvar("wims_rafale",rbuf);
00134 }
00135 
00136        /* when score is got: erase 2 rafale information. */
00137 void lessrafale(void)
00138 {
00139     char *p;
00140     double s;
00141     int i;
00142     p=getvar("module_score"); if(p==NULL) return;
00143     s=atof(p); if(s<3) return;
00144     p=getvar("wims_rafale"); if(p==NULL || *p==0) return;
00145     for(i=0;i<2;i++) p=find_word_end(find_word_start(p));
00146     p=find_word_start(p);
00147     force_setvar("wims_rafale",p);
00148 }
00149 
00150 #define ac_class 0x1 /* class access */
00151 #define ac_exo   0x2 /* access to exercises */
00152 #define ac_tool  0x4 /* access to tools */
00153 #define ac_recre 0x8 /* access to recreations */
00154 #define ac_doc        0x10  /* access to documents */
00155 #define ac_local 0x20       /* access to local modules */
00156 #define ac_com   0x40       /* access to commercial modules */
00157 #define ac_hint  0x80   /* hint command */
00158 #define ac_sheet 0x100  /* use within a worksheet */
00159 #define ac_exam  0x200  /* work during an exam */
00160 
00161        /* Check site's access policy. */
00162 void access_check(int isclass)
00163 {
00164     char *p, *p1, *p2, *p3, *pp1, *pp2;
00165     char cbuf[MAX_LINELEN+1];
00166     long int thisaccess, lineaccess, linepol, thispol;
00167     int non, refuse;
00168     
00169     if(manageable>=2 || robot_access) return;
00170     thisaccess=0;
00171     p=getvar(ro_name[ro_module]); if(p==NULL || *p==0) return;
00172     if(strncmp(p,"adm/doc",7)==0) thisaccess|=ac_doc;
00173     else if(strncmp(p,"adm/",4)==0 || strcmp(p,home_module)==0) return;
00174     if(strncmp(p,"local/",6)==0) thisaccess|=ac_local;
00175     if(strncmp(p,"com/",4)==0) thisaccess|=ac_com;
00176     p=getvar("wims_user");
00177     if(p!=NULL && *p!=0) {
00178        if(!isclass && strcmp(p,"supervisor")!=0) access_check(1); 
00179        thisaccess|=ac_class;
00180     }
00181     if(isclass) {
00182        if(class_dir[0]==0) return;
00183        accessfile(cbuf,"r","%s/access.conf",class_dir);
00184     }
00185     else accessfile(cbuf,"r",ACCESS_CONF);
00186     if(cbuf[0]==0) return;
00187     if(cmd_type==cmd_hint) thisaccess|=ac_hint;
00188     p1=getvar("wims_accessright"); if(p1!=NULL && *p1!=0) {
00189        p=getvar(ro_name[ro_module]);
00190        for(p1=find_word_start(p1);*p1; p1=find_word_start(p2)) {
00191            p2=find_word_end(p1);
00192            if(strncmp(p,p1,p2-p1)==0) return;
00193        }
00194     }
00195     p=getvar("module_category"); if(p) {
00196        if(strstr(p,"exercise")!=NULL) thisaccess|=ac_exo;
00197        if(strstr(p,"tool")!=NULL) thisaccess|=ac_tool;
00198        if(strstr(p,"recre")!=NULL) thisaccess|=ac_recre;
00199        if(strstr(p,"doc")!=NULL) thisaccess|=ac_doc;
00200     }
00201     for(p1=find_word_start(cbuf);*p1;p1=find_word_start(p2)) {
00202        p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1);
00203        if(!myisalpha(*p1)) continue;
00204        p3=strchr(p1,':'); if(p3==NULL) continue;
00205        *p3++=0; p3=find_word_start(p3); strip_trailing_spaces(p3);
00206        refuse=0; if(*p3=='!') {
00207            p3=find_word_start(p3+1); refuse=1;
00208        }
00209        if(*p3 && checkhostt(p3)==0) continue;
00210        for(p=p1; *p; p++) {
00211            if(myisalpha(*p)) *p=tolower(*p);
00212            else *p=' ';
00213        }
00214        lineaccess=thisaccess; linepol=0;
00215        for(pp1=find_word_start(p1); *pp1; pp1=find_word_start(pp2)) {
00216            pp2=find_word_end(pp1); if(*pp2) *pp2++=0;
00217            if(strncmp(pp1,"non",3)==0) {
00218               pp1=find_word_start(pp1+3); non=1;
00219            }
00220            else non=0;
00221            thispol=0;
00222            if(strcmp(pp1,"class")==0) {thispol=ac_class; goto nxt;}
00223            if(strcmp(pp1,"exo")==0) {thispol=ac_exo; goto nxt;}
00224            if(strcmp(pp1,"exercise")==0) {thispol=ac_exo; goto nxt;}
00225            if(strcmp(pp1,"tool")==0) {thispol=ac_tool; goto nxt;}
00226            if(strcmp(pp1,"recre")==0) {thispol=ac_recre; goto nxt;}
00227            if(strcmp(pp1,"recreation")==0) {thispol=ac_recre; goto nxt;}
00228            if(strcmp(pp1,"doc")==0) {thispol=ac_doc; goto nxt;}
00229            if(strcmp(pp1,"document")==0) {thispol=ac_doc; goto nxt;}
00230            if(strcmp(pp1,"local")==0) {thispol=ac_local; goto nxt;}
00231            if(strcmp(pp1,"com")==0) {thispol=ac_com; goto nxt;}
00232            if(strcmp(pp1,"hint")==0) {thispol=ac_hint; goto nxt;}
00233            nxt:
00234            if(thispol==0) continue;
00235            if(non) lineaccess^=thispol;
00236            linepol|=thispol;
00237        }
00238        if(linepol==0 || (linepol&lineaccess)!=linepol) continue;
00239        if(refuse) user_error("no_access");
00240        else return;
00241     }
00242 }
00243