~malept/ubuntu/lucid/python2.6/dev-dependency-fix

« back to all changes in this revision

Viewing changes to Misc/setuid-prog.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-02-13 12:51:00 UTC
  • Revision ID: james.westby@ubuntu.com-20090213125100-uufgcb9yeqzujpqw
Tags: upstream-2.6.1
ImportĀ upstreamĀ versionĀ 2.6.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Template for a setuid program that calls a script.
 
3
 
 
4
   The script should be in an unwritable directory and should itself
 
5
   be unwritable.  In fact all parent directories up to the root
 
6
   should be unwritable.  The script must not be setuid, that's what
 
7
   this program is for.
 
8
 
 
9
   This is a template program.  You need to fill in the name of the
 
10
   script that must be executed.  This is done by changing the
 
11
   definition of FULL_PATH below.
 
12
 
 
13
   There are also some rules that should be adhered to when writing
 
14
   the script itself.
 
15
 
 
16
   The first and most important rule is to never, ever trust that the
 
17
   user of the program will behave properly.  Program defensively.
 
18
   Check your arguments for reasonableness.  If the user is allowed to
 
19
   create files, check the names of the files.  If the program depends
 
20
   on argv[0] for the action it should perform, check it.
 
21
 
 
22
   Assuming the script is a Bourne shell script, the first line of the
 
23
   script should be
 
24
        #!/bin/sh -
 
25
   The - is important, don't omit it.  If you're using esh, the first
 
26
   line should be
 
27
        #!/usr/local/bin/esh -f
 
28
   and for ksh, the first line should be
 
29
        #!/usr/local/bin/ksh -p
 
30
   The script should then set the variable IFS to the string
 
31
   consisting of <space>, <tab>, and <newline>.  After this (*not*
 
32
   before!), the PATH variable should be set to a reasonable value and
 
33
   exported.  Do not expect the PATH to have a reasonable value, so do
 
34
   not trust the old value of PATH.  You should then set the umask of
 
35
   the program by calling
 
36
        umask 077 # or 022 if you want the files to be readable
 
37
   If you plan to change directories, you should either unset CDPATH
 
38
   or set it to a good value.  Setting CDPATH to just ``.'' (dot) is a
 
39
   good idea.
 
40
   If, for some reason, you want to use csh, the first line should be
 
41
        #!/bin/csh -fb
 
42
   You should then set the path variable to something reasonable,
 
43
   without trusting the inherited path.  Here too, you should set the
 
44
   umask using the command
 
45
        umask 077 # or 022 if you want the files to be readable
 
46
*/
 
47
 
 
48
#include <unistd.h>
 
49
#include <stdlib.h>
 
50
#include <stdio.h>
 
51
#include <sys/types.h>
 
52
#include <sys/stat.h>
 
53
#include <string.h>
 
54
 
 
55
/* CONFIGURATION SECTION */
 
56
 
 
57
#ifndef FULL_PATH       /* so that this can be specified from the Makefile */
 
58
/* Uncomment the following line:
 
59
#define FULL_PATH       "/full/path/of/script" 
 
60
* Then comment out the #error line. */
 
61
#error "You must define FULL_PATH somewhere"
 
62
#endif
 
63
#ifndef UMASK
 
64
#define UMASK           077
 
65
#endif
 
66
 
 
67
/* END OF CONFIGURATION SECTION */
 
68
 
 
69
#if defined(__STDC__) && defined(__sgi)
 
70
#define environ _environ
 
71
#endif
 
72
 
 
73
/* don't change def_IFS */
 
74
char def_IFS[] = "IFS= \t\n";
 
75
/* you may want to change def_PATH, but you should really change it in */
 
76
/* your script */
 
77
#ifdef __sgi
 
78
char def_PATH[] = "PATH=/usr/bsd:/usr/bin:/bin:/usr/local/bin:/usr/sbin";
 
79
#else
 
80
char def_PATH[] = "PATH=/usr/ucb:/usr/bin:/bin:/usr/local/bin";
 
81
#endif
 
82
/* don't change def_CDPATH */
 
83
char def_CDPATH[] = "CDPATH=.";
 
84
/* don't change def_ENV */
 
85
char def_ENV[] = "ENV=:";
 
86
 
 
87
/*
 
88
   This function changes all environment variables that start with LD_
 
89
   into variables that start with XD_.  This is important since we
 
90
   don't want the script that is executed to use any funny shared
 
91
   libraries.
 
92
 
 
93
   The other changes to the environment are, strictly speaking, not
 
94
   needed here.  They can safely be done in the script.  They are done
 
95
   here because we don't trust the script writer (just like the script
 
96
   writer shouldn't trust the user of the script).
 
97
   If IFS is set in the environment, set it to space,tab,newline.
 
98
   If CDPATH is set in the environment, set it to ``.''.
 
99
   Set PATH to a reasonable default.
 
100
*/
 
101
void
 
102
clean_environ(void)
 
103
{
 
104
        char **p;
 
105
        extern char **environ;
 
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);
 
122
}
 
123
 
 
124
int
 
125
main(int argc, char **argv)
 
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 writeable 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
}