]> git.pld-linux.org Git - packages/sudo.git/blob - sudo-selinux.patch
- add PAM session support to sudo
[packages/sudo.git] / sudo-selinux.patch
1 --- sudo-1.6.7p5/sesh.c.selinux 2004-07-08 13:18:28.000000000 -0400
2 +++ sudo-1.6.7p5/sesh.c 2004-07-08 13:18:28.000000000 -0400
3 @@ -0,0 +1,50 @@
4 +#include <stdio.h>
5 +#include <unistd.h>
6 +#include <limits.h>
7 +#include <sys/types.h>
8 +#include <sys/wait.h>
9 +#include <errno.h>
10 +
11 +main (int argc, char **argv) {
12 +  char buf[PATH_MAX];
13 +  pid_t pid;
14 +  if ( argc < 2 ) {
15 +    fprintf(stderr,"%s: Requires at least one argument\n", argv[0]);
16 +    exit(-1);
17 +  }
18 +  if ( argv[1][0] != '/' ) {
19 +    fprintf(stderr,"%s: First argument must have a full path\n", argv[0]);
20 +    exit(-1);
21 +  }
22 +
23 +  if ((pid = fork()) < 0) {
24 +    snprintf(buf, sizeof(buf), "%s: Couldn't fork");
25 +    perror(buf);
26 +    exit(-1);
27 +  } else if (pid > 0) {
28 +    /* Parent */
29 +    int status;
30 +    int ret;
31 +
32 +    do {
33 +      if ((ret = waitpid(pid, &status, 0)) < 0 && errno == EINTR)
34 +        continue;
35 +      else if (ret < 0) {
36 +        perror("waitpid failed");
37 +        exit(1);
38 +      }
39 +    } while (0);
40 +
41 +    if (WIFEXITED(status))
42 +      exit(WEXITSTATUS(status));
43 +    else
44 +      exit(1);
45 +  } else {
46 +    /* Child */
47 +    execv(argv[1], &argv[1]);
48 +
49 +    snprintf(buf, sizeof(buf), "%s: Error execing %s", argv[0], argv[1]);
50 +    perror(buf);
51 +    exit(-1);
52 +  }
53 +}
54 --- sudo-1.6.7p5/configure.in.selinux   2003-05-06 11:22:36.000000000 -0400
55 +++ sudo-1.6.7p5/configure.in   2004-07-08 13:18:28.000000000 -0400
56 @@ -90,7 +90,7 @@
57  dnl Initial values for Makefile variables listed above
58  dnl May be overridden by environment variables..
59  dnl
60 -PROGS="sudo visudo"
61 +PROGS="sudo visudo sesh"
62  test -n "$MANTYPE" || MANTYPE="man"
63  test -n "$mansrcdir" || mansrcdir="."
64  test -n "$SUDOERS_MODE" || SUDOERS_MODE=0440
65 --- sudo-1.6.8/sudo.c.orig      2004-08-07 01:42:52.000000000 +0200
66 +++ sudo-1.6.8/sudo.c   2004-08-29 20:45:31.556903000 +0200
67 @@ -92,6 +92,17 @@
68  #include "interfaces.h"
69  #include "version.h"
70  
71 +#ifdef WITH_SELINUX
72 +#include <selinux/flask.h>             /* for SECCLASS_CHR_FILE */
73 +#include <selinux/selinux.h>           /* for is_selinux_enabled() */
74 +#include <selinux/context.h>           /* for context-mangling functions */
75 +#include <selinux/get_default_type.h>
76 +char *role_s = NULL;                  /* role spec'd by user in argv[] */
77 +char *type_s = NULL;                  /* type spec'd by user in argv[] */
78 +security_context_t new_tty_context=NULL; /* security context to change to while running command*/
79 +security_context_t tty_context=NULL;  /* current security context of tty */
80 +#endif
81 +
82  #ifndef lint
83  static const char rcsid[] = "$Sudo: sudo.c,v 1.369 2004/08/06 23:42:52 millert Exp $";
84  #endif /* lint */
85 @@ -141,7 +152,151 @@
86  sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld;
87  void (*set_perms) __P((int));
88  
89 +#ifdef WITH_SELINUX
90 +security_context_t setup_tty_context(int fd, char *ttyn, security_context_t new_context) {
91 +  security_context_t tty_context=NULL;  /* current sid of tty */
92 +
93 +  tty_context = NULL;
94 +  if (fgetfilecon(fd,&tty_context) <0 ) 
95 +    fprintf(stderr, "Warning!  Could not get current context for %s, not relabeling.\n", ttyn);
96 +  
97 +#ifdef CANTSPELLGDB
98 +  if (tty_context)
99 +    printf("Your tty %s was labeled with context %s\n", ttyn, tty_context);
100 +#endif
101 +  
102 +  new_tty_context = NULL;
103 +  if (tty_context && security_compute_relabel(new_context,tty_context,SECCLASS_CHR_FILE,&new_tty_context) < 0)
104 +    fprintf(stderr, "Warning!  Could not get new context for %s, not relabeling.\n", ttyn);
105 +  
106 +#ifdef CANTSPELLGDB
107 +  if (new_tty_context)
108 +    printf("Relabeling tty %s to context %s\n", ttyn, new_tty_context);
109 +#endif
110 +  
111 +  if (new_tty_context) {
112 +    if( fsetfilecon(fd,new_tty_context)!=0 ) {
113 +      fprintf(stderr,"sudo: error: setfilecon on %s to %s",ttyn,new_tty_context);
114 +    }
115 +  }
116 +  return tty_context;
117 +}
118 +security_context_t get_exec_context(char *role_s, char *type_s) {
119 +
120 +  security_context_t old_context=NULL; /* our original securiy ID ("old_context") */
121 +  security_context_t new_context=NULL;  /* our target security ID ("sid") */
122 +
123 +  /*
124 +   *   
125 +   * Step 1:  Handle command-line arguments.
126 +   *
127 +   */
128 +  
129 +  security_context_t context_s;      /* our security context as a string */
130 +  int context_length;
131 +  context_t context;                 /* manipulatable form of context_s */
132 +  
133 +  
134 +  /*
135 +   * Get the SID and context of the caller, and extract
136 +   * the username from the context.  Don't rely on the Linux
137 +   * uid information - it isn't trustworthy.
138 +   */
139 +  
140 +  /* Put the caller's SID into `old_context'. */
141 +  if( 0!=(getprevcon(&old_context)) ) {
142 +    fprintf(stderr,"failed to get old_context.\n");
143 +    exit(-1);
144 +  }
145 +  
146 +#ifdef CANTSPELLGDB
147 +  printf( "Your old context was %s\n", old_context );
148 +#endif
149 +  /* 
150 +   * Create a context structure so that we extract and modify 
151 +   * components easily. 
152 +   */
153 +  context=context_new(old_context);
154 +  
155 +  /*
156 +   *
157 +   * Step 3:  Construct a new SID based on our old SID and the
158 +   *          arguments specified on the command line.
159 +   *
160 +   */
161 +  
162 +  /* The first step in constructing a new SID for the new shell we  *
163 +   * plan to exec is to take our old context in `context' as a   *
164 +   * starting point, and modify it according to the options the user *
165 +   * specified on the command line.                                  */
166 +
167 +  /* Set the SELinux user identity to root */
168 +  context_user_set(context, "root");
169 +  
170 +  /* If the user specified a new role on the command line (if `role_s'   *
171 +   * is set), then replace the old role in `context' with this new role. */
172 +  if( role_s ) {
173 +    if( !type_s ) {
174 +      if( get_default_type(role_s,&type_s) )
175 +       {
176 +         fprintf(stderr,"Couldn't get default type.\n");
177 +         exit(-1);
178 +       }
179 +#ifdef CANTSPELLGDB
180 +      printf( "Your type will be %s.\n", type_s );
181 +#endif  
182 +    }
183 +    
184 +    if( context_role_set(context,role_s)) {
185 +      fprintf(stderr,"failed to set new role %s\n",role_s);
186 +      exit(-1);
187 +    }
188 +#ifdef CANTSPELLGDB
189 +    printf("Your new role is %s\n",context_role_get(context));
190 +#endif
191 +    
192 +    /* If the user specified a new type on the command line (if `type_s'   *
193 +     * is set), then replace the old type in `context' with this new type. */
194 +    if( type_s ) {
195 +      if( context_type_set(context,type_s)) {
196 +       fprintf(stderr,"failed to set new type %s\n",type_s);
197 +       exit(-1);
198 +      }
199 +#ifdef CANTSPELLGDB
200 +      printf("Your new type is %s\n",context_type_get(context));
201 +#endif
202 +    } /* if user specified new type */
203 +    
204 +    /* The second step in creating the new SID is to convert our modified *
205 +     * `context' structure back to a context string and then to a SID.    */
206 +    
207 +    /* Make `context_s' point to a string version of the new `context'.  */
208 +    if( !(new_context=strdup(context_str(context)))) {
209 +      fprintf(stderr,"failed to convert new context to string\n" );
210 +      exit(-1);
211 +    }
212 +    
213 +  } /* if user specified new role */
214 +  else {
215 +    if (get_default_context(context_user_get(context),
216 +                           NULL,
217 +                           &new_context)) {
218 +      fprintf(stderr,"failed to get default context\n" );
219 +      exit(-1);
220 +    }
221 +  }
222 +  context_free(context);
223 +  freecon(old_context);
224 +
225 +  if (security_check_context(new_context) < 0) {
226 +    fprintf(stderr, "%s is not a valid context\n", new_context);
227 +    exit(-1);
228 +  }
229 +
230 +  return new_context;
231 +}
232  
233 +#endif
234  int
235  main(argc, argv, envp)
236      int argc;
237 @@ -149,10 +304,10 @@
238      char **envp;
239  {
240      int validated;
241 -    int fd;
242      int cmnd_status;
243      int sudo_mode;
244      int pwflag;
245 +    int fd;
246      char **new_environ;
247      sigaction_t sa;
248      extern int printmatches;
249 @@ -203,9 +358,6 @@
250      /* Setup defaults data structures. */
251      init_defaults();
252  
253 -    /* Load the list of local ip addresses and netmasks.  */
254 -    load_interfaces();
255 -
256      pwflag = 0;
257      if (ISSET(sudo_mode, MODE_SHELL))
258         user_cmnd = "shell";
259 @@ -219,6 +371,8 @@
260                     putchar('\n');
261                     dump_auth_methods();
262                     dump_defaults();
263 +                   /* Load the list of local ip addresses and netmasks.  */
264 +                   load_interfaces();
265                     dump_interfaces();
266                 }
267                 exit(0);
268 @@ -445,7 +599,43 @@
269  #ifndef PROFILING
270         if (ISSET(sudo_mode, MODE_BACKGROUND) && fork() > 0)
271             exit(0);
272 -       else
273 +#ifdef WITH_SELINUX
274 +       if(is_selinux_enabled() > 0) {
275 +         int fd;
276 +         char *ttyn   = NULL;                  /* tty path */
277 +         security_context_t new_context=NULL;  /* our target security ID ("sid") */
278 +         security_context_t chk_tty_context= NULL;
279 +
280 +         new_context=get_exec_context(role_s,type_s);
281 +#ifdef CANTSPELLGDB
282 +         printf("Your new context is %s\n",new_context);
283 +#endif
284 +
285 +         if (setexeccon(new_context) < 0) {
286 +           fprintf(stderr, "Could not set exec context to %s.\n", new_context);
287 +           exit(-1);
288 +         }
289 +         freecon(new_context);
290 +         {
291 +           /* 
292 +              SELinux will only not transition properly with the following
293 +              code.  Basically if the user chooses to use a different security
294 +              context.  We need to start the selinux shell, before executing 
295 +              the command.  This way the process transition will happen 
296 +              correctly. For example if they user wants to run rpm from 
297 +              sysadm_r.  Sudo will exec the /usr/sbin/sesh followed by the 
298 +              specified command.*/
299 +           char **dst, **src = NewArgv+1;
300 +           NewArgv = (char **) emalloc2((++NewArgc + 1), sizeof(char *));
301 +           NewArgv[0] = estrdup("sesh");
302 +           NewArgv[1] = safe_cmnd;
303 +           safe_cmnd = estrdup("/usr/sbin/sesh");
304 +           /* copy the args from Argv */
305 +           for (dst = NewArgv + 2; (*dst = *src) != NULL; ++src, ++dst)
306 +             ;
307 +         }
308 +       }
309 +#endif
310             EXECV(safe_cmnd, NewArgv);  /* run the command */
311  #else
312         exit(0);
313 @@ -729,6 +919,30 @@
314                 NewArgv++;
315                 break;
316  #endif
317 +#ifdef WITH_SELINUX
318 +           case 'r':
319 +               /* Must have an associated SELinux role. */
320 +               if (NewArgv[1] == NULL)
321 +                   usage(1);
322 +
323 +               role_s = NewArgv[1];
324 +
325 +               /* Shift Argv over and adjust Argc. */
326 +               NewArgc--;
327 +               NewArgv++;
328 +               break;
329 +           case 't':
330 +               /* Must have an associated SELinux type. */
331 +               if (NewArgv[1] == NULL)
332 +                   usage(1);
333 +
334 +               type_s = NewArgv[1];
335 +
336 +               /* Shift Argv over and adjust Argc. */
337 +               NewArgc--;
338 +               NewArgv++;
339 +               break;
340 +#endif
341  #ifdef HAVE_LOGIN_CAP_H
342             case 'c':
343                 /* Must have an associated login class. */
344 @@ -1111,6 +1325,9 @@
345  #ifdef HAVE_LOGIN_CAP_H
346         " [-c class|-]",
347  #endif
348 +#ifdef WITH_SELINUX
349 +       " [-r role] [-t type]",
350 +#endif
351         " [-p prompt]",
352         " [-u username|#uid]",
353         " { -e file [...] | -i | -s | <command> }",
354 --- sudo-1.6.8/sudo.man.in.orig 2004-08-17 20:53:39.000000000 +0200
355 +++ sudo-1.6.8/sudo.man.in      2004-08-29 20:48:39.189378528 +0200
356 @@ -156,7 +156,7 @@
357  .IX Header "SYNOPSIS"
358  \&\fBsudo\fR \fB\-K\fR | \fB\-L\fR | \fB\-V\fR | \fB\-h\fR | \fB\-k\fR | \fB\-l\fR | \fB\-v\fR
359  .PP
360 -\&\fBsudo\fR [\fB\-HPSb\fR] [\fB\-a\fR\ \fIauth_type\fR] [\fB\-c\fR\ \fIclass\fR|\fI\-\fR]
361 +\&\fBsudo\fR [\fB\-HPSb\fR] [\fB\-a\fR\ \fIauth_type\fR] [\fB\-c\fR\ \fIclass\fR|\fI\-\fR] [\fB\-r\fR \fIrole\fR ] [\fB\-t\fR \fItype\fR ]
362  [\fB\-p\fR\ \fIprompt\fR] [\fB\-u\fR\ \fIusername\fR|\fI#uid\fR]
363  {\fB\-e\fR\ file\ [...]\ |\ \fB\-i\fR\ |\ \fB\-s\fR\ |\ \fIcommand\fR}
364  .PP
365 @@ -235,6 +235,16 @@
366  \&\fBsudo\fR will initialize the group vector to the list of groups the
367  target user is in.  The real and effective group IDs, however, are
368  still set to match the target user.
369 +.IP "\-r" 4
370 +.IX Item "-r"
371 +The \fB\-r\fR (\fRrole\fR) option causes the new (SELinux) security context to have the role specified by
372 +\fIROLE\fR.
373 +.IP "\-t" 4
374 +.IX Item "-t" 
375 +The \fB\-t\fR (\fRtype\fR) option causes the new (SELinux) security context to have the have the type (domain)
376 +specified by
377 +\fITYPE\fR.
378 +If no type is specified, the default type is derived from the specified role.
379  .IP "\-S" 4
380  .IX Item "-S"
381  The \fB\-S\fR (\fIstdin\fR) option causes \fBsudo\fR to read the password from
382 --- sudo-1.6.8p1/Makefile.in.orig       2004-09-15 22:11:22.000000000 +0200
383 +++ sudo-1.6.8p1/Makefile.in    2004-09-19 12:26:11.212233352 +0200
384 @@ -43,7 +43,8 @@
385  # Libraries
386  LIBS = @LIBS@
387  NET_LIBS = @NET_LIBS@
388 -SUDO_LIBS = @SUDO_LIBS@ @AFS_LIBS@ $(LIBS) $(NET_LIBS)
389 +SELINUX_LIBS = -lselinux 
390 +SUDO_LIBS = @SUDO_LIBS@ @AFS_LIBS@ $(LIBS) $(NET_LIBS) $(SELINUX_LIBS)
391  
392  # C preprocessor flags
393  CPPFLAGS = -I. -I$(srcdir) @CPPFLAGS@
394 @@ -90,7 +91,7 @@
395  sudoers_mode = @SUDOERS_MODE@
396  
397  # Pass in paths and uid/gid + OS dependent defined
398 -DEFS = @OSDEFS@ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" -D_PATH_SUDOERS_TMP=\"$(sudoersdir)/sudoers.tmp\" -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) -DSUDOERS_MODE=$(sudoers_mode)
399 +DEFS = @OSDEFS@ -D_PATH_SUDOERS=\"$(sudoersdir)/sudoers\" -D_PATH_SUDOERS_TMP=\"$(sudoersdir)/sudoers.tmp\" -DSUDOERS_UID=$(sudoers_uid) -DSUDOERS_GID=$(sudoers_gid) -DSUDOERS_MODE=$(sudoers_mode) -DWITH_SELINUX
400  
401  #### End of system configuration section. ####
402  
403 @@ -104,7 +105,7 @@
404         parse.c parse.lex parse.yacc set_perms.c sigaction.c snprintf.c \
405         strcasecmp.c strerror.c strlcat.c strlcpy.c sudo.c sudo_noexec.c \
406         sudo.tab.c sudo_edit.c testsudoers.c tgetpass.c utimes.c visudo.c \
407 -       zero_bytes.c $(AUTH_SRCS)
408 +       zero_bytes.c $(AUTH_SRCS) sesh.c
409  
410  AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
411             auth/kerb4.c auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \
412 @@ -126,6 +127,8 @@
413  
414  VISUDOBJS = visudo.o fileops.o gettime.o goodpath.o find_path.o $(PARSEOBJS)
415  
416 +SESH_OBJS = sesh.o
417 +
418  TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS)
419  
420  LIBOBJS = @LIBOBJS@ @ALLOCA@
421 @@ -145,7 +148,7 @@
422  BINFILES= BUGS CHANGES HISTORY LICENSE README TODO TROUBLESHOOTING \
423           UPGRADE install-sh mkinstalldirs sample.syslog.conf sample.sudoers \
424           sudo sudo.cat sudo.man sudo.pod sudoers sudoers.cat sudoers.man \
425 -         sudoers.pod visudo visudo.cat visudo.man visudo.pod
426 +         sudoers.pod visudo visudo.cat visudo.man visudo.pod sesh
427  
428  BINSPECIAL= INSTALL.binary Makefile.binary libtool
429  
430 @@ -177,6 +180,9 @@
431  visudo: $(VISUDOBJS) $(LIBOBJS)
432         $(CC) -o $@ $(VISUDOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
433  
434 +sesh: $(SESH_OBJS) 
435 +       $(CC) -o $@ $(SESH_OBJS) $(LDFLAGS) $(LIBS)
436 +
437  testsudoers: $(TESTOBJS) $(LIBOBJS)
438         $(CC) -o $@ $(TESTOBJS) $(LIBOBJS) $(LDFLAGS) $(LIBS) $(NET_LIBS)
439  
440 @@ -215,6 +221,7 @@
441  set_perms.o: set_perms.c $(SUDODEP)
442  tgetpass.o: tgetpass.c $(SUDODEP)
443  visudo.o: visudo.c $(SUDODEP) version.h
444 +sesh.o: sesh.c 
445  sudo.o: sudo.c $(SUDODEP) interfaces.h version.h
446  interfaces.o: interfaces.c $(SUDODEP) interfaces.h
447  testsudoers.o: testsudoers.c $(SUDODEP) parse.h interfaces.h
448 @@ -306,6 +313,7 @@
449         ln $(DESTDIR)$(sudodir)/sudo $(DESTDIR)$(sudodir)/sudoedit
450  
451         $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s visudo $(DESTDIR)$(visudodir)/visudo
452 +       $(INSTALL) -O $(install_uid) -G $(install_gid) -M 0111 -s sesh $(DESTDIR)$(visudodir)/sesh
453  
454  install-noexec: sudo_noexec.la
455         $(LIBTOOL) --mode=install $(INSTALL) sudo_noexec.la $(DESTDIR)$(noexecdir)
This page took 0.126558 seconds and 3 git commands to generate.