view ie-virsh.c @ 4:349bbbd3fbd5

added dumpxml command
author Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp>
date Mon, 12 Nov 2012 21:37:14 +0900
parents 203445eb53a8
children 9ecd833b9570
line wrap: on
line source



#include <stdlib.h>
#include <unistd.h>

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#include <sys/types.h>
#include <regex.h>

/********************************************
 * Virsh Wrapper - Secure Yourself          *
 *                                          *
 * 2007 - Mike Golvach - eggi@comcast.net   *
 * 2012 - Shinji KONO  kono@ie.u-rykyu.ac.jp *
 *                                          *
 * Usage: COMMAND [start|stop]              *
 *                                          *
 ********************************************/
 
 /* Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License */

#define command "/usr/bin/virsh"
#define list_command "/usr/bin/virsh list --all"
#define start_command "start"
#define stop_command "destroy"
#define dumpxml_command "dumpxml"

#define VMNAME_MAX (512)

typedef struct vmlist {
    char name[VMNAME_MAX];
    struct vmlist *next;
} VMLIST, *VMLISTPTR;

#define NEW(type)  ((type*)malloc(sizeof(type)))

/* Define global variables */



VMLISTPTR
get_vmlist(regex_t *list_pattern)
{
    VMLISTPTR list = NEW(VMLIST);
    VMLISTPTR p = list ;
    p->name[0] = 0;
    p->next = 0;
    FILE *fp = popen(list_command,"r");
    while(fgets(p->name,VMNAME_MAX,fp)!=NULL) {
        if (regexec(list_pattern, p->name, (size_t) 0, NULL, 0)) continue;
        p->next = NEW(VMLIST);
        p = p->next;
    }
    p->name[0] = 0;
    pclose(fp);
    return list;
}

void 
print_vmlist(VMLISTPTR list) 
{
    for(;list && list->name[0]; list=list->next) {
        fprintf(stdout, "   %s\n",list->name);
    }
}

int
check_vmlist_name(VMLISTPTR list, char *arg)
{
    for(;list && list->name[0]; list=list->next) {
        if (strcmp(list->name,arg)==0) return 1;
    }
    return 0;
}

void 
usage()
{
  printf("Usage: COMMAND [list|start|stop|xmldump] [vm-name]\n");
}

/* main(int argc, char **argv) - main process loop */

int main(int argc, char **argv)
{
    int gid;
    int uid;

/* Set euid and egid to actual user */

 char *name = getlogin();
 uid = getuid();
 gid = getgid();
 printf("uid %d gid %d name %s\n", uid,gid,name);
 setegid(getgid());
 seteuid(getuid());

 regex_t *pattern = NEW(regex_t);
 if (regcomp(pattern, name, 0) != 0) {
    exit(0);
 }

/* Confirm user is in GROUP(999) group */

/*
 if ( gid != 999 ) {
  printf("User Not Authorized!  Exiting...\n");
  exit(1);
 }
 */

/* Set uid, gid, euid and egid to root */

 setegid(0);
 seteuid(0);
 setgid(0);
 setuid(0);

 VMLISTPTR vmlist = get_vmlist(pattern);

 if (argc==3) {
    if (check_vmlist_name(vmlist, argv[2])!=0) {
        fprintf(stderr, "bad vmname\n");
        print_vmlist(vmlist);
        exit(0);
    }
 } else if (argc<2) {
        usage();
        exit(0);
 }

/* Check argv for proper arguments and run 
 * the corresponding script, if invoked.
 */

 if ( argv[1]==0 || strncmp(argv[1], "list", 4) == 0 ) {
    print_vmlist(vmlist);
 } else if ( strncmp(argv[1], "start", 5) == 0 ) {
  if (execl(command, command, start_command, argv[2], NULL) < 0) {
   perror("Execl:");
  }
 } else if ( strncmp(argv[1], "stop", 4) == 0 ) {
  if (execl(command, command, stop_command, argv[2], NULL) < 0) {
   perror("Execl:");
  }
 } else if ( strncmp(argv[1], "dumpxml", 7) == 0 ) {
  if (execl(command, command, dumpxml_command, argv[2], NULL) < 0) {
   perror("Execl:");
  }
 } else {
    usage();
    exit(1);
 }
 exit(0);
}

/* end */