version 1.3.2.6, 2013/04/09 15:51:11
|
version 1.6.2.1, 2015/06/18 22:15:47
|
Line 5
|
Line 5
|
* $Author$ |
* $Author$ |
* $Id$ |
* $Id$ |
* |
* |
*************************************************************************/ | ************************************************************************* |
| The ELWIX and AITNET software is distributed under the following |
| terms: |
| |
| All of the documentation and software included in the ELWIX and AITNET |
| Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org> |
| |
| Copyright 2004 - 2015 |
| by Michael Pounov <misho@elwix.org>. All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions |
| are met: |
| 1. Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| 2. Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| 3. All advertising materials mentioning features or use of this software |
| must display the following acknowledgement: |
| This product includes software developed by Michael Pounov <misho@elwix.org> |
| ELWIX - Embedded LightWeight unIX and its contributors. |
| 4. Neither the name of AITNET nor the names of its contributors |
| may be used to endorse or promote products derived from this software |
| without specific prior written permission. |
| |
| THIS SOFTWARE IS PROVIDED BY AITNET AND CONTRIBUTORS ``AS IS'' AND |
| ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| SUCH DAMAGE. |
| */ |
#include "global.h" |
#include "global.h" |
|
|
|
|
Line 26 Log(int lvl, const char *fmt, ...)
|
Line 63 Log(int lvl, const char *fmt, ...)
|
vfprintf(lf, fmt, lst); |
vfprintf(lf, fmt, lst); |
va_end(lst); |
va_end(lst); |
fprintf(lf, "\n"); |
fprintf(lf, "\n"); |
vsyslog(LOG_WARNING, fmt, cp); | vsyslog(LOG_INFO, fmt, cp); |
va_end(cp); |
va_end(cp); |
} |
} |
} |
} |
Line 48 Err(const char *fmt, ...)
|
Line 85 Err(const char *fmt, ...)
|
static inline void |
static inline void |
DumpProc(const char *txt) |
DumpProc(const char *txt) |
{ |
{ |
Log(0, "%s:: UID:GID=%d:%d Prio=%d Class=%s Name=%s Dir=%s Cmd=%s Script=%s From=%s:%s%s", | Log(1, "%s:: uid:gid=%d:%d UID:GID=%d:%d Prio=%d Class=%s Name=%s Dir=%s Cmd=%s " |
txt ? txt : __func__, AIT_GET_I16(&proc.proc_uid), | "Script=%s From=%s:%s Get=%s", txt ? txt : __func__, |
| geteuid(), getegid(), AIT_GET_I16(&proc.proc_uid), |
AIT_GET_I16(&proc.proc_gid), AIT_GET_I32(&proc.proc_prio), |
AIT_GET_I16(&proc.proc_gid), AIT_GET_I32(&proc.proc_prio), |
AIT_GET_STR(&proc.proc_class), AIT_GET_STR(&proc.proc_name), |
AIT_GET_STR(&proc.proc_class), AIT_GET_STR(&proc.proc_name), |
AIT_GET_STR(&proc.proc_dir), AIT_GET_STR(&proc.proc_cmd), |
AIT_GET_STR(&proc.proc_dir), AIT_GET_STR(&proc.proc_cmd), |
Line 57 DumpProc(const char *txt)
|
Line 95 DumpProc(const char *txt)
|
getenv("REMOTE_PORT"), getenv("REQUEST_URI")); |
getenv("REMOTE_PORT"), getenv("REQUEST_URI")); |
} |
} |
|
|
static void | static int |
initProg() |
initProg() |
{ |
{ |
char d[MAXPATHLEN]; |
|
|
|
AIT_SET_I16(&proc.proc_uid, getuid()); |
AIT_SET_I16(&proc.proc_uid, getuid()); |
AIT_SET_I16(&proc.proc_gid, getgid()); |
AIT_SET_I16(&proc.proc_gid, getgid()); |
AIT_SET_I32(&proc.proc_prio, getpriority(PRIO_PROCESS, 0)); |
AIT_SET_I32(&proc.proc_prio, getpriority(PRIO_PROCESS, 0)); |
AIT_INIT_VAL2(&proc.proc_class, string); |
AIT_INIT_VAL2(&proc.proc_class, string); |
getcwd(d, sizeof d); | AIT_INIT_VAL2(&proc.proc_dir, string); |
AIT_SET_STR(&proc.proc_dir, d); | |
AIT_INIT_VAL2(&proc.proc_name, string); |
AIT_INIT_VAL2(&proc.proc_name, string); |
AIT_INIT_VAL2(&proc.proc_cmd, string); |
AIT_INIT_VAL2(&proc.proc_cmd, string); |
|
|
Line 78 initProg()
|
Line 113 initProg()
|
lf = stdout; |
lf = stdout; |
|
|
openlog(PACKAGE_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); |
openlog(PACKAGE_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); |
|
return 0; |
} |
} |
|
|
static void |
static void |
Line 97 Usage()
|
Line 133 Usage()
|
{ |
{ |
printf( " -= suX =- suExecutor designed for web based applicaions\n" |
printf( " -= suX =- suExecutor designed for web based applicaions\n" |
"(C)`11 AITNET ltd - Sofia/Bulgaria - <office@aitnet.org>\n\n" |
"(C)`11 AITNET ltd - Sofia/Bulgaria - <office@aitnet.org>\n\n" |
" Syntax: %s [options] <program> [arguments]\n" | " Syntax: %s [options] <program|-> [arguments]\n" |
"\t-u <user>\t\t\tUser for suID\n" |
"\t-u <user>\t\t\tUser for suID\n" |
"\t-g <group>\t\t\tGroup for suID\n" |
"\t-g <group>\t\t\tGroup for suID\n" |
"\t-p <priority (-20..20)>\t\tExecute with priority\n" |
"\t-p <priority (-20..20)>\t\tExecute with priority\n" |
Line 114 static inline int
|
Line 150 static inline int
|
setUIDGID(char flg, const char *name) |
setUIDGID(char flg, const char *name) |
{ |
{ |
struct stat sb; |
struct stat sb; |
|
struct passwd *pass; |
|
short uid, gid; |
|
|
if (stat(name, &sb) == -1) { | if (name) { |
ESYSERR(0); | if (stat(name, &sb) == -1) { |
return -1; | ESYSERR(0); |
| return -1; |
| } |
| uid = sb.st_uid; |
| gid = sb.st_gid; |
| } else { |
| pass = getpwnam(getenv("SUX_USER") ? getenv("SUX_USER") : DEFAULT_SUX_USER); |
| if (!pass) { |
| Err("Error:: User %s not found", getenv("SUX_USER")); |
| endpwent(); |
| return -1; |
| } |
| uid = pass->pw_uid; |
| gid = pass->pw_gid; |
| endpwent(); |
} |
} |
|
|
if (!(flg & SUX_GET_UID)) |
if (!(flg & SUX_GET_UID)) |
AIT_SET_I16(&proc.proc_uid, sb.st_uid); | AIT_SET_I16(&proc.proc_uid, uid); |
if (!(flg & SUX_GET_GID)) |
if (!(flg & SUX_GET_GID)) |
AIT_SET_I16(&proc.proc_gid, sb.st_gid); | AIT_SET_I16(&proc.proc_gid, gid); |
|
|
return 0; |
return 0; |
} |
} |
|
|
static inline int |
static inline int |
SetClass() | setClassDir() |
{ |
{ |
struct passwd *pass; |
struct passwd *pass; |
int ret = 0; |
int ret = 0; |
Line 137 SetClass()
|
Line 189 SetClass()
|
pass = getpwuid(AIT_GET_I16(&proc.proc_uid)); |
pass = getpwuid(AIT_GET_I16(&proc.proc_uid)); |
if (!pass) { |
if (!pass) { |
Err("Error:: User with this UID %d not found", AIT_GET_I16(&proc.proc_uid)); |
Err("Error:: User with this UID %d not found", AIT_GET_I16(&proc.proc_uid)); |
endpwent(); | ret = -1; |
return -1; | } else { |
} else | |
AIT_SET_STR(&proc.proc_class, pass->pw_class); |
AIT_SET_STR(&proc.proc_class, pass->pw_class); |
|
AIT_SET_STR(&proc.proc_dir, pass->pw_dir); |
|
|
if (setusercontext(NULL, pass, AIT_GET_I16(&proc.proc_uid), | if (setusercontext(NULL, pass, AIT_GET_I16(&proc.proc_uid), |
LOGIN_SETRESOURCES | LOGIN_SETGROUP | LOGIN_SETLOGIN | | LOGIN_SETLOGIN | LOGIN_SETGROUP | LOGIN_SETUSER | |
LOGIN_SETPRIORITY)) { | LOGIN_SETPRIORITY | LOGIN_SETRESOURCES)) { |
Err("Error:: Cant set login class %s", AIT_GET_STR(&proc.proc_class)); | Err("Error:: Can't set login class %s", AIT_GET_STR(&proc.proc_class)); |
ret = -1; | ret = -1; |
| } |
} |
} |
|
|
endpwent(); |
endpwent(); |
Line 166 LoadCfgData(char flg)
|
Line 219 LoadCfgData(char flg)
|
} |
} |
if (!strcasecmp(str, "SCRIPT")) { |
if (!strcasecmp(str, "SCRIPT")) { |
mode = 1; |
mode = 1; |
if (setUIDGID(flg, AIT_GET_STR(&proc.proc_name)) == -1) | if (setUIDGID(flg, (getenv("SUX_USER") ? NULL : getenv("PATH_TRANSLATED"))) == -1) |
return -1; |
return -1; |
} else if (!strcasecmp(str, "FILE")) { |
} else if (!strcasecmp(str, "FILE")) { |
mode = 2; |
mode = 2; |
if (setUIDGID(flg, AIT_GET_STR(&proc.proc_name)) == -1) |
if (setUIDGID(flg, AIT_GET_STR(&proc.proc_name)) == -1) |
return -1; |
return -1; |
} else if (!strcasecmp(str, "DIR") && | } else if (!strcasecmp(str, "DIR")) { |
(str = cfg_getAttribute(&cfg, "global", "directory"))) { | |
mode = 3; |
mode = 3; |
if (!(flg & SUX_GET_DIR)) | str = AIT_GET_STR(&proc.proc_dir) ? AIT_GET_STR(&proc.proc_dir) : "."; |
AIT_SET_STR(&proc.proc_dir, str); | if (setUIDGID(flg, str) == -1) |
| |
if (setUIDGID(flg, AIT_GET_STR(&proc.proc_dir)) == -1) | |
return -1; |
return -1; |
} else { |
} else { |
Err("Error:: Unknown mode %s", str); |
Err("Error:: Unknown mode %s", str); |
Line 200 LoadCfgData(char flg)
|
Line 250 LoadCfgData(char flg)
|
ELIBERR(cfg); |
ELIBERR(cfg); |
return -1; |
return -1; |
case 0: |
case 0: |
cfg_loadAttribute(&cfg, "associate", "default", &proc.proc_cmd, DEFAULT_CMD); | cfg_loadAttribute(&cfg, "associate", "default", |
| &proc.proc_cmd, DEFAULT_CMD); |
} |
} |
} else |
} else |
AIT_SET_STR(&proc.proc_cmd, DEFAULT_CMD); |
AIT_SET_STR(&proc.proc_cmd, DEFAULT_CMD); |
Line 224 Run(char **argv, char flg)
|
Line 275 Run(char **argv, char flg)
|
if (!(aarg = array_From((const char***) &argv, 0))) { |
if (!(aarg = array_From((const char***) &argv, 0))) { |
array_Destroy(&acmd); |
array_Destroy(&acmd); |
return -1; |
return -1; |
} else if (*array(acmd, 0, char*) == '!') { | } |
| /* '!' exclude associated wrapper aka direct args execution */ |
| if (*array(acmd, 0, char*) == '!') { |
if (array_Grow(acmd, 0, 0)) { |
if (array_Grow(acmd, 0, 0)) { |
array_Destroy(&aarg); |
array_Destroy(&aarg); |
array_Destroy(&acmd); |
array_Destroy(&acmd); |
Line 234 Run(char **argv, char flg)
|
Line 287 Run(char **argv, char flg)
|
} else |
} else |
cmd = array(acmd, 0, char*); |
cmd = array(acmd, 0, char*); |
|
|
if (array_Concat(acmd, aarg) == -1) { | if (!(flg & SUX_GET_STDIN) && array_Concat(acmd, aarg) == -1) { |
array_Destroy(&aarg); |
array_Destroy(&aarg); |
array_Destroy(&acmd); |
array_Destroy(&acmd); |
return -1; |
return -1; |
Line 246 Run(char **argv, char flg)
|
Line 299 Run(char **argv, char flg)
|
} |
} |
array_Destroy(&acmd); |
array_Destroy(&acmd); |
|
|
if (SetClass()) { | if (setClassDir()) { |
if (args) |
if (args) |
e_free(args); |
e_free(args); |
return -1; |
return -1; |
} |
} |
|
|
if (flg & SUX_GET_FORCE) { |
if (flg & SUX_GET_FORCE) { |
/* |
|
if (setegid(AIT_GET_I16(&proc.proc_gid)) == -1) |
if (setegid(AIT_GET_I16(&proc.proc_gid)) == -1) |
goto err; |
goto err; |
if (seteuid(AIT_GET_I16(&proc.proc_uid)) == -1) |
if (seteuid(AIT_GET_I16(&proc.proc_uid)) == -1) |
goto err; |
goto err; |
*/ |
|
if (setpriority(PRIO_PROCESS, 0, AIT_GET_I32(&proc.proc_prio)) == -1) |
if (setpriority(PRIO_PROCESS, 0, AIT_GET_I32(&proc.proc_prio)) == -1) |
goto err; |
goto err; |
} |
} |
|
|
DumpProc(__func__); |
|
|
|
EVERBS(3) { |
EVERBS(3) { |
char **el = args - 1; |
char **el = args - 1; |
while (*++el) |
while (*++el) |
Log(3, "args: %s", *el); |
Log(3, "args: %s", *el); |
} |
} |
|
|
|
DumpProc(__func__); |
|
|
fflush(lf); |
fflush(lf); |
|
|
execve(cmd, args, environ); |
execve(cmd, args, environ); |
Line 376 main(int argc, char **argv)
|
Line 427 main(int argc, char **argv)
|
return 1; |
return 1; |
} else |
} else |
AIT_SET_STR(&proc.proc_name, str); |
AIT_SET_STR(&proc.proc_name, str); |
} else | } else if (strcmp(*argv, "-")) |
AIT_SET_STR(&proc.proc_name, *argv); |
AIT_SET_STR(&proc.proc_name, *argv); |
|
else { |
|
flg |= SUX_GET_STDIN; |
|
AIT_SET_STR(&proc.proc_name, "-.stdin"); /* hack for associate to stdin */ |
|
} |
Log(2, "Try to load config %s", szCfg); |
Log(2, "Try to load config %s", szCfg); |
if (cfgLoadConfig(szCfg, &cfg)) { |
if (cfgLoadConfig(szCfg, &cfg)) { |
ELIBERR(cfg); |
ELIBERR(cfg); |