An Overlay-based
Virtual Network Substrate
SpoVNet

source: source/ariba/utility/transport/tcpip/protlib/setuid.cpp @ 9686

Last change on this file since 9686 was 9686, checked in by mies, 8 years ago

put protlib doc to protlib module

File size: 5.4 KB
Line 
1/// ----------------------------------------*- mode: C++; -*--
2/// @file setuid.cpp
3/// Change effective user ID in a thread-safe way.
4/// ----------------------------------------------------------
5/// $Id: setuid.cpp 2549 2007-04-02 22:17:37Z bless $
6/// $HeadURL: https://svn.ipv6.tm.uka.de/nsis/protlib/trunk/src/setuid.cpp $
7// ===========================================================
8//                     
9// Copyright (C) 2005-2007, all rights reserved by
10// - Institute of Telematics, Universitaet Karlsruhe (TH)
11//
12// More information and contact:
13// https://projekte.tm.uka.de/trac/NSIS
14//                     
15// This program is free software; you can redistribute it and/or modify
16// it under the terms of the GNU General Public License as published by
17// the Free Software Foundation; version 2 of the License
18//
19// This program is distributed in the hope that it will be useful,
20// but WITHOUT ANY WARRANTY; without even the implied warranty of
21// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22// GNU General Public License for more details.
23//
24// You should have received a copy of the GNU General Public License along
25// with this program; if not, write to the Free Software Foundation, Inc.,
26// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27//
28// ===========================================================
29/** @ingroup protlib
30 *
31 * Thread-safe setuid support for linux.
32 * Change effective user ID in a thread-safe way.
33 *
34 * tsdb::init() must be called before calling setuid::init().
35 */
36
37#include <sys/types.h>
38#include <unistd.h>
39#include <errno.h>
40#include <string.h>
41
42#include "setuid.h"
43#include "threadsafe_db.h"
44#include "cleanuphandler.h"
45#include "logfile.h"
46
47
48namespace protlib { 
49
50/** @addtogroup protlib
51 * @{
52 */
53
54  using namespace log;
55
56void setuid::init() {
57        if (is_init) {
58          Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to initialize setuid although already initialized.");
59        } else {
60                pthread_mutex_init(&mutex,NULL);
61                count = 0;
62                file_userid = ::geteuid();
63                real_userid = ::getuid();
64                is_setuid = (real_userid!=file_userid);
65                file_username = tsdb::get_username(file_userid);
66                real_username = tsdb::get_username(real_userid);
67                is_init = true;
68                if (is_setuid) {
69                  Log(INFO_LOG,LOG_CRIT, "setuid", "Setuid-bit is set, euid is " << file_userid << " " << file_username << ", realuid is " << real_userid << " " << real_username << ". Turning off setuid as soon as possible");
70                  count = 1;
71                  off();
72                } else {
73                  Log(INFO_LOG,LOG_CRIT, "setuid", "Setuid-bit is not set or euid and ruid are equal. setuid::on() and setuid::off() will do nothing");
74                } // end if is_setuid
75        } // end if is_init
76} // end init
77
78void setuid::end() {
79        if (is_init) {
80                is_init = false;
81                pthread_mutex_destroy(&mutex);
82                count = 0;
83                // turn off setuid
84                if (is_setuid) {
85                  Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::end() turn off setuid. Switching (maybe permamently) to " << real_userid << " " << real_username << " using setuid()");
86                  ::setuid(real_userid);
87                } // end if is_setuid
88        } else {
89          Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to end setuid although not initialized.");
90        } // end if is_init
91} // end end
92
93void setuid::on() {
94        if (is_setuid) {
95                if (is_init) {
96                        pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
97                        if (count==0) {
98                          Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::on(): setting euid to " << file_userid << " " << file_username);
99                          int status;
100                          #ifdef _POSIX_SAVED_IDS
101                          status = seteuid(file_userid);
102                                #else
103                                        status = setreuid(real_userid,file_userid);
104                                #endif
105                                if (status<0) {
106                                  Log(ERROR_LOG,LOG_ALERT, "setuid", "setuid::on(): error " << strerror(errno));
107                                } else count++;
108                        } else {
109                          Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::on(): setuid already on");
110                          count++;
111                        } // end if count
112                        pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
113                } else {
114                  Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to use setuid although not initialized.");
115                } // end if is_init
116        } // end if is_setuid
117} // end on
118
119void setuid::off() {
120        if (is_setuid) {
121                if (is_init) {
122                        pthread_mutex_lock(&mutex); // install_cleanup_mutex_lock(&mutex);
123                        if (count==1) {
124                                int status;
125                                #ifdef _POSIX_SAVED_IDS
126                                        status = seteuid(real_userid);
127                                #else
128                                        status = setreuid(file_userid,real_userid);
129                                #endif
130                                if (status<0) {
131                                  Log(ERROR_LOG,LOG_ALERT, "setuid", "setuid::off(): error " << strerror(errno));
132                                } else {
133                                  count = 0;
134                                  Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::off(): set euid to " << real_userid << " " << real_username);
135                                } // end if count
136                        } else if (count==0) {
137                          Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::off(): setuid already off");
138                        } else {
139                          Log(INFO_LOG,LOG_CRIT, "setuid", "setuid::off(): setuid still on");
140                          count--;
141                        } // end if count
142                        pthread_mutex_unlock(&mutex); // uninstall_cleanup(1);
143                } else {
144                  Log(ERROR_LOG,LOG_CRIT, "setuid", "Tried to use setuid although not initialized.");
145                } // end if is_init
146        } // end if is_setuid
147} // end off
148
149bool setuid::is_init = false;
150
151pthread_mutex_t setuid::mutex =
152#ifdef _DEBUG
153    PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
154#else
155    PTHREAD_MUTEX_INITIALIZER;
156#endif
157
158uint32 setuid::count = 0;
159
160uid_t setuid::file_userid = 65534;
161
162string setuid::file_username = "nobody";
163
164uid_t setuid::real_userid = 65534;
165
166string setuid::real_username = "nobody";
167
168bool setuid::is_setuid = true; // important!
169
170//@}
171
172} // end namespace protlib
Note: See TracBrowser for help on using the repository browser.