Subversion Repositories wimsdev

Rev

Rev 10 | Rev 8171 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*    Copyright (C) 1998-2003 XIAO, Gang of Universite de Nice - Sophia Antipolis
  2.  *
  3.  *  This program is free software; you can redistribute it and/or modify
  4.  *  it under the terms of the GNU General Public License as published by
  5.  *  the Free Software Foundation; either version 2 of the License, or
  6.  *  (at your option) any later version.
  7.  *
  8.  *  This program is distributed in the hope that it will be useful,
  9.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.  *  GNU General Public License for more details.
  12.  *
  13.  *  You should have received a copy of the GNU General Public License
  14.  *  along with this program; if not, write to the Free Software
  15.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16.  */
  17.  
  18. /* This file contains user authentification routines */
  19.  
  20. void refuse_log(int th);
  21. void set_module_prefix(void);
  22.  
  23. /* check machine load. 2-threshold system.
  24.  * Threshold 1: anonymous new session refused.
  25.  * Threshold 2: New session and anonymous request refused. */
  26. void check_load(int th)
  27. {
  28.     int load, pload;
  29.     char *p1, *p2, buf[64];
  30.     char *pp;
  31.     double dload;
  32.  
  33.     pload=0; pp=strchr(loadavg,'/'); if(pp) {
  34.      for(;pp>loadavg && isdigit(pp[-1]); pp--);
  35.      pload=atoi(pp);
  36.      if(pload*12>threshold2+3) {
  37.          pload_refuse:
  38.          refuse_log(pload+100); user_error("threshold");
  39.      }
  40.     }
  41.     if(ispriority) goto repcheck; /* priority connections will not be refused. */
  42.     if(pload*20>threshold1+2) goto pload_refuse;
  43.     if(th<0 || th>2) goto repcheck;
  44. /* Operating system load average facility */
  45.     if(robot_access && loadavg[0]==0) goto refuse;
  46.     if(loadavg[0]==0) goto repcheck;
  47.     p1=find_word_start(loadavg); p2=find_word_end(p1);*p2=0;
  48.     dload=atof(p1);
  49.     if(robot_access &&
  50.        (!finite(dload) || dload>1000 || dload<0 || dload*200>threshold1))
  51.       goto refuse;
  52.     if(!finite(dload) || dload<=0 || dload>1000) goto repcheck; /* unreasonable */
  53. /* very small 1 min load average */
  54.     if(dload*200<threshold1) goto repcheck;
  55.     if(dload*50>threshold2) goto refuse;
  56.     p1=find_word_start(p2+1); /* go to second average: 5 min. */
  57.     *find_word_end(p1)=0;
  58.     dload=atof(p1);
  59.     if(!finite(dload) || dload<=0 || dload>1000) goto repcheck; /* unreasonable */
  60.     load=dload*100;
  61.     snprintf(buf,sizeof(buf),"%d",load);
  62.     setvar("wims_server_load",buf);
  63. /* cut cpu allowance to 3/4 or half if load is high.
  64.  * But alarm time is not changed */
  65.     if(load*3>=threshold1*2) {
  66.      struct rlimit rlim;
  67.      rlimit_cpu=(3*rlimit_cpu+1)/4;
  68.      if(load>=threshold1) rlimit_cpu=(3*rlimit_cpu+1)/4;
  69.      rlim.rlim_cur=rlim.rlim_max=rlimit_cpu;
  70.      setrlimit(RLIMIT_CPU,&rlim);
  71.     }
  72.     if((th==0 && load*2>threshold1) ||
  73.        (th==1 && load>threshold1) || (th==2 && load>threshold2)) {
  74.      refuse:
  75.      if(new_session && *session_prefix!=0) {
  76.          remove_tree(session_prefix); remove_tree(s2_prefix);
  77.      }
  78.      refuse_log(th); user_error("threshold");
  79.     }
  80.     repcheck:
  81.     if(robot_access) return;
  82.     if(new_session && *session_prefix!=0 && *remote_addr
  83.        && hostcquota && strcmp(remote_addr,"127.0.0.1")!=0
  84.        && !ispriority) {
  85. /* overload: */
  86.      remove_tree(session_prefix); remove_tree(s2_prefix);
  87.      user_error("overload");
  88.     }
  89. }
  90.  
  91. /* User authentification routine, obsolete */
  92. void auth(void)
  93. {
  94.     check_load(1); return;
  95. }
  96.  
  97. #define rafinfono 10
  98.  
  99. /* check rapidfire information */
  100. void checkrafale(void)
  101. {
  102.     char *p, *p1, *p2, *sh, *u;
  103.     char rbuf[MAX_LINELEN+1];
  104.     time_t rr, rafinfo[rafinfono];
  105.     int i, t, mm, rafinfocnt;
  106.     double coef=0.23;
  107.  
  108.     if(rafalvl<=0) return;
  109.     p=getvar("module_scoring"); if(p==NULL || strcasecmp(p,"yes")!=0) return;
  110.     u=getvar("wims_user"); if(u!=NULL && strcmp(u,"supervisor")==0) return;
  111.     p=getvar("wims_developer"); if(p!=NULL && *p!=0) return;
  112.     p=getenv("REMOTE_ADDR");if(p!=NULL && strcmp(p,"127.0.0.1")==0) return;
  113.     p=getvar("session"); if(p!=NULL && strstr(p,"_exam")!=NULL) return;
  114.     sh=getvar("wims_sheet"); if(sh!=NULL && *sh>'0') coef*=3;
  115.     p=getvar("wims_rafale"); if(p==NULL) p="";
  116.     mm=0;
  117.     for(p1=find_word_start(p),i=0;i<rafinfono && *p1;p1=find_word_start(p2)) {
  118.      p2=find_word_end(p1); if(*p2) *p2++=0;
  119.      rr=atol(p1); if(rr<=0 || rr>nowtime) continue;
  120.      t=coef*rafalvl*pow(i,1+rafalvl*0.05)-(nowtime-rr); if(t>mm) mm=t;
  121.      rafinfo[i++]=rr;
  122.     }
  123.     if(mm>0) {
  124.      if(u!=NULL && *u!=0) user_log("rafale");
  125.      user_error("rafale");
  126.     }
  127.     rafinfocnt=i;
  128.     snprintf(rbuf,sizeof(rbuf),"%lu",nowtime);
  129.     for(i=0;i<rafinfocnt;i++) {
  130.      snprintf(rbuf+strlen(rbuf),sizeof(rbuf)-strlen(rbuf),
  131.            " %lu",rafinfo[i]);
  132.     }
  133.     force_setvar("wims_rafale",rbuf);
  134. }
  135.  
  136. /* when score is got: erase 2 rafale information. */
  137. void lessrafale(void)
  138. {
  139.     char *p;
  140.     double s;
  141.     int i;
  142.     p=getvar("module_score"); if(p==NULL) return;
  143.     s=atof(p); if(s<3) return;
  144.     p=getvar("wims_rafale"); if(p==NULL || *p==0) return;
  145.     for(i=0;i<2;i++) p=find_word_end(find_word_start(p));
  146.     p=find_word_start(p);
  147.     force_setvar("wims_rafale",p);
  148. }
  149.  
  150. #define ac_class 0x1 /* class access */
  151. #define ac_exo   0x2 /* access to exercises */
  152. #define ac_tool  0x4 /* access to tools */
  153. #define ac_recre 0x8 /* access to recreations */
  154. #define ac_doc  0x10 /* access to documents */
  155. #define ac_local 0x20 /* access to local modules */
  156. #define ac_com   0x40 /* access to commercial modules */
  157. #define ac_hint  0x80   /* hint command */
  158. #define ac_sheet 0x100  /* use within a worksheet */
  159. #define ac_exam  0x200  /* work during an exam */
  160.  
  161. /* Check site's access policy. */
  162. void access_check(int isclass)
  163. {
  164.     char *p, *p1, *p2, *p3, *pp1, *pp2;
  165.     char cbuf[MAX_LINELEN+1];
  166.     long int thisaccess, lineaccess, linepol, thispol;
  167.     int non, refuse;
  168.  
  169.     if(manageable>=2 || robot_access) return;
  170.     thisaccess=0;
  171.     p=getvar(ro_name[ro_module]); if(p==NULL || *p==0) return;
  172.     if(strncmp(p,"adm/doc",7)==0) thisaccess|=ac_doc;
  173.     else if(strncmp(p,"adm/",4)==0 || strcmp(p,home_module)==0) return;
  174.     if(strncmp(p,"local/",6)==0) thisaccess|=ac_local;
  175.     if(strncmp(p,"com/",4)==0) thisaccess|=ac_com;
  176.     p=getvar("wims_user");
  177.     if(p!=NULL && *p!=0) {
  178.      if(!isclass && strcmp(p,"supervisor")!=0) access_check(1);
  179.      thisaccess|=ac_class;
  180.     }
  181.     if(isclass) {
  182.      if(class_dir[0]==0) return;
  183.      accessfile(cbuf,"r","%s/access.conf",class_dir);
  184.     }
  185.     else accessfile(cbuf,"r",ACCESS_CONF);
  186.     if(cbuf[0]==0) return;
  187.     if(cmd_type==cmd_hint) thisaccess|=ac_hint;
  188.     p1=getvar("wims_accessright"); if(p1!=NULL && *p1!=0) {
  189.      p=getvar(ro_name[ro_module]);
  190.      for(p1=find_word_start(p1);*p1; p1=find_word_start(p2)) {
  191.          p2=find_word_end(p1);
  192.          if(strncmp(p,p1,p2-p1)==0) return;
  193.      }
  194.     }
  195.     p=getvar("module_category"); if(p) {
  196.      if(strstr(p,"exercise")!=NULL) thisaccess|=ac_exo;
  197.      if(strstr(p,"tool")!=NULL) thisaccess|=ac_tool;
  198.      if(strstr(p,"recre")!=NULL) thisaccess|=ac_recre;
  199.      if(strstr(p,"doc")!=NULL) thisaccess|=ac_doc;
  200.     }
  201.     for(p1=find_word_start(cbuf);*p1;p1=find_word_start(p2)) {
  202.      p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1);
  203.      if(!myisalpha(*p1)) continue;
  204.      p3=strchr(p1,':'); if(p3==NULL) continue;
  205.      *p3++=0; p3=find_word_start(p3); strip_trailing_spaces(p3);
  206.      refuse=0; if(*p3=='!') {
  207.          p3=find_word_start(p3+1); refuse=1;
  208.      }
  209.      if(*p3 && checkhostt(p3)==0) continue;
  210.      for(p=p1; *p; p++) {
  211.          if(myisalpha(*p)) *p=tolower(*p);
  212.          else *p=' ';
  213.      }
  214.      lineaccess=thisaccess; linepol=0;
  215.      for(pp1=find_word_start(p1); *pp1; pp1=find_word_start(pp2)) {
  216.          pp2=find_word_end(pp1); if(*pp2) *pp2++=0;
  217.          if(strncmp(pp1,"non",3)==0) {
  218.           pp1=find_word_start(pp1+3); non=1;
  219.          }
  220.          else non=0;
  221.          thispol=0;
  222.          if(strcmp(pp1,"class")==0) {thispol=ac_class; goto nxt;}
  223.          if(strcmp(pp1,"exo")==0) {thispol=ac_exo; goto nxt;}
  224.          if(strcmp(pp1,"exercise")==0) {thispol=ac_exo; goto nxt;}
  225.          if(strcmp(pp1,"tool")==0) {thispol=ac_tool; goto nxt;}
  226.          if(strcmp(pp1,"recre")==0) {thispol=ac_recre; goto nxt;}
  227.          if(strcmp(pp1,"recreation")==0) {thispol=ac_recre; goto nxt;}
  228.          if(strcmp(pp1,"doc")==0) {thispol=ac_doc; goto nxt;}
  229.          if(strcmp(pp1,"document")==0) {thispol=ac_doc; goto nxt;}
  230.          if(strcmp(pp1,"local")==0) {thispol=ac_local; goto nxt;}
  231.          if(strcmp(pp1,"com")==0) {thispol=ac_com; goto nxt;}
  232.          if(strcmp(pp1,"hint")==0) {thispol=ac_hint; goto nxt;}
  233.          nxt:
  234.          if(thispol==0) continue;
  235.          if(non) lineaccess^=thispol;
  236.          linepol|=thispol;
  237.      }
  238.      if(linepol==0 || (linepol&lineaccess)!=linepol) continue;
  239.      if(refuse) user_error("no_access");
  240.      else return;
  241.     }
  242. }
  243.  
  244.