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