Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : gain/lose root privileges
5 :
6 : Copyright (C) Andrew Tridgell 2004
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "replace.h"
23 : #include <talloc.h>
24 : #include "lib/util/fault.h"
25 : #include "system/passwd.h"
26 :
27 : #ifdef HAVE_UNISTD_H
28 : #include <unistd.h>
29 : #endif
30 :
31 : #include "../lib/util/unix_privs.h"
32 : #include "../lib/util/setid.h"
33 :
34 : /**
35 : * @file
36 : * @brief Gaining/losing root privileges
37 : */
38 :
39 : /*
40 : there are times when smbd needs to temporarily gain root privileges
41 : to do some operation. To do this you call root_privileges(), which
42 : returns a talloc handle. To restore your previous privileges
43 : talloc_free() this pointer.
44 :
45 : Note that this call is considered successful even if it does not
46 : manage to gain root privileges, but it will call smb_abort() if it
47 : fails to restore the privileges afterwards. The logic is that
48 : failing to gain root access can be caught by whatever operation
49 : needs to be run as root failing, but failing to lose the root
50 : privileges is dangerous.
51 :
52 : This also means that this code is safe to be called from completely
53 : unprivileged processes.
54 : */
55 :
56 : struct saved_state {
57 : uid_t uid;
58 : };
59 :
60 585 : static int privileges_destructor(struct saved_state *s)
61 : {
62 1170 : if (geteuid() != s->uid &&
63 585 : samba_seteuid(s->uid) != 0) {
64 0 : smb_panic("Failed to restore privileges");
65 : }
66 585 : return 0;
67 : }
68 :
69 : /**
70 : * Obtain root privileges for the current process.
71 : *
72 : * The privileges can be dropped by talloc_free()-ing the
73 : * token returned by this function
74 : */
75 585 : void *root_privileges(void)
76 : {
77 : struct saved_state *s;
78 585 : s = talloc(NULL, struct saved_state);
79 585 : if (!s) return NULL;
80 585 : s->uid = geteuid();
81 585 : if (s->uid != 0) {
82 585 : samba_seteuid(0);
83 : }
84 585 : talloc_set_destructor(s, privileges_destructor);
85 585 : return s;
86 : }
87 :
88 0 : uid_t root_privileges_original_uid(void *s)
89 : {
90 0 : struct saved_state *saved = talloc_get_type_abort(s, struct saved_state);
91 0 : return saved->uid;
92 : }
|