Subversion Repositories wimsdev

Rev

Rev 11539 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11539 Rev 12248
Line 49... Line 49...
49
int execgid=15999;
49
int execgid=15999;
50
int must=0;
50
int must=0;
51
time_t now;
51
time_t now;
52
 
52
 
53
char *env_rm[]={
53
char *env_rm[]={
54
    "s2_dir", "w_wims_home", "session_base_dir", "trusted_module",
54
  "s2_dir", "w_wims_home", "session_base_dir", "trusted_module",
55
      "session_dir", "wims_server_base", "w_httpd_PWD",
55
    "session_dir", "wims_server_base", "w_httpd_PWD",
56
      "w_wims_sesdir", "HTTP_CONNECTION",
56
    "w_wims_sesdir", "HTTP_CONNECTION",
57
      "w_gnuplot_format", "w_insplot_font", "w_ins_anim_limit",
57
    "w_gnuplot_format", "w_insplot_font", "w_ins_anim_limit",
58
      "w_ins_density", "w_ins_format",
58
    "w_ins_density", "w_ins_format",
59
      "texgif_fontdir", "texgif_texheader",
59
    "texgif_fontdir", "texgif_texheader",
60
      "w_wims_tmp_debug", "w_insmath_logic", "w_insmath_rawmath",
60
    "w_wims_tmp_debug", "w_insmath_logic", "w_insmath_rawmath",
61
      "SERVER_ADMIN", "SERVER_ADDR", "SERVER_NAME"
61
    "SERVER_ADMIN", "SERVER_ADDR", "SERVER_NAME"
62
};
62
};
63
 
63
 
64
#define env_rm_cnt (sizeof(env_rm)/sizeof(env_rm[0]))
64
#define env_rm_cnt (sizeof(env_rm)/sizeof(env_rm[0]))
65
 
65
 
66
char name_sh[32]="/bin/ash.static";
66
char name_sh[32]="/bin/ash.static";
Line 80... Line 80...
80
 
80
 
81
 
81
 
82
/* Remove a tree */
82
/* Remove a tree */
83
int remove_tree(char *dirname)
83
int remove_tree(char *dirname)
84
{
84
{
85
    DIR *sdir;
85
  DIR *sdir;
86
    struct dirent *f;
86
  struct dirent *f;
87
    struct stat dst;
87
  struct stat dst;
88
 
88
 
89
    sdir=opendir(dirname);
89
  sdir=opendir(dirname);
90
    if(sdir==NULL) {   /* Cannot open session directory. */
90
  if(sdir==NULL) {   /* Cannot open session directory. */
91
       return -1;
91
     return -1;
92
    }
92
  }
93
    while((f=readdir(sdir))!=NULL) {
93
  while((f=readdir(sdir))!=NULL) {
94
        char fname[255];
94
    char fname[255];
95
        if(strcmp(".",f->d_name)==0 || strcmp("..",f->d_name)==0) continue;
95
    if(strcmp(".",f->d_name)==0 || strcmp("..",f->d_name)==0) continue;
96
        snprintf(fname,sizeof(fname),"%s/%s",dirname,f->d_name);
96
    snprintf(fname,sizeof(fname),"%s/%s",dirname,f->d_name);
97
        if(lstat(fname,&dst)) continue;
97
    if(lstat(fname,&dst)) continue;
98
        if(S_ISDIR(dst.st_mode)) remove_tree(fname);
98
    if(S_ISDIR(dst.st_mode)) remove_tree(fname);
99
        else {
99
    else {
100
            if(remove(fname)<0)
100
      if(remove(fname)<0)
101
              fprintf(stderr,"ch..root: unable to remove %s. %s\n",fname,strerror(errno));
101
        fprintf(stderr,"ch..root: unable to remove %s. %s\n",fname,strerror(errno));
102
        }
102
    }
103
    }
103
  }
104
    closedir(sdir);
104
  closedir(sdir);
105
    if(rmdir(dirname)<0) {  /* Cannot remove directory. */
105
  if(rmdir(dirname)<0) {  /* Cannot remove directory. */
106
       return -1;
106
     return -1;
107
    }
107
  }
108
    return 0;
108
  return 0;
109
}
109
}
110
 
110
 
111
/* Clean TMP */
111
/* Clean TMP */
112
void cleantmp(void)
112
void cleantmp(void)
113
{
113
{
114
    DIR *sdir_base;
114
  DIR *sdir_base;
115
    struct dirent *ses;
115
  struct dirent *ses;
116
    struct stat dst;
116
  struct stat dst;
117
 
117
 
118
    if(chdir("../chroot/tmp/sessions")<0) return;
118
  if(chdir("../chroot/tmp/sessions")<0) return;
119
    sdir_base=opendir(".");
119
  sdir_base=opendir(".");
120
    if(sdir_base==NULL) return;
120
  if(sdir_base==NULL) return;
121
    while((ses=readdir(sdir_base))!=NULL) {
121
  while((ses=readdir(sdir_base))!=NULL) {
122
        if(ses->d_name[0]=='.') continue;
122
    if(ses->d_name[0]=='.') continue;
123
        if(lstat(ses->d_name,&dst)) continue;
123
    if(lstat(ses->d_name,&dst)) continue;
124
        if(!S_ISDIR(dst.st_mode)) continue;
124
    if(!S_ISDIR(dst.st_mode)) continue;
125
        if(dst.st_mtime <= now) {
125
    if(dst.st_mtime <= now) {
126
            if(dst.st_mtime>=now-CLEAN_DELAY) continue;
126
        if(dst.st_mtime>=now-CLEAN_DELAY) continue;
127
            if(dst.st_mtime>=now-CLEAN_DELAY2 && (dst.st_mode&S_IRWXO)==0) continue;
127
        if(dst.st_mtime>=now-CLEAN_DELAY2 && (dst.st_mode&S_IRWXO)==0) continue;
128
        }
-
 
129
        remove_tree(ses->d_name);
-
 
130
    }
128
    }
-
 
129
    remove_tree(ses->d_name);
-
 
130
  }
131
}
131
}
132
 
132
 
133
/* Cleaning */
133
/* Cleaning */
134
void cleaning(void)
134
void cleaning(void)
135
{
135
{
136
    DIR *sdir_base;
136
  DIR *sdir_base;
137
    struct dirent *ses;
137
  struct dirent *ses;
138
    struct stat dst;
138
  struct stat dst;
139
    struct utimbuf ub;
139
  struct utimbuf ub;
140
    char dbuf[256];
140
  char dbuf[256];
141
 
141
 
142
    if(stat(timestamp,&dst)==0 && dst.st_mtime==now) return;
142
  if(stat(timestamp,&dst)==0 && dst.st_mtime==now) return;
143
    ub.actime=ub.modtime=now; utime(timestamp,&ub);
143
  ub.actime=ub.modtime=now; utime(timestamp,&ub);
144
    sdir_base=opendir("/proc");
144
  sdir_base=opendir("/proc");
145
    if(sdir_base==NULL) goto tmpdir;
145
  if(sdir_base==NULL) goto tmpdir;
146
    while((ses=readdir(sdir_base))!=NULL) {
146
  while((ses=readdir(sdir_base))!=NULL) {
147
        if(ses->d_name[0]<'0' || ses->d_name[9]>'9') continue;
147
    if(ses->d_name[0]<'0' || ses->d_name[9]>'9') continue;
148
        snprintf(dbuf,sizeof(dbuf),"/proc/%s",ses->d_name);
148
    snprintf(dbuf,sizeof(dbuf),"/proc/%s",ses->d_name);
149
        if(lstat(dbuf,&dst)) continue;
149
    if(lstat(dbuf,&dst)) continue;
150
        if(!S_ISDIR(dst.st_mode)) continue;
150
    if(!S_ISDIR(dst.st_mode)) continue;
151
        if(dst.st_uid<UID_MIN || dst.st_uid>UID_MIN+UID_MASK) continue;
151
    if(dst.st_uid<UID_MIN || dst.st_uid>UID_MIN+UID_MASK) continue;
152
        if(((dst.st_gid-UID_MIN-now)&TIME_MASK)<=CPU_MAX) continue;
152
    if(((dst.st_gid-UID_MIN-now)&TIME_MASK)<=CPU_MAX) continue;
153
        kill(atoi(ses->d_name),SIGKILL);
153
    kill(atoi(ses->d_name),SIGKILL);
154
    }
154
  }
155
    closedir(sdir_base);
155
  closedir(sdir_base);
156
    tmpdir: return;
156
  tmpdir: return;
157
}
157
}
158
 
158
 
159
/* Test Must */
159
/* Test Must */
160
int test_must(void)
160
int test_must(void)
161
{
161
{
162
    char *pc;
162
  char *pc;
163
    if(must) return 1;
163
  if(must) return 1;
164
    pc=getenv("chroot"); if(pc && strcmp(pc,"must")==0) return 1;
164
  pc=getenv("chroot"); if(pc && strcmp(pc,"must")==0) return 1;
165
    else return 0;
165
  else return 0;
166
}
166
}
167
 
167
 
168
/* MAIN */
168
/* MAIN */
169
int main(int argc,char *argv[])
169
int main(int argc,char *argv[])
170
{
170
{
171
    char *args[1024];
171
  char *args[1024];
172
    char parm[MAX_PARMLEN];
172
  char parm[MAX_PARMLEN];
173
    char tmpbuf[256];
173
  char tmpbuf[256];
174
    int i,k,uid,t;
174
  int i,k,uid,t;
175
    struct stat st;
175
  struct stat st;
176
    struct rlimit lim;
176
  struct rlimit lim;
177
    char *p, *pp;
177
  char *p, *pp;
178
 
178
 
179
    if(argc<2) return 0;
179
  if(argc<2) return 0;
180
    now=time(NULL);
180
  now=time(NULL);
181
    uid=geteuid();
181
  uid=geteuid();
182
    t=stat("../chroot/tmp/sessions/.chroot",&st);
182
  t=stat("../chroot/tmp/sessions/.chroot",&st);
183
    if(uid!=0 || t!=0) {
183
  if(uid!=0 || t!=0) {
184
        if(test_must()) goto abandon;
184
    if(test_must()) goto abandon;
185
        args[0]="bin/wrap..exec"; k=1;
185
    args[0]="bin/wrap..exec"; k=1;
186
    }
186
  }
187
    else {
187
  else {
188
        k=0;
188
    k=0;
189
        p=getenv("REMOTE_ADDR");
189
    p=getenv("REMOTE_ADDR");
190
        if(p && *p) {
190
    if(p && *p) {
191
            pp=strrchr(p,'.'); if(pp) execuid=(atoi(++pp)&UID_MASK)+UID_MIN;
191
      pp=strrchr(p,'.'); if(pp) execuid=(atoi(++pp)&UID_MASK)+UID_MIN;
192
        }
192
    }
193
        getrlimit(RLIMIT_CPU,&lim);
193
    getrlimit(RLIMIT_CPU,&lim);
194
        i=lim.rlim_max; if(i<0) i=0; if(i>=CPU_MAX) i=CPU_MAX-1;
194
    i=lim.rlim_max; if(i<0) i=0; if(i>=CPU_MAX) i=CPU_MAX-1;
195
        execgid=((i+now+1)&TIME_MASK)+UID_MIN;
195
    execgid=((i+now+1)&TIME_MASK)+UID_MIN;
196
        cleaning();
196
    cleaning();
197
    }
197
  }
198
    if(argc>1 && strcmp(argv[1],"cleantmpdir")==0) {
198
  if(argc>1 && strcmp(argv[1],"cleantmpdir")==0) {
199
        if(uid!=0) fprintf(stderr,"ch..root cleantmpdir: uid not changed.\n");
199
    if(uid!=0) fprintf(stderr,"ch..root cleantmpdir: uid not changed.\n");
200
        else cleantmp();
200
    else cleantmp();
201
        return 0;
201
    return 0;
202
    }
202
  }
203
    if(argc>3 && argv[1][0]=='&') {
203
  if(argc>3 && argv[1][0]=='&') {
204
        if(k) goto abandon;
204
    if(k) goto abandon;
205
        if(strcmp(argv[2],"sh")==0) {
205
    if(strcmp(argv[2],"sh")==0) {
206
            lim.rlim_cur=lim.rlim_max=MAX_OUTLEN;
206
      lim.rlim_cur=lim.rlim_max=MAX_OUTLEN;
207
            setrlimit(RLIMIT_FSIZE,&lim);
207
      setrlimit(RLIMIT_FSIZE,&lim);
208
            args[0]=name_sh; args[1]=opt_sh;
208
      args[0]=name_sh; args[1]=opt_sh;
209
            snprintf(parm,sizeof(parm),"%s\n%s\n",pre_sh,argv[3]);
209
      snprintf(parm,sizeof(parm),"%s\n%s\n",pre_sh,argv[3]);
210
            args[2]=parm; args[3]=NULL; must=1;
210
      args[2]=parm; args[3]=NULL; must=1;
211
            goto cont;
211
      goto cont;
212
        }
212
    }
213
        if(strcmp(argv[2],"perl")==0) {
213
    if(strcmp(argv[2],"perl")==0) {
214
            lim.rlim_cur=lim.rlim_max=MAX_OUTLEN;
214
      lim.rlim_cur=lim.rlim_max=MAX_OUTLEN;
215
            setrlimit(RLIMIT_FSIZE,&lim);
215
      setrlimit(RLIMIT_FSIZE,&lim);
216
            args[0]=name_perl; args[1]=opt_perl;
216
      args[0]=name_perl; args[1]=opt_perl;
217
            snprintf(parm,sizeof(parm),"%s\n%s\n",pre_perl,argv[3]);
217
      snprintf(parm,sizeof(parm),"%s\n%s\n",pre_perl,argv[3]);
218
            args[2]=parm; args[3]=NULL; must=1;
218
      args[2]=parm; args[3]=NULL; must=1;
219
            goto cont;
219
      goto cont;
220
        }
-
 
221
        goto abandon;
-
 
222
    }
-
 
223
    for(i=0;i<1000 && i<argc; i++) args[i+k]=argv[i+1];
-
 
224
    args[i]=NULL;
-
 
225
    cont:
-
 
226
    if(uid!=0) {
-
 
227
        if(test_must()) goto abandon;
-
 
228
        goto ex2;
-
 
229
    }
-
 
230
    if(t!=0) {
-
 
231
        stat("bin",&st); execuid=execgid=st.st_uid;
-
 
232
        if(test_must()) goto abandon;
-
 
233
        goto ex;
-
 
234
    }
220
    }
-
 
221
    goto abandon;
-
 
222
  }
-
 
223
  for(i=0;i<1000 && i<argc; i++) args[i+k]=argv[i+1];
-
 
224
  args[i]=NULL;
-
 
225
  cont:
-
 
226
  if(uid!=0) {
-
 
227
    if(test_must()) goto abandon;
-
 
228
    goto ex2;
-
 
229
  }
-
 
230
  if(t!=0) {
-
 
231
    stat("bin",&st); execuid=execgid=st.st_uid;
-
 
232
    if(test_must()) goto abandon;
-
 
233
    goto ex;
-
 
234
  }
235
    if(chroot("../chroot")==0) {
235
  if(chroot("../chroot")==0) {
236
        (void)chdir("/tmp");
236
    (void)chdir("/tmp");
237
        lim.rlim_cur=lim.rlim_max=PROC_QUOTA;
237
    lim.rlim_cur=lim.rlim_max=PROC_QUOTA;
238
        setrlimit(RLIMIT_NPROC,&lim);
238
    setrlimit(RLIMIT_NPROC,&lim);
239
        setenv("PATH",chroot_path,1);
239
    setenv("PATH",chroot_path,1);
240
        p=getenv("w_wims_session");
240
    p=getenv("w_wims_session");
241
        if(p && *p) {
241
    if(p && *p) {
242
            snprintf(tmpbuf,sizeof(tmpbuf),"/tmp/sessions/%s",p);
242
      snprintf(tmpbuf,sizeof(tmpbuf),"/tmp/sessions/%s",p);
243
            p=strchr(tmpbuf,'_'); if(p) *p=0;
243
      p=strchr(tmpbuf,'_'); if(p) *p=0;
244
            setenv("TMPDIR",tmpbuf,1);
244
      setenv("TMPDIR",tmpbuf,1);
245
            setenv("tmp_dir",tmpbuf,1);
245
      setenv("tmp_dir",tmpbuf,1);
246
            p=getenv("w_wims_priv_chroot");
246
      p=getenv("w_wims_priv_chroot");
247
            if(p && strstr(p,"tmpdir")!=NULL)
247
      if(p && strstr(p,"tmpdir")!=NULL)
248
              (void)chdir(tmpbuf);
248
        (void)chdir(tmpbuf);
249
        }
-
 
250
    }
249
    }
-
 
250
  }
251
    else if(test_must()) goto abandon;
251
  else if(test_must()) goto abandon;
252
    ex:
252
  ex:
253
    if(setregid(execgid,execgid)<0) goto abandon;
253
  if(setregid(execgid,execgid)<0) goto abandon;
254
    if(setreuid(execuid,execuid)<0) goto abandon;
254
  if(setreuid(execuid,execuid)<0) goto abandon;
255
    ex2:
255
  ex2:
256
    for(i=0;i<env_rm_cnt;i++) unsetenv(env_rm[i]);
256
  for(i=0;i<env_rm_cnt;i++) unsetenv(env_rm[i]);
257
    if(strchr(args[0],'/')) execv(args[0],args); else execvp(args[0],args);
257
  if(strchr(args[0],'/')) execv(args[0],args); else execvp(args[0],args);
258
    abandon: return 127;
258
  abandon: return 127;
259
}
259
}
260
 
-