/*
 * T.C.F.S. Utils 2.0 $Revision: 2.11 $
 *
 * Authors:	Giuseppe Cattaneo, <cattaneo@udsab.dia.unisa.it>
 *		Giuseppe Persiano, <giuper@udsab.dia.unisa.it>
 *		Luigi Catuogno, <luicat@mikonos.dia.unisa.it>
 *		Angelo Celentano, <angcel@mikonos.dia.unisa.it>
 *		Andrea Cozzolino, <andcoz@mikonos.dia.unisa.it>
 *		Aniello Del Sorbo, <anidel@mikonos.dia.unisa.it>
 *		Ermelindo Mauriello, <ermmau@mikonos.dia.unisa.it>
 *		Raffaele Pisapia, <rafpis@mikonos.dia.unisa.it>
 *
 * Permission  to use,  copy,  and modify this  software  without fee
 * is hereby granted, provided that this entire notice is included in
 * all  copies  of  any  software  which  is  or includes  a copy  or
 * modification of this  software and in all copies of the supporting
 * documentation for such software.
 *
 * This  software maybe  be used for  any purpose provided  the above 
 * copyright  notice  is  retained.  It is  supplied as  is, with  no 
 * warranty expressed or implied.
 */

/*
 *       $Source: /home/anidel/Wip/TCFS-2.2.0a/tcfsutils-1.2.1/src/RCS/tcfsputkey.c,v $
 *        $State: Exp $
 *
 *     $Revision: 2.11 $
 *       $Author: anidel $
 *         $Date: 1999/01/25 16:01:46 $
 *       $Locker:  $
 */

static const char *RCSid="$Id: tcfsputkey.c,v 2.11 1999/01/25 16:01:46 anidel Exp $";
/* -+-_== */ 

#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <tcfslib.h>
#include <string.h>
#include <grp.h>
#include <sys/types.h>

#include "tcfserrors.h"

static struct option long_options[]=
{
	{ "permanent", 0, NULL, 'p' },
	{ "key", 1, NULL, 'k' },
	{ "unpermanent", 0, NULL, 'u'},
	{ "help", 0, NULL, 'h'},
	{ "verbose", 0, NULL, 'v'},
	{ "group", 1, NULL, 'g'},
	{ 0, 0, 0, 0 }
};

char *usage="Usage: %s [OPTION]
Push the user's TCFS key/share into the kernel.
Also increments the key/share counter.

  -p [--permanent]       Makes the key permanent
  -u [--unpermanent]     Removes the permanent flag
  -k [--key] <key>       Push key <key> into the kernel (does'nt work with -g)
  -b                     The <key> is given UUENCODED (see tcfsviewkey(1))
  -g [--group] <group>   Push the group key for the TCFS <group> into the kernel
  -h [--help]            Shows this help
  -v [--verbose]         Makes the output a little more verbose\n";

int main (int argn, char *argv[])
{
	int len, index, val, permanent_action=NONE, be_verbose=FALSE;
	int key_isuuencoded=FALSE, have_key=FALSE, groupkey=FALSE, groupid;
	char *user, *passwd;
	unsigned char *tcfskey, *key;
	tcfspwdb *user_info;

	/*
	 * Going to check the arguments
	 */
	while ((val=getopt_long (argn, argv, "g:bpk:uhv", long_options, &index))!=EOF)
		switch (val)
		{
			case 'b':
				key_isuuencoded=TRUE;
				break;
			case 'p':
				permanent_action=SET;
				break;
			case 'u':
				permanent_action=UNSET;
				break;
			case 'k':
				key= (char *) malloc(UUKEYSIZE);
				strncpy (key, optarg, UUKEYSIZE);
				have_key=TRUE;
				break;
			case 'g':
				groupkey=TRUE;
				groupid=atoi(optarg);
				if (!groupid && optarg[0]!='0')
				{
					struct group *group_id;

					group_id=getgrnam(optarg);
					if (!group_id)
						tcfs_error (ER_CUSTOM, "Nonexistent group.");

					groupid=group_id->gr_gid;
					//printf ("optarg: %s\tgroupid: %d\n", optarg, groupid);
				}
				break;
			case 'v':
				be_verbose=TRUE;
				break;
			case 'h':
				show_usage (usage, argv[0]);
				exit (OK);
				break; /* Useless code */
			default:
				fprintf (stderr, "Try %s --help for more information.\n", argv[0]);
				exit (ER_UNKOPT);
				break;
		}

	if (argn-optind)
		tcfs_error (ER_UNKOPT, NULL);

	/*
	 * Consistency check
	 */
	if (key_isuuencoded && !have_key)
		tcfs_error (ER_CUSTOM, "Use -b only with -k [--key].");

	if (groupkey && have_key)
		tcfs_error (ER_CUSTOM, "Not yet implemented.");

	/*
	 * Getting user information
	 */
	if (!unix_auth (&user, &passwd, TRUE))
		tcfs_error (ER_AUTH, user);

	/*
	 * Check if the user have an entry in the TCFS database
	 */
	if (!tcfspwdbr_new (&user_info))
		tcfs_error (ER_MEM, NULL);

	if (!tcfs_getpwnam (user, &user_info) && !groupkey)
		tcfs_error (ER_CUSTOM, "You do not have a TCFS entry.\nAsk your superuser to add an entry for you.");

	if (!strlen(user_info->upw) && !groupkey && !have_key)
		tcfs_error (ER_CUSTOM, "You do not have a TCFS key.");

	/*
	 * Getting key...
	 */
	tcfskey=(unsigned char*)malloc(UUKEYSIZE);
	if (!tcfskey)
		tcfs_error (ER_MEM, NULL);

	if (have_key) /* ...from command line ... */
		strncpy (tcfskey, (key_isuuencoded)? (unsigned char*)tcfs_decode (key, &len):key, UUKEYSIZE);
	else /* ... or from database */
		if (!groupkey)
			tcfs_decrypt_key (user, passwd, user_info->upw, tcfskey, USERKEY);

	if (groupkey)
	{
		if (permanent_action!=NONE && !tcfs_group_permanent (user, groupid, permanent_action))
			tcfs_error (ER_PERM, NULL);

		if (!tcfs_group_enable_default (user, groupid, passwd))
			tcfs_error (ER_ENABLE, NULL);
	}
	else
	{
		if (!(tcfs_getcount (user) && permanent_action!=NONE))
			if (!tcfs_enable (user, tcfskey))
				tcfs_error (ER_ENABLE, NULL);
	
		if (permanent_action!=NONE && !tcfs_permanent (user, permanent_action))
				tcfs_error (ER_PERM, NULL);
	}
	tcfs_error (OK, NULL);
}
