Diff for /suX/src/sux.c between versions 1.3.2.1 and 1.5.2.2

version 1.3.2.1, 2013/04/09 08:17:40 version 1.5.2.2, 2015/06/17 14:01:33
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);
                 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 45  Err(const char *fmt, ...) Line 45  Err(const char *fmt, ...)
         va_end(cp);          va_end(cp);
 }  }
   
static voidstatic inline void
 DumpProc(const char *txt)
 {
         Log(1, "%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"
                 "(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 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") ? 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 & 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 146  LoadCfgData(char flg) Line 182  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 & 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 204  Run(char **argv) Line 238  Run(char **argv)
         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 214  Run(char **argv) Line 250  Run(char **argv)
         } 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 226  Run(char **argv) Line 262  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",         EVERBS(3) {
                        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;                  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);
   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 307  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 321  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 341  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 357  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 374  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 384  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;
                 } 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)) {
                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 414  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();

Removed from v.1.3.2.1  
changed lines
  Added in v.1.5.2.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>