summaryrefslogtreecommitdiffabout
path: root/src/process.cc
authorMichael Krelin <hacker@klever.net>2004-07-15 04:13:35 (UTC)
committer Michael Krelin <hacker@klever.net>2004-07-15 04:13:35 (UTC)
commit5e437102c59f4544e3803598eabcb643d403272d (patch) (unidiff)
tree7703657f2dac2fd9fb2b2a1f453ca2f30227efa1 /src/process.cc
parent4f8a6f291a231410a03c438bc9d63a7beb861e7b (diff)
downloaddudki-5e437102c59f4544e3803598eabcb643d403272d.zip
dudki-5e437102c59f4544e3803598eabcb643d403272d.tar.gz
dudki-5e437102c59f4544e3803598eabcb643d403272d.tar.bz2
initgroups() call added when changing uid
Diffstat (limited to 'src/process.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--src/process.cc17
1 files changed, 10 insertions, 7 deletions
diff --git a/src/process.cc b/src/process.cc
index fda35e8..bfab311 100644
--- a/src/process.cc
+++ b/src/process.cc
@@ -37,88 +37,91 @@ void process::check(const string& id,configuration& config) {
37 syslog(LOG_NOTICE,"The process '%s' is down, trying to launch.",id.c_str()); 37 syslog(LOG_NOTICE,"The process '%s' is down, trying to launch.",id.c_str());
38 do_notify(id,"Starting up", 38 do_notify(id,"Starting up",
39 "The named process seems to be down. Dudki will try\n" 39 "The named process seems to be down. Dudki will try\n"
40 "to revive it by running the specified command.\n", 40 "to revive it by running the specified command.\n",
41 config); 41 config);
42 try { 42 try {
43 launch(id,config); 43 launch(id,config);
44 }catch(exception& e) { 44 }catch(exception& e) {
45 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what()); 45 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what());
46 } 46 }
47 }else if(patience==10){ // TODO: configurable like the above 47 }else if(patience==10){ // TODO: configurable like the above
48 syslog(LOG_NOTICE,"Giving up on process '%s' for a while",id.c_str()); 48 syslog(LOG_NOTICE,"Giving up on process '%s' for a while",id.c_str());
49 do_notify(id,"Giving up", 49 do_notify(id,"Giving up",
50 "After a number of attempts to relaunch the named process\n" 50 "After a number of attempts to relaunch the named process\n"
51 "It still seems to be down. Dudki is giving up attempts\n" 51 "It still seems to be down. Dudki is giving up attempts\n"
52 "to revive the process for a while.\n", 52 "to revive the process for a while.\n",
53 config); 53 config);
54 } 54 }
55 patience++; 55 patience++;
56 } 56 }
57 } 57 }
58} 58}
59 59
60void process::launch(const string& id,configuration& config) { 60void process::launch(const string& id,configuration& config) {
61 uid_t uid = 0; 61 uid_t uid = (uid_t)-1;
62 gid_t gid = (gid_t)-1;
62 if(!user.empty()) { 63 if(!user.empty()) {
63 struct passwd *ptmp = getpwnam(user.c_str()); 64 struct passwd *ptmp = getpwnam(user.c_str());
64 if(ptmp) { 65 if(ptmp) {
65 uid = ptmp->pw_uid; 66 uid = ptmp->pw_uid;
67 gid = ptmp->pw_gid;
66 }else{ 68 }else{
67 errno=0; 69 errno=0;
68 uid = strtol(user.c_str(),NULL,0); 70 uid = strtol(user.c_str(),NULL,0);
69 if(errno) 71 if(errno)
70 throw runtime_error("Failed to resolve User value to uid"); 72 throw runtime_error("Failed to resolve User value to uid");
71 } 73 }
72 } 74 }
73 gid_t gid = 0;
74 if(!group.empty()) { 75 if(!group.empty()) {
75 struct group *gtmp = getgrnam(group.c_str()); 76 struct group *gtmp = getgrnam(group.c_str());
76 if(gtmp) { 77 if(gtmp) {
77 gid = gtmp->gr_gid; 78 gid = gtmp->gr_gid;
78 }else{ 79 }else{
79 errno = 0; 80 errno = 0;
80 gid = strtol(group.c_str(),NULL,0); 81 gid = strtol(group.c_str(),NULL,0);
81 if(errno) 82 if(errno)
82 throw runtime_error("Failed to reslove Group value to gid"); 83 throw runtime_error("Failed to reslove Group value to gid");
83 } 84 }
84 } 85 }
85 pid_t p = fork(); 86 pid_t p = fork();
86 if(p<0) 87 if(p<0)
87 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to fork()"); 88 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to fork()");
88 if(!p) { 89 if(!p) {
89 // child 90 // child
90 try { 91 try {
91 setsid(); 92 setsid();
93 if(user.empty()) {
94 if((getgid()!=gid) && setgid(gid))
95 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setgid()");
96 }else{
97 if(initgroups(user.c_str(),gid))
98 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to initgroups()");
99 }
92 if(!chroot.empty()) { 100 if(!chroot.empty()) {
93 if(::chroot(chroot.c_str())) 101 if(::chroot(chroot.c_str()))
94 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to chroot()"); 102 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to chroot()");
95 } 103 }
96 if(!group.empty()) {
97 // TODO: initgroups()?
98 if((getgid()!=gid) && setgid(gid))
99 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setgid()");
100 }
101 if(!user.empty()) { 104 if(!user.empty()) {
102 if((getuid()!=uid) && setuid(uid)) 105 if((getuid()!=uid) && setuid(uid))
103 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setuid()"); 106 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to setuid()");
104 } 107 }
105 char *argv[] = { "/bin/sh", "-c", (char*)restart_cmd.c_str(), NULL }; 108 char *argv[] = { "/bin/sh", "-c", (char*)restart_cmd.c_str(), NULL };
106 close(0); close(1); close(2); 109 close(0); close(1); close(2);
107 execv("/bin/sh",argv); 110 execv("/bin/sh",argv);
108 }catch(exception& e) { 111 }catch(exception& e) {
109 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what()); 112 syslog(LOG_ERR,"Error trying to launch process '%s': %s",id.c_str(),e.what());
110 } 113 }
111 _exit(-1); 114 _exit(-1);
112 } 115 }
113 // parent 116 // parent
114 int rv; 117 int rv;
115 if(waitpid(p,&rv,0)<0) 118 if(waitpid(p,&rv,0)<0)
116 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to waitpid()"); 119 throw runtime_error(string(__PRETTY_FUNCTION__)+": failed to waitpid()");
117} 120}
118 121
119void process::do_notify(const string& id,const string& event,const string& description,configuration& config) { 122void process::do_notify(const string& id,const string& event,const string& description,configuration& config) {
120 string the_notify; 123 string the_notify;
121 if(!notify.empty()) 124 if(!notify.empty())
122 the_notify=notify; 125 the_notify=notify;
123 else if(!config.notify.empty()) 126 else if(!config.notify.empty())
124 the_notify=config.notify; 127 the_notify=config.notify;