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

« back to all changes in this revision

Viewing changes to trampoline/trampoline.c

  • Committer: mattgiuca
  • Date: 2008-01-10 00:10:11 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:149
fileservice:
    * Both subversion and OS mode listings now output "." as one of the files.
        This is deliberate in order for the client to see (by the presence or
        absence of the "svnstatus" attribute) whether this directory is
        under version control.
    * Directories no longer display a "type" attribute (since this was always
        just the default type, it's meaningless).
    * Fixed bug where unversioned directories inside a versioned directory
        output an empty listing.

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
/* Argument names */
 
47
#define ARG_UID         1
 
48
#define ARG_JAILPATH    2
 
49
#define ARG_CWD         3
 
50
#define ARG_PROG        4
 
51
 
 
52
#define MIN_ARGC        5
 
53
 
 
54
#define UID_ROOT        0
 
55
 
 
56
/* Returns TRUE if the given uid is allowed to execute trampoline.
 
57
 * Only root or the web server should be allowed to execute.
 
58
 * This is determined by the whitelist allowed_uids in conf.h.
 
59
 */
 
60
int uid_allowed(int uid)
 
61
{
 
62
    int i;
 
63
    /* root is always allowed to execute trampoline */
 
64
    if (uid == 0)
 
65
        return 1;
 
66
    /* loop over all allowed_uids */
 
67
    for (i=(sizeof(allowed_uids)/sizeof(*allowed_uids))-1; i>=0; i--)
 
68
    {
 
69
        if (allowed_uids[i] == uid)
 
70
            return 1;
 
71
    }
 
72
    /* default to disallowing */
 
73
    return 0;
 
74
}
 
75
 
 
76
int main(int argc, char* const argv[])
 
77
{
 
78
    char* jailpath;
 
79
    int uid;
 
80
 
 
81
    /* Disallow execution from all users but the whitelisted ones, and root */
 
82
    if (!uid_allowed(getuid()))
 
83
    {
 
84
        fprintf(stderr, "only the web server may execute trampoline\n");
 
85
        exit(1);
 
86
    }
 
87
 
 
88
    /* Args check and usage */
 
89
    if (argc < MIN_ARGC)
 
90
    {
 
91
        fprintf(stderr, "usage: %s <uid> <jail> <cwd> <program> [args...]\n",
 
92
            argv[0]);
 
93
        exit(EXIT_FAILURE);
 
94
    }
 
95
 
 
96
    /* Disallow suiding to the root user */
 
97
    uid = atoi(argv[ARG_UID]);
 
98
    if (uid == UID_ROOT)
 
99
    {
 
100
        fprintf(stderr, "cannot set up a jail as root\n");
 
101
        exit(1);
 
102
    }
 
103
 
 
104
    /* Jail path must:
 
105
     * Be non-empty
 
106
     * Start with a '/'
 
107
     * Not contain "/.."
 
108
     * Begin with jail_base
 
109
     */
 
110
    jailpath = argv[ARG_JAILPATH];
 
111
    if (strlen(jailpath) < 1 || jailpath[0] != '/'
 
112
            || strstr(jailpath, "/..")
 
113
            || strncmp(jailpath, jail_base, strlen(jail_base)))
 
114
    {
 
115
        fprintf(stderr, "bad jail path: %s\n", jailpath);
 
116
        exit(1);
 
117
    }
 
118
 
 
119
    /* chroot into the jail.
 
120
     * Henceforth this process, and its children, cannot see anything above
 
121
     * jailpath. */
 
122
    if (chroot(jailpath))
 
123
    {
 
124
        perror("could not chroot");
 
125
        exit(1);
 
126
    }
 
127
 
 
128
    /* chdir into the specified working directory */
 
129
    if (chdir(argv[ARG_CWD]))
 
130
    {
 
131
        perror("could not chdir");
 
132
        exit(1);
 
133
    }
 
134
 
 
135
    /* setuid to the given user ID.
 
136
     * Henceforth we will be running as this user instead of root.
 
137
     */
 
138
    if (setuid(uid))
 
139
    {
 
140
        perror("could not setuid");
 
141
        exit(1);
 
142
    }
 
143
 
 
144
    /* exec (replace this process with the a new instance of the target
 
145
     * program). Pass along all the arguments.
 
146
     * Note that for script execution, the "program" will be the interpreter,
 
147
     * and the first argument will be the script. */
 
148
    execv(argv[ARG_PROG], argv + ARG_PROG);
 
149
 
 
150
    /* nb exec won't return unless there was an error */
 
151
    perror("could not exec");
 
152
    return EXIT_FAILURE;
 
153
}