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 614 : static int privileges_destructor(struct saved_state *s) 61 : { 62 1228 : if (geteuid() != s->uid && 63 614 : samba_seteuid(s->uid) != 0) { 64 0 : smb_panic("Failed to restore privileges"); 65 : } 66 614 : 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 614 : void *root_privileges(void) 76 : { 77 0 : struct saved_state *s; 78 614 : s = talloc(NULL, struct saved_state); 79 614 : if (!s) return NULL; 80 614 : s->uid = geteuid(); 81 614 : if (s->uid != 0) { 82 614 : samba_seteuid(0); 83 : } 84 614 : talloc_set_destructor(s, privileges_destructor); 85 614 : 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 : }