1 /* persona.c - handle the persona of the process
2 *
3 * Copyright 1999 Jochen Voss */
4
5 static const char rcsid[] = "$Id: persona.c 4839 2003-04-13 16:50:02Z voss $";
6
7 #ifdef HAVE_CONFIG_H
8 #include <config.h>
9 #endif
10
11 #ifdef _XOPEN_SOURCE
12 #define _XOPEN_SOURCE_EXTENDED 1
13 #endif
14
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <sys/types.h>
18 #include <unistd.h>
19
20 #if defined(__hp9000s800)
21 #include <stdarg.h>
22 #endif
23
24 #include "moon-buggy.h"
25
26
27 /* which method of uid handling is used? */
28 static enum { m_NONE, m_SAVED, m_EXCH } method = m_NONE;
29
30 /* the current effective user id */
31 static enum persona current = pers_GAME;
32
33 /* The real and effective ids */
34 static uid_t user_uid, game_uid;
35 static gid_t user_gid, game_gid;
36
37
38 void
initialise_persona(void)39 initialise_persona (void)
40 {
41 long int saved_ids_flag;
42
43 current = pers_GAME;
44 method = m_NONE;
45
46 user_uid = getuid ();
47 game_uid = geteuid ();
48 user_gid = getgid ();
49 game_gid = getegid ();
50 if (user_uid == game_uid && user_gid == game_gid) return;
51
52 /* check for the POSIX saved id feature. */
53 #ifdef _POSIX_SAVED_IDS
54 saved_ids_flag = 1;
55 #else /* not defined(_POSIX_SAVED_IDS) */
56 saved_ids_flag = sysconf (_SC_SAVED_IDS);
57 #endif /* not defined(_POSIX_SAVED_IDS) */
58 if (saved_ids_flag != -1) {
59 method = m_SAVED;
60 return;
61 }
62
63 #ifdef HAVE_SETREUID
64 method = m_EXCH;
65 #else
66 fputs ("WARNING: setuid/setgid usage not supported on this system!\n",
67 stderr);
68 sleep (3);
69 setuid (user_uid);
70 setgid (user_gid);
71 method = m_NONE;
72 #endif
73 }
74
75 int
is_setgid(void)76 is_setgid (void)
77 /* Return true, iff the game is run setgid and we currently use
78 * privileged access. */
79 {
80 return (user_gid != game_gid && current == pers_GAME);
81 }
82
83
84 static char *name[] = { "game", "user" };
85
86 void
set_persona(enum persona pers)87 set_persona (enum persona pers)
88 /* Switch to process persona (effective user id) PERS. */
89 {
90 int res;
91 uid_t old_uid, new_uid;
92 gid_t old_gid, new_gid;
93
94 if (current == pers) return;
95 switch (pers) {
96 case pers_GAME:
97 old_uid = user_uid;
98 new_uid = game_uid;
99 old_gid = user_gid;
100 new_gid = game_gid;
101 break;
102 case pers_USER:
103 old_uid = game_uid;
104 new_uid = user_uid;
105 old_gid = game_gid;
106 new_gid = user_gid;
107 break;
108 default:
109 abort (); /* should not happen */
110 }
111
112 switch (method) {
113 case m_NONE:
114 break;
115 case m_SAVED:
116 res = setuid (new_uid);
117 if (res < 0) fatal ("Cannot set uid to %s", name[pers]);
118 res = setgid (new_gid);
119 if (res < 0) fatal ("Cannot set gid to %s", name[pers]);
120 break;
121 case m_EXCH:
122 #ifdef HAVE_SETREUID
123 res = setreuid (old_uid, new_uid);
124 if (res < 0) fatal ("Cannot switch real/effective uid to %s", name[pers]);
125 res = setregid (old_gid, new_gid);
126 if (res < 0) fatal ("Cannot switch real/effective gid to %s", name[pers]);
127 #else
128 abort (); /* should not happen */
129 #endif
130 break;
131 }
132 current = pers;
133 }
134