| version 1.3.2.1, 2013/04/09 08:17:40 | version 1.4.2.1, 2013/04/09 23:50:14 | 
| Line 20  Log(int lvl, const char *fmt, ...) | Line 20  Log(int lvl, const char *fmt, ...) | 
 | { | { | 
 | va_list lst, cp; | va_list lst, cp; | 
 |  |  | 
| if (lvl <= Verbose) { | EVERBS(lvl) { | 
 | va_start(lst, fmt); | va_start(lst, fmt); | 
 | va_copy(cp, lst); | va_copy(cp, lst); | 
 | vfprintf(lf, fmt, lst); | vfprintf(lf, fmt, lst); | 
| Line 45  Err(const char *fmt, ...) | Line 45  Err(const char *fmt, ...) | 
 | va_end(cp); | va_end(cp); | 
 | } | } | 
 |  |  | 
| static void | static inline void | 
|  | DumpProc(const char *txt) | 
|  | { | 
|  | Log(0, "%s:: uid:gid=%d:%d UID:GID=%d:%d Prio=%d Class=%s Name=%s Dir=%s Cmd=%s " | 
|  | "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_STR(&proc.proc_class), AIT_GET_STR(&proc.proc_name), | 
|  | AIT_GET_STR(&proc.proc_dir), AIT_GET_STR(&proc.proc_cmd), | 
|  | getenv("PATH_TRANSLATED"), getenv("REMOTE_ADDR"), | 
|  | getenv("REMOTE_PORT"), getenv("REQUEST_URI")); | 
|  | } | 
|  |  | 
|  | static int | 
 | initProg() | initProg() | 
 | { | { | 
| char d[MAXPATHLEN]; | AIT_SET_I16(&proc.proc_uid, getuid()); | 
|  | AIT_SET_I16(&proc.proc_gid, getgid()); | 
|  | AIT_SET_I32(&proc.proc_prio, getpriority(PRIO_PROCESS, 0)); | 
|  | AIT_INIT_VAL2(&proc.proc_class, string); | 
|  | AIT_INIT_VAL2(&proc.proc_dir, string); | 
|  | AIT_INIT_VAL2(&proc.proc_name, string); | 
|  | AIT_INIT_VAL2(&proc.proc_cmd, string); | 
 |  |  | 
 | proc.proc_uid = getuid(); |  | 
 | proc.proc_gid = getgid(); |  | 
 | proc.proc_prio = getpriority(PRIO_PROCESS, 0); |  | 
 | getcwd(d, sizeof d); |  | 
 | AIT_SET_STR(&proc.proc_dir, d); |  | 
 |  |  | 
 | #if 0 | #if 0 | 
 | lf = fopen(DEFAULT_LOG, "a"); | lf = fopen(DEFAULT_LOG, "a"); | 
 | if (!lf) | if (!lf) | 
| Line 63  initProg() | Line 76  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 | 
 |  | endProg() | 
 |  | { | 
 |  | AIT_FREE_VAL(&proc.proc_uid); | 
 |  | AIT_FREE_VAL(&proc.proc_gid); | 
 |  | AIT_FREE_VAL(&proc.proc_prio); | 
 |  | AIT_FREE_VAL(&proc.proc_class); | 
 |  | AIT_FREE_VAL(&proc.proc_dir); | 
 |  | AIT_FREE_VAL(&proc.proc_name); | 
 |  | AIT_FREE_VAL(&proc.proc_cmd); | 
 |  | } | 
 |  |  | 
 |  | static void | 
 | Usage() | Usage() | 
 | { | { | 
 | printf( " -= suX =- suExecutor designed for web based applicaions\n" | printf( " -= suX =- suExecutor designed for web based applicaions\n" | 
| Line 78  Usage() | Line 104  Usage() | 
 | "\t-C <directory>\t\t\tChroot to directory\n" | "\t-C <directory>\t\t\tChroot to directory\n" | 
 | "\t-c <cfgfile>\t\t\tConfig file\n" | "\t-c <cfgfile>\t\t\tConfig file\n" | 
 | "\t-l <logfile>\t\t\tLog file path (default:/var/log/suX.log)\n" | "\t-l <logfile>\t\t\tLog file path (default:/var/log/suX.log)\n" | 
 |  | "\t-o\t\t\t\tForce set UID,GID and Priority for program\n" | 
 | "\t-v\t\t\t\tVerbose, (more -v, more verbosity)\n" | "\t-v\t\t\t\tVerbose, (more -v, more verbosity)\n" | 
 | "\t-h\t\t\t\tThis help screen!\n\n", PACKAGE_NAME); | "\t-h\t\t\t\tThis help screen!\n\n", PACKAGE_NAME); | 
 | } | } | 
| Line 86  static inline int | Line 113  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) { | 
| Err("Error:: %s stat #%d - %s", name, errno, strerror(errno)); | 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")); | 
|  | 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 & 1)) | if (!(flg & SUX_GET_UID)) | 
| proc.proc_uid = sb.st_uid; | AIT_SET_I16(&proc.proc_uid, uid); | 
| if (!(flg & 2)) | if (!(flg & SUX_GET_GID)) | 
| 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() | 
 | { | { | 
 | login_cap_t *cap; |  | 
 | struct passwd *pass; | struct passwd *pass; | 
 |  | int ret = 0; | 
 |  |  | 
| pass = getpwuid(proc.proc_uid); | pass = getpwuid(AIT_GET_I16(&proc.proc_uid)); | 
 | if (!pass) { | if (!pass) { | 
| Err("Error:: User with this UID %d not found", 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); | 
 |  |  | 
| cap = login_getclass(AIT_GET_STR(&proc.proc_class)); | if (setusercontext(NULL, pass, AIT_GET_I16(&proc.proc_uid), | 
| if (!cap) { | LOGIN_SETLOGIN | LOGIN_SETGROUP | LOGIN_SETUSER | | 
| Err("Error:: Cant get login class %s", AIT_GET_STR(&proc.proc_class)); | LOGIN_SETPRIORITY | LOGIN_SETRESOURCES)) { | 
| endpwent(); | Err("Error:: Can't set login class %s", AIT_GET_STR(&proc.proc_class)); | 
| return -1; | ret = -1; | 
|  | } | 
 | } | } | 
 |  |  | 
 | if (setusercontext(cap, pass, proc.proc_uid, LOGIN_SETALL)) { |  | 
 | Err("Error:: Cant set login class %s", AIT_GET_STR(&proc.proc_class)); |  | 
 | login_close(cap); |  | 
 | endpwent(); |  | 
 | return -1; |  | 
 | } |  | 
 |  |  | 
 | login_close(cap); |  | 
 | endpwent(); | endpwent(); | 
| return 0; | return ret; | 
 | } | } | 
 |  |  | 
 | static int | static int | 
| Line 144  LoadCfgData(char flg) | Line 180  LoadCfgData(char flg) | 
 | Err("Error:: Unknown mode ..."); | Err("Error:: Unknown mode ..."); | 
 | return -1; | return -1; | 
 | } | } | 
| if (!strcasecmp(str, "SCRIPT")) { | if (!strcasecmp(str, "SCRIPT") && getenv("SUX_USER")) { | 
 | mode = 1; | mode = 1; | 
| if (setUIDGID(flg, AIT_GET_STR(&proc.proc_name)) == -1) | if (setUIDGID(flg, NULL) == -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 & 8)) | 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); | 
 | return -1; | return -1; | 
 | } | } | 
| if (!(flg & 4)) { | if (!(flg & SUX_GET_PRIO)) { | 
 | str = cfg_getAttribute(&cfg, "global", "priority"); | str = cfg_getAttribute(&cfg, "global", "priority"); | 
 | if (str) | if (str) | 
| proc.proc_prio = strtol(str, NULL, 10); | AIT_SET_I32(&proc.proc_prio, strtol(str, NULL, 10)); | 
 | } | } | 
 |  |  | 
 | /* find associate extension */ | /* find associate extension */ | 
| Line 180  LoadCfgData(char flg) | Line 213  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 189  LoadCfgData(char flg) | Line 223  LoadCfgData(char flg) | 
 | } | } | 
 |  |  | 
 | static int | static int | 
| Run(char **argv) | Run(char **argv, char flg) | 
 | { | { | 
 | char **args, *cmd; | char **args, *cmd; | 
 | array_t *acmd, *aarg; | array_t *acmd, *aarg; | 
| Line 226  Run(char **argv) | Line 260  Run(char **argv) | 
 | } | } | 
 | array_Destroy(&acmd); | array_Destroy(&acmd); | 
 |  |  | 
| if (SetClass()) { | if (setClassDir()) { | 
 | if (args) | if (args) | 
| free(args); | e_free(args); | 
 | return -1; | return -1; | 
 | } | } | 
 |  |  | 
| /* | if (flg & SUX_GET_FORCE) { | 
| if (setgid(proc.proc_gid) == -1) { | if (setegid(AIT_GET_I16(&proc.proc_gid)) == -1) | 
| Err("Error:: setgid #%d - %s\n", errno, strerror(errno)); | goto err; | 
| if (args) | if (seteuid(AIT_GET_I16(&proc.proc_uid)) == -1) | 
| free(args); | goto err; | 
| return -1; | if (setpriority(PRIO_PROCESS, 0, AIT_GET_I32(&proc.proc_prio)) == -1) | 
|  | goto err; | 
 | } | } | 
 | if (setuid(proc.proc_uid) == -1) { |  | 
 | Err("Error:: setuid #%d - %s\n", errno, strerror(errno)); |  | 
 | if (args) |  | 
 | free(args); |  | 
 | return -1; |  | 
 | } |  | 
 | if (setpriority(PRIO_PROCESS, 0, proc.proc_prio) == -1) { |  | 
 | Err("Error:: setpriority #%d - %s\n", errno, strerror(errno)); |  | 
 | if (args) |  | 
 | free(args); |  | 
 | return -1; |  | 
 | } |  | 
 | */ |  | 
 |  |  | 
| Log(0, "UID:GID=%d:%d Prio=%d Class=%s Name=%s Dir=%s Cmd=%s Script=%s", | DumpProc(__func__); | 
| proc.proc_uid, proc.proc_gid, proc.proc_prio, AIT_GET_STR(&proc.proc_class), |  | 
| AIT_GET_STR(&proc.proc_name), AIT_GET_STR(&proc.proc_dir), |  | 
| AIT_GET_STR(&proc.proc_cmd), getenv("PATH_TRANSLATED")); |  | 
 |  |  | 
| if (3 <= Verbose) { | EVERBS(3) { | 
 | char **el = args - 1; | char **el = args - 1; | 
 | while (*++el) | while (*++el) | 
 | Log(3, "args: %s", *el); | Log(3, "args: %s", *el); | 
| Line 267  Run(char **argv) | Line 286  Run(char **argv) | 
 | fflush(lf); | fflush(lf); | 
 |  |  | 
 | execve(cmd, args, environ); | execve(cmd, args, environ); | 
 |  | err: | 
 |  | ESYSERR(0); | 
 | if (args) | if (args) | 
| free(args); | e_free(args); | 
| Err("Error:: in exec() #%d - %s", errno, strerror(errno)); |  | 
 | return -1; | return -1; | 
 | } | } | 
 |  |  | 
| Line 285  main(int argc, char **argv) | Line 305  main(int argc, char **argv) | 
 | initProg(); | initProg(); | 
 | strlcpy(szCfg, DEFAULT_CONFIG, sizeof szCfg); | strlcpy(szCfg, DEFAULT_CONFIG, sizeof szCfg); | 
 |  |  | 
| while ((ch = getopt(argc, argv, "hvC:c:u:g:p:d:l:")) != -1) | while ((ch = getopt(argc, argv, "hvoC:c:u:g:p:d:l:")) != -1) | 
 | switch (ch) { | switch (ch) { | 
 | case 'l': | case 'l': | 
 | f = fopen(optarg, "a"); | f = fopen(optarg, "a"); | 
| Line 299  main(int argc, char **argv) | Line 319  main(int argc, char **argv) | 
 | break; | break; | 
 | case 'd': | case 'd': | 
 | AIT_SET_STR(&proc.proc_dir, optarg); | AIT_SET_STR(&proc.proc_dir, optarg); | 
| flg |= 8; | flg |= SUX_GET_DIR; | 
 | break; | break; | 
 | case 'p': | case 'p': | 
| proc.proc_prio = strtol(optarg, NULL, 0); | AIT_SET_I32(&proc.proc_prio, strtol(optarg, NULL, 0)); | 
| flg |= 4; | flg |= SUX_GET_PRIO; | 
 | break; | break; | 
 | case 'g': | case 'g': | 
 | setgrent(); | setgrent(); | 
 | grp = getgrnam(optarg); | grp = getgrnam(optarg); | 
 | if (grp) { | if (grp) { | 
| proc.proc_gid = grp->gr_gid; | AIT_SET_I16(&proc.proc_gid, grp->gr_gid); | 
| flg |= 2; | flg |= SUX_GET_GID; | 
 | } else | } else | 
 | Err("Error:: Group not found!"); | Err("Error:: Group not found!"); | 
 | endgrent(); | endgrent(); | 
| Line 319  main(int argc, char **argv) | Line 339  main(int argc, char **argv) | 
 | setpwent(); | setpwent(); | 
 | pass = getpwnam(optarg); | pass = getpwnam(optarg); | 
 | if (pass) { | if (pass) { | 
| proc.proc_uid = pass->pw_uid; | AIT_SET_I16(&proc.proc_uid, pass->pw_uid); | 
| flg |= 1; | flg |= SUX_GET_UID; | 
 | } else | } else | 
 | Err("Error:: User not found!"); | Err("Error:: User not found!"); | 
 | endpwent(); | endpwent(); | 
| Line 335  main(int argc, char **argv) | Line 355  main(int argc, char **argv) | 
 | if ((wrk = strstr(str, optarg))) | if ((wrk = strstr(str, optarg))) | 
 | setenv("PATH_TRANSLATED", str + strlen(optarg), 42); | setenv("PATH_TRANSLATED", str + strlen(optarg), 42); | 
 | break; | break; | 
 |  | case 'o': | 
 |  | flg |= SUX_GET_FORCE; | 
 |  | break; | 
 | case 'v': | case 'v': | 
| Verbose++; | e_incVerbose; | 
 | break; | break; | 
 | case 'h': | case 'h': | 
 | default: | default: | 
 | Usage(); | Usage(); | 
 |  | endProg(); | 
 | if (fileno(lf) > 2) | if (fileno(lf) > 2) | 
 | fclose(lf); | fclose(lf); | 
 | return 1; | return 1; | 
| Line 348  main(int argc, char **argv) | Line 372  main(int argc, char **argv) | 
 | argc -= optind; | argc -= optind; | 
 | argv += optind; | argv += optind; | 
 |  |  | 
| if (2 <= Verbose) { | EVERBS(2) { | 
 | for (pp = argv; *pp; pp++) | for (pp = argv; *pp; pp++) | 
 | Log(2, "Args=%s\n", *pp); | Log(2, "Args=%s\n", *pp); | 
 | for (pp = environ; *pp; pp++) | for (pp = environ; *pp; pp++) | 
| Line 358  main(int argc, char **argv) | Line 382  main(int argc, char **argv) | 
 | if (!argc) { | if (!argc) { | 
 | if (!(str = getenv("PATH_TRANSLATED"))) { | if (!(str = getenv("PATH_TRANSLATED"))) { | 
 | Usage(); | Usage(); | 
 |  | endProg(); | 
 | if (fileno(lf) > 2) | if (fileno(lf) > 2) | 
 | fclose(lf); | fclose(lf); | 
 | return 1; | return 1; | 
| Line 367  main(int argc, char **argv) | Line 392  main(int argc, char **argv) | 
 | AIT_SET_STR(&proc.proc_name, *argv); | AIT_SET_STR(&proc.proc_name, *argv); | 
 | Log(2, "Try to load config %s", szCfg); | Log(2, "Try to load config %s", szCfg); | 
 | if (cfgLoadConfig(szCfg, &cfg)) { | if (cfgLoadConfig(szCfg, &cfg)) { | 
| Err("Error:: can`t load config #%d - %s\n", cfg_GetErrno(), cfg_GetError()); | ELIBERR(cfg); | 
|  | endProg(); | 
 | if (fileno(lf) > 2) | if (fileno(lf) > 2) | 
 | fclose(lf); | fclose(lf); | 
 | return 2; | return 2; | 
 | } else | } else | 
 | if (LoadCfgData(flg) == -1) { | if (LoadCfgData(flg) == -1) { | 
 | cfgUnloadConfig(&cfg); | cfgUnloadConfig(&cfg); | 
 |  | endProg(); | 
 | if (fileno(lf) > 2) | if (fileno(lf) > 2) | 
 | fclose(lf); | fclose(lf); | 
 | closelog(); | closelog(); | 
| Line 381  main(int argc, char **argv) | Line 408  main(int argc, char **argv) | 
 | } | } | 
 | cfgUnloadConfig(&cfg); | cfgUnloadConfig(&cfg); | 
 |  |  | 
| if (Run(argv) == -1) { | if (Run(argv, flg) == -1) { | 
|  | endProg(); | 
 | if (fileno(lf) > 2) | if (fileno(lf) > 2) | 
 | fclose(lf); | fclose(lf); | 
 | closelog(); | closelog(); | 
 | return 4; | return 4; | 
 | } | } | 
 |  |  | 
 |  | endProg(); | 
 | if (fileno(lf) > 2) | if (fileno(lf) > 2) | 
 | fclose(lf); | fclose(lf); | 
 | closelog(); | closelog(); |