~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
 
 
41
 
/* conf.h is admin-configured by the setup process.
42
 
 * It defines jail_base.
43
 
 */
44
 
#include "conf.h"
45
 
 
46
 
/* Returns TRUE if the given uid is allowed to execute trampoline.
47
 
 * Only root or the web server should be allowed to execute.
48
 
 * This is determined by the whitelist allowed_uids in conf.h.
49
 
 */
50
 
int uid_allowed(int uid)
51
 
{
52
 
    int i;
53
 
    /* root is always allowed to execute trampoline */
54
 
    if (uid == 0)
55
 
        return 1;
56
 
    /* loop over all allowed_uids */
57
 
    for (i=(sizeof(allowed_uids)/sizeof(*allowed_uids))-1; i>=0; i--)
58
 
    {
59
 
        if (allowed_uids[i] == uid)
60
 
            return 1;
61
 
    }
62
 
    /* default to disallowing */
63
 
    return 0;
64
 
}
65
 
 
66
 
/* Turn the process into a daemon using the standard
67
 
 * 2-fork technique.
68
 
 */
69
 
void daemonize(void)
70
 
{
71
 
    pid_t pid, sid;
72
 
 
73
 
    /* already a daemon */
74
 
    if ( getppid() == 1 ) return;
75
 
 
76
 
    /* Fork off the parent process */
77
 
    pid = fork();
78
 
    if (pid < 0) {
79
 
        exit(1);
80
 
    }
81
 
    /* If we got a good PID, then we can exit the parent process. */
82
 
    if (pid > 0) {
83
 
        exit(0);
84
 
    }
85
 
 
86
 
    /* At this point we are executing as the child process */
87
 
 
88
 
    /* Change the file mode mask */
89
 
    umask(0);
90
 
 
91
 
    /* Create a new SID for the child process */
92
 
    sid = setsid();
93
 
    if (sid < 0) {
94
 
        exit(1);
95
 
    }
96
 
 
97
 
    /* Change the current working directory.  This prevents the current
98
 
       directory from being locked; hence not being able to remove it. */
99
 
    if ((chdir("/")) < 0) {
100
 
        exit(1);
101
 
    }
102
 
 
103
 
    /* Redirect standard files to /dev/null */
104
 
    freopen( "/dev/null", "r", stdin);
105
 
    freopen( "/dev/null", "w", stdout);
106
 
    freopen( "/dev/null", "w", stderr);
107
 
}
108
 
 
109
 
static void usage(const char* nm)
110
 
{
111
 
    fprintf(stderr,
112
 
        "usage: %s [-d] <uid> <jail> <cwd> <program> [args...]\n", nm);
113
 
    exit(1);
114
 
}
115
 
 
116
 
int main(int argc, char* const argv[])
117
 
{
118
 
    char* jailpath;
119
 
    char* work_dir;
120
 
    char* prog;
121
 
    char* const * args;
122
 
    int uid;
123
 
    int arg_num = 1;
124
 
    int daemon_mode = 0;
125
 
 
126
 
    /* Disallow execution from all users but the whitelisted ones, and root */
127
 
    if (!uid_allowed(getuid()))
128
 
    {
129
 
        fprintf(stderr, "only the web server may execute trampoline\n");
130
 
        exit(1);
131
 
    }
132
 
 
133
 
    /* Args check and usage */
134
 
    if (argc < 5)
135
 
    {
136
 
        usage(argv[0]);
137
 
    }
138
 
 
139
 
    if (strcmp(argv[arg_num], "-d") == 0)
140
 
    {
141
 
        if (argc < 6)
142
 
        {
143
 
            usage(argv[0]);
144
 
        }
145
 
        daemon_mode = 1;
146
 
        arg_num++;
147
 
    }
148
 
    uid = atoi(argv[arg_num++]);
149
 
    jailpath = argv[arg_num++];
150
 
    work_dir = argv[arg_num++];
151
 
    prog = argv[arg_num];
152
 
    args = argv + arg_num;
153
 
 
154
 
    /* Disallow suiding to the root user */
155
 
    if (uid == 0)
156
 
    {
157
 
        fprintf(stderr, "cannot set up a jail as root\n");
158
 
        exit(1);
159
 
    }
160
 
 
161
 
    /* Jail path must:
162
 
     * Be non-empty
163
 
     * Start with a '/'
164
 
     * Not contain "/.."
165
 
     * Begin with jail_base
166
 
     */
167
 
    if (strlen(jailpath) < 1 || jailpath[0] != '/'
168
 
            || strstr(jailpath, "/..")
169
 
            || strncmp(jailpath, jail_base, strlen(jail_base)))
170
 
    {
171
 
        fprintf(stderr, "bad jail path: %s\n", jailpath);
172
 
        exit(1);
173
 
    }
174
 
 
175
 
    /* chroot into the jail.
176
 
     * Henceforth this process, and its children, cannot see anything above
177
 
     * jailpath. */
178
 
    if (chroot(jailpath))
179
 
    {
180
 
        perror("could not chroot");
181
 
        exit(1);
182
 
    }
183
 
 
184
 
    /* chdir into the specified working directory */
185
 
    if (chdir(work_dir))
186
 
    {
187
 
        perror("could not chdir");
188
 
        exit(1);
189
 
    }
190
 
 
191
 
    /* setuid to the given user ID.
192
 
     * Henceforth we will be running as this user instead of root.
193
 
     */
194
 
    if (setuid(uid))
195
 
    {
196
 
        perror("could not setuid");
197
 
        exit(1);
198
 
    }
199
 
 
200
 
    if (daemon_mode)
201
 
    {
202
 
        daemonize();
203
 
    }
204
 
 
205
 
    /* exec (replace this process with the a new instance of the target
206
 
     * program). Pass along all the arguments.
207
 
     * Note that for script execution, the "program" will be the interpreter,
208
 
     * and the first argument will be the script. */
209
 
    execv(prog, args);
210
 
 
211
 
    /* XXX if (daemon_mode) use syslog? */
212
 
    /* nb exec won't return unless there was an error */
213
 
    perror("could not exec");
214
 
    return 1;
215
 
}