101 lines
2.0 KiB
C
101 lines
2.0 KiB
C
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <pwd.h>
|
|
#include <errno.h>
|
|
#include <sys/stat.h>
|
|
|
|
/* 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<strlen(s); i++){
|
|
int found = 0;
|
|
for (int j=0; j<strlen(VALID_CHARS); j++) {
|
|
if ( s[i] == VALID_CHARS[j] ) {
|
|
found = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[] )
|
|
{
|
|
if ( argc != 2) {
|
|
printf("usage: %s <service-name>\n",argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
if (validate(argv[1]) != 0) {
|
|
printf("Bad service name\n");
|
|
exit(1);
|
|
}
|
|
runServiceDeployment(argv[1]);
|
|
return 0;
|
|
}
|
|
|
|
|