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