Diff for /embedtools/src/cfexec.c between versions 1.2.2.2 and 1.5.20.3

version 1.2.2.2, 2011/06/13 20:23:35 version 1.5.20.3, 2017/10/08 22:28:26
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011Copyright 2004 - 2017
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 46  SUCH DAMAGE. Line 46  SUCH DAMAGE.
 #include "global.h"  #include "global.h"
   
   
sl_config cfg;cfg_root_t cfg;
 int Verbose, Timeout, kq;  int Verbose, Timeout, kq;
char szUser[MAX_STR], szMount[MAXPATHLEN], szDev[MAXPATHLEN], ait_val_t User, Mount, Dev, Chroot;
     szChroot[MAXPATHLEN], szSess[MAXPATHLEN], szConfig[MAXPATHLEN];char szSess[MAXPATHLEN], szSLCK[MAXPATHLEN], szConfig[MAXPATHLEN];
 extern char compiled[], compiledby[], compilehost[];  extern char compiled[], compiledby[], compilehost[];
   
   
static void Usage()static void
 Usage()
 {  {
   
         printf( "CFExec is tool for managment R/W operation with CompactFlash\n"          printf( "CFExec is tool for managment R/W operation with CompactFlash\n"
Line 63  static void Usage() Line 64  static void Usage()
                 "\t-c <dir>\tAfter execute chroot to dir [default=/]\n"                  "\t-c <dir>\tAfter execute chroot to dir [default=/]\n"
                 "\t-u <user>\tAfter execute suid to user [default=root]\n"                  "\t-u <user>\tAfter execute suid to user [default=root]\n"
                 "\t-d <dev>\tOther device [default=/dev/ufs/elwix]\n"                  "\t-d <dev>\tOther device [default=/dev/ufs/elwix]\n"
                "\t-m <mnt>\tOther mount dir [default=/cf]\n"                "\t-m <mnt>\tOther mount dir [default=/]\n"
                 "\t-t <sec>\tTimeout for autolock mount dir after seconds [default=300]\n"                  "\t-t <sec>\tTimeout for autolock mount dir after seconds [default=300]\n"
                   "\t-L <reason>\tService lock and set RW state of device with reason\n"
                   "\t-U \t\tService unlock and set RO state of device\n"
                 "\n", compiled, compiledby, compilehost);                  "\n", compiled, compiledby, compilehost);
 }  }
   
static int update(int flags)static int
 update(int flags)
 {  {
         struct ufs_args mnt;          struct ufs_args mnt;
   
         memset(&mnt, 0, sizeof mnt);          memset(&mnt, 0, sizeof mnt);
        mnt.fspec = szDev;        mnt.fspec = AIT_GET_STR(&Dev);
 #ifdef __NetBSD__  #ifdef __NetBSD__
        if (mount("ufs", szMount, flags, &mnt, sizeof mnt) == -1) {        if (mount("ufs", AIT_GET_STR(&Mount), flags, &mnt, sizeof mnt) == -1) {
 #else  #else
        if (mount("ufs", szMount, flags, &mnt) == -1) {        if (mount("ufs", AIT_GET_STR(&Mount), flags, &mnt) == -1) {
 #endif  #endif
                printf("Error:: can`t update mount %s #%d - %s\n", szMount, errno, strerror(errno));                printf("Error:: can`t update mount %s #%d - %s\n", AIT_GET_STR(&Mount), 
                                 errno, strerror(errno));
                 return -1;                  return -1;
         }          }
   
         VERB(5) printf("Info(5):: safe mount for device %s to %s operation (%s)\n",           VERB(5) printf("Info(5):: safe mount for device %s to %s operation (%s)\n", 
                        szDev, szMount, (flags & MNT_RDONLY) ? "ro" : "rw");                        AIT_GET_STR(&Dev), AIT_GET_STR(&Mount), (flags & MNT_RDONLY) ? "ro" : "rw");
         return 0;          return 0;
 }  }
   
static void setuser()static void
 setuser()
 {  {
         struct passwd *pw;          struct passwd *pw;
   
        pw = getpwnam(szUser);        pw = getpwnam(AIT_GET_LIKE(&User, char*));
         if (pw) {          if (pw) {
                 setuid(pw->pw_uid);                  setuid(pw->pw_uid);
                 setgid(pw->pw_gid);                  setgid(pw->pw_gid);
                 endpwent();                  endpwent();
   
                VERB(5) printf("Info(5):: Suid to user %s.\n", szUser);                VERB(5) printf("Info(5):: Suid to user %s.\n", AIT_GET_STR(&User));
         } else          } else
                VERB(5) printf("Info(5):: Can`t suid to user %s !\n", szUser);                VERB(5) printf("Info(5):: Can`t suid to user %s !\n", AIT_GET_STR(&User));
 }  }
   
static int mkevent(struct kevent *chg, struct kevent *evt)static int
 mkevent(struct kevent *chg, struct kevent *evt)
 {  {
         int f;          int f;
        char szStr[MAX_STR];        char szStr[STRSIZ];
   
         f = open(szSess, O_CREAT | O_WRONLY | O_TRUNC, 0644);          f = open(szSess, O_CREAT | O_WRONLY | O_TRUNC, 0644);
         if (f == -1) {          if (f == -1) {
                 printf("Error:: can`t lock session #%d - %s\n", errno, strerror(errno));                  printf("Error:: can`t lock session #%d - %s\n", errno, strerror(errno));
                 return -1;                  return -1;
         } else {          } else {
                memset(szStr, 0, MAX_STR);                memset(szStr, 0, sizeof szStr);
                snprintf(szStr, MAX_STR, "%d", getpid());                snprintf(szStr, sizeof szStr, "%d", getpid());
                 write(f, szStr, strlen(szStr));                  write(f, szStr, strlen(szStr));
         }          }
         VERB(3) printf("Created lock file %s\n", szSess);          VERB(3) printf("Created lock file %s\n", szSess);
   
        kq = kqueue();        if (chg && evt) {
        if (kq == -1) {                kq = kqueue();
                printf("Error:: can`t execute safe mount #%d - %s\n", errno, strerror(errno));                if (kq == -1) {
                close(f);                        printf("Error:: can`t execute safe mount #%d - %s\n", errno, strerror(errno));
                unlink(szSess);                        close(f);
                return -1;                        unlink(szSess);
        } else {                        return -1;
                memset(chg, 0, sizeof(struct kevent));                } else {
                memset(evt, 0, sizeof(struct kevent));                        memset(chg, 0, sizeof(struct kevent));
                         memset(evt, 0, sizeof(struct kevent));
   
                EV_SET(chg, f, EVFILT_VNODE, EV_ADD, NOTE_DELETE | NOTE_RENAME | NOTE_REVOKE, 0, (intptr_t) NULL);                        EV_SET(chg, f, EVFILT_VNODE, EV_ADD, NOTE_DELETE | NOTE_RENAME | NOTE_REVOKE, 
                                         0, NULL);
                 }
         }          }
   
         return f;          return f;
 }  }
   
// ---------------------------------static void
 cleanexit()
 {
         AIT_FREE_VAL(&User);
         AIT_FREE_VAL(&Dev);
         AIT_FREE_VAL(&Mount);
         AIT_FREE_VAL(&Chroot);
   
int main(int argc, char **argv)        cfgUnloadConfig(&cfg);
 }
 
 static int
 s_unlck()
 {  {
        char ch;        if (access(szSLCK, F_OK))
                 return 1;
 
         if (access(szSess, F_OK) && update(MNT_UPDATE | MNT_RDONLY) == -1)
                 return 8;
 
         unlink(szSLCK);
         VERB(3) printf("Unlock & deleted service lock file %s\n", szSLCK);
         return 0;
 }
 
 static int
 s_lck(const char *reason)
 {
         int f;
         char szStr[STRSIZ];
 
         if (!access(szSLCK, F_OK)) {
                 printf("cfexec:: Service held lock ...\n");
                 return 127;
         }
 
         f = open(szSLCK, O_CREAT | O_WRONLY | O_TRUNC, 0644);
         if (f == -1) {
                 printf("Error:: can`t service lock session #%d - %s\n", errno, strerror(errno));
                 return 5;
         } else {
                 memset(szStr, 0, sizeof szStr);
                 snprintf(szStr, sizeof szStr, "[%d] - %s", getpid(), reason);
                 write(f, szStr, strlen(szStr));
         }
         close(f);
 
         if (update(MNT_UPDATE) == -1) {
                 unlink(szSLCK);
                 return 4;
         }
 
         VERB(3) printf("Lock & created service lock file %s\n", szSLCK);
         return 0;
 }
 
 
 int
 main(int argc, char **argv)
 {
         char ch, mod = 0, reason[STRSIZ];
         const char *err = NULL;          const char *err = NULL;
         struct kevent chg, evt;          struct kevent chg, evt;
         struct timespec ts;          struct timespec ts;
         pid_t pid;          pid_t pid;
        int f, stat = 0;        int f, ret = 0, stat = 0;
//      sigset_t sig, oldsig; 
   
         strlcpy(szConfig, DEFAULT_CONFIG, MAXPATHLEN);          strlcpy(szConfig, DEFAULT_CONFIG, MAXPATHLEN);
        // Load variables from config if exists        /* Load variables from config if exists */
        if (!LoadConfig(szConfig, &cfg)) {        if (!cfgLoadConfig(szConfig, &cfg)) {
                cfg_LoadAttribute(&cfg, CFG("cfexec"), CFG("timeout"), CFG(szUser), MAX_STR, DEFAULT_TIMEOUT);                cfg_loadAttribute(&cfg, "cfexec", "timeout", &User, DEFAULT_TIMEOUT);
 #ifndef HAVE_STRTONUM  #ifndef HAVE_STRTONUM
                 Timeout = (int) strtol(szUser, NULL, 0);                  Timeout = (int) strtol(szUser, NULL, 0);
 #else  #else
                Timeout = strtonum(szUser, 0, 3600, &err);                Timeout = strtonum(AIT_GET_STR(&User), 0, 3600, &err);
 #endif  #endif
                   AIT_FREE_VAL(&User);
                 if (!Timeout && err) {                  if (!Timeout && err) {
                         printf("Error:: in seconds for timeout %s - %s\n", optarg, err);                          printf("Error:: in seconds for timeout %s - %s\n", optarg, err);
                        UnloadConfig(&cfg);                        cfgUnloadConfig(&cfg);
                         return 1;                          return 1;
                 }                  }
                cfg_LoadAttribute(&cfg, CFG("cfexec"), CFG("suid"), CFG(szUser), MAX_STR, DEFAULT_USER);                cfg_loadAttribute(&cfg, "cfexec", "suid", &User, DEFAULT_USER);
                cfg_LoadAttribute(&cfg, CFG("cfexec"), CFG("mount"), CFG(szMount), MAXPATHLEN, DEFAULT_MOUNT);                cfg_loadAttribute(&cfg, "cfexec", "mount", &Mount, DEFAULT_MOUNT);
                cfg_LoadAttribute(&cfg, CFG("cfexec"), CFG("device"), CFG(szDev), MAXPATHLEN, DEFAULT_DEVICE);                cfg_loadAttribute(&cfg, "cfexec", "device", &Dev, DEFAULT_DEVICE);
                cfg_LoadAttribute(&cfg, CFG("cfexec"), CFG("chroot"), CFG(szChroot), MAXPATHLEN, DEFAULT_CHROOT);                cfg_loadAttribute(&cfg, "cfexec", "chroot", &Chroot, DEFAULT_CHROOT);
   
                UnloadConfig(&cfg);                cfgUnloadConfig(&cfg);
         } else {          } else {
                 Timeout = atoi(DEFAULT_TIMEOUT);                  Timeout = atoi(DEFAULT_TIMEOUT);
                strlcpy(szUser, DEFAULT_USER, MAX_STR);                AIT_SET_STR(&User, DEFAULT_USER);
                strlcpy(szMount, DEFAULT_MOUNT, MAXPATHLEN);                AIT_SET_STR(&Mount, DEFAULT_MOUNT);
                strlcpy(szDev, DEFAULT_DEVICE, MAXPATHLEN);                AIT_SET_STR(&Dev, DEFAULT_DEVICE);
                strlcpy(szChroot, DEFAULT_CHROOT, MAXPATHLEN);                AIT_SET_STR(&Chroot, DEFAULT_CHROOT);
         }          }
   
        // Load variables from arguments if exists        atexit(cleanexit);
        while ((ch = getopt(argc, argv, "hvu:c:d:m:t:")) != -1)
         /* Load variables from arguments if exists */
         while ((ch = getopt(argc, argv, "hvUu:c:d:m:t:L:")) != -1)
                 switch (ch) {                  switch (ch) {
                         case 'v':                          case 'v':
                                 Verbose++;                                  Verbose++;
                                 break;                                  break;
                         case 'u':                          case 'u':
                                strlcpy(szUser, optarg, MAX_STR);                                AIT_SET_STR(&User, optarg);
                                 break;                                  break;
                         case 'c':                          case 'c':
                                strlcpy(szChroot, optarg, MAXPATHLEN);                                AIT_SET_STR(&Chroot, optarg);
                                 break;                                  break;
                         case 'd':                          case 'd':
                                strlcpy(szDev, optarg, MAXPATHLEN);                                AIT_SET_STR(&Dev, optarg);
                                 break;                                  break;
                         case 'm':                          case 'm':
                                strlcpy(szMount, optarg, MAXPATHLEN);                                AIT_SET_STR(&Mount, optarg);
                                 break;                                  break;
                           case 'L':
                                   strlcpy(reason, optarg, sizeof reason);
                                   mod = 1;
                                   break;
                           case 'U':
                                   mod = -1;
                                   break;
                         case 't':                          case 't':
 #ifndef HAVE_STRTONUM  #ifndef HAVE_STRTONUM
                                Timeout = (int) strtol(szUser, NULL, 0);                                Timeout = (int) strtol(optarg, NULL, 0);
 #else  #else
                                 Timeout = strtonum(optarg, 0, 3600, &err);                                  Timeout = strtonum(optarg, 0, 3600, &err);
 #endif  #endif
Line 214  int main(int argc, char **argv) Line 289  int main(int argc, char **argv)
         argv += optind;          argv += optind;
   
         memset(szSess, 0, MAXPATHLEN);          memset(szSess, 0, MAXPATHLEN);
        snprintf(szSess, MAXPATHLEN, "%s%s-cfexec.LCK", DEFAULT_TMP, szMount);        snprintf(szSess, MAXPATHLEN, "%s%s-cfexec.LCK", DEFAULT_TMP, AIT_GET_STR(&Mount));
         memset(szSLCK, 0, MAXPATHLEN);
         snprintf(szSLCK, MAXPATHLEN, CFEXEC_SLOCK, DEFAULT_TMP);
   
           /* we have request for service lock! */
           if (mod) {
                   VERB(3) printf("Info(3):: mode=%hhd\n", mod);
                   if (mod == -1)
                           ret = s_unlck();
                   else
                           ret = s_lck(reason);
                   return ret;
           }
   
         VERB(3) printf("Info(3):: Chroot=%s SUID=%s Device=%s Mount=%s Timeout=%d Session=%s\n",           VERB(3) printf("Info(3):: Chroot=%s SUID=%s Device=%s Mount=%s Timeout=%d Session=%s\n", 
                        szChroot, szUser, szDev, szMount, Timeout, szSess);                        AIT_GET_STR(&Chroot), AIT_GET_STR(&User), AIT_GET_STR(&Dev), 
                         AIT_GET_STR(&Mount), Timeout, szSess);
   
         if (!access(szSess, F_OK)) {          if (!access(szSess, F_OK)) {
                 printf("cfexec already running ...\n");                  printf("cfexec already running ...\n");
Line 234  int main(int argc, char **argv) Line 322  int main(int argc, char **argv)
                                 VERB(5) printf("Info(5):: Go safe mount.\n");                                  VERB(5) printf("Info(5):: Go safe mount.\n");
                                 setsid();                                  setsid();
   
                                if (update(MNT_UPDATE) == -1)                                if ((f = mkevent(&chg, &evt)) == -1)
                                         return 4;                                          return 4;
   
                                if ((f = mkevent(&chg, &evt)) == -1)                                if (update(MNT_UPDATE) == -1)
                                         return 5;                                          return 5;
   
                                 if (Timeout) {                                  if (Timeout) {
Line 251  int main(int argc, char **argv) Line 339  int main(int argc, char **argv)
                                                 stat = 7;                                                  stat = 7;
                                                 break;                                                  break;
                                         case 0:                                          case 0:
                                                   if (!access(szSLCK, F_OK)) {
                                                           VERB(1) printf("Timeout reached - service locked\n");
                                                           break;
                                                   }
                                                 VERB(1) printf("Timeout reached - secure mount\n");                                                  VERB(1) printf("Timeout reached - secure mount\n");
                                         default:                                          default:
                                                 VERB(1) printf("Lock file is deleted - secure mount\n");                                                  VERB(1) printf("Lock file is deleted - secure mount\n");
                                                if (update(MNT_UPDATE | MNT_RDONLY) == -1)                                                if (access(szSLCK, F_OK) && update(MNT_UPDATE | MNT_RDONLY) == -1)
                                                         stat = 8;                                                          stat = 8;
                                 }                                  }
   
Line 271  int main(int argc, char **argv) Line 363  int main(int argc, char **argv)
                 sigprocmask(SIG_BLOCK, &sig, &oldsig);                  sigprocmask(SIG_BLOCK, &sig, &oldsig);
                 */                  */
   
                if (update(MNT_UPDATE) == -1)                if ((f = mkevent(NULL, NULL)) == -1)
                         return 4;                          return 4;
                   else
                           close(f);
   
                   if (update(MNT_UPDATE) == -1)
                           return 5;
   
                 switch ((pid = vfork())) {                  switch ((pid = vfork())) {
                         case -1:                          case -1:
                                 printf("Error:: can`t execute safe mount #%d - %s\n",                                   printf("Error:: can`t execute safe mount #%d - %s\n", 
                                                 errno, strerror(errno));                                                  errno, strerror(errno));
                                return 5;                                stat = 3;
                                 break;
                         case 0:                          case 0:
                                 VERB(5) printf("Go to running process %s\n", *argv);                                  VERB(5) printf("Go to running process %s\n", *argv);
                                if (chroot(szChroot) == -1) {                                if (chroot(AIT_GET_STR(&Chroot)) == -1) {
                                         printf("Error:: can`t chroot to dir %s #%d - %s\n",                                           printf("Error:: can`t chroot to dir %s #%d - %s\n", 
                                                        szChroot, errno, strerror(errno));                                                        AIT_GET_STR(&Chroot), errno, strerror(errno));
                                 } else {                                  } else {
                                        if (strncmp(szUser, "root", 5))                                        if (strncmp(AIT_GET_STR(&User), "root", 5))
                                                 setuser();                                                  setuser();
   
                                         /* chdir("/"); */                                          /* chdir("/"); */
Line 295  int main(int argc, char **argv) Line 393  int main(int argc, char **argv)
                                 break;                                  break;
                         default:                          default:
                                 waitpid(pid, &stat, 0);                                  waitpid(pid, &stat, 0);
                                   stat = WEXITSTATUS(stat);
                                 VERB(3) printf("Return code: %d\n", stat);                                  VERB(3) printf("Return code: %d\n", stat);
                                 if (stat == 32512)   
                                         stat = 127;  
   
                                if (update(MNT_UPDATE | MNT_RDONLY) == -1)                                if (access(szSLCK, F_OK) && update(MNT_UPDATE | MNT_RDONLY) == -1)
                                        return 8;                                        stat = 8;
                                 break;
                 }                  }
   
//              sigprocmask(SIG_SETMASK, &oldsig, NULL);                unlink(szSess);
         }          }
   
         return stat;          return stat;

Removed from v.1.2.2.2  
changed lines
  Added in v.1.5.20.3


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