Subversion Repositories wimsdev

Rev

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