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

« back to all changes in this revision

Viewing changes to trampoline/trampoline.c

  • Committer: mattgiuca
  • Date: 2008-02-19 08:26:11 UTC
  • Revision ID: svn-v3-trunk0:2b9c9e99-6f39-0410-b283-7f802c844ae2:trunk:509
common.db: Rewrote user_authenticate to return 3 values (True, false, None)
    Now returns False if the password did not match, None if the password
    field is NULL (None implying a soft failure, with the possibility of
    validating against LDAP or something else).

auth.authenticate: Rewrote this module with a new plugin interface
    (as discussed with Tom Conway). Allows successive modules to try to
    authenticate the user.
    Changed the authenticate function interface: Now raises an AuthError
    when auth fails, instead of returning None.

dispatch.login: Handle new auth interface (exception catch).
    Auth is now able to provide an error message, in the exception.
    The exception message is displayed as an error to the user.

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
#include <stdlib.h>
38
38
#include <string.h>
39
39
#include <unistd.h>
40
 
#include <syslog.h>
41
 
#include <sys/mount.h>
42
40
#include <sys/types.h>
43
41
#include <sys/stat.h>
44
 
#include <sys/time.h>
45
 
#include <sys/resource.h>
46
42
#include <limits.h>
47
43
 
48
44
/* conf.h is admin-configured by the setup process.
50
46
 */
51
47
#include "conf.h"
52
48
 
53
 
#include "norm.h"
54
 
 
55
49
/* Returns TRUE if the given uid is allowed to execute trampoline.
56
50
 * Only root or the web server should be allowed to execute.
57
51
 * This is determined by the whitelist allowed_uids in conf.h.
118
112
static void usage(const char* nm)
119
113
{
120
114
    fprintf(stderr,
121
 
        "usage: %s [-d] [-u] <uid> <jail> <cwd> <program> [args...]\n", nm);
 
115
        "usage: %s [-d] <uid> <jail> <cwd> <program> [args...]\n", nm);
122
116
    exit(1);
123
117
}
124
118
 
125
 
#ifdef IVLE_AUFS_JAILS
126
 
/* Die more pleasantly if mallocs fail. */
127
 
void *die_if_null(void *ptr)
128
 
{
129
 
    if (ptr == NULL)
130
 
    {
131
 
        perror("not enough memory");
132
 
        exit(1);
133
 
    }
134
 
    return ptr;
135
 
}
136
 
 
137
 
/* Find the path of the user components of a jail, given a mountpoint. */
138
 
char *jail_src(const char* jailpath)
139
 
{
140
 
    char* src;
141
 
    int srclen;
142
 
    int dstlen;
143
 
 
144
 
    srclen = strlen(jail_src_base);
145
 
    dstlen = strlen(jail_base);
146
 
    
147
 
    src = die_if_null(malloc(strlen(jailpath) + (srclen - dstlen) + 1));
148
 
    strcpy(src, jail_src_base);
149
 
    strcat(src, jailpath+dstlen);
150
 
 
151
 
    return src;
152
 
}
153
 
 
154
 
/* Check for the validity of a jail in the given path, mounting it if it looks
155
 
 * empty.
156
 
 * TODO: Updating /etc/mtab would be nice. */
157
 
void mount_if_needed(const char* jailpath)
158
 
{
159
 
    char *jailsrc;
160
 
    char *jaillib;
161
 
    char *mountdata;
162
 
 
163
 
    /* Check if there is something useful in the jail. If not, it's probably
164
 
     * not mounted. */
165
 
    jaillib = die_if_null(malloc(strlen(jailpath) + 5));
166
 
    sprintf(jaillib, "%s/lib", jailpath);
167
 
 
168
 
    if (access(jaillib, F_OK))
169
 
    {
170
 
        /* No /lib? Mustn't be mounted. Mount it, creating the dir if needed. */
171
 
        if (access(jailpath, F_OK))
172
 
        {
173
 
             if(mkdir(jailpath, 0755))
174
 
             {
175
 
                 syslog(LOG_ERR, "could not create mountpoint %s\n", jailpath);
176
 
                 perror("could not create jail mountpoint");
177
 
                 exit(1);
178
 
             }
179
 
             syslog(LOG_NOTICE, "created mountpoint %s\n", jailpath);
180
 
        }
181
 
       
182
 
        jailsrc = jail_src(jailpath);
183
 
        mountdata = die_if_null(malloc(3 + strlen(jailsrc) + 4 + strlen(jail_system) + 3 + 1));
184
 
        sprintf(mountdata, "br:%s=rw:%s=ro", jailsrc, jail_system);
185
 
        if (mount("none", jailpath, "aufs", 0, mountdata))
186
 
        {
187
 
            syslog(LOG_ERR, "could not mount %s\n", jailpath);
188
 
            perror("could not mount");
189
 
            exit(1);
190
 
        } 
191
 
 
192
 
        syslog(LOG_INFO, "mounted %s\n", jailpath);
193
 
 
194
 
        free(jailsrc);
195
 
        free(mountdata);
196
 
    }
197
 
 
198
 
    free(jaillib);
199
 
}
200
 
#endif /* IVLE_AUFS_JAILS */
201
 
 
202
119
int main(int argc, char* const argv[])
203
120
{
204
121
    char* jailpath;
208
125
    int uid;
209
126
    int arg_num = 1;
210
127
    int daemon_mode = 0;
211
 
    int unlimited = 0;
212
128
    char canonical_jailpath[PATH_MAX];
213
129
 
214
130
    /* Disallow execution from all users but the whitelisted ones, and root */
233
149
        daemon_mode = 1;
234
150
        arg_num++;
235
151
    }
236
 
 
237
 
    if (strcmp(argv[arg_num], "-u") == 0)
238
 
    {
239
 
        if (argc < 6)
240
 
        {
241
 
            usage(argv[0]);
242
 
        }
243
 
        unlimited = 1;
244
 
        arg_num++;
245
 
    }
246
152
    uid = atoi(argv[arg_num++]);
247
153
    jailpath = argv[arg_num++];
248
154
    work_dir = argv[arg_num++];
270
176
        exit(1);
271
177
    }
272
178
 
273
 
    openlog("trampoline", LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER);
274
 
 
275
 
    #ifdef IVLE_AUFS_JAILS
276
 
    mount_if_needed(canonical_jailpath);
277
 
    #endif /* IVLE_AUFS_JAILS */
278
 
 
279
179
    /* chroot into the jail.
280
180
     * Henceforth this process, and its children, cannot see anything above
281
181
     * canoncial_jailpath. */
282
182
    if (chroot(canonical_jailpath))
283
183
    {
284
 
        syslog(LOG_ERR, "chroot to %s failed\n", canonical_jailpath);
285
 
 
286
184
        perror("could not chroot");
287
185
        exit(1);
288
186
    }
297
195
    /* setuid to the given user ID.
298
196
     * Henceforth we will be running as this user instead of root.
299
197
     */
300
 
    if (setgid(uid))
301
 
    {
302
 
        perror("could not setgid");
303
 
        exit(1);
304
 
    }
305
 
 
306
198
    if (setuid(uid))
307
199
    {
308
200
        perror("could not setuid");
314
206
        daemonize();
315
207
    }
316
208
 
317
 
    /* set user resource limits */
318
 
    if (!unlimited)
319
 
    {
320
 
        struct rlimit l;
321
 
        /* Process size in virtual memory */
322
 
        l.rlim_cur = 64 * 1024 * 1024; /* 64Mb */
323
 
        l.rlim_max = 72 * 1024 * 1024; /* 64Mb */
324
 
        if (setrlimit(RLIMIT_AS, &l))
325
 
        {
326
 
            perror("could not setrlimit/RLIMIT_AS");
327
 
            exit(1);
328
 
        }
329
 
 
330
 
        /* Core */
331
 
        l.rlim_cur = 0;
332
 
        l.rlim_max = 0;
333
 
        if (setrlimit(RLIMIT_CORE, &l))
334
 
        {
335
 
            perror("could not setrlimit/RLIMIT_CORE");
336
 
            exit(1);
337
 
        }
338
 
 
339
 
        /* CPU */
340
 
        l.rlim_cur = 25;
341
 
        l.rlim_max = 30;
342
 
        if (setrlimit(RLIMIT_CPU, &l))
343
 
        {
344
 
            perror("could not setrlimit/RLIMIT_CPU");
345
 
            exit(1);
346
 
        }
347
 
 
348
 
        /* File Size */
349
 
        l.rlim_cur = 64 * 1024 * 1024; /* 64Mb */
350
 
        l.rlim_max = 72 * 1024 * 1024; /* 72Mb */
351
 
        if (setrlimit(RLIMIT_FSIZE, &l))
352
 
        {
353
 
            perror("could not setrlimit/RLIMIT_FSIZE");
354
 
            exit(1);
355
 
        }
356
 
    }
357
 
 
358
209
    /* exec (replace this process with the a new instance of the target
359
210
     * program). Pass along all the arguments.
360
211
     * Note that for script execution, the "program" will be the interpreter,
361
212
     * and the first argument will be the script. */
362
213
    execv(prog, args);
363
214
 
 
215
    /* XXX if (daemon_mode) use syslog? */
364
216
    /* nb exec won't return unless there was an error */
365
 
    syslog(LOG_ERR, "exec of %s in %s failed", prog, canonical_jailpath);
366
 
 
367
217
    perror("could not exec");
368
 
    closelog();
369
218
    return 1;
370
219
}