~azzar1/unity/add-show-desktop-key

« back to all changes in this revision

Viewing changes to trampoline/trampoline.c

  • Committer: chadnickbok
  • Date: 2009-01-19 22:56:46 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:1170
This commit fixes issue #10 and part of issue #9

There are now two options for moving files with their
svn history intact; svn move and svn copy. These
use the svn commands to move the files, allowing students
to move and rename files without their histories being
lost.

This commit also shows the svn status of a dir, if it is
the 'head' of an svn repository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* IVLE - Informatics Virtual Learning Environment
2
 
 * Copyright (C) 2007-2008 The University of Melbourne
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
7
 
 * (at your option) any later version.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; if not, write to the Free Software
16
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17
 
 *
18
 
 * Program: Trampoline
19
 
 * Author:  Tom Conway, Matt Giuca
20
 
 * Date:    20/12/2007
21
 
 *
22
 
 * This program runs a given program in a given working dir.
23
 
 * First, it chroots to a jail path and setuids to a given user ID.
24
 
 * This is intented to provide a safe execution environment for arbitrary
25
 
 * programs and scripts.
26
 
 *
27
 
 * Scripts (such as Python programs) should be executed by supplying
28
 
 * "/usr/bin/python" as the program, and the script as the first argument.
29
 
 *
30
 
 * Usage: trampoline uid jail-path working-path program [args...]
31
 
 * Must run as root. Will safely setuid to the supplied uid, checking that it
32
 
 * is not root. Recommended that the file is set up as follows:
33
 
 *  sudo chown root:root trampoline; sudo chroot +s trampoline
34
 
 */
35
 
 
36
 
#include <stdio.h>
37
 
#include <stdlib.h>
38
 
#include <string.h>
39
 
#include <unistd.h>
40
 
#include <sys/types.h>
41
 
#include <sys/stat.h>
42
 
#include <limits.h>
43
 
 
44
 
/* conf.h is admin-configured by the setup process.
45
 
 * It defines jail_base.
46
 
 */
47
 
#include "conf.h"
48
 
 
49
 
/* Returns TRUE if the given uid is allowed to execute trampoline.
50
 
 * Only root or the web server should be allowed to execute.
51
 
 * This is determined by the whitelist allowed_uids in conf.h.
52
 
 */
53
 
int uid_allowed(int uid)
54
 
{
55
 
    int i;
56
 
    /* root is always allowed to execute trampoline */
57
 
    if (uid == 0)
58
 
        return 1;
59
 
    /* loop over all allowed_uids */
60
 
    for (i=(sizeof(allowed_uids)/sizeof(*allowed_uids))-1; i>=0; i--)
61
 
    {
62
 
        if (allowed_uids[i] == uid)
63
 
            return 1;
64
 
    }
65
 
    /* default to disallowing */
66
 
    return 0;
67
 
}
68
 
 
69
 
/* Turn the process into a daemon using the standard
70
 
 * 2-fork technique.
71
 
 */
72
 
void daemonize(void)
73
 
{
74
 
    pid_t pid, sid;
75
 
 
76
 
    /* already a daemon */
77
 
    if ( getppid() == 1 ) return;
78
 
 
79
 
    /* Fork off the parent process */
80
 
    pid = fork();
81
 
    if (pid < 0) {
82
 
        exit(1);
83
 
    }
84
 
    /* If we got a good PID, then we can exit the parent process. */
85
 
    if (pid > 0) {
86
 
        exit(0);
87
 
    }
88
 
 
89
 
    /* At this point we are executing as the child process */
90
 
 
91
 
    /* Change the file mode mask */
92
 
    umask(022);
93
 
 
94
 
    /* Create a new SID for the child process */
95
 
    sid = setsid();
96
 
    if (sid < 0) {
97
 
        exit(1);
98
 
    }
99
 
 
100
 
    /* Change the current working directory.  This prevents the current
101
 
       directory from being locked; hence not being able to remove it. */
102
 
    if ((chdir("/")) < 0) {
103
 
        exit(1);
104
 
    }
105
 
 
106
 
    /* Redirect standard files to /dev/null */
107
 
    freopen( "/dev/null", "r", stdin);
108
 
    freopen( "/dev/null", "w", stdout);
109
 
    freopen( "/dev/null", "w", stderr);
110
 
}
111
 
 
112
 
static void usage(const char* nm)
113
 
{
114
 
    fprintf(stderr,
115
 
        "usage: %s [-d] <uid> <jail> <cwd> <program> [args...]\n", nm);
116
 
    exit(1);
117
 
}
118
 
 
119
 
int main(int argc, char* const argv[])
120
 
{
121
 
    char* jailpath;
122
 
    char* work_dir;
123
 
    char* prog;
124
 
    char* const * args;
125
 
    int uid;
126
 
    int arg_num = 1;
127
 
    int daemon_mode = 0;
128
 
    char canonical_jailpath[PATH_MAX];
129
 
 
130
 
    /* Disallow execution from all users but the whitelisted ones, and root */
131
 
    if (!uid_allowed(getuid()))
132
 
    {
133
 
        fprintf(stderr, "only the web server may execute trampoline\n");
134
 
        exit(1);
135
 
    }
136
 
 
137
 
    /* Args check and usage */
138
 
    if (argc < 5)
139
 
    {
140
 
        usage(argv[0]);
141
 
    }
142
 
 
143
 
    if (strcmp(argv[arg_num], "-d") == 0)
144
 
    {
145
 
        if (argc < 6)
146
 
        {
147
 
            usage(argv[0]);
148
 
        }
149
 
        daemon_mode = 1;
150
 
        arg_num++;
151
 
    }
152
 
    uid = atoi(argv[arg_num++]);
153
 
    jailpath = argv[arg_num++];
154
 
    work_dir = argv[arg_num++];
155
 
    prog = argv[arg_num];
156
 
    args = argv + arg_num;
157
 
 
158
 
    /* Disallow suiding to the root user */
159
 
    if (uid == 0)
160
 
    {
161
 
        fprintf(stderr, "cannot set up a jail as root\n");
162
 
        exit(1);
163
 
    }
164
 
 
165
 
    /* Jail path must be an absolute path,
166
 
     * and it must begin with jail_base.
167
 
     */
168
 
    if (norm(canonical_jailpath, PATH_MAX, jailpath) != 0)
169
 
    {
170
 
        fprintf(stderr, "bad jail path: %s\n", jailpath);
171
 
        exit(1);
172
 
    }
173
 
    if (strncmp(canonical_jailpath, jail_base, strlen(jail_base)))
174
 
    {
175
 
        fprintf(stderr, "bad jail path: %s\n", jailpath);
176
 
        exit(1);
177
 
    }
178
 
 
179
 
    /* chroot into the jail.
180
 
     * Henceforth this process, and its children, cannot see anything above
181
 
     * canoncial_jailpath. */
182
 
    if (chroot(canonical_jailpath))
183
 
    {
184
 
        perror("could not chroot");
185
 
        exit(1);
186
 
    }
187
 
 
188
 
    /* chdir into the specified working directory */
189
 
    if (chdir(work_dir))
190
 
    {
191
 
        perror("could not chdir");
192
 
        exit(1);
193
 
    }
194
 
 
195
 
    /* setuid to the given user ID.
196
 
     * Henceforth we will be running as this user instead of root.
197
 
     */
198
 
    if (setuid(uid))
199
 
    {
200
 
        perror("could not setuid");
201
 
        exit(1);
202
 
    }
203
 
 
204
 
    if (daemon_mode)
205
 
    {
206
 
        daemonize();
207
 
    }
208
 
 
209
 
    /* exec (replace this process with the a new instance of the target
210
 
     * program). Pass along all the arguments.
211
 
     * Note that for script execution, the "program" will be the interpreter,
212
 
     * and the first argument will be the script. */
213
 
    execv(prog, args);
214
 
 
215
 
    /* XXX if (daemon_mode) use syslog? */
216
 
    /* nb exec won't return unless there was an error */
217
 
    perror("could not exec");
218
 
    return 1;
219
 
}