File: python-wrapper.c

package info (click to toggle)
calendarserver 9.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 25,688 kB
  • sloc: python: 195,037; sql: 78,794; xml: 16,936; sh: 2,502; ansic: 66; makefile: 26
file content (94 lines) | stat: -rw-r--r-- 2,489 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//
//  python-wrapper.c
//
//  Copyright © 2016 Apple Inc. All rights reserved.
//

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pwd.h>
#include <Python/Python.h>

const char * const allowedUsernames[] = {
    "_calendar",
    "_devicemgr",
    "_teamsserver",
    "_xserverdocs"
};

const char* python = "/usr/bin/python2.7";
const char* bin = "/Applications/Server.app/Contents/ServerRoot/Library/CalendarServer/bin";
const char* site = "/Applications/Server.app/Contents/ServerRoot/Library/CalendarServer/lib/python2.7/site-packages";

// Prepend a path to the named environment variable
int prependToPath(const char* name, const char* prepend) {
    const char* old_value = getenv(name);
    char* new_value = NULL;
    if (old_value == NULL) {
        // No existing value - set to the prepend value
        size_t max_length = strlen(prepend) + 1;
        new_value = malloc(max_length);
        strlcpy(new_value, prepend, max_length);
    } else {
        // Existing value - so prepend with a ":" in between
        size_t max_length = strlen(old_value) + strlen(prepend) + 2;
        new_value = malloc(max_length);
        strlcpy(new_value, prepend, max_length);
        strlcat(new_value, ":", max_length);
        strlcat(new_value, old_value, max_length);
    }
    setenv(name, new_value, 1);
    free(new_value);
    return 0;
}

int uidIsAllowed() {
    // Returns 1 if we're root or any of the whitelisted users; 0 otherwise

    int uid = getuid();

    if (uid == 0) {
        // Always allow root
        return 1;

    } else {
        // Check the other whitelisted users
        int i, len;
        struct passwd* passwdInfo;

        len = sizeof(allowedUsernames) / sizeof(allowedUsernames[0]);
        for (i = 0; i < len; i++) {
            passwdInfo = getpwnam(allowedUsernames[i]);
            if (passwdInfo != NULL) {
                if (passwdInfo->pw_uid == uid) {
                    return 1;
                }
            }
        }
    }

    // No match
    return 0;
}


int main(int argc, const char * argv[]) {

    if (uidIsAllowed()) {
        int result;

        // Update PATH and PYTHONPATH
        prependToPath("PATH", bin);
        prependToPath("PYTHONPATH", site);

        Py_Initialize();
        result = Py_Main(argc, (char **)argv);
        Py_Finalize();
        return result;
    } else {
        printf("You are not allowed to run this executable.\n");
        return 1;
    }
}