1 /* 2 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * All rights reserved 5 * Created: Sat Sep 9 01:56:14 1995 ylo 6 * Code for uid-swapping. 7 */ 8 9 #include "includes.h" 10 RCSID("$Id: uidswap.c,v 1.5 1999/11/24 19:53:54 markus Exp $"); 11 12 #include "ssh.h" 13 #include "uidswap.h" 14 15 /* 16 * Note: all these functions must work in all of the following cases: 17 * 1. euid=0, ruid=0 18 * 2. euid=0, ruid!=0 19 * 3. euid!=0, ruid!=0 20 * Additionally, they must work regardless of whether the system has 21 * POSIX saved uids or not. 22 */ 23 24 #ifdef _POSIX_SAVED_IDS 25 /* Lets assume that posix saved ids also work with seteuid, even though that 26 is not part of the posix specification. */ 27 #define SAVED_IDS_WORK_WITH_SETEUID 28 #endif /* _POSIX_SAVED_IDS */ 29 30 /* Saved effective uid. */ 31 static uid_t saved_euid = 0; 32 33 /* 34 * Temporarily changes to the given uid. If the effective user 35 * id is not root, this does nothing. This call cannot be nested. 36 */ 37 void 38 temporarily_use_uid(uid_t uid) 39 { 40 #ifdef SAVED_IDS_WORK_WITH_SETEUID 41 /* Save the current euid. */ 42 saved_euid = geteuid(); 43 44 /* Set the effective uid to the given (unprivileged) uid. */ 45 if (seteuid(uid) == -1) 46 debug("seteuid %d: %.100s", (int) uid, strerror(errno)); 47 #else /* SAVED_IDS_WORK_WITH_SETUID */ 48 /* Propagate the privileged uid to all of our uids. */ 49 if (setuid(geteuid()) < 0) 50 debug("setuid %d: %.100s", (int) geteuid(), strerror(errno)); 51 52 /* Set the effective uid to the given (unprivileged) uid. */ 53 if (seteuid(uid) == -1) 54 debug("seteuid %d: %.100s", (int) uid, strerror(errno)); 55 #endif /* SAVED_IDS_WORK_WITH_SETEUID */ 56 } 57 58 /* 59 * Restores to the original uid. 60 */ 61 void 62 restore_uid() 63 { 64 #ifdef SAVED_IDS_WORK_WITH_SETEUID 65 /* Set the effective uid back to the saved uid. */ 66 if (seteuid(saved_euid) < 0) 67 debug("seteuid %d: %.100s", (int) saved_euid, strerror(errno)); 68 #else /* SAVED_IDS_WORK_WITH_SETEUID */ 69 /* 70 * We are unable to restore the real uid to its unprivileged value. 71 * Propagate the real uid (usually more privileged) to effective uid 72 * as well. 73 */ 74 setuid(getuid()); 75 #endif /* SAVED_IDS_WORK_WITH_SETEUID */ 76 } 77 78 /* 79 * Permanently sets all uids to the given uid. This cannot be 80 * called while temporarily_use_uid is effective. 81 */ 82 void 83 permanently_set_uid(uid_t uid) 84 { 85 if (setuid(uid) < 0) 86 debug("setuid %d: %.100s", (int) uid, strerror(errno)); 87 } 88