jean-cloud-services/provisioning/roles/deploy_all/files/bin/deploy_as.c
2024-01-02 17:50:14 +01:00

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;
}