privs.h revision 227269
1218893Sdim/* 2193326Sed * privs.h - header for privileged operations 3193326Sed * Copyright (C) 1993 Thomas Koenig 4193326Sed * 5193326Sed * Redistribution and use in source and binary forms, with or without 6193326Sed * modification, are permitted provided that the following conditions 7193326Sed * are met: 8193326Sed * 1. Redistributions of source code must retain the above copyright 9193326Sed * notice, this list of conditions and the following disclaimer. 10193326Sed * 2. The name of the author(s) may not be used to endorse or promote 11252723Sdim * products derived from this software without specific prior written 12252723Sdim * permission. 13252723Sdim * 14252723Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15193326Sed * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16252723Sdim * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17198893Srdivacky * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18198893Srdivacky * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19193326Sed * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20199512Srdivacky * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21263509Sdim * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22193326Sed * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23193326Sed * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24263509Sdim * 25198092Srdivacky * $FreeBSD: head/usr.bin/at/privs.h 227269 2011-11-06 20:30:21Z ed $ 26263509Sdim */ 27198893Srdivacky 28198092Srdivacky#ifndef _PRIVS_H 29263509Sdim#define _PRIVS_H 30263509Sdim 31263509Sdim#include <unistd.h> 32252723Sdim 33218893Sdim/* Relinquish privileges temporarily for a setuid or setgid program 34193326Sed * with the option of getting them back later. This is done by 35218893Sdim * utilizing POSIX saved user and group IDs. Call RELINQUISH_PRIVS once 36263509Sdim * at the beginning of the main program. This will cause all operations 37263509Sdim * to be executed with the real userid. When you need the privileges 38218893Sdim * of the setuid/setgid invocation, call PRIV_START; when you no longer 39252723Sdim * need it, call PRIV_END. Note that it is an error to call PRIV_START 40263509Sdim * and not PRIV_END within the same function. 41193326Sed * 42193326Sed * Use RELINQUISH_PRIVS_ROOT(a,b) if your program started out running 43193326Sed * as root, and you want to drop back the effective userid to a 44226890Sdim * and the effective group id to b, with the option to get them back 45263509Sdim * later. 46193326Sed * 47198092Srdivacky * If you no longer need root privileges, but those of some other 48198092Srdivacky * userid/groupid, you can call REDUCE_PRIV(a,b) when your effective 49198092Srdivacky * is the user's. 50198092Srdivacky * 51263509Sdim * Problems: Do not use return between PRIV_START and PRIV_END; this 52226890Sdim * will cause the program to continue running in an unprivileged 53198092Srdivacky * state. 54198092Srdivacky * 55198092Srdivacky * It is NOT safe to call exec(), system() or popen() with a user- 56198092Srdivacky * supplied program (i.e. without carefully checking PATH and any 57198092Srdivacky * library load paths) with relinquished privileges; the called program 58198092Srdivacky * can acquire them just as easily. Set both effective and real userid 59198092Srdivacky * to the real userid before calling any of them. 60198092Srdivacky */ 61198092Srdivacky 62198092Srdivacky#ifndef MAIN 63226890Sdimextern 64198092Srdivacky#endif 65198092Srdivackyuid_t real_uid, effective_uid; 66198092Srdivacky 67206084Srdivacky#ifndef MAIN 68206084Srdivackyextern 69226890Sdim#endif 70226890Sdimgid_t real_gid, effective_gid; 71206084Srdivacky 72206084Srdivacky#define RELINQUISH_PRIVS { \ 73206084Srdivacky real_uid = getuid(); \ 74206084Srdivacky effective_uid = geteuid(); \ 75206084Srdivacky real_gid = getgid(); \ 76206084Srdivacky effective_gid = getegid(); \ 77206084Srdivacky seteuid(real_uid); \ 78206084Srdivacky setegid(real_gid); \ 79206084Srdivacky} 80206084Srdivacky 81206084Srdivacky#define RELINQUISH_PRIVS_ROOT(a, b) { \ 82206084Srdivacky real_uid = (a); \ 83206084Srdivacky effective_uid = geteuid(); \ 84206084Srdivacky real_gid = (b); \ 85206084Srdivacky effective_gid = getegid(); \ 86206084Srdivacky setegid(real_gid); \ 87206084Srdivacky seteuid(real_uid); \ 88206084Srdivacky} 89206084Srdivacky 90206084Srdivacky#define PRIV_START { \ 91206084Srdivacky seteuid(effective_uid); \ 92206084Srdivacky setegid(effective_gid); \ 93206084Srdivacky} 94206084Srdivacky 95206084Srdivacky#define PRIV_END { \ 96235633Sdim setegid(real_gid); \ 97235633Sdim seteuid(real_uid); \ 98235633Sdim} 99235633Sdim 100235633Sdim#define REDUCE_PRIV(a, b) { \ 101245431Sdim PRIV_START \ 102245431Sdim effective_uid = (a); \ 103235633Sdim effective_gid = (b); \ 104235633Sdim setreuid((uid_t)-1, effective_uid); \ 105235633Sdim setregid((gid_t)-1, effective_gid); \ 106245431Sdim PRIV_END \ 107245431Sdim} 108245431Sdim#endif 109245431Sdim