--- suX/src/sux.c 2011/05/20 16:41:31 1.1.1.1.2.4 +++ suX/src/sux.c 2013/04/09 08:17:40 1.3.2.1 @@ -3,13 +3,13 @@ * by Michael Pounov * * $Author: misho $ - * $Id: sux.c,v 1.1.1.1.2.4 2011/05/20 16:41:31 misho Exp $ + * $Id: sux.c,v 1.3.2.1 2013/04/09 08:17:40 misho Exp $ * *************************************************************************/ #include "global.h" -sl_config cfg; +cfg_root_t cfg; int Verbose; struct tagProc proc; FILE *lf; @@ -18,42 +18,51 @@ FILE *lf; static inline void Log(int lvl, const char *fmt, ...) { - va_list lst; + va_list lst, cp; if (lvl <= Verbose) { va_start(lst, fmt); + va_copy(cp, lst); vfprintf(lf, fmt, lst); - fprintf(lf, "\n"); - vsyslog(LOG_WARNING, fmt, lst); va_end(lst); + fprintf(lf, "\n"); + vsyslog(LOG_WARNING, fmt, cp); + va_end(cp); } } static inline void Err(const char *fmt, ...) { - va_list lst; + va_list lst, cp; va_start(lst, fmt); + va_copy(cp, lst); vfprintf(lf, fmt, lst); - fprintf(lf, "\n"); - vsyslog(LOG_ERR, fmt, lst); va_end(lst); + fprintf(lf, "\n"); + vsyslog(LOG_ERR, fmt, cp); + va_end(cp); } static void initProg() { + char d[MAXPATHLEN]; + proc.proc_uid = getuid(); proc.proc_gid = getgid(); proc.proc_prio = getpriority(PRIO_PROCESS, 0); - getcwd(proc.proc_dir, sizeof proc.proc_dir); + getcwd(d, sizeof d); + AIT_SET_STR(&proc.proc_dir, d); +#if 0 lf = fopen(DEFAULT_LOG, "a"); if (!lf) +#endif lf = stdout; - openlog(PACKAGE_NAME, LOG_CONS | LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER); + openlog(PACKAGE_NAME, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_USER); } static void @@ -66,6 +75,8 @@ Usage() "\t-g \t\t\tGroup for suID\n" "\t-p \t\tExecute with priority\n" "\t-d \t\t\tDirectory for suID\n" + "\t-C \t\t\tChroot to directory\n" + "\t-c \t\t\tConfig file\n" "\t-l \t\t\tLog file path (default:/var/log/suX.log)\n" "\t-v\t\t\t\tVerbose, (more -v, more verbosity)\n" "\t-h\t\t\t\tThis help screen!\n\n", PACKAGE_NAME); @@ -101,17 +112,17 @@ SetClass() endpwent(); return -1; } else - strlcpy(proc.proc_class, pass->pw_class, sizeof proc.proc_class); + AIT_SET_STR(&proc.proc_class, pass->pw_class); - cap = login_getclass(proc.proc_class); + cap = login_getclass(AIT_GET_STR(&proc.proc_class)); if (!cap) { - Err("Error:: Cant get login class %s", proc.proc_class); + Err("Error:: Cant get login class %s", AIT_GET_STR(&proc.proc_class)); endpwent(); return -1; } if (setusercontext(cap, pass, proc.proc_uid, LOGIN_SETALL)) { - Err("Error:: Cant set login class %s", proc.proc_class); + Err("Error:: Cant set login class %s", AIT_GET_STR(&proc.proc_class)); login_close(cap); endpwent(); return -1; @@ -125,55 +136,54 @@ SetClass() static int LoadCfgData(char flg) { - char *str, mode = 0; + const char *str; + char mode = 0; - str = (char*) cfg_GetAttribute(&cfg, CFG("global"), CFG("mode")); + str = cfg_getAttribute(&cfg, "global", "mode"); if (!str) { Err("Error:: Unknown mode ..."); return -1; } if (!strcasecmp(str, "SCRIPT")) { mode = 1; - if (setUIDGID(flg, proc.proc_name) == -1) + if (setUIDGID(flg, AIT_GET_STR(&proc.proc_name)) == -1) return -1; } else if (!strcasecmp(str, "FILE")) { mode = 2; - if (setUIDGID(flg, proc.proc_name) == -1) + if (setUIDGID(flg, AIT_GET_STR(&proc.proc_name)) == -1) return -1; } else if (!strcasecmp(str, "DIR") && - (str = (char*) cfg_GetAttribute(&cfg, CFG("global"), CFG("directory")))) { + (str = cfg_getAttribute(&cfg, "global", "directory"))) { mode = 3; if (!(flg & 8)) - strlcpy(proc.proc_dir, str, sizeof proc.proc_dir); + AIT_SET_STR(&proc.proc_dir, str); - if (setUIDGID(flg, proc.proc_dir) == -1) + if (setUIDGID(flg, AIT_GET_STR(&proc.proc_dir)) == -1) return -1; } else { Err("Error:: Unknown mode %s", str); return -1; } if (!(flg & 4)) { - str = (char*) cfg_GetAttribute(&cfg, CFG("global"), CFG("priority")); + str = cfg_getAttribute(&cfg, "global", "priority"); if (str) proc.proc_prio = strtol(str, NULL, 10); } /* find associate extension */ - str = strrchr(proc.proc_name, '.'); + str = strrchr(AIT_GET_STR(&proc.proc_name), '.'); if (str) { str++; str = (*str) ? str : "default"; - switch (cfg_LoadAttribute(&cfg, CFG("associate"), CFG(str), - CFG(proc.proc_cmd), sizeof proc.proc_cmd, NULL)) { + switch (cfg_loadAttribute(&cfg, "associate", str, &proc.proc_cmd, NULL)) { case -1: - Err("Error:: can`t load attribute #%d - %s\n", cfg_GetErrno(), cfg_GetError()); + ELIBERR(cfg); return -1; case 0: - cfg_LoadAttribute(&cfg, CFG("associate"), CFG("default"), - CFG(proc.proc_cmd), sizeof proc.proc_cmd, DEFAULT_CMD); + cfg_loadAttribute(&cfg, "associate", "default", &proc.proc_cmd, DEFAULT_CMD); } } else - strlcpy(proc.proc_cmd, DEFAULT_CMD, sizeof proc.proc_cmd); + AIT_SET_STR(&proc.proc_cmd, DEFAULT_CMD); return 0; } @@ -188,33 +198,33 @@ Run(char **argv) if (!argv) return -1; - n = io_arrayMake(proc.proc_cmd, 0, " \t", &acmd); + n = array_Args(AIT_GET_STR(&proc.proc_cmd), 0, " \t", &acmd); if (n < 1) return -1; - if (!(aarg = io_arrayFrom((const char**) argv, 0))) { - io_arrayDestroy(&acmd); + if (!(aarg = array_From((const char***) &argv, 0))) { + array_Destroy(&acmd); return -1; - } else if (*io_arrayGet(acmd, 0, char*) == '!') { - if (io_arrayGrow(acmd, 0)) { - io_arrayDestroy(&aarg); - io_arrayDestroy(&acmd); + } else if (*array(acmd, 0, char*) == '!') { + if (array_Grow(acmd, 0, 0)) { + array_Destroy(&aarg); + array_Destroy(&acmd); return -1; } - cmd = io_arrayGet(aarg, 0, char*); + cmd = array(aarg, 0, char*); } else - cmd = io_arrayGet(acmd, 0, char*); + cmd = array(acmd, 0, char*); - if (io_arrayConcat(acmd, aarg) == -1) { - io_arrayDestroy(&aarg); - io_arrayDestroy(&acmd); + if (array_Concat(acmd, aarg) == -1) { + array_Destroy(&aarg); + array_Destroy(&acmd); return -1; } - io_arrayDestroy(&aarg); - if (!(args = io_arrayTo(acmd))) { - io_arrayDestroy(&acmd); + array_Destroy(&aarg); + if (!(args = array_To(acmd))) { + array_Destroy(&acmd); return -1; } - io_arrayDestroy(&acmd); + array_Destroy(&acmd); if (SetClass()) { if (args) @@ -222,6 +232,7 @@ Run(char **argv) return -1; } + /* if (setgid(proc.proc_gid) == -1) { Err("Error:: setgid #%d - %s\n", errno, strerror(errno)); if (args) @@ -240,9 +251,12 @@ Run(char **argv) free(args); return -1; } + */ - Log(0, "UID:GID=%d:%d Prio=%d Class=%s Name=%s Dir=%s Cmd=%s", proc.proc_uid, proc.proc_gid, - proc.proc_prio, proc.proc_class, proc.proc_name, proc.proc_dir, proc.proc_cmd); + Log(0, "UID:GID=%d:%d Prio=%d Class=%s Name=%s Dir=%s Cmd=%s Script=%s", + 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) { char **el = args - 1; @@ -263,7 +277,7 @@ Run(char **argv) int main(int argc, char **argv) { - char ch, *str, szCfg[MAXPATHLEN], flg = 0; + char ch, *str, *wrk, szCfg[MAXPATHLEN], **pp, flg = 0; struct passwd *pass; struct group *grp; FILE *f; @@ -271,7 +285,7 @@ main(int argc, char **argv) initProg(); strlcpy(szCfg, DEFAULT_CONFIG, sizeof szCfg); - while ((ch = getopt(argc, argv, "hvc:u:g:p:d:l:")) != -1) + while ((ch = getopt(argc, argv, "hvC:c:u:g:p:d:l:")) != -1) switch (ch) { case 'l': f = fopen(optarg, "a"); @@ -284,7 +298,7 @@ main(int argc, char **argv) lf = f; break; case 'd': - strlcpy(proc.proc_dir, optarg, sizeof proc.proc_dir); + AIT_SET_STR(&proc.proc_dir, optarg); flg |= 8; break; case 'p': @@ -314,6 +328,13 @@ main(int argc, char **argv) case 'c': strlcpy(szCfg, optarg, sizeof szCfg); break; + case 'C': + if (chroot(optarg) == -1) + Err("Error:: chroot to dir"); + if ((str = getenv("PATH_TRANSLATED"))) + if ((wrk = strstr(str, optarg))) + setenv("PATH_TRANSLATED", str + strlen(optarg), 42); + break; case 'v': Verbose++; break; @@ -326,6 +347,14 @@ main(int argc, char **argv) } argc -= optind; argv += optind; + + if (2 <= Verbose) { + for (pp = argv; *pp; pp++) + Log(2, "Args=%s\n", *pp); + for (pp = environ; *pp; pp++) + Log(2, "Envs=%s\n", *pp); + } + if (!argc) { if (!(str = getenv("PATH_TRANSLATED"))) { Usage(); @@ -333,24 +362,24 @@ main(int argc, char **argv) fclose(lf); return 1; } else - strlcpy(proc.proc_name, str, sizeof proc.proc_name); + AIT_SET_STR(&proc.proc_name, str); } else - strlcpy(proc.proc_name, *argv, sizeof proc.proc_name); + AIT_SET_STR(&proc.proc_name, *argv); Log(2, "Try to load config %s", szCfg); - if (LoadConfig(szCfg, &cfg)) { + if (cfgLoadConfig(szCfg, &cfg)) { Err("Error:: can`t load config #%d - %s\n", cfg_GetErrno(), cfg_GetError()); if (fileno(lf) > 2) fclose(lf); return 2; } else if (LoadCfgData(flg) == -1) { - UnloadConfig(&cfg); + cfgUnloadConfig(&cfg); if (fileno(lf) > 2) fclose(lf); closelog(); return 3; } - UnloadConfig(&cfg); + cfgUnloadConfig(&cfg); if (Run(argv) == -1) { if (fileno(lf) > 2)