Rev 10 | Rev 8155 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
10 | reyssat | 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 | |||
7673 | bpr | 18 | /* This file contains user authentification routines */ |
10 | reyssat | 19 | |
20 | void refuse_log(int th); |
||
21 | void set_module_prefix(void); |
||
22 | |||
7673 | bpr | 23 | /* check machine load. 2-threshold system. |
24 | * Threshold 1: anonymous new session refused. |
||
25 | * Threshold 2: New session and anonymous request refused. */ |
||
10 | reyssat | 26 | void check_load(int th) |
27 | { |
||
28 | int load, pload; |
||
29 | char *p1, *p2, buf[64]; |
||
30 | char *pp; |
||
31 | double dload; |
||
7673 | bpr | 32 | |
10 | reyssat | 33 | pload=0; pp=strchr(loadavg,'/'); if(pp) { |
7673 | bpr | 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 | } |
||
10 | reyssat | 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; |
||
7673 | bpr | 44 | /* Operating system load average facility */ |
10 | reyssat | 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); |
||
7673 | bpr | 49 | if(robot_access && |
10 | reyssat | 50 | (!finite(dload) || dload>1000 || dload<0 || dload*200>threshold1)) |
51 | goto refuse; |
||
52 | if(!finite(dload) || dload<=0 || dload>1000) goto repcheck; /* unreasonable */ |
||
7673 | bpr | 53 | /* very small 1 min load average */ |
10 | reyssat | 54 | if(dload*200<threshold1) goto repcheck; |
55 | if(dload*50>threshold2) goto refuse; |
||
7673 | bpr | 56 | p1=find_word_start(p2+1); /* go to second average: 5 min. */ |
10 | reyssat | 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); |
||
7673 | bpr | 63 | /* cut cpu allowance to 3/4 or half if load is high. |
64 | * But alarm time is not changed */ |
||
10 | reyssat | 65 | if(load*3>=threshold1*2) { |
7673 | bpr | 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); |
||
10 | reyssat | 71 | } |
72 | if((th==0 && load*2>threshold1) || |
||
73 | (th==1 && load>threshold1) || (th==2 && load>threshold2)) { |
||
7673 | bpr | 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"); |
||
10 | reyssat | 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) { |
||
7673 | bpr | 85 | /* overload: */ |
86 | remove_tree(session_prefix); remove_tree(s2_prefix); |
||
87 | user_error("overload"); |
||
10 | reyssat | 88 | } |
89 | } |
||
90 | |||
7673 | bpr | 91 | /* User authentification routine, obsolete */ |
10 | reyssat | 92 | void auth(void) |
93 | { |
||
94 | check_load(1); return; |
||
95 | } |
||
96 | |||
97 | #define rafinfono 10 |
||
98 | |||
7673 | bpr | 99 | /* check rapidfire information */ |
10 | reyssat | 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)) { |
||
7673 | bpr | 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; |
||
10 | reyssat | 122 | } |
123 | if(mm>0) { |
||
7673 | bpr | 124 | if(u!=NULL && *u!=0) user_log("rafale"); |
125 | user_error("rafale"); |
||
10 | reyssat | 126 | } |
127 | rafinfocnt=i; |
||
128 | snprintf(rbuf,sizeof(rbuf),"%lu",nowtime); |
||
129 | for(i=0;i<rafinfocnt;i++) { |
||
7673 | bpr | 130 | snprintf(rbuf+strlen(rbuf),sizeof(rbuf)-strlen(rbuf), |
131 | " %lu",rafinfo[i]); |
||
10 | reyssat | 132 | } |
133 | force_setvar("wims_rafale",rbuf); |
||
134 | } |
||
135 | |||
7673 | bpr | 136 | /* when score is got: erase 2 rafale information. */ |
10 | reyssat | 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 | |||
7673 | bpr | 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 */ |
||
10 | reyssat | 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 | |||
7673 | bpr | 161 | /* Check site's access policy. */ |
10 | reyssat | 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; |
||
7673 | bpr | 168 | |
10 | reyssat | 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) { |
||
7673 | bpr | 178 | if(!isclass && strcmp(p,"supervisor")!=0) access_check(1); |
179 | thisaccess|=ac_class; |
||
10 | reyssat | 180 | } |
181 | if(isclass) { |
||
7673 | bpr | 182 | if(class_dir[0]==0) return; |
183 | accessfile(cbuf,"r","%s/access.conf",class_dir); |
||
10 | reyssat | 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) { |
||
7673 | bpr | 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 | } |
||
10 | reyssat | 194 | } |
195 | p=getvar("module_category"); if(p) { |
||
7673 | bpr | 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; |
||
10 | reyssat | 200 | } |
201 | for(p1=find_word_start(cbuf);*p1;p1=find_word_start(p2)) { |
||
7673 | bpr | 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; |
||
10 | reyssat | 241 | } |
242 | } |
||
243 |