xref: /freebsd/usr.bin/at/privs.h (revision 5ebc7e6281887681c3a348a5a4c902e262ccd656)
1 /*
2  *  privs.h - header for privileged operations
3  *  Copyright (C) 1993  Thomas Koenig
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 
20 #ifndef _PRIVS_H
21 #define _PRIVS_H
22 
23 #ifndef _USE_BSD
24 #define _USE_BSD 1
25 #include <unistd.h>
26 #undef _USE_BSD
27 #else
28 #include <unistd.h>
29 #endif
30 
31 /* Relinquish privileges temporarily for a setuid or setgid program
32  * with the option of getting them back later.  This is done by swapping
33  * the real and effective userid BSD style.  Call RELINQUISH_PRIVS once
34  * at the beginning of the main program.  This will cause all operatons
35  * to be executed with the real userid.  When you need the privileges
36  * of the setuid/setgid invocation, call PRIV_START; when you no longer
37  * need it, call PRIV_END.  Note that it is an error to call PRIV_START
38  * and not PRIV_END within the same function.
39  *
40  * Use RELINQUISH_PRIVS_ROOT(a,b) if your program started out running
41  * as root, and you want to drop back the effective userid to a
42  * and the effective group id to b, with the option to get them back
43  * later.
44  *
45  * If you no longer need root privileges, but those of some other
46  * userid/groupid, you can call REDUCE_PRIV(a,b) when your effective
47  * is the user's.
48  *
49  * Problems: Do not use return between PRIV_START and PRIV_END; this
50  * will cause the program to continue running in an unprivileged
51  * state.
52  *
53  * It is NOT safe to call exec(), system() or popen() with a user-
54  * supplied program (i.e. without carefully checking PATH and any
55  * library load paths) with relinquished privileges; the called program
56  * can aquire them just as easily.  Set both effective and real userid
57  * to the real userid before calling any of them.
58  */
59 
60 #ifndef MAIN
61 extern
62 #endif
63 uid_t real_uid, effective_uid;
64 
65 #ifndef MAIN
66 extern
67 #endif
68 gid_t real_gid, effective_gid;
69 
70 #define RELINQUISH_PRIVS { \
71 			      real_uid = getuid(); \
72 			      effective_uid = geteuid(); \
73 			      real_gid = getgid(); \
74 			      effective_gid = getegid(); \
75 			      setreuid(effective_uid, real_uid); \
76 			      setregid(effective_gid, real_gid); \
77 		          }
78 
79 #define RELINQUISH_PRIVS_ROOT(a,b) { \
80 			      real_uid = (a); \
81 			      effective_uid = geteuid(); \
82 			      real_gid = (b); \
83 			      effective_gid = getegid(); \
84 			      setreuid(effective_uid, real_uid); \
85 			      setregid(effective_gid, real_gid); \
86 		          }
87 
88 #define PRIV_START {\
89 		    setreuid(real_uid, effective_uid); \
90 		    setregid(real_gid, effective_gid);
91 
92 #define PRIV_END \
93 		    setreuid(effective_uid, real_uid); \
94 		    setregid(effective_gid, real_gid); \
95 		    }
96 
97 #define REDUCE_PRIV(a,b) {\
98 			setreuid(real_uid, effective_uid); \
99 			setregid(real_gid, effective_gid); \
100 			effective_uid = (a); \
101 			effective_gid = (b); \
102 			setregid(effective_gid, real_gid); \
103 			setreuid(effective_uid, real_uid); \
104 		    }
105 #endif
106