/*
 * T.C.F.S. Utils 2.0 $Revision: 1.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: /usr/src/linux-2.0.33-tcfs/fs/tcfs/contrib/utils/src/RCS/tcfsputkey.c,v $
 *        $State: Exp $
 *
 *     $Revision: 1.11 $
 *       $Author: anidel $
 *         $Date: 1998/01/19 14:12:28 $
 *       $Locker:  $
 */

static const char *RCSid="$Id: tcfsputkey.c,v 1.11 1998/01/19 14:12:28 anidel Exp $";
/* -+-_== */ 

#include <stdio.h>
#include <unistd.h>
#include <getopt.h>

#include "tcfserrors.h"
#include "tcfslib.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'},
	{ 0, 0, 0, 0 }
};

char *usage="Usage: %s [[-b] -k key | --key key] [OPTION]...
Set TCFS key, taken from the TCFS database or from the command line (-k),
in the kernel. Also increments key counter.

  -p [--permanent]    Makes the key permanent
  -u [--unpermanent]  Removes the permanent flag
  -k [--key] key      Put key <key> into the kernel
  -b                  The <key> is given UUENCODED (see tcfsviewkey(1))
  -h [--help]         Shows this help
  -v [--verbose]      Be 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;
	char *user, *passwd, *key, *tcfskey;
	tcfspwdb *user_info;

	/*
	 * Going to check the arguments
	 */
	while ((val=getopt_long (argn, argv, "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 'v':
				be_verbose=TRUE;
				break;
			case 'h':
				show_usage (usage, argv[0]);
				exit (OK);
				break; /* Useless code */
			default:
				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].\n");

	/*
	 * Getting user information
	 */
	if (!unix_auth (&user, &passwd))
		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))
		tcfs_error (ER_TCFS, NULL);

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

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

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