source: branches/samba-3.0/source/smbd/sec_ctx.c@ 710

Last change on this file since 710 was 1, checked in by Paul Smedley, 19 years ago

Initial code import

File size: 10.3 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 uid/user handling
4 Copyright (C) Tim Potter 2000
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "includes.h"
22
23extern struct current_user current_user;
24
25struct sec_ctx {
26 UNIX_USER_TOKEN ut;
27 NT_USER_TOKEN *token;
28};
29
30/* A stack of security contexts. We include the current context as being
31 the first one, so there is room for another MAX_SEC_CTX_DEPTH more. */
32
33static struct sec_ctx sec_ctx_stack[MAX_SEC_CTX_DEPTH + 1];
34static int sec_ctx_stack_ndx;
35
36/****************************************************************************
37 Become the specified uid.
38****************************************************************************/
39
40static BOOL become_uid(uid_t uid)
41{
42 /* Check for dodgy uid values */
43
44 if (uid == (uid_t)-1 ||
45 ((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) {
46 static int done;
47
48 if (!done) {
49 DEBUG(1,("WARNING: using uid %d is a security risk\n",
50 (int)uid));
51 done = 1;
52 }
53 }
54
55 /* Set effective user id */
56
57 set_effective_uid(uid);
58
59 DO_PROFILE_INC(uid_changes);
60 return True;
61}
62
63/****************************************************************************
64 Become the specified gid.
65****************************************************************************/
66
67static BOOL become_gid(gid_t gid)
68{
69 /* Check for dodgy gid values */
70
71 if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) &&
72 (gid == (gid_t)65535))) {
73 static int done;
74
75 if (!done) {
76 DEBUG(1,("WARNING: using gid %d is a security risk\n",
77 (int)gid));
78 done = 1;
79 }
80 }
81
82 /* Set effective group id */
83
84 set_effective_gid(gid);
85 return True;
86}
87
88/****************************************************************************
89 Become the specified uid and gid.
90****************************************************************************/
91
92static BOOL become_id(uid_t uid, gid_t gid)
93{
94 return become_gid(gid) && become_uid(uid);
95}
96
97/****************************************************************************
98 Drop back to root privileges in order to change to another user.
99****************************************************************************/
100
101static void gain_root(void)
102{
103 if (non_root_mode()) {
104 return;
105 }
106
107 if (geteuid() != 0) {
108 set_effective_uid(0);
109
110 if (geteuid() != 0) {
111 DEBUG(0,
112 ("Warning: You appear to have a trapdoor "
113 "uid system\n"));
114 }
115 }
116
117 if (getegid() != 0) {
118 set_effective_gid(0);
119
120 if (getegid() != 0) {
121 DEBUG(0,
122 ("Warning: You appear to have a trapdoor "
123 "gid system\n"));
124 }
125 }
126}
127
128/****************************************************************************
129 Get the list of current groups.
130****************************************************************************/
131
132static int get_current_groups(gid_t gid, int *p_ngroups, gid_t **p_groups)
133{
134 int i;
135 gid_t grp;
136 int ngroups;
137 gid_t *groups = NULL;
138
139 (*p_ngroups) = 0;
140 (*p_groups) = NULL;
141
142 /* this looks a little strange, but is needed to cope with
143 systems that put the current egid in the group list
144 returned from getgroups() (tridge) */
145 save_re_gid();
146 set_effective_gid(gid);
147 setgid(gid);
148
149 ngroups = sys_getgroups(0,&grp);
150 if (ngroups <= 0) {
151 goto fail;
152 }
153
154 if((groups = SMB_MALLOC_ARRAY(gid_t, ngroups+1)) == NULL) {
155 DEBUG(0,("setup_groups malloc fail !\n"));
156 goto fail;
157 }
158
159 if ((ngroups = sys_getgroups(ngroups,groups)) == -1) {
160 goto fail;
161 }
162
163 restore_re_gid();
164
165 (*p_ngroups) = ngroups;
166 (*p_groups) = groups;
167
168 DEBUG( 3, ( "get_current_groups: user is in %u groups: ", ngroups));
169 for (i = 0; i < ngroups; i++ ) {
170 DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) );
171 }
172 DEBUG( 3, ( "\n" ) );
173
174 return ngroups;
175
176fail:
177 SAFE_FREE(groups);
178 restore_re_gid();
179 return -1;
180}
181