privs.h revision 241852
11590Srgrimes/* 21590Srgrimes * privs.h - header for privileged operations 31590Srgrimes * Copyright (C) 1993 Thomas Koenig 41590Srgrimes * 51590Srgrimes * Redistribution and use in source and binary forms, with or without 61590Srgrimes * modification, are permitted provided that the following conditions 71590Srgrimes * are met: 81590Srgrimes * 1. Redistributions of source code must retain the above copyright 91590Srgrimes * notice, this list of conditions and the following disclaimer. 101590Srgrimes * 2. The name of the author(s) may not be used to endorse or promote 111590Srgrimes * products derived from this software without specific prior written 121590Srgrimes * permission. 131590Srgrimes * 141590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 151590Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 161590Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 171590Srgrimes * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 181590Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 191590Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 201590Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 211590Srgrimes * THEORY OF LIABILITY, WETHER IN CONTRACT, STRICT LIABILITY, OR TORT 221590Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 231590Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 241590Srgrimes * 251590Srgrimes * $FreeBSD: head/usr.bin/at/privs.h 241852 2012-10-22 03:31:22Z eadler $ 261590Srgrimes */ 271590Srgrimes 281590Srgrimes#ifndef _PRIVS_H 291590Srgrimes#define _PRIVS_H 301590Srgrimes 3187693Smarkm#include <unistd.h> 3287693Smarkm 3387693Smarkm/* Relinquish privileges temporarily for a setuid or setgid program 3487693Smarkm * with the option of getting them back later. This is done by 351590Srgrimes * utilizing POSIX saved user and group IDs. Call RELINQUISH_PRIVS once 3687693Smarkm * at the beginning of the main program. This will cause all operations 371590Srgrimes * to be executed with the real userid. When you need the privileges 381590Srgrimes * of the setuid/setgid invocation, call PRIV_START; when you no longer 3987693Smarkm * need it, call PRIV_END. Note that it is an error to call PRIV_START 401590Srgrimes * and not PRIV_END within the same function. 411590Srgrimes * 4287693Smarkm * Use RELINQUISH_PRIVS_ROOT(a,b) if your program started out running 4387693Smarkm * as root, and you want to drop back the effective userid to a 441590Srgrimes * and the effective group id to b, with the option to get them back 451590Srgrimes * later. 461590Srgrimes * 47282457Sbapt * If you no longer need root privileges, but those of some other 481590Srgrimes * userid/groupid, you can call REDUCE_PRIV(a,b) when your effective 4987693Smarkm * is the user's. 501590Srgrimes * 511590Srgrimes * Problems: Do not use return between PRIV_START and PRIV_END; this 5292922Simp * will cause the program to continue running in an unprivileged 531590Srgrimes * state. 54282457Sbapt * 5536053Sjb * It is NOT safe to call exec(), system() or popen() with a user- 56282457Sbapt * supplied program (i.e. without carefully checking PATH and any 571590Srgrimes * library load paths) with relinquished privileges; the called program 581590Srgrimes * can acquire them just as easily. Set both effective and real userid 591590Srgrimes * to the real userid before calling any of them. 601590Srgrimes */ 611590Srgrimes 621590Srgrimesextern uid_t real_uid, effective_uid; 631590Srgrimesextern gid_t real_gid, effective_gid; 641590Srgrimes 651590Srgrimes#ifdef MAIN 66282449Sbaptuid_t real_uid, effective_uid; 671590Srgrimesgid_t real_gid, effective_gid; 681590Srgrimes#endif 691590Srgrimes 701590Srgrimes#define RELINQUISH_PRIVS { \ 711590Srgrimes real_uid = getuid(); \ 721590Srgrimes effective_uid = geteuid(); \ 731590Srgrimes real_gid = getgid(); \ 741590Srgrimes effective_gid = getegid(); \ 751590Srgrimes if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \ 761590Srgrimes if (setegid(real_gid) != 0) err(1, "setegid failed"); \ 771590Srgrimes} 781590Srgrimes 791590Srgrimes#define RELINQUISH_PRIVS_ROOT(a, b) { \ 801590Srgrimes real_uid = (a); \ 811590Srgrimes effective_uid = geteuid(); \ 821590Srgrimes real_gid = (b); \ 831590Srgrimes effective_gid = getegid(); \ 841590Srgrimes if (setegid(real_gid) != 0) err(1, "setegid failed"); \ 851590Srgrimes if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \ 861590Srgrimes} 871590Srgrimes 881590Srgrimes#define PRIV_START { \ 891590Srgrimes if (seteuid(effective_uid) != 0) err(1, "seteuid failed"); \ 901590Srgrimes if (setegid(effective_gid) != 0) err(1, "setegid failed"); \ 911590Srgrimes} 921590Srgrimes 931590Srgrimes#define PRIV_END { \ 94284047Sbapt if (setegid(real_gid) != 0) err(1, "setegid failed"); \ 951590Srgrimes if (seteuid(real_uid) != 0) err(1, "seteuid failed"); \ 961590Srgrimes} 971590Srgrimes 981590Srgrimes#define REDUCE_PRIV(a, b) { \ 991590Srgrimes PRIV_START \ 1001590Srgrimes effective_uid = (a); \ 1011590Srgrimes effective_gid = (b); \ 1021590Srgrimes if (setreuid((uid_t)-1, effective_uid) != 0) err(1, "setreuid failed"); \ 1031590Srgrimes if (setregid((gid_t)-1, effective_gid) != 0) err(1, "setregid failed"); \ 1041590Srgrimes PRIV_END \ 1051590Srgrimes} 1061590Srgrimes#endif 1071590Srgrimes