1/* uid.c 2 Switch back and forth between UUCP and user permissions. 3 4 Copyright (C) 1992, 1995, 2002 Ian Lance Taylor 5 6 This file is part of the Taylor UUCP package. 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License as 10 published by the Free Software Foundation; either version 2 of the 11 License, or (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 22 The author of the program may be contacted at ian@airs.com. 23 */ 24 25#include "uucp.h" 26 27#include "uudefs.h" 28#include "sysdep.h" 29 30#include <errno.h> 31 32/* NetBSD apparently does not support setuid as required by POSIX when 33 using saved setuid, so use seteuid instead. */ 34 35#if HAVE_SETEUID 36#define setuid seteuid 37#endif 38 39/* Switch to permissions of the invoking user. */ 40 41boolean 42fsuser_perms (pieuid, piegid) 43 uid_t *pieuid; 44 gid_t *piegid; 45{ 46 uid_t ieuid, iuid; 47 gid_t iegid, igid; 48 49 ieuid = geteuid (); 50 iuid = getuid (); 51 if (pieuid != NULL) 52 *pieuid = ieuid; 53 54 iegid = getegid (); 55 igid = getgid (); 56 if (piegid != NULL) 57 *piegid = iegid; 58 59#if HAVE_SETREUID 60 /* Swap the effective user id and the real user id. We can then 61 swap them back again when we want to return to the uucp user's 62 permissions. */ 63 if (setregid (iegid, igid) < 0) 64 { 65 ulog (LOG_ERROR, "setregid (%ld, %ld): %s", 66 (long) iegid, (long) igid, strerror (errno)); 67 return FALSE; 68 } 69 if (setreuid (ieuid, iuid) < 0) 70 { 71 ulog (LOG_ERROR, "setreuid (%ld, %ld): %s", 72 (long) ieuid, (long) iuid, strerror (errno)); 73 return FALSE; 74 } 75#else /* ! HAVE_SETREUID */ 76#if HAVE_SAVED_SETUID 77 /* Set the effective user id to the real user id. Since the 78 effective user id is saved (it's the saved setuid) we will able 79 to set back to it later. If the real user id is root we will not 80 be able to switch back and forth, so don't even try. */ 81 if (iuid != 0) 82 { 83 if (setgid (igid) < 0) 84 { 85 ulog (LOG_ERROR, "setgid (%ld): %s", (long) igid, strerror (errno)); 86 return FALSE; 87 } 88 if (setuid (iuid) < 0) 89 { 90 ulog (LOG_ERROR, "setuid (%ld): %s", (long) iuid, strerror (errno)); 91 return FALSE; 92 } 93 } 94#else /* ! HAVE_SAVED_SETUID */ 95 /* There's no way to switch between real permissions and effective 96 permissions. Just try to open the file with the uucp 97 permissions. */ 98#endif /* ! HAVE_SAVED_SETUID */ 99#endif /* ! HAVE_SETREUID */ 100 101 return TRUE; 102} 103 104/* Restore the uucp permissions. */ 105 106/*ARGSUSED*/ 107boolean 108fsuucp_perms (ieuid, iegid) 109 long ieuid ATTRIBUTE_UNUSED; 110 long iegid ATTRIBUTE_UNUSED; 111{ 112#if HAVE_SETREUID 113 /* Swap effective and real user id's back to what they were. */ 114 if (! fsuser_perms ((uid_t *) NULL, (gid_t *) NULL)) 115 return FALSE; 116#else /* ! HAVE_SETREUID */ 117#if HAVE_SAVED_SETUID 118 /* Set ourselves back to our original effective user id. */ 119 if (setgid ((gid_t) iegid) < 0) 120 { 121 ulog (LOG_ERROR, "setgid (%ld): %s", (long) iegid, strerror (errno)); 122 /* Is this error message helpful or confusing? */ 123 if (errno == EPERM) 124 ulog (LOG_ERROR, 125 "Probably HAVE_SAVED_SETUID in policy.h should be set to 0"); 126 return FALSE; 127 } 128 if (setuid ((uid_t) ieuid) < 0) 129 { 130 ulog (LOG_ERROR, "setuid (%ld): %s", (long) ieuid, strerror (errno)); 131 /* Is this error message helpful or confusing? */ 132 if (errno == EPERM) 133 ulog (LOG_ERROR, 134 "Probably HAVE_SAVED_SETUID in policy.h should be set to 0"); 135 return FALSE; 136 } 137#else /* ! HAVE_SAVED_SETUID */ 138 /* We didn't switch, no need to switch back. */ 139#endif /* ! HAVE_SAVED_SETUID */ 140#endif /* ! HAVE_SETREUID */ 141 142 return TRUE; 143} 144