summaryrefslogtreecommitdiff
path: root/libexec/login_token/tokendb.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2000-12-20 01:41:54 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2000-12-20 01:41:54 +0000
commitcffcf376225c41635be9c952a0a26c0c0f12d4e7 (patch)
treed56292c95b8b6140045f29baf9e41f0c6d177b51 /libexec/login_token/tokendb.c
parent005d89db1e301780453d7ba2b1ba4f9c0c7ae81a (diff)
Provides ActivCard, CRYPTOCard and SNK-004 authentication from BSDi
Will be used when BSD authentication is enabled
Diffstat (limited to 'libexec/login_token/tokendb.c')
-rw-r--r--libexec/login_token/tokendb.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/libexec/login_token/tokendb.c b/libexec/login_token/tokendb.c
new file mode 100644
index 00000000000..bfc021ac4aa
--- /dev/null
+++ b/libexec/login_token/tokendb.c
@@ -0,0 +1,343 @@
+/* $OpenBSD: tokendb.c,v 1.1 2000/12/20 01:41:53 millert Exp $ */
+
+/*-
+ * Copyright (c) 1995 Berkeley Software Design, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Berkeley Software Design,
+ * Inc.
+ * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * BSDI $From: tokendb.c,v 1.1 1996/08/26 20:13:10 prb Exp $
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include <ctype.h>
+#include <db.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "token.h"
+#include "tokendb.h"
+
+static DB *tokendb;
+
+/*
+ * Static function prototypes
+ */
+
+static int tokendb_open(void);
+static void tokendb_close(void);
+
+/*
+ * Retrieve a user record from the token database file
+ */
+
+int
+tokendb_getrec(char *username, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+ memset(&data, 0, sizeof(data));
+
+ if (tokendb_open())
+ return(-1);
+
+ status = (tokendb->get)(tokendb, &key, &data, 0);
+ tokendb_close();
+
+ switch (status) {
+ case 1:
+ return(ENOENT);
+ case -1:
+ return(-1);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+ return (0);
+}
+
+/*
+ * Put a user record to the token database file.
+ */
+
+int
+tokendb_putrec(char *username, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+
+ if (tokenrec->mode)
+ tokenrec->flags |= TOKEN_USEMODES;
+ data.data = tokenrec;
+ data.size = sizeof(TOKENDB_Rec);
+
+ if (!tokendb_open()) {
+ if (flock((tokendb->fd)(tokendb), LOCK_EX)) {
+ tokendb_close();
+ return (-1);
+ }
+ status = (tokendb->put)(tokendb, &key, &data, 0);
+ }
+ tokendb_close();
+ return (status);
+}
+
+/*
+ * Remove a user record from the token database file.
+ */
+
+int
+tokendb_delrec(char *username)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+ memset(&data, 0, sizeof(data));
+
+ if (!tokendb_open()) {
+ if (flock((tokendb->fd)(tokendb), LOCK_EX)) {
+ tokendb_close();
+ return (-1);
+ }
+ status = (tokendb->del)(tokendb, &key, 0);
+ }
+ tokendb_close();
+ return (status);
+}
+
+/*
+ * Open the token database. In order to expedite access in
+ * heavily loaded conditions, we employ a N1 lock method.
+ * Updates should be brief, so all locks wait infinitely.
+ * Wait for a read (shared) lock as all updates read first.
+ */
+
+static int
+tokendb_open(void)
+{
+ int must_set_perms = 0;
+ struct stat statb;
+
+ if (stat(tt->db, &statb) < 0) {
+ if (errno != ENOENT)
+ return (-1);
+ must_set_perms++;
+ } else {
+ if (statb.st_uid != 0 || statb.st_gid != 0) {
+#ifdef PARANOID
+ printf("Authentication disabled\n");
+ fflush(stdout);
+ syslog(LOG_ALERT,
+ "POTENTIAL COMPROMISE of %s. Owner was %d, "
+ "Group was %d", tt->db, statb.st_uid, statb.st_gid);
+ return (-1);
+#else
+ must_set_perms++;
+#endif
+ }
+ if ((statb.st_mode & 0777) != 0600) {
+#ifdef PARANOID
+ printf("Authentication disabled\n");
+ fflush(stdout);
+ syslog(LOG_ALERT,
+ "POTENTIAL COMPROMISE of %s. Mode was %o",
+ tt->db, statb.st_mode);
+ return (-1);
+#else
+ must_set_perms++;
+#endif
+ }
+ }
+ if (!(tokendb =
+ dbopen(tt->db, O_CREAT | O_RDWR, 0600, DB_BTREE, 0)) )
+ return (-1);
+
+ if (flock((tokendb->fd)(tokendb), LOCK_SH)) {
+ (tokendb->close)(tokendb);
+ return (-1);
+ }
+ if (must_set_perms && chown(tt->db, 0, 0))
+ syslog(LOG_INFO,
+ "Can't set owner/group of %s errno=%m", tt->db);
+
+ return (0);
+}
+
+/*
+ * Close the token database. We are holding an unknown lock.
+ * Release it, then close the db. Since little can be done
+ * about errors, we ignore them.
+ */
+
+static void
+tokendb_close(void)
+{
+ (void)flock((tokendb->fd)(tokendb), LOCK_UN);
+ (tokendb->close)(tokendb);
+}
+
+/*
+ * Retrieve the first user record from the database, leaving the
+ * database open for the next retrieval. If the march thru the
+ * the database is aborted before end-of-file, the caller should
+ * call tokendb_close to release the read lock.
+ */
+
+int
+tokendb_firstrec(int reverse_flag, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status = 0;
+
+ memset(&data, 0, sizeof(data));
+
+ if (!tokendb_open()) {
+ status = (tokendb->seq)(tokendb, &key, &data,
+ reverse_flag ? R_LAST : R_FIRST);
+ }
+ if (status) {
+ tokendb_close();
+ return (status);
+ }
+ if (!data.data) {
+ tokendb_close();
+ return (ENOENT);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+ return (0);
+}
+
+/*
+ * Retrieve the next sequential user record from the database. Close
+ * the database only on end-of-file or error.
+ */
+
+
+int
+tokendb_nextrec(int reverse_flag, TOKENDB_Rec *tokenrec)
+{
+ DBT key;
+ DBT data;
+ int status;
+
+ memset(&data, 0, sizeof(data));
+
+ status = (tokendb->seq)(tokendb, &key, &data,
+ reverse_flag ? R_PREV : R_NEXT);
+
+ if (status) {
+ tokendb_close();
+ return (status);
+ }
+ if (!data.data) {
+ tokendb_close();
+ return (ENOENT);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+ return (0);
+}
+
+/*
+ * Retrieve and lock a user record. Since there are no facilities in
+ * BSD for record locking, we hack a bit lock into the user record.
+ */
+
+int
+tokendb_lockrec(char *username, TOKENDB_Rec *tokenrec, unsigned recflags)
+{
+ DBT key;
+ DBT data;
+ int status;
+
+ key.data = username;
+ key.size = strlen(username) + 1;
+ memset(&data, 0, sizeof(data));
+
+ if (tokendb_open())
+ return(-1);
+
+ if (flock((tokendb->fd)(tokendb), LOCK_EX)) {
+ tokendb_close();
+ return(-1);
+ }
+ switch ((tokendb->get)(tokendb, &key, &data, 0)) {
+ case 1:
+ tokendb_close();
+ return (ENOENT);
+ case -1:
+ tokendb_close();
+ return(-1);
+ }
+ memcpy(tokenrec, data.data, sizeof(TOKENDB_Rec));
+
+ if ((tokenrec->flags & TOKEN_LOCKED)||(tokenrec->flags & recflags)) {
+ tokendb_close();
+ return(1);
+ }
+ data.data = tokenrec;
+ data.size = sizeof(TOKENDB_Rec);
+
+ time(&tokenrec->lock_time);
+ tokenrec->flags |= recflags;
+ status = (tokendb->put)(tokendb, &key, &data, 0);
+ tokendb_close();
+ if (status)
+ return(-1);
+ if ((tokenrec->flags & TOKEN_USEMODES) == 0)
+ tokenrec->mode = tt->modes & ~TOKEN_RIM;
+
+ return(0);
+}
+