summaryrefslogtreecommitdiff
path: root/usr.bin/ssh/uidswap.c
blob: 314be45298000b03746f2712e5bbbbc6af5f5a83 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*

uidswap.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Sat Sep  9 01:56:14 1995 ylo

Code for uid-swapping.

*/

#include "includes.h"
RCSID("$Id: uidswap.c,v 1.1 1999/09/26 20:53:38 deraadt Exp $");

#include "ssh.h"
#include "uidswap.h"

/* Note: all these functions must work in all of the following cases:

   1. euid=0, ruid=0
   2. euid=0, ruid!=0
   3. euid!=0, ruid!=0

   Additionally, they must work regardless of whether the system has
   POSIX saved uids or not. */

#ifdef HAVE_SETEUID

#ifdef _POSIX_SAVED_IDS
/* Lets assume that posix saved ids also work with seteuid, even though that
   is not part of the posix specification. */
#define SAVED_IDS_WORK_WITH_SETEUID
#endif /* _POSIX_SAVED_IDS */

/* Saved effective uid. */
static uid_t saved_euid = 0;

/* Temporarily changes to the given uid.  If the effective user id is not
   root, this does nothing.  This call cannot be nested. */

void temporarily_use_uid(uid_t uid)
{
#ifdef SAVED_IDS_WORK_WITH_SETEUID

  /* Save the current euid. */
  saved_euid = geteuid();

  /* Set the effective uid to the given (unprivileged) uid. */
  if (seteuid(uid) == -1)
    debug("seteuid %d: %.100s", (int)uid, strerror(errno));

#else /* SAVED_IDS_WORK_WITH_SETUID */

  /* Propagate the privileged uid to all of our uids. */
  if (setuid(geteuid()) < 0)
    debug("setuid %d: %.100s", (int)geteuid(), strerror(errno));

  /* Set the effective uid to the given (unprivileged) uid. */
  if (seteuid(uid) == -1)
    debug("seteuid %d: %.100s", (int)uid, strerror(errno));

#endif /* SAVED_IDS_WORK_WITH_SETEUID */

}

/* Restores to the original uid. */

void restore_uid()
{
#ifdef SAVED_IDS_WORK_WITH_SETEUID

  /* Set the effective uid back to the saved uid. */
  if (seteuid(saved_euid) < 0)
    debug("seteuid %d: %.100s", (int)saved_euid, strerror(errno));

#else /* SAVED_IDS_WORK_WITH_SETEUID */

  /* We are unable to restore the real uid to its unprivileged value. */
  /* Propagate the real uid (usually more privileged) to effective uid
     as well. */
  setuid(getuid());

#endif /* SAVED_IDS_WORK_WITH_SETEUID */
}

/* Permanently sets all uids to the given uid.  This cannot be called while
   temporarily_use_uid is effective. */

void permanently_set_uid(uid_t uid)
{
  if (setuid(uid) < 0)
    debug("setuid %d: %.100s", (int)uid, strerror(errno));
}

#else /* HAVE_SETEUID */

YOUR_SYSTEM_DOES_NOT_PERMIT_UID_SWAPPING_READ_AND_EDIT_UIDSWAP_C;
/* If we ever come here, if means that your system does not support any of
   the uid swapping methods we are aware of.  Tough.  This means that
   ssh will have to read certain files as root, which causes some security
   problems.  Unless your are very concerned about security, you can
   comment out the above line.  The effect is that local users on your
   machine might be able to read each other's files.  Also, you may encounter
   problems if home directories are on a NFS volume.  You may also
   encounter other problems; please don't complain unless you have some idea
   how to fix it. */

void temporarily_use_uid(uid_t uid)
{
}

void restore_uid()
{
}

void permanently_set_uid(uid_t uid)
{
  if (setuid(uid) < 0)
    debug("setuid %d: %.100s", (int)uid, strerror(errno));
}

#endif /* HAVE_SETEUID */