1 /* $Id: suid.c,v 1.3 2002/03/02 21:02:21 sverrehu Exp $ */
2 /**************************************************************************
3  *
4  *  FILE            suid.c
5  *
6  *  DESCRIPTION     Helper functions for programs running part time
7  *                  with a different effective user ID.
8  *
9  *                  The executable file must have the set-UID bit set.
10  *                  At startup, the function suidInit() is called to set
11  *                  the effective UID to the user running the program,
12  *                  to run securely.
13  *
14  *                  Before a privileged action is to be done, the function
15  *                  suidStartPrivilegedAction() is called to set the
16  *                  effective UID to the owner of the executable file.
17  *
18  *                  when the privileged action is done, call
19  *                  suidEndPrivilegedAction() to reenter the secure state
20  *                  where the effective UID matches the user running the
21  *                  program.
22  *
23  *                  I have tested this on Linux, Irix, Solaris and SunOS.
24  *                  If it doesn't work for you, and you fix it, please
25  *                  mail me a patch.
26  *
27  *  WRITTEN BY      Sverre H. Huseby <shh@thathost.com>
28  *
29  **************************************************************************/
30 
31 #include <sys/types.h>  /* uid_t */
32 #include <unistd.h>
33 
34 #include <shhmsg.h>
35 
36 #define HAVE_SETEUID    /* possibly move this to a Makefile or something */
37 
38 #ifdef HAVE_SETEUID
39 #  define SETUID seteuid
40 #else
41 #  define SETUID setuid
42 #endif
43 
44 /**************************************************************************
45  *                                                                        *
46  *                       P R I V A T E    D A T A                         *
47  *                                                                        *
48  **************************************************************************/
49 
50 static uid_t uidOwner;  /* the effective uid at startup */
51 static uid_t uidUser;   /* the real uid at startup */
52 
53 
54 
55 /**************************************************************************
56  *                                                                        *
57  *                    P U B L I C    F U N C T I O N S                    *
58  *                                                                        *
59  **************************************************************************/
60 
61 /*-------------------------------------------------------------------------
62  *
63  *  NAME          suidInit
64  *
65  *  FUNCTION      Do initialization at program startup.
66  *
67  *  SYNOPSIS      #include "suid.h"
68  *                void suidInit(void);
69  *
70  *  RETURNS       Nothing. Aborts the program in case of an error.
71  *
72  *  DESCRIPTION   Sets the effective UID equal to the real UID, to run
73  *                securely. Also sets up variables used by the other
74  *                functions.
75  */
76 void
suidInit(void)77 suidInit(void)
78 {
79     uidOwner = geteuid();
80     uidUser = getuid();
81     if (uidOwner == 0 && uidUser != 0)
82 	msgFatal("won't run as set-UID root\n");
83     if (SETUID(uidUser) < 0)
84 	msgFatalPerror("suidInit");
85 }
86 
87 /*-------------------------------------------------------------------------
88  *
89  *  NAME          suidStartPrivilegedAction
90  *
91  *  FUNCTION      Prepare a privileged action.
92  *
93  *  SYNOPSIS      #include "suid.h"
94  *                void suidStartPrivilegedAction(void);
95  *
96  *  RETURNS       Nothing. Aborts the program in case of an error.
97  *
98  *  DESCRIPTION   Sets the effective UID to the program owner.
99  */
100 void
suidStartPrivilegedAction(void)101 suidStartPrivilegedAction(void)
102 {
103     if (SETUID(uidOwner) < 0)
104 	msgFatalPerror("suidStartPrivilegedAction");
105 }
106 
107 /*-------------------------------------------------------------------------
108  *
109  *  NAME          suidEndPrivilegedAction
110  *
111  *  FUNCTION      Reenter secure mode after a privileged action.
112  *
113  *  SYNOPSIS      #include "suid.h"
114  *                void suidEndPrivilegedAction(void);
115  *
116  *  RETURNS       Nothing. Aborts the program in case of an error.
117  *
118  *  DESCRIPTION   Sets the effective UID to the program user.
119  */
120 void
suidEndPrivilegedAction(void)121 suidEndPrivilegedAction(void)
122 {
123     if (SETUID(uidUser) < 0)
124 	msgFatalPerror("suidEndPrivilegedAction");
125 }
126