#include #include #include #include #include #include #include /* Valid chars in service name */ #define VALID_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_" #define DEPLOY_AS_SH "/usr/local/bin/deploy_user.sh" /* Translate username to uid/gid */ struct passwd * getUid(char *name) { struct passwd *p; if ((p = getpwnam(name)) == NULL) { printf("Error: User '%s' not found.\n", name); exit(1); } return p; } /* Run deploy as user */ int runServiceDeployment(char *service) { /* Set uid and gid */ struct passwd *p = getUid(service); setgid(p->pw_gid); setuid(p->pw_uid); /* Check if executable exists */ if ( access( DEPLOY_AS_SH, F_OK ) == -1 ) { printf("No such file: %s\n", DEPLOY_AS_SH); exit(1); } /* Stat executable */ struct stat sb; if (stat(DEPLOY_AS_SH, &sb) != 0) { printf("cant stat file: %s\n", DEPLOY_AS_SH); exit(1); } /* Test if file is executable */ if ( ! (sb.st_mode & S_IXUSR )) { printf("Not executable: %s\n", DEPLOY_AS_SH); exit(1); } /* Test if regular file */ if (! S_ISREG(sb.st_mode)) { printf("Not a regular file: %s\n", DEPLOY_AS_SH); exit(1); } /* Execute DEPLOY_AS_SH */ if (execl("/bin/bash", "--noediting", "--noprofile", "--norc", "--", DEPLOY_AS_SH, service, (char *)NULL) == -1) { printf("Error exec %s\n", DEPLOY_AS_SH); printf("%s\n", strerror(errno)); exit(1); } return 0; } /* Just check only allowed chars are present */ int validate (char *s) { for (int i=0; i\n",argv[0]); exit(1); } if (validate(argv[1]) != 0) { printf("Bad service name\n"); exit(1); } runServiceDeployment(argv[1]); return 0; }