[BACK]Return to tcfs_dbmaint.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tcfs

File: [local] / src / usr.bin / tcfs / Attic / tcfs_dbmaint.c (download)

Revision 1.11, Tue Jun 20 07:58:57 2000 UTC (23 years, 11 months ago) by fgsch
Branch: MAIN
CVS Tags: OPENBSD_3_2_BASE, OPENBSD_3_2, OPENBSD_3_1_BASE, OPENBSD_3_1, OPENBSD_3_0_BASE, OPENBSD_3_0, OPENBSD_2_9_BASE, OPENBSD_2_9, OPENBSD_2_8_BASE, OPENBSD_2_8
Changes since 1.10: +7 -7 lines

add openbsd tags. rearrange headers as per style(9) and indent.
replace some strcpy by strlcpy.

/*	$OpenBSD: tcfs_dbmaint.c,v 1.11 2000/06/20 07:58:57 fgsch Exp $	*/

/*
 *	Transparent Cryptographic File System (TCFS) for NetBSD 
 *	Author and mantainer: 	Luigi Catuogno [luicat@tcfs.unisa.it]
 *	
 *	references:		http://tcfs.dia.unisa.it
 *				tcfs-bsd@tcfs.unisa.it
 */

/*
 *	Base utility set v0.1
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <db.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>

#include <miscfs/tcfs/tcfs.h>
#include "tcfslib.h"

#define PERM_SECURE	(S_IRUSR|S_IWUSR)

int 
tcfspwdbr_new(tcfspwdb **new)
{
	*new = (tcfspwdb *)calloc(1, sizeof(tcfspwdb));

	if (!*new)
		return (0);

	return (1);
}

int
tcfsgpwdbr_new(tcfsgpwdb **new)
{
	*new = (tcfsgpwdb *)calloc(1, sizeof(tcfsgpwdb));

	if (!*new)
		return (0);

	return (1);
}

int 
tcfspwdbr_edit(tcfspwdb **tmp, int flags, ...)
{
	va_list argv;
	char *d;

	if (!*tmp)
		if (!tcfspwdbr_new(tmp))
			return (0);

	va_start(argv, flags);

	if (flags & F_USR) {
		d = va_arg(argv, char *);
		strcpy((*tmp)->user, d);
	}

	if (flags & F_PWD) {
		d = va_arg(argv, char *);
		strcpy((*tmp)->upw, d);
	}

	va_end(argv);
	return (1);
}

int 
tcfsgpwdbr_edit(tcfsgpwdb **tmp, int flags, ...)
{
	va_list argv;
	char *d;

	if (!*tmp)
		if (!tcfsgpwdbr_new(tmp))
			return (0);

	va_start(argv, flags);

	if (flags & F_USR) {
		d = va_arg(argv, char *);
		strcpy((*tmp)->user, d);
	}

	if (flags & F_GKEY) {
		d = va_arg(argv, char *);
		strcpy((*tmp)->gkey, d);
	}

	if (flags & F_GID) {
		gid_t d;

		d = va_arg(argv, gid_t);
		(*tmp)->gid = d;
	}

	if (flags & F_MEMBERS) {
		int d;

		d = va_arg(argv, int);
		(*tmp)->n = d;
	}

	if (flags & F_THRESHOLD) {
		int d;

		d = va_arg(argv, int);
		(*tmp)->soglia = d;
	}

	va_end(argv);
	return (1);
}

int 
tcfspwdbr_read(tcfspwdb *t, int flags, ...)
{
	va_list argv;
	char *d;

	va_start(argv, flags);

	if (flags & F_USR) {
		d = va_arg(argv, char *);
		memset(d, 0, UserLen);
		strcpy(d, t->user);
	}

	if (flags & F_PWD) {
		d = va_arg(argv, char *);
		memset(d, 0, PassLen);
		strcpy(d, t->upw);
	}

	va_end(argv);
	return (0);
}

int 
tcfsgpwdbr_read(tcfsgpwdb *t, int flags, ...)
{
	va_list argv;
	char *d;

	va_start(argv, flags);

	if (flags & F_USR) {
		d = va_arg(argv, char *);
		strcpy(d, t->user);
	}

	if (flags & F_GKEY) {
		d = va_arg(argv, char *);
		strcpy(d, t->gkey);
	}

	if (flags & F_GID) {
		gid_t *d;

		d = va_arg(argv, gid_t *);
		memcpy(d, &t->gid, sizeof (gid_t));
	}
	/* Incomplete... */

	va_end(argv);
	return (0);
}

void 
tcfspwdbr_dispose(tcfspwdb *t)
{
	free((void *)t);
}

void 
tcfsgpwdbr_dispose(tcfsgpwdb *t)
{
	free((void *)t);
}

tcfspwdb *
tcfs_getpwnam(char *user, tcfspwdb **dest)
{
	DB *pdb;
	DBT srchkey, r;

	if (!*dest)
		if (!tcfspwdbr_new(dest))
			return (NULL);

	pdb = dbopen(TCFSPWDB, O_RDONLY, 0, DB_HASH, NULL);
	if (!pdb)
		return (NULL);

	srchkey.data = user;
	srchkey.size = (int)strlen(user);

	if (pdb->get(pdb, &srchkey, &r, 0)) {
		pdb->close(pdb);
		return (0);
	}

	if (r.size != sizeof(tcfspwdb)) {
		fprintf(stderr, "db: incorrect record size: %d != %d\n",
			r.size, sizeof(tcfspwdb));
		pdb->close(pdb);
		return (0);
	}

	memcpy(*dest, r.data, sizeof(tcfspwdb));

	pdb->close(pdb);

	return ((tcfspwdb *)*dest);
}

tcfsgpwdb *
tcfs_ggetpwnam(char *user, gid_t gid, tcfsgpwdb **dest)
{
	DB *pdb;
	DBT srchkey, r;
	char *key;
	int res;

	if (!*dest)
		if (!tcfsgpwdbr_new(dest))
			return (NULL);

	pdb = dbopen(TCFSGPWDB, O_RDONLY, 0, DB_HASH, NULL);
	if (!pdb)
		return (NULL);

	key = (char *)malloc(strlen(user) + 6);
	if (!key)
		return (NULL);

	sprintf(key, "%s\33%d", user, (int)gid);
	srchkey.data = key;
	srchkey.size = (int)strlen(key);

	if ((res = pdb->get(pdb, &srchkey, &r, 0))) {
		if (res == -1)
			perror("dbget");
		pdb->close(pdb);
		return (NULL);
	}

	memcpy(*dest, r.data, sizeof(tcfsgpwdb));

	pdb->close(pdb);

	return (*dest);
}

int 
tcfs_putpwnam(char *user, tcfspwdb *src, int flags)
{
	DB *pdb;
	static DBT srchkey, d;
	int open_flag = 0, res;

	open_flag = O_RDWR|O_EXCL;
	if (access(TCFSPWDB, F_OK) < 0)
		open_flag |= O_CREAT;

	pdb = dbopen(TCFSPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
	if (!pdb)
		return (0);

	srchkey.data = user;
	srchkey.size = (int)strlen(user);

	if (flags != U_DEL) {
		d.data = (char *)src;
		d.size = (int)sizeof(tcfspwdb);

		if (pdb->put(pdb, &srchkey, &d, 0) == -1) {
			fprintf(stderr, "db: put failed\n");
			pdb->close(pdb);
			return (0);
		}
	} else if ((res = pdb->del(pdb, &srchkey, 0))) {
		fprintf(stderr, "db: del failed: %s\n", 
			res == -1 ? "error" : "not found");
		pdb->close(pdb);
		return (0);
	}

	pdb->close(pdb);
	return (1);
}

int 
tcfs_gputpwnam(char *user, tcfsgpwdb *src, int flags)
{
	DB *pdb;
	static DBT srchkey, d;
	int open_flag = 0;
	char *key;

	open_flag = O_RDWR|O_EXCL;
	if (access(TCFSGPWDB, F_OK) < 0)
		open_flag |= O_CREAT;

	pdb = dbopen(TCFSGPWDB, open_flag, PERM_SECURE, DB_HASH, NULL);
	if (!pdb) {
		perror("dbopen");
		return (0);
	}

	key = (char *)malloc(strlen(src->user) + 6);
	sprintf(key, "%s\33%d", src->user, (int)src->gid);

	srchkey.data = key;
	srchkey.size = strlen(key);

	if (flags != U_DEL) {
		d.data = (char *)src;
		d.size = sizeof(tcfsgpwdb);

		if (pdb->put(pdb, &srchkey, &d, 0) == -1) {
			fprintf(stderr, "db: put failed\n");
			pdb->close(pdb);
			return (0);
		}
	} else if (pdb->del(pdb, &srchkey, 0)) {
		fprintf(stderr, "db: del failed\n");
		pdb->close(pdb);
		return (0);
	}

	pdb->close(pdb);
	return (1);
}

int
tcfs_rmgroup(gid_t gid)
{
	DB *gdb;
	DBT dbkey;

	gdb = dbopen(TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
	if (!gdb)
		return (0);

	if (gdb->seq(gdb, &dbkey, NULL, R_FIRST))
		dbkey.data = NULL;

	while (dbkey.data) {
		char *tmp;

		tmp = (char *)calloc(1024, sizeof(char));

		sprintf(tmp, "\33%d", gid);
		if (strstr(dbkey.data, tmp)) {
			if (gdb->del(gdb, &dbkey, 0)) {
				gdb->close(gdb);
				free(tmp);
				return (0);
			}
		}
		free(tmp);

		if (gdb->seq(gdb, &dbkey, NULL, R_NEXT)) {
			gdb->close(gdb);
			return (0);
		}
	}

	gdb->close(gdb);
	return (1);
}


int
tcfs_group_chgpwd(char *user, gid_t gid, char *old, char *new)
{
	tcfsgpwdb *group_info = NULL;
	unsigned char *key;

	key = (unsigned char *)calloc(UUGKEYSIZE + 1, sizeof (char));
	if (!key)
		return (0);

	if (!tcfs_decrypt_key(old, group_info->gkey, key, GKEYSIZE))
		return (0);

	if (!tcfs_encrypt_key(new, key, GKEYSIZE, group_info->gkey,
			       UUGKEYSIZE + 1))
		return (0);

	if (!tcfs_gputpwnam(user, group_info, U_CHG))
		return (0);

	free(group_info);
	free(key);

	return (1);
}

int 
tcfs_chgpwd(char *user, char *old, char *new)
{
	tcfspwdb *user_info = NULL;
	unsigned char *key;

	key = (unsigned char *)calloc(UUKEYSIZE + 1, sizeof(char));

	if (!tcfs_getpwnam(user, &user_info))
		return (0);

	if (!tcfs_decrypt_key(old,  user_info->upw, key, KEYSIZE))
		return (0);

	if (!tcfs_encrypt_key(new, key, KEYSIZE, user_info->upw, UUKEYSIZE + 1))
		return (0);

	if (!tcfs_putpwnam(user, user_info, U_CHG))
		return (0);

	free(user_info);
	free(key);

	return (1);
}

int
tcfs_chgpassword(char *user, char *old, char *new)
{
	int error1 = 0;
	DB *gpdb;
	DBT found, key;
	unsigned char *ckey;

	ckey = (unsigned char *)calloc(UUGKEYSIZE + 1, sizeof(char));
	if (!ckey)
		return (0);

	gpdb = dbopen(TCFSGPWDB, O_RDWR|O_EXCL, PERM_SECURE, DB_HASH, NULL);
	if (!gpdb)
		return (0);

	error1 = tcfs_chgpwd(user, old, new);
	if (!error1)
		return (0);

	/* Reencrypt group shares */
	if (gpdb->seq(gpdb, &key, NULL, R_FIRST)) 
		key.data = NULL;
	
	while (key.data) {
		if (strncmp(user, key.data, strlen(user))) {
			if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
			    key.data = NULL;
			continue;
		}

		gpdb->get(gpdb, &key, &found, 0);

		if (!tcfs_decrypt_key(old, ((tcfsgpwdb *)found.data)->gkey,
		    ckey, GKEYSIZE))
			return (0);

		if (!tcfs_encrypt_key(new, ckey, GKEYSIZE,
		    ((tcfsgpwdb *)found.data)->gkey, UUGKEYSIZE + 1))
			return (0);

		if (gpdb->put(gpdb, &key, &found, 0)) {
			free(ckey);
			gpdb->close(gpdb);
			return (0);
		}

		free(ckey);

		if (gpdb->seq(gpdb, &key, NULL, R_NEXT))
			key.data = NULL;
	}

	return (1);
}