1511b41d2SMark Murray /* 2511b41d2SMark Murray * Author: Tatu Ylonen <ylo@cs.hut.fi> 3511b41d2SMark Murray * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4511b41d2SMark Murray * All rights reserved 5511b41d2SMark Murray * Created: Sat Sep 9 01:56:14 1995 ylo 6511b41d2SMark Murray * Code for uid-swapping. 7511b41d2SMark Murray */ 8511b41d2SMark Murray 9511b41d2SMark Murray #include "includes.h" 10511b41d2SMark Murray RCSID("$Id: uidswap.c,v 1.5 1999/11/24 19:53:54 markus Exp $"); 11511b41d2SMark Murray 12511b41d2SMark Murray #include "ssh.h" 13511b41d2SMark Murray #include "uidswap.h" 14511b41d2SMark Murray 15511b41d2SMark Murray /* 16511b41d2SMark Murray * Note: all these functions must work in all of the following cases: 17511b41d2SMark Murray * 1. euid=0, ruid=0 18511b41d2SMark Murray * 2. euid=0, ruid!=0 19511b41d2SMark Murray * 3. euid!=0, ruid!=0 20511b41d2SMark Murray * Additionally, they must work regardless of whether the system has 21511b41d2SMark Murray * POSIX saved uids or not. 22511b41d2SMark Murray */ 23511b41d2SMark Murray 24511b41d2SMark Murray #ifdef _POSIX_SAVED_IDS 25511b41d2SMark Murray /* Lets assume that posix saved ids also work with seteuid, even though that 26511b41d2SMark Murray is not part of the posix specification. */ 27511b41d2SMark Murray #define SAVED_IDS_WORK_WITH_SETEUID 28511b41d2SMark Murray #endif /* _POSIX_SAVED_IDS */ 29511b41d2SMark Murray 30511b41d2SMark Murray /* Saved effective uid. */ 31511b41d2SMark Murray static uid_t saved_euid = 0; 32511b41d2SMark Murray 33511b41d2SMark Murray /* 34511b41d2SMark Murray * Temporarily changes to the given uid. If the effective user 35511b41d2SMark Murray * id is not root, this does nothing. This call cannot be nested. 36511b41d2SMark Murray */ 37511b41d2SMark Murray void 38511b41d2SMark Murray temporarily_use_uid(uid_t uid) 39511b41d2SMark Murray { 40511b41d2SMark Murray #ifdef SAVED_IDS_WORK_WITH_SETEUID 41511b41d2SMark Murray /* Save the current euid. */ 42511b41d2SMark Murray saved_euid = geteuid(); 43511b41d2SMark Murray 44511b41d2SMark Murray /* Set the effective uid to the given (unprivileged) uid. */ 45511b41d2SMark Murray if (seteuid(uid) == -1) 46511b41d2SMark Murray debug("seteuid %d: %.100s", (int) uid, strerror(errno)); 47511b41d2SMark Murray #else /* SAVED_IDS_WORK_WITH_SETUID */ 48511b41d2SMark Murray /* Propagate the privileged uid to all of our uids. */ 49511b41d2SMark Murray if (setuid(geteuid()) < 0) 50511b41d2SMark Murray debug("setuid %d: %.100s", (int) geteuid(), strerror(errno)); 51511b41d2SMark Murray 52511b41d2SMark Murray /* Set the effective uid to the given (unprivileged) uid. */ 53511b41d2SMark Murray if (seteuid(uid) == -1) 54511b41d2SMark Murray debug("seteuid %d: %.100s", (int) uid, strerror(errno)); 55511b41d2SMark Murray #endif /* SAVED_IDS_WORK_WITH_SETEUID */ 56511b41d2SMark Murray } 57511b41d2SMark Murray 58511b41d2SMark Murray /* 59511b41d2SMark Murray * Restores to the original uid. 60511b41d2SMark Murray */ 61511b41d2SMark Murray void 62511b41d2SMark Murray restore_uid() 63511b41d2SMark Murray { 64511b41d2SMark Murray #ifdef SAVED_IDS_WORK_WITH_SETEUID 65511b41d2SMark Murray /* Set the effective uid back to the saved uid. */ 66511b41d2SMark Murray if (seteuid(saved_euid) < 0) 67511b41d2SMark Murray debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno)); 68511b41d2SMark Murray #else /* SAVED_IDS_WORK_WITH_SETEUID */ 69511b41d2SMark Murray /* 70511b41d2SMark Murray * We are unable to restore the real uid to its unprivileged value. 71511b41d2SMark Murray * Propagate the real uid (usually more privileged) to effective uid 72511b41d2SMark Murray * as well. 73511b41d2SMark Murray */ 74511b41d2SMark Murray setuid(getuid()); 75511b41d2SMark Murray #endif /* SAVED_IDS_WORK_WITH_SETEUID */ 76511b41d2SMark Murray } 77511b41d2SMark Murray 78511b41d2SMark Murray /* 79511b41d2SMark Murray * Permanently sets all uids to the given uid. This cannot be 80511b41d2SMark Murray * called while temporarily_use_uid is effective. 81511b41d2SMark Murray */ 82511b41d2SMark Murray void 83511b41d2SMark Murray permanently_set_uid(uid_t uid) 84511b41d2SMark Murray { 85511b41d2SMark Murray if (setuid(uid) < 0) 86511b41d2SMark Murray debug("setuid %d: %.100s", (int) uid, strerror(errno)); 87511b41d2SMark Murray } 88