Subversion Repositories wimsdev

Rev

Rev 15874 | Rev 17879 | 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 && (!isfinite(dload) || dload>1000 || dload<0 || dload*200>threshold1))
  52.     goto refuse;
  53.   if(!isfinite(dload) || dload<=0 || dload>1000) goto repcheck; /* unreasonable */
  54.   /* very small 1 min load average */
  55.   if(dload*200<threshold1) goto repcheck;
  56.   if(dload*50>threshold2) goto refuse;
  57.   p1=find_word_start(p2+1); /* go to second average: 5 min. */
  58.   *find_word_end(p1)=0;
  59.   dload=atof(p1);
  60.   if(!isfinite(dload) || dload<=0 || dload>1000) goto repcheck; /* unreasonable */
  61.   load=dload*100;
  62.   snprintf(buf,sizeof(buf),"%d",load);
  63.   setvar("wims_server_load",buf);
  64.   /* cut cpu allowance to 3/4 or half if load is high.
  65.    * But alarm time is not changed */
  66.   if(load*3>=threshold1*2) {
  67.     struct rlimit rlim;
  68.     rlimit_cpu=(3*rlimit_cpu+1)/4;
  69.     if(load>=threshold1) rlimit_cpu=(3*rlimit_cpu+1)/4;
  70.     rlim.rlim_cur=rlim.rlim_max=rlimit_cpu;
  71.     setrlimit(RLIMIT_CPU,&rlim);
  72.   }
  73.   if((th==0 && load*2>threshold1) ||
  74.      (th==1 && load>threshold1) || (th==2 && load>threshold2)) {
  75.     refuse:
  76.   if(new_session && *session_prefix!=0) {
  77.       remove_tree(session_prefix); remove_tree(s2_prefix);
  78.     }
  79.     refuse_log(th); user_error("threshold");
  80.   }
  81.   repcheck:
  82.   if(robot_access) return;
  83.   if(new_session && *session_prefix!=0 && *remote_addr
  84.      && hostcquota && strcmp(remote_addr,"127.0.0.1")!=0
  85.      && !ispriority) {
  86.     /* overload: */
  87.     remove_tree(session_prefix); remove_tree(s2_prefix);
  88.     user_error("overload");
  89.   }
  90. }
  91.  
  92. /* User authentification routine, obsolete */
  93. void auth(void)
  94. {
  95.   check_load(1); return;
  96. }
  97.  
  98. #define rafinfono 10
  99.  
  100. /* check rapidfire information */
  101. void checkrafale(void)
  102. {
  103.   char *p, *p1, *p2, *sh, *u;
  104.   char rbuf[MAX_LINELEN+1];
  105.   time_t rr, rafinfo[rafinfono];
  106.   int i, t, mm, rafinfocnt;
  107.   double coef=0.23;
  108.  
  109.   if(rafalvl<=0) return;
  110.   p=getvar("module_scoring"); if(p==NULL || strcasecmp(p,"yes")!=0) return;
  111.   u=getvar("wims_user"); if(u!=NULL && strcmp(u,"supervisor")==0) return;
  112.   p=getvar("wims_developer"); if(p!=NULL && *p!=0) return;
  113.   p=getenv("REMOTE_ADDR");if(p!=NULL && strcmp(p,"127.0.0.1")==0) return;
  114.   p=getvar("session"); if(p!=NULL && strstr(p,"_exam")!=NULL) return;
  115.   sh=getvar("wims_sheet"); if(sh!=NULL && *sh>'0') coef*=3;
  116.   p=getvar("wims_rafale"); if(p==NULL) p="";
  117.   mm=0;
  118.   for(p1=find_word_start(p),i=0;i<rafinfono && *p1;p1=find_word_start(p2)) {
  119.    p2=find_word_end(p1); if(*p2) *p2++=0;
  120.    rr=atol(p1); if(rr<=0 || rr>nowtime) continue;
  121.    t=coef*rafalvl*pow(i,1+rafalvl*0.05)-(nowtime-rr); if(t>mm) mm=t;
  122.    rafinfo[i++]=rr;
  123.   }
  124.   if(mm>0) {
  125.     if(u!=NULL && *u!=0) user_log("rafale");
  126.     user_error("rafale");
  127.   }
  128.   rafinfocnt=i;
  129.   snprintf(rbuf,sizeof(rbuf),"%lu",nowtime);
  130.   for(i=0;i<rafinfocnt;i++) {
  131.     snprintf(rbuf+strlen(rbuf),sizeof(rbuf)-strlen(rbuf),
  132.          " %lu",rafinfo[i]);
  133.   }
  134.   force_setvar("wims_rafale",rbuf);
  135. }
  136.  
  137. /* when score is got: erase 2 rafale information. */
  138. void lessrafale(void)
  139. {
  140.   char *p;
  141.   double s;
  142.   int i;
  143.   p=getvar("module_score"); if(p==NULL) return;
  144.   s=atof(p); if(s<3) return;
  145.   p=getvar("wims_rafale"); if(p==NULL || *p==0) return;
  146.   for(i=0;i<2;i++) p=find_word_end(find_word_start(p));
  147.   p=find_word_start(p);
  148.   force_setvar("wims_rafale",p);
  149. }
  150.  
  151. #define ac_class 0x1  /* class access */
  152. #define ac_exo   0x2  /* access to exercises */
  153. #define ac_tool  0x4  /* access to tools */
  154. #define ac_recre 0x8  /* access to recreations */
  155. #define ac_doc  0x10  /* access to documents */
  156. #define ac_local 0x20 /* access to local modules */
  157. #define ac_com   0x40 /* access to commercial modules */
  158. #define ac_hint  0x80 /* hint command */
  159. #define ac_sheet 0x100/* use within a worksheet */
  160. #define ac_exam  0x200/* work during an exam */
  161.  
  162. /* Check site or class access policy. */
  163. void access_check(int isclass)
  164. {
  165.   char *p, *p1, *p2, *p3, *pp1, *pp2;
  166.   char msg[200], *name="";
  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.   /* access limited */
  190.   if(cmd_type==cmd_hint) thisaccess|=ac_hint;
  191.   p1=getvar("wims_accessright"); if(p1!=NULL && *p1!=0) {
  192.     p=getvar(ro_name[ro_module]);
  193.     for(p1=find_word_start(p1);*p1; p1=find_word_start(p2)) {
  194.       p2=find_word_end(p1);
  195.       if(strncmp(p,p1,p2-p1)==0) return;
  196.     }
  197.   }
  198.   p=getvar("module_category");
  199.   if(p) {
  200.     if(strstr(p,"exercise")!=NULL) thisaccess|=ac_exo;
  201.     if(strstr(p,"tool")!=NULL) thisaccess|=ac_tool;
  202.     if(strstr(p,"recre")!=NULL) thisaccess|=ac_recre;
  203.     if(strstr(p,"doc")!=NULL) thisaccess|=ac_doc;
  204.   }
  205.   for(p1=find_word_start(cbuf);*p1;p1=find_word_start(p2)) {
  206.     p2=strchr(p1,'\n'); if(p2) *p2++=0; else p2=p1+strlen(p1);
  207.     if(!myisalpha(*p1)) continue;
  208.     p3=strchr(p1,':'); if(p3==NULL) continue;
  209.     *p3++=0; p3=find_word_start(p3); strip_trailing_spaces(p3);
  210.     refuse=0;
  211.     if(*p3=='!') { p3=find_word_start(p3+1); refuse=1;}
  212.     if(*p3 && checkhostt(p3)==0) continue;
  213.     for(p=p1; *p; p++) {
  214.       if(myisalpha(*p)) *p=tolower(*p); 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.       }  else non=0;
  222.       thispol=0;
  223.       if(strcmp(pp1,"class")==0) {thispol=ac_class; name="class"; goto nxt;}
  224.       if(strcmp(pp1,"exo")==0) {thispol=ac_exo; name="exo"; goto nxt;}
  225.       if(strcmp(pp1,"exercise")==0) {thispol=ac_exo; name="exo"; goto nxt;}
  226.       if(strcmp(pp1,"tool")==0) {thispol=ac_tool; name="tool"; goto nxt;}
  227.       if(strcmp(pp1,"recre")==0) {thispol=ac_recre; name="recre"; goto nxt;}
  228.       if(strcmp(pp1,"recreation")==0) {thispol=ac_recre; name="recre"; goto nxt;}
  229.       if(strcmp(pp1,"doc")==0) {thispol=ac_doc; name="doc"; goto nxt;}
  230.       if(strcmp(pp1,"document")==0) {thispol=ac_doc; name="doc"; goto nxt;}
  231.       if(strcmp(pp1,"local")==0) {thispol=ac_local; name="local"; goto nxt;}
  232.       if(strcmp(pp1,"com")==0) {thispol=ac_com; name="com"; goto nxt;}
  233.       if(strcmp(pp1,"hint")==0) {thispol=ac_hint; name="hint"; goto nxt;}
  234.       nxt:
  235.       if(thispol==0) continue;
  236.       if(non) lineaccess^=thispol;
  237.       linepol|=thispol;
  238.     }
  239.     if(linepol==0 || (linepol&lineaccess)!=linepol) continue;
  240.     snprintf(msg,200,"no_access_class %s",name);
  241.     if(refuse)
  242.       if (isclass) user_error(msg); else user_error("no_access");
  243.     else return;
  244.   }
  245.   /* end of limited access */
  246. }
  247.