~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to Misc/setuid-prog.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 
22
22
   Assuming the script is a Bourne shell script, the first line of the
23
23
   script should be
24
 
        #!/bin/sh -
 
24
    #!/bin/sh -
25
25
   The - is important, don't omit it.  If you're using esh, the first
26
26
   line should be
27
 
        #!/usr/local/bin/esh -f
 
27
    #!/usr/local/bin/esh -f
28
28
   and for ksh, the first line should be
29
 
        #!/usr/local/bin/ksh -p
 
29
    #!/usr/local/bin/ksh -p
30
30
   The script should then set the variable IFS to the string
31
31
   consisting of <space>, <tab>, and <newline>.  After this (*not*
32
32
   before!), the PATH variable should be set to a reasonable value and
33
33
   exported.  Do not expect the PATH to have a reasonable value, so do
34
34
   not trust the old value of PATH.  You should then set the umask of
35
35
   the program by calling
36
 
        umask 077 # or 022 if you want the files to be readable
 
36
    umask 077 # or 022 if you want the files to be readable
37
37
   If you plan to change directories, you should either unset CDPATH
38
38
   or set it to a good value.  Setting CDPATH to just ``.'' (dot) is a
39
39
   good idea.
40
40
   If, for some reason, you want to use csh, the first line should be
41
 
        #!/bin/csh -fb
 
41
    #!/bin/csh -fb
42
42
   You should then set the path variable to something reasonable,
43
43
   without trusting the inherited path.  Here too, you should set the
44
44
   umask using the command
45
 
        umask 077 # or 022 if you want the files to be readable
 
45
    umask 077 # or 022 if you want the files to be readable
46
46
*/
47
47
 
48
48
#include <unistd.h>
54
54
 
55
55
/* CONFIGURATION SECTION */
56
56
 
57
 
#ifndef FULL_PATH       /* so that this can be specified from the Makefile */
 
57
#ifndef FULL_PATH       /* so that this can be specified from the Makefile */
58
58
/* Uncomment the following line:
59
 
#define FULL_PATH       "/full/path/of/script" 
 
59
#define FULL_PATH       "/full/path/of/script"
60
60
* Then comment out the #error line. */
61
61
#error "You must define FULL_PATH somewhere"
62
62
#endif
63
63
#ifndef UMASK
64
 
#define UMASK           077
 
64
#define UMASK           077
65
65
#endif
66
66
 
67
67
/* END OF CONFIGURATION SECTION */
101
101
void
102
102
clean_environ(void)
103
103
{
104
 
        char **p;
105
 
        extern char **environ;
 
104
    char **p;
 
105
    extern char **environ;
106
106
 
107
 
        for (p = environ; *p; p++) {
108
 
                if (strncmp(*p, "LD_", 3) == 0)
109
 
                        **p = 'X';
110
 
                else if (strncmp(*p, "_RLD", 4) == 0)
111
 
                        **p = 'X';
112
 
                else if (strncmp(*p, "PYTHON", 6) == 0)
113
 
                        **p = 'X';
114
 
                else if (strncmp(*p, "IFS=", 4) == 0)
115
 
                        *p = def_IFS;
116
 
                else if (strncmp(*p, "CDPATH=", 7) == 0)
117
 
                        *p = def_CDPATH;
118
 
                else if (strncmp(*p, "ENV=", 4) == 0)
119
 
                        *p = def_ENV;
120
 
        }
121
 
        putenv(def_PATH);
 
107
    for (p = environ; *p; p++) {
 
108
        if (strncmp(*p, "LD_", 3) == 0)
 
109
            **p = 'X';
 
110
        else if (strncmp(*p, "_RLD", 4) == 0)
 
111
            **p = 'X';
 
112
        else if (strncmp(*p, "PYTHON", 6) == 0)
 
113
            **p = 'X';
 
114
        else if (strncmp(*p, "IFS=", 4) == 0)
 
115
            *p = def_IFS;
 
116
        else if (strncmp(*p, "CDPATH=", 7) == 0)
 
117
            *p = def_CDPATH;
 
118
        else if (strncmp(*p, "ENV=", 4) == 0)
 
119
            *p = def_ENV;
 
120
    }
 
121
    putenv(def_PATH);
122
122
}
123
123
 
124
124
int
125
125
main(int argc, char **argv)
126
126
{
127
 
        struct stat statb;
128
 
        gid_t egid = getegid();
129
 
        uid_t euid = geteuid();
130
 
 
131
 
        /*
132
 
           Sanity check #1.
133
 
           This check should be made compile-time, but that's not possible.
134
 
           If you're sure that you specified a full path name for FULL_PATH,
135
 
           you can omit this check.
136
 
        */
137
 
        if (FULL_PATH[0] != '/') {
138
 
                fprintf(stderr, "%s: %s is not a full path name\n", argv[0],
139
 
                        FULL_PATH);
140
 
                fprintf(stderr, "You can only use this wrapper if you\n");
141
 
                fprintf(stderr, "compile it with an absolute path.\n");
142
 
                exit(1);
143
 
        }
144
 
 
145
 
        /*
146
 
           Sanity check #2.
147
 
           Check that the owner of the script is equal to either the
148
 
           effective uid or the super user.
149
 
        */
150
 
        if (stat(FULL_PATH, &statb) < 0) {
151
 
                perror("stat");
152
 
                exit(1);
153
 
        }
154
 
        if (statb.st_uid != 0 && statb.st_uid != euid) {
155
 
                fprintf(stderr, "%s: %s has the wrong owner\n", argv[0],
156
 
                        FULL_PATH);
157
 
                fprintf(stderr, "The script should be owned by root,\n");
158
 
                fprintf(stderr, "and shouldn't be writable by anyone.\n");
159
 
                exit(1);
160
 
        }
161
 
 
162
 
        if (setregid(egid, egid) < 0)
163
 
                perror("setregid");
164
 
        if (setreuid(euid, euid) < 0)
165
 
                perror("setreuid");
166
 
 
167
 
        clean_environ();
168
 
 
169
 
        umask(UMASK);
170
 
 
171
 
        while (**argv == '-')   /* don't let argv[0] start with '-' */
172
 
                (*argv)++;
173
 
        execv(FULL_PATH, argv);
174
 
        fprintf(stderr, "%s: could not execute the script\n", argv[0]);
175
 
        exit(1);
 
127
    struct stat statb;
 
128
    gid_t egid = getegid();
 
129
    uid_t euid = geteuid();
 
130
 
 
131
    /*
 
132
       Sanity check #1.
 
133
       This check should be made compile-time, but that's not possible.
 
134
       If you're sure that you specified a full path name for FULL_PATH,
 
135
       you can omit this check.
 
136
    */
 
137
    if (FULL_PATH[0] != '/') {
 
138
        fprintf(stderr, "%s: %s is not a full path name\n", argv[0],
 
139
            FULL_PATH);
 
140
        fprintf(stderr, "You can only use this wrapper if you\n");
 
141
        fprintf(stderr, "compile it with an absolute path.\n");
 
142
        exit(1);
 
143
    }
 
144
 
 
145
    /*
 
146
       Sanity check #2.
 
147
       Check that the owner of the script is equal to either the
 
148
       effective uid or the super user.
 
149
    */
 
150
    if (stat(FULL_PATH, &statb) < 0) {
 
151
        perror("stat");
 
152
        exit(1);
 
153
    }
 
154
    if (statb.st_uid != 0 && statb.st_uid != euid) {
 
155
        fprintf(stderr, "%s: %s has the wrong owner\n", argv[0],
 
156
            FULL_PATH);
 
157
        fprintf(stderr, "The script should be owned by root,\n");
 
158
        fprintf(stderr, "and shouldn't be writable by anyone.\n");
 
159
        exit(1);
 
160
    }
 
161
 
 
162
    if (setregid(egid, egid) < 0)
 
163
        perror("setregid");
 
164
    if (setreuid(euid, euid) < 0)
 
165
        perror("setreuid");
 
166
 
 
167
    clean_environ();
 
168
 
 
169
    umask(UMASK);
 
170
 
 
171
    while (**argv == '-')       /* don't let argv[0] start with '-' */
 
172
        (*argv)++;
 
173
    execv(FULL_PATH, argv);
 
174
    fprintf(stderr, "%s: could not execute the script\n", argv[0]);
 
175
    exit(1);
176
176
}