adb_openclose.c revision 54925bf60766fbb4f1f2d7c843721406a7b7a3fb
/*
* Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
* Openvision retains the copyright to derivative works of
* this source code. Do *NOT* create a derivative of this
* source code before consulting with your legal department.
* Do *NOT* integrate *ANY* of this source code into another
* product before consulting with your legal department.
*
* For further information, read the top-level Openvision
* copyright which is contained in the top-level MIT Kerberos
* copyright.
*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*
*/
/*
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
*
*/
#if !defined(lint) && !defined(__CODECENTER__)
static char *rcsid = "$Header: /cvs/krbdev/krb5/src/lib/kadm5/srv/adb_openclose.c,v 1.8 2002/10/08 20:20:29 tlyu Exp $";
#endif
#include <fcntl.h>
#include <unistd.h>
#include <k5-int.h>
#include "policy_db.h"
#include <stdlib.h>
#include <db.h>
#define MAX_LOCK_TRIES 5
struct _locklist {
};
int magic)
{
int lf;
btinfo.minkeypage = 0;
return errno;
return errno;
/* only create the lock file if we successfully created the db */
if (lf == -1)
return errno;
return OSA_ADB_OK;
}
int magic)
{
/* the admin databases do not contain security-critical data */
unlink(lockfilename) < 0)
return errno;
return OSA_ADB_OK;
}
{
/* make sure todb exists */
/*LINTED*/
return ret;
return ret;
return ret;
}
return ret;
}
return ret;
}
return errno;
}
/*
* Do not release the lock on fromdb because it is being renamed
* out of existence; no one can ever use it again.
*/
return ret;
}
return 0;
}
char *lockfilename, int magic)
{
return EINVAL;
return ENOMEM;
/*
* A process is allowed to open the same database multiple times
* and access it via different handles. If the handles use
* distinct lockinfo structures, things get confused: lock(A),
* lock(B), release(B) will result in the kernel unlocking the
* lock file but handle A will still think the file is locked.
* Therefore, all handles using the same lock file must share a
* single lockinfo structure.
*
* It is not sufficient to have a single lockinfo structure,
* however, because a single process may also wish to open
* multiple different databases simultaneously, with different
* lock files. This code used to use a single static lockinfo
* structure, which means that the second database opened used
* the first database's lock file. This was Bad.
*
* We now maintain a linked list of lockinfo structures, keyed by
* lockfilename. An entry is added when this function is called
* with a new lockfilename, and all subsequent calls with that
* lockfilename use the existing entry, updating the refcnt.
* When the database is closed with fini_db(), the refcnt is
* decremented, and when it is zero the lockinfo structure is
* freed and reset. The entry in the linked list, however, is
* never removed; it will just be reinitialized the next time
* init_db is called with the right lockfilename.
*/
/* find or create the lockinfo structure for lockfilename */
while (lockp) {
break;
else
}
/* doesn't exist, create it, add to list */
return ENOMEM;
}
}
/* now initialize lockp->lockinfo if necessary */
return((krb5_error_code) code);
}
/*
* POSIX systems
*/
/*
* maybe someone took away write permission so we could only
* get shared locks?
*/
== NULL) {
return OSA_ADB_NOLOCKFILE;
}
}
}
/* lockp is set, lockinfo is initialized, update the reference count */
return OSA_ADB_OK;
}
{
return EINVAL;
/* barry says this can't happen */
return OSA_ADB_FAILURE;
} else {
}
/*
* Don't free db->lock->filename, it is used as a key to
* find the lockinfo entry in the linked list. If the
* lockfile doesn't exist, we must be closing the database
* after trashing it. This has to be allowed, so don't
* generate an error.
*/
}
return OSA_ADB_OK;
}
{
/* No need to upgrade lock, just incr refcnt and return */
return(OSA_ADB_OK);
}
perm = 0;
switch (mode) {
perm = 1;
/*LINTED*/
break;
case KRB5_DB_LOCKMODE_SHARED:
break;
default:
return(EINVAL);
}
krb5_mode|KRB5_LOCKMODE_DONTBLOCK)) == 0) {
gotlock++;
break;
/* tried to exclusive-lock something we don't have */
/* write access to */
return OSA_ADB_NOEXCL_PERM;
sleep(1);
}
/* test for all the likely "can't get lock" error codes */
return OSA_ADB_CANTLOCK_DB;
else if (ret != 0)
return ret;
/*
* If the file no longer exists, someone acquired a permanent
* lock. If that process terminates its exclusive lock is lost,
* but if we already had the file open we can (probably) lock it
* even though it has been unlinked. So we need to insist that
* it exist.
*/
return OSA_ADB_NOLOCKFILE;
}
if (perm) {
/* somehow we can't delete the file, but we already */
/* have the lock, so release it and return */
/* maybe we should return CANTLOCK_DB.. but that would */
/* look just like the db was already locked */
return ret;
}
/* this releases our exclusive lock.. which is okay because */
/* now no one else can get one either */
}
return OSA_ADB_OK;
}
{
return OSA_ADB_NOTLOCKED;
/* now we need to create the file since it does not exist */
0600);
return OSA_ADB_NOLOCKFILE;
return ret;
}
return OSA_ADB_OK;
}
{
int ret;
if (ret != OSA_ADB_OK)
return ret;
goto open_ok;
goto open_ok;
switch (errno) {
#ifdef EFTYPE
case EFTYPE:
#endif
case EINVAL:
goto open_ok;
default:
(void) osa_adb_release_lock(db);
return OSA_ADB_BAD_DB;
return errno;
}
return OSA_ADB_OK;
}
{
return osa_adb_release_lock(db);
(void) osa_adb_release_lock(db);
return OSA_ADB_FAILURE;
}
return(osa_adb_release_lock(db));
}