/*-------------------------------------------------------------------------*
 * title        : iis admin                                                *
 * version      : v0.8                                                     *       
 * programmer   : nam tran [neuropunk]                                     *
 * programmed   : december 1999                                            *            
 * affiliations : neuropunk productions && neuronetwork                    *        
 * urls	        : neuropunk.com && neuronetwork.cx                         *   
 * e-mail       : neuroticism@hotmail.com                                  *        
 * description  : adds accounts like yahoo and such. will add users,       *             
 *              : create their directories, edit ACL, etc... only needs    *          
 *              : two arguments to work. this program can be considered    *
 *              : as a "back end", some cgi can be programmed to utilize   *
 *              : this program remotely. must be under security context    *
 *              : of administrator to work though, made for NT             *
 *-------------------------------------------------------------------------*/  




/*-----------------------------------------------------------------------*
  NOTES ABOUT THE PROGRAM

  i need to implement something that will check for "unauthorized" characters

  I should implement a checker to make sure the strings don't approach
  pass a value. There's a potential buffer overflow error because the
  string are only allocated 256 char bytes. Currently, the way
  to prevent this is from the html/cgi page. The html page <form></form>
  prevents the user from enter more then X characters. This is lame though.

  When you input an already existing name/password, it'll still create
  the directories and all, but it won't edit/add/overwrite the exiting
  user name or password.

  i don't think i'll support this anymore... apache seems to have more promises
  as a http daemon, who knows...
 *-----------------------------------------------------------------------*/


/*--------------*
 * header files *
 *--------------*/
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <direct.h>
 #include <errno.h>


/*-----------*
 * constants *
 *-----------*/
 char root_users[] = "c:\\inetpub\\users";
 char root_users_reg[] = "c:\\\\inetpub\\\\users";	//same as top, just "\\"
 char root_ftp[] = "c:\\inetpub\\root_ftp";

 char group_add[] = "users";		//add user to this group
 char group_del[] = "users";		//delete user from this group

 char user_info[] = "web user";		//description of user [in part w/ net]

 int DIR_MAX = 256;	//maximum size of mem block, thuse also dir


/*----------------*
 * error messages *
 *----------------*/
 char error_mem[] = "\n\n[error allocating memory], exiting\n\n";
 char error_dir[] = "\n\n[error creating directories], exiting\n\n";
 char error_file[] = "\n\n[error creating files], exiting\n\n";
 char error_arg[] ="\n\nincorrect arguments: admin <user_name> <password>\n\n";



/*---------------------*
 * function prototypes *
 *---------------------*/
 void create_dir(char *name);                 //has a "check" bonus
 void add_user(char *name, char *password);
 void edit_acl(char *name);
 void restart_box(void);
 void create_vd(char *name);                  //vd == virtual directory




/*----------------------*
 * start of the program *
 *----------------------*/
 void main(int argc, char *argv[])
 {
	char *name;
	char *password;

	name = (char *) malloc(DIR_MAX * sizeof(char));
	password = (char *) malloc(DIR_MAX * sizeof(char));

	if((name==NULL)||(password==NULL))
	{
		printf("%s", error_mem);
		exit(1);
	}

	if(argc != 3)
	{
		printf("%s", error_arg);
		exit(1);
	}

	strcpy(name, argv[1]);
	strcpy(password, argv[2]);

	create_dir(name);
	add_user(name, password);
	edit_acl(name);
	create_vd(name);
	restart_box();

 	free(name);
	free(password);
 }





/*------------------------------------------------------*
 * name	    : create_dir()                              *
 * purpose  : create dirs for user                      *
 * accepts  : char *                                    *
 * returns  : void                                      *
 * comments : none                                      *
 *------------------------------------------------------*/
 void create_dir(char *name)
 {
	char *ftp_dir;		//the [hypothetically] e:\users\name\ftp
	char *www_dir;		//the [hypothetically] e:\users\name\www
	char *usr_dir;		//the [hypothetically] e:\users\name

	char *ftp_pnt;		//the [hypothetically] e:\ftp_root\users\name
						//essentially going to become a virtual directory
						//that's where the "pnt" comes in

 	ftp_dir = (char *) malloc(DIR_MAX * sizeof(char));
	www_dir = (char *) malloc(DIR_MAX * sizeof(char));
	usr_dir = (char *) malloc(DIR_MAX * sizeof(char));
	ftp_pnt = (char *) malloc(DIR_MAX * sizeof(char));

	if((ftp_dir==NULL)||(www_dir==NULL)||(usr_dir==NULL)||(ftp_pnt==NULL))
	{
		printf("%s", error_mem);
		exit(1);
	}


	//going to create the base template user/name directory, everything else
	//is then based off of it
	strcpy(usr_dir, root_users);
	strcat(usr_dir, "\\");
	strcat(usr_dir, name);

	strcpy(ftp_dir, usr_dir);
	strcat(ftp_dir, "\\ftp");

	strcpy(www_dir, usr_dir);
	strcat(www_dir, "\\www");

	strcpy(ftp_pnt, root_ftp);
	strcat(ftp_pnt, "\\users\\");
	strcat(ftp_pnt, name);


	//if directories already exists, it returns a non zero value
	if((mkdir(usr_dir)!=0) || (mkdir(ftp_dir)!=0) || (mkdir(www_dir)!=0))
	{
		printf("%s", error_dir);
		exit(1);
	}

	if(mkdir(ftp_pnt) != 0)
	{
		printf("%s", error_dir);
		exit(1);
	}

	free(ftp_pnt);
	free(usr_dir);
	free(www_dir);
	free(ftp_dir);
 }


/*------------------------------------------------------*
 * name	    : add_user()                                *
 * purpose  : adds user to user.db, and to a group      *
 * accepts  : 2x char *                                 *
 * returns  : void                                      *
 * comments : none                                      *
 *------------------------------------------------------*/
 void add_user(char *name, char *password)
 {
	char *command_usr;			//string that will be sent to system()
	char *command_grp_add;		//""
	char *command_grp_del;		//""

	command_usr = (char *) malloc(DIR_MAX * sizeof(char));
	command_grp_add = (char *) malloc(DIR_MAX * sizeof(char));
	command_grp_del = (char *) malloc(DIR_MAX * sizeof(char));

	if((command_usr==NULL)||(command_grp_add==NULL)||(command_grp_del==NULL))
	{
		printf("%s", error_mem);
		exit(1);
	}

	//making string for command net user
	strcpy(command_usr, "net user ");
	strcat(command_usr, name);
	strcat(command_usr, " ");
	strcat(command_usr, password);
	strcat(command_usr, " ");
	strcat(command_usr, "/add ");
	strcat(command_usr, "/comment:");
	strcat(command_usr, "\"");
	strcat(command_usr, user_info);
	strcat(command_usr, "\"");

	//making string to add user to a group
	strcpy(command_grp_add, "net localgroup ");
	strcat(command_grp_add, group_add);
	strcat(command_grp_add, " ");
	strcat(command_grp_add, name);
	strcat(command_grp_add, " ");
	strcat(command_grp_add, "/add");

	//making string to delete user from a group
	strcpy(command_grp_del, "net localgroup ");
	strcat(command_grp_del, group_del);
	strcat(command_grp_del, " ");
	strcat(command_grp_del, name);
	strcat(command_grp_del, " ");
	strcat(command_grp_del, "/delete");

	system(command_usr);
	system(command_grp_del);
	system(command_grp_add);

	free(command_usr);
	free(command_grp_del);
	free(command_grp_add);
 }


/*------------------------------------------------------*
 * name	    : edit_acl()                                *
 * purpose  : edits acl, "allowing" user to upload      *
 * accepts  : 1x char *                                 *
 * returns  : void                                      *
 * comments : none                                      *
 *------------------------------------------------------*/
 void edit_acl(char *name)
 {
	char *command_acl;
	char *command_acl_ftp;
	char *command_acl_www;

	command_acl = (char *) malloc(DIR_MAX * sizeof(char));
	command_acl_ftp = (char *) malloc(DIR_MAX * sizeof(char));
	command_acl_www = (char *) malloc(DIR_MAX * sizeof(char));

	if((command_acl==NULL)||(command_acl_ftp==NULL)||(command_acl_www==NULL))
	{
		printf("%s", error_mem);
		exit(1);
	}


	strcpy(command_acl, "cacls ");
	strcat(command_acl, root_users);
	strcat(command_acl, "\\");
	strcat(command_acl, name);
	strcat(command_acl, " ");
	strcat(command_acl, "/t /e /c /g ");
	strcat(command_acl, name);
	strcat(command_acl, ":r");

	strcpy(command_acl_ftp, "cacls ");
	strcat(command_acl_ftp, root_users);
	strcat(command_acl_ftp, "\\");
	strcat(command_acl_ftp, name);
	strcat(command_acl_ftp, "\\ftp");
	strcat(command_acl_ftp, " ");
	strcat(command_acl_ftp, "/t /e /c /g ");
	strcat(command_acl_ftp, name);
	strcat(command_acl_ftp, ":c");


	strcpy(command_acl_www, "cacls ");
	strcat(command_acl_www, root_users);
	strcat(command_acl_www, "\\");
	strcat(command_acl_www, name);
	strcat(command_acl_www, "\\www");
	strcat(command_acl_www, " ");
	strcat(command_acl_www, "/t /e /c /g ");
	strcat(command_acl_www, name);
	strcat(command_acl_www, ":c");

	system(command_acl);
	system(command_acl_ftp);
	system(command_acl_www);

	free(command_acl);
	free(command_acl_www);
	free(command_acl_ftp);
 }


/*------------------------------------------------------*
 * name	    : restart_box()                             *
 * purpose  : restarts www/ftp service                  *
 * accepts  : void                                      *
 * returns  : void                                      *
 * comments : none                                      *
 *------------------------------------------------------*/
 void restart_box()
 {
	char *start_www;	//string to start www service
	char *start_ftp;

	char *stop_www;
	char *stop_ftp;

	start_www = (char *) malloc(DIR_MAX * sizeof(char));
	start_ftp = (char *) malloc(DIR_MAX * sizeof(char));
	stop_www = (char *) malloc(DIR_MAX * sizeof(char));
	stop_ftp = (char *) malloc(DIR_MAX * sizeof(char));

	if((start_www==NULL)||(start_ftp==NULL)||(stop_www==NULL)||(stop_ftp==NULL))
	{
		printf("%s", error_mem);
		exit(1);
	}

	strcpy(start_www, "net start w3svc");
	strcpy(start_ftp, "net start msftpsvc");
	strcpy(stop_www, "net stop w3svc");
	strcpy(stop_ftp, "net stop msftpsvc");

	system(stop_www);
	system(start_www);
	system(stop_ftp);
	system(start_ftp);

	free(start_www);
	free(start_ftp);
	free(stop_www);
	free(stop_ftp);
 }

/*------------------------------------------------------*
 * name	    : create_vd()                               *
 * purpose  : creates reg fils for vd's, and opens thm  *
 * accepts  : char *                                    *
 * returns  : void                                      *
 * comments : none                                      *
 *------------------------------------------------------*/
 void create_vd(char *name)
 {
	char *value_ftp;		//holds a value for the service
	char *value_www;		//holds a value for the service
	char *command_reg;		//registry command [regedit /s]
	FILE *f_user;			//pointer to file to be created

	value_ftp = (char *) malloc(DIR_MAX * sizeof(char));
	value_www = (char *) malloc(DIR_MAX * sizeof(char));
	command_reg = (char *) malloc(DIR_MAX * sizeof(char));

	if((value_ftp==NULL)||(value_www==NULL)||(command_reg==NULL))
	{
		printf("%s", error_mem);
		exit(1);
	}

	if((f_user = fopen("adduser.reg", "w")) == NULL)
	{
		printf("%s", error_file);
		exit(1);
	}


	//creating a ftp virtual directory registry value
	strcpy(value_ftp, "\"/users/");
	strcat(value_ftp, name);
	strcat(value_ftp, ",\"=\"");
	strcat(value_ftp, root_users_reg);
	strcat(value_ftp, "\\\\");
	strcat(value_ftp, name);
	strcat(value_ftp, ",,3\"");		//means user can read/write

	//creating a www virtual directory registry value
	strcpy(value_www, "\"/");
	strcat(value_www, name);
	strcat(value_www, ",\"=\"");
	strcat(value_www, root_users_reg);
	strcat(value_www, "\\\\");
	strcat(value_www, name);
	strcat(value_www, "\\\\www");
	strcat(value_www, ",,1\"");		//means user can read


	//TEMPLATE FOR REGISTRY FILE
	fprintf(f_user, "REGEDIT4");
	fprintf(f_user, "\n\n");
	fprintf(f_user, "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters\\Virtual Roots]");
	fprintf(f_user, "\n");
	fprintf(f_user, "%s", value_www);
	fprintf(f_user, "\n\n");
	fprintf(f_user, "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\MSFTPSVC\\Parameters\\Virtual Roots]");
	fprintf(f_user, "\n");
	fprintf(f_user, "%s", value_ftp);
	fprintf(f_user, "  \n\n");

	fclose(f_user);	//file isn't needed anymore, closing, going to open l8r..


	strcpy(command_reg, "regedit /s adduser.reg");
	system(command_reg);


	free(value_www);
	free(value_ftp);
	free(command_reg);
 }



