]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/uidswap.c
This commit was generated by cvs2svn to compensate for changes in r73393,
[FreeBSD/FreeBSD.git] / crypto / openssh / uidswap.c
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  * Code for uid-swapping.
6  *
7  * As far as I am concerned, the code I have written for this software
8  * can be used freely for any purpose.  Any derived versions of this
9  * software must be clearly marked as such, and if the derived work is
10  * incompatible with the protocol description in the RFC file, it must be
11  * called by a name other than "ssh" or "Secure Shell".
12  */
13
14 #include "includes.h"
15 RCSID("$OpenBSD: uidswap.c,v 1.9 2000/09/07 20:27:55 deraadt Exp $");
16
17 #include "ssh.h"
18 #include "uidswap.h"
19
20 /*
21  * Note: all these functions must work in all of the following cases:
22  *    1. euid=0, ruid=0
23  *    2. euid=0, ruid!=0
24  *    3. euid!=0, ruid!=0
25  * Additionally, they must work regardless of whether the system has
26  * POSIX saved uids or not.
27  */
28
29 #ifdef _POSIX_SAVED_IDS
30 /* Lets assume that posix saved ids also work with seteuid, even though that
31    is not part of the posix specification. */
32 #define SAVED_IDS_WORK_WITH_SETEUID
33 #endif /* _POSIX_SAVED_IDS */
34
35 /* Saved effective uid. */
36 static uid_t saved_euid = 0;
37
38 /*
39  * Temporarily changes to the given uid.  If the effective user
40  * id is not root, this does nothing.  This call cannot be nested.
41  */
42 void
43 temporarily_use_uid(uid_t uid)
44 {
45 #ifdef SAVED_IDS_WORK_WITH_SETEUID
46         /* Save the current euid. */
47         saved_euid = geteuid();
48
49         /* Set the effective uid to the given (unprivileged) uid. */
50         if (seteuid(uid) == -1)
51                 debug("seteuid %u: %.100s", (u_int) uid, strerror(errno));
52 #else /* SAVED_IDS_WORK_WITH_SETUID */
53         /* Propagate the privileged uid to all of our uids. */
54         if (setuid(geteuid()) < 0)
55                 debug("setuid %u: %.100s", (u_int) geteuid(), strerror(errno));
56
57         /* Set the effective uid to the given (unprivileged) uid. */
58         if (seteuid(uid) == -1)
59                 debug("seteuid %u: %.100s", (u_int) uid, strerror(errno));
60 #endif /* SAVED_IDS_WORK_WITH_SETEUID */
61 }
62
63 /*
64  * Restores to the original uid.
65  */
66 void
67 restore_uid()
68 {
69 #ifdef SAVED_IDS_WORK_WITH_SETEUID
70         /* Set the effective uid back to the saved uid. */
71         if (seteuid(saved_euid) < 0)
72                 debug("seteuid %u: %.100s", (u_int) saved_euid, strerror(errno));
73 #else /* SAVED_IDS_WORK_WITH_SETEUID */
74         /*
75          * We are unable to restore the real uid to its unprivileged value.
76          * Propagate the real uid (usually more privileged) to effective uid
77          * as well.
78          */
79         setuid(getuid());
80 #endif /* SAVED_IDS_WORK_WITH_SETEUID */
81 }
82
83 /*
84  * Permanently sets all uids to the given uid.  This cannot be
85  * called while temporarily_use_uid is effective.
86  */
87 void
88 permanently_set_uid(uid_t uid)
89 {
90         if (setuid(uid) < 0)
91                 debug("setuid %u: %.100s", (u_int) uid, strerror(errno));
92 }