Projet

Général

Profil

Télécharger (5,26 ko) Statistiques
| Branche: | Révision:

root / larpe-reload-apache2.c @ master

1 223dc031 dlaniel
/*
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
  #define FULL_PATH	"/usr/sbin/larpe-reload-apache2-script"
59
#endif
60
#ifndef UMASK
61
  #define UMASK		077
62
#endif
63
64
/* END OF CONFIGURATION SECTION */
65
66
#if defined(__STDC__) && defined(__sgi)
67
#define environ _environ
68
#endif
69
70
/* don't change def_IFS */
71
char def_IFS[] = "IFS= \t\n";
72
/* you may want to change def_PATH, but you should really change it in */
73
/* your script */
74
#ifdef __sgi
75
char def_PATH[] = "PATH=/usr/bsd:/usr/bin:/bin:/usr/local/bin:/usr/sbin";
76
#else
77
char def_PATH[] = "PATH=/usr/ucb:/usr/bin:/bin:/usr/local/bin";
78
#endif
79
/* don't change def_CDPATH */
80
char def_CDPATH[] = "CDPATH=.";
81
/* don't change def_ENV */
82
char def_ENV[] = "ENV=:";
83
84
/*
85
  This function changes all environment variables that start with LD_
86
  into variables that start with XD_.  This is important since we
87
  don't want the script that is executed to use any funny shared
88
  libraries.
89
90
  The other changes to the environment are, strictly speaking, not
91
  needed here.  They can safely be done in the script.  They are done
92
  here because we don't trust the script writer (just like the script
93
  writer shouldn't trust the user of the script).
94
  If IFS is set in the environment, set it to space,tab,newline.
95
  If CDPATH is set in the environment, set it to ``.''.
96
  Set PATH to a reasonable default.
97
*/
98
void
99
clean_environ(void)
100
{
101
    char **p;
102
    extern char **environ;
103
104
    for (p = environ; *p; p++) {
105
	if (strncmp(*p, "LD_", 3) == 0)
106
	    **p = 'X';
107
	else if (strncmp(*p, "_RLD", 4) == 0)
108
	    **p = 'X';
109
	else if (strncmp(*p, "PYTHON", 6) == 0)
110
	    **p = 'X';
111
	else if (strncmp(*p, "IFS=", 4) == 0)
112
	    *p = def_IFS;
113
	else if (strncmp(*p, "CDPATH=", 7) == 0)
114
	    *p = def_CDPATH;
115
	else if (strncmp(*p, "ENV=", 4) == 0)
116
	    *p = def_ENV;
117
    }
118
    putenv(def_PATH);
119
}
120
121
int
122
main(int argc, char **argv)
123
{
124
    struct stat statb;
125
    gid_t egid = getegid();
126
    uid_t euid = geteuid();
127
128
    /*
129
      Sanity check #1.
130
      This check should be made compile-time, but that's not possible.
131
      If you're sure that you specified a full path name for FULL_PATH,
132
      you can omit this check.
133
    */
134
    if (FULL_PATH[0] != '/') {
135
	fprintf(stderr, "%s: %s is not a full path name\n", argv[0],
136
		FULL_PATH);
137
	fprintf(stderr, "You can only use this wrapper if you\n");
138
	fprintf(stderr, "compile it with an absolute path.\n");
139
	exit(1);
140
    }
141
142
    /*
143
      Sanity check #2.
144
      Check that the owner of the script is equal to either the
145
      effective uid or the super user.
146
    */
147
    if (stat(FULL_PATH, &statb) < 0) {
148
	perror("stat");
149
	exit(1);
150
    }
151
    if (statb.st_uid != 0 && statb.st_uid != euid) {
152
	fprintf(stderr, "%s: %s has the wrong owner\n", argv[0],
153
		FULL_PATH);
154
	fprintf(stderr, "The script should be owned by root,\n");
155
	fprintf(stderr, "and shouldn't be writeable by anyone.\n");
156
	exit(1);
157
    }
158
159
    if (setregid(egid, egid) < 0)
160
	perror("setregid");
161
    if (setreuid(euid, euid) < 0)
162
	perror("setreuid");
163
164
    clean_environ();
165
166
    umask(UMASK);
167
168
    while (**argv == '-')/* don't let argv[0] start with '-' */
169
	(*argv)++;
170
    execv(FULL_PATH, argv);
171
    fprintf(stderr, "%s: could not execute the script\n", argv[0]);
172
    exit(1);
173
}