summaryrefslogtreecommitdiffstats
path: root/ldap/servers/slapd/protect_db.c
diff options
context:
space:
mode:
authorcvsadm <cvsadm>2005-01-21 00:44:34 +0000
committercvsadm <cvsadm>2005-01-21 00:44:34 +0000
commitb2093e3016027d6b5cf06b3f91f30769bfc099e2 (patch)
treecf58939393a9032182c4fbc4441164a9456e82f8 /ldap/servers/slapd/protect_db.c
downloadds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.gz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.xz
ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.zip
Moving NSCP Directory Server from DirectoryBranch to TRUNK, initial drop. (foxworth)ldapserver7x
Diffstat (limited to 'ldap/servers/slapd/protect_db.c')
-rw-r--r--ldap/servers/slapd/protect_db.c758
1 files changed, 758 insertions, 0 deletions
diff --git a/ldap/servers/slapd/protect_db.c b/ldap/servers/slapd/protect_db.c
new file mode 100644
index 00000000..34a63e80
--- /dev/null
+++ b/ldap/servers/slapd/protect_db.c
@@ -0,0 +1,758 @@
+/** BEGIN COPYRIGHT BLOCK
+ * Copyright 2001 Sun Microsystems, Inc.
+ * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+/* protect_db.c
+ * Used to police access to the db. Prevents different instances of
+ * slapd from clobbering each other
+ */
+
+
+
+#ifndef _WIN32
+
+#define LOCK_DIR "locks"
+#define LOCK_FILE "lock"
+#define IMPORT_DIR "imports"
+#define EXPORT_DIR "exports"
+#define SERVER_DIR "server"
+#define NUM_TRIES 20
+#define WAIT_TIME 250
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <fcntl.h> /* open */
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/param.h> /* MAXPATHLEN */
+#include <dirent.h>
+#include <pwd.h>
+#endif
+
+#include "protect_db.h"
+
+#include "slap.h"
+
+
+#ifndef _WIN32
+/* This is the unix version of the code to protect the db. */
+
+static int
+grab_lockfile()
+{
+ pid_t pid, owning_pid;
+ char lockfile[MAXPATHLEN];
+ int fd, x;
+ int removed_lockfile = 0;
+ struct timeval t;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+
+ /* Don't use anything that makes a NSPR call here (like LDAPDebug)! This function
+ gets called by an atexit function, and NSPR is long gone by then. */
+
+ /* Get the name of the lockfile */
+ sprintf(lockfile, "%s/%s", slapdFrontendConfig->instancedir, LOCK_FILE);
+ /* Get our pid */
+ pid = getpid();
+
+ /* Try to grab it */
+ if ((fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, 0664)) != -1) {
+ /* We got the lock, write our pid to the file */
+ write(fd, (void *) &pid, sizeof(pid_t));
+ close(fd);
+ return 0;
+ }
+
+ /* We weren't able to get the lock. Find out why. */
+ if (errno != EEXIST) {
+ /* Hmm, something happened that we weren't prepared to handle */
+ fprintf(stderr, ERROR_ACCESSING_LOCKFILE, lockfile);
+ return -1;
+ }
+
+ while(1) {
+ /* Try to grab the lockfile NUM_TRIES times waiting WAIT_TIME milliseconds after each try */
+ t.tv_sec = 0;
+ t.tv_usec = WAIT_TIME * 1000;
+ for(x = 0; x < NUM_TRIES; x++) {
+ if ((fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL)) != -1) {
+ /* Got the lock */
+ write(fd, (void *) &pid, sizeof(pid_t));
+ close(fd);
+ return 0;
+ }
+ select(0, NULL, NULL, NULL, &t);
+ }
+
+ /* We still haven't got the lockfile. Find out who owns it and see if they are still up */
+ if ((fd = open(lockfile, O_RDONLY)) != -1) {
+ size_t nb_bytes=0;
+
+ nb_bytes = read(fd, (void *) &owning_pid, sizeof(pid_t));
+ if ( (nb_bytes != (size_t)(sizeof(pid_t)) ) || (owning_pid == 0) || (kill(owning_pid, 0) != 0 && errno == ESRCH) ) {
+ /* The process that owns the lock is dead. Try to remove the old lockfile. */
+ if (unlink(lockfile) != 0) {
+ /* Unable to remove the stale lockfile. */
+ fprintf(stderr, LOCKFILE_DEAD_OWNER, lockfile, owning_pid);
+ return -1;
+ }
+ if (removed_lockfile) {
+ /* We already removed the lockfile once. Best thing to do is give up. */
+ /* I'm not sure what should be given as an error here */
+ fprintf(stderr, UNABLE_TO_GET_LOCKFILE, lockfile);
+ return -1;
+ } else {
+ removed_lockfile = 1;
+ }
+ } else {
+ /* It looks like the owner of the lockfile is still up and running. */
+ fprintf(stderr, LOCKFILE_ALREADY_OWNED, owning_pid);
+ return -1;
+ }
+ }
+ }
+}
+
+static void
+release_lockfile()
+{
+ char lockfile[MAXPATHLEN];
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ /* This function assumes that the caller owns the lock, it doesn't check to make sure! */
+
+ sprintf(lockfile, "%s/%s", slapdFrontendConfig->instancedir, LOCK_FILE);
+ unlink(lockfile);
+}
+
+
+/* Takes the pid of a process. Returns 1 if the process seems
+ * to be up, otherwise it returns 0.
+ */
+static int
+is_process_up(pid_t pid)
+{
+ if (kill(pid, 0) == -1 && errno == ESRCH) {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+/* Make sure the directory 'dir' exists and is owned bye the user
+ * the server runs as. Returns 0 if everything is ok.
+ */
+static int
+make_sure_dir_exists(char *dir)
+{
+ struct passwd* pw;
+ struct stat stat_buffer;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ /* Make sure it exists */
+ if (PR_MkDir(dir, 0755) != PR_SUCCESS) {
+ PRErrorCode prerr = PR_GetError();
+ if (prerr != PR_FILE_EXISTS_ERROR) {
+ LDAPDebug(LDAP_DEBUG_ANY, FILE_CREATE_ERROR, dir, prerr, slapd_pr_strerror(prerr));
+ return 1;
+ }
+ }
+
+ /* Make sure it's owned by the correct user */
+ if (slapdFrontendConfig->localuser != NULL) {
+ if ( (pw = getpwnam(slapdFrontendConfig->localuser)) == NULL ) {
+ LDAPDebug(LDAP_DEBUG_ANY, GETPWNAM_WARNING, slapdFrontendConfig->localuser, errno, strerror(errno));
+ } else {
+ if (chown(dir, pw->pw_uid, -1) == -1) {
+ stat(dir, &stat_buffer);
+ if (stat_buffer.st_uid != pw->pw_uid) {
+ LDAPDebug(LDAP_DEBUG_ANY, CHOWN_WARNING, dir, 0, 0);
+ }
+ }
+ } /* else */
+ }
+
+ return 0;
+}
+
+/* Creates a file in the directory 'dir_name' whose name is the
+ * pid for this process.
+ */
+static void
+add_this_process_to(char *dir_name)
+{
+ char file_name[MAXPATHLEN];
+ struct passwd* pw;
+ struct stat stat_buffer;
+ PRFileDesc* prfd;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ sprintf(file_name, "%s/%d", dir_name, getpid());
+
+ if ((prfd = PR_Open(file_name, PR_RDWR | PR_CREATE_FILE, 0666)) == NULL) {
+ LDAPDebug(LDAP_DEBUG_ANY, FILE_CREATE_WARNING, file_name, 0, 0);
+ return;
+ }
+
+ /* Make sure the owner is of the file is the user the server
+ * runs as. */
+ if (slapdFrontendConfig->localuser != NULL) {
+ if ( (pw = getpwnam(slapdFrontendConfig->localuser)) == NULL ) {
+ LDAPDebug(LDAP_DEBUG_ANY, GETPWNAM_WARNING, slapdFrontendConfig->localuser, errno, strerror(errno));
+ } else {
+ if (chown(file_name, pw->pw_uid, -1) == -1) {
+ stat(file_name, &stat_buffer);
+ if (stat_buffer.st_uid != pw->pw_uid) {
+ LDAPDebug(LDAP_DEBUG_ANY, CHOWN_WARNING, file_name, 0, 0);
+ }
+ }
+ } /* else */
+ }
+ PR_Close(prfd);
+}
+
+
+/* The directory 'dir_name' is expected to contain files whose
+ * names are the pid of running slapd processes. This
+ * function will check each entry in the directory and remove
+ * any files that represent processes that don't exist.
+ * Returns 0 if there are no processes represented, or
+ * the pid of one of the processes.
+ */
+static long
+sample_and_update(char *dir_name)
+{
+ PRDir *dir;
+ PRDirEntry *entry;
+ pid_t pid;
+ long result = 0;
+ char *endp;
+ char file_name[MAXPATHLEN];
+
+ if ((dir = PR_OpenDir(dir_name)) == NULL) {
+ return 0;
+ }
+
+ while((entry = PR_ReadDir(dir, PR_SKIP_BOTH)) != NULL) {
+ pid = (pid_t) strtol(entry->name, &endp, 0);
+ if (*endp != '\0') {
+ /* not quite sure what this file was, but we
+ * didn't put it there */
+ continue;
+ }
+ if (is_process_up(pid)) {
+ result = (long) pid;
+ } else {
+ sprintf(file_name, "%s/%s", dir_name, entry->name);
+ PR_Delete(file_name);
+ }
+ }
+ PR_CloseDir(dir);
+ return result;
+}
+
+
+/* Removes any stale pid entries and the pid entry for this
+ * process from the directory 'dir_name'.
+ */
+static void
+remove_and_update(char *dir_name)
+{
+ /* since this is called from an atexit function, we can't use
+ * NSPR. */
+
+ DIR *dir;
+ struct dirent *entry;
+ pid_t pid;
+ pid_t our_pid;
+ char *endp;
+ char file_name[MAXPATHLEN];
+
+ /* get our pid */
+ our_pid = getpid();
+
+ if ((dir = opendir(dir_name)) == NULL) {
+ return;
+ }
+
+ while((entry = readdir(dir)) != NULL) {
+
+ /* skip dot and dot-dot */
+ if (strcmp(entry->d_name, ".") == 0 ||
+ strcmp(entry->d_name, "..") == 0)
+ continue;
+
+ pid = (pid_t) strtol(entry->d_name, &endp, 0);
+ if (*endp != '\0') {
+ /* not quite sure what this file was, but we
+ * didn't put it there */
+ continue;
+ }
+ if (!is_process_up(pid) || pid == our_pid) {
+ sprintf(file_name, "%s/%s", dir_name, entry->d_name);
+ unlink(file_name);
+ }
+ }
+ closedir(dir);
+}
+
+
+
+/* Walks through all the pid directories and clears any stale
+ * pids. It also removes the files for this process.
+ */
+void
+remove_slapd_process()
+{
+ char lock_dir[MAXPATHLEN];
+ char import_dir[MAXPATHLEN];
+ char export_dir[MAXPATHLEN];
+ char server_dir[MAXPATHLEN];
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+
+ /* Create the name of the directories that hold the pids of the currently running
+ * ns-slapd processes */
+ sprintf(lock_dir, "%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR);
+ sprintf(import_dir, "%s/%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR, IMPORT_DIR);
+ sprintf(export_dir, "%s/%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR, EXPORT_DIR);
+ sprintf(server_dir, "%s/%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR, SERVER_DIR);
+
+ /* Grab the lockfile */
+ if (grab_lockfile() != 0) {
+ /* Unable to grab the lockfile */
+ return;
+ }
+
+
+ remove_and_update(import_dir);
+ remove_and_update(export_dir);
+ remove_and_update(server_dir);
+
+ release_lockfile();
+}
+
+int
+add_new_slapd_process(int exec_mode, int r_flag, int skip_flag)
+{
+ char lock_dir[MAXPATHLEN];
+ char import_dir[MAXPATHLEN];
+ char export_dir[MAXPATHLEN];
+ char server_dir[MAXPATHLEN];
+ int running, importing, exporting;
+ int result = 0;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ if (skip_flag) {
+ return 0;
+ }
+
+ /* Create the name of the directories that hold the pids of the currently running
+ * ns-slapd processes */
+ sprintf(lock_dir, "%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR);
+ sprintf(import_dir, "%s/%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR, IMPORT_DIR);
+ sprintf(export_dir, "%s/%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR, EXPORT_DIR);
+ sprintf(server_dir, "%s/%s/%s", slapdFrontendConfig->instancedir, LOCK_DIR, SERVER_DIR);
+
+ /* Grab the lockfile */
+ if (grab_lockfile() != 0) {
+ /* Unable to grab the lockfile */
+ return -1;
+ }
+
+ /* Make sure the directories exist */
+ if (make_sure_dir_exists(lock_dir) != 0 ||
+ make_sure_dir_exists(import_dir) != 0 ||
+ make_sure_dir_exists(export_dir) != 0 ||
+ make_sure_dir_exists(server_dir) != 0) {
+ release_lockfile();
+ return -1;
+ }
+
+ /* Go through the directories and find out what's going on.
+ * Clear any stale pids encountered. */
+ importing = sample_and_update(import_dir);
+ exporting = sample_and_update(export_dir);
+ running = sample_and_update(server_dir);
+
+ switch (exec_mode) {
+ case SLAPD_EXEMODE_SLAPD:
+ if (running) {
+ result = -1;
+ LDAPDebug(LDAP_DEBUG_ANY, NO_SERVER_DUE_TO_SERVER, running, 0, 0);
+ } else if (importing) {
+ result = -1;
+ LDAPDebug(LDAP_DEBUG_ANY, NO_SERVER_DUE_TO_IMPORT, importing, 0, 0);
+ } else {
+ add_this_process_to(server_dir);
+ result = 0;
+ }
+ break;
+ case SLAPD_EXEMODE_DB2LDIF:
+ if (r_flag) {
+ /* When the -r flag is used in db2ldif we need to make sure
+ * we get a consistent snapshot of the server. As a result
+ * it needs to run by itself, so no other slapd process can
+ * change the database while it is running. */
+ if (running || importing) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_DB2LDIFR_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ /* Even though this is really going to export code, we will
+ * but it in the importing dir so no other process can change
+ * things while we are doing ldif2db with the -r flag. */
+ add_this_process_to(import_dir);
+ result = 0;
+ }
+ } else {
+ if (importing) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_DB2LDIF_DUE_TO_IMPORT, importing, 0, 0);
+ result = -1;
+ } else {
+ add_this_process_to(export_dir);
+ result = 0;
+ }
+ }
+ break;
+ case SLAPD_EXEMODE_DB2ARCHIVE:
+ if (importing) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_DB2BAK_DUE_TO_IMPORT, importing, 0, 0);
+ result = -1;
+ } else {
+ add_this_process_to(export_dir);
+ result = 0;
+ }
+ break;
+ case SLAPD_EXEMODE_ARCHIVE2DB:
+ case SLAPD_EXEMODE_LDIF2DB:
+ if (running || importing || exporting) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_IMPORT_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ add_this_process_to(import_dir);
+ result = 0;
+ }
+ break;
+ case SLAPD_EXEMODE_DB2INDEX:
+ if (running || importing || exporting) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_DB2INDEX_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ add_this_process_to(import_dir);
+ result = 0;
+ }
+ break;
+#if defined(UPGRADEDB)
+ case SLAPD_EXEMODE_UPGRADEDB:
+ if (running || importing || exporting) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_UPGRADEDB_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ add_this_process_to(import_dir);
+ result = 0;
+ }
+ break;
+#endif
+ case SLAPD_EXEMODE_DBTEST:
+ if (running || importing || exporting) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_DBTEST_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ add_this_process_to(import_dir);
+ result = 0;
+ }
+ break;
+ }
+
+ release_lockfile();
+
+ if (result == 0) {
+ atexit(remove_slapd_process);
+ }
+
+ return result;
+}
+
+
+
+/* is_slapd_running()
+ * returns 1 if slapd is running, 0 if not, -1 on error
+ */
+
+
+int
+is_slapd_running() {
+ char server_dir[MAXPATHLEN];
+ char lock_dir[MAXPATHLEN];
+ slapdFrontendConfig_t *cfg = getFrontendConfig();
+ int running = 0;
+
+ sprintf(lock_dir, "%s/%s", cfg->instancedir, LOCK_DIR);
+ sprintf( server_dir, "%s/%s/%s", cfg->instancedir, LOCK_DIR, SERVER_DIR);
+
+ /* Grab the lockfile */
+ if (grab_lockfile() != 0) {
+ /* Unable to grab the lockfile */
+ return -1;
+ }
+
+ /* Make sure the directories exist */
+ if (make_sure_dir_exists(lock_dir) != 0 ||
+ make_sure_dir_exists(server_dir) != 0) {
+ release_lockfile();
+ return -1;
+ }
+
+ running = sample_and_update(server_dir);
+ release_lockfile();
+ return running;
+}
+
+
+#else /* _WIN32 */
+
+/* The NT version of this code */
+
+/* Returns 1 if the mutex named 'mutexName' otherwise it
+ * returns 0
+ */
+int
+mutex_exists( char *mutexName )
+{
+ if ( OpenMutex( SYNCHRONIZE, FALSE, mutexName ) == NULL ) {
+ return( 0 );
+ } else {
+ return( 1 );
+ }
+}
+
+/* is_slapd_running():
+ * returns 1 if slapd is running, 0 if not
+ */
+
+int
+is_slapd_running() {
+ char mutexName[ MAXPATHLEN + 1 ];
+ char serverMutexName[ MAXPATHLEN + 1 ];
+ int result = 0;
+ slapdFrontendConfig_t *cfg = getFrontendConfig();
+
+ strncpy( mutexName, cfg->instancedir, MAXPATHLEN );
+ strncpy( serverMutexName, cfg->instancedir, MAXPATHLEN );
+ mutexName[ MAXPATHLEN ] = '\0';
+
+ serverMutexName[ MAXPATHLEN ] = '\0';
+ strcat( serverMutexName, "/server" );
+
+ return mutex_exists ( serverMutexName );
+}
+
+static void fix_mutex_name(char *name)
+{
+ /* On NT mutex names cannot contain the '\' character.
+ * This functions replaces '\' with '/' in the supplied
+ * name. */
+ int x;
+
+ for (x = 0; name[x] != '\0'; x++) {
+ if ('\\' == name[x]) {
+ name[x] = '/';
+ }
+ }
+}
+
+/*
+ * We retain any opened handle to the mutex we create here,
+ * to use when we shutdown, to delete the mutex prior to
+ * signaling that we've exited.
+ */
+static HANDLE open_mutex = NULL;
+
+/*
+ * Call this to clean up the locks, before signaling
+ * that the server is down.
+ */
+void
+remove_slapd_process()
+{
+ if (open_mutex) {
+ CloseHandle(open_mutex);
+ }
+}
+
+/* This function makes sure different instances of slapd don't
+ * run in conflicting modes at the same time. The WIN32 version
+ * uses mutexes as names that the kernel handles. Basically there
+ * is a server mutex, and import mutex, and an export mutex. If
+ * the server mutex exists, then the server is running. If the
+ * import mutex exists, then either ldif2db or bak2db is running.
+ * If the export mutex exists, then one or more of db2ldif or db2bak
+ * are running. There is also a mutex that is actually locked when
+ * checking the existence of the other mutexes. The OS will
+ * automatically remove a mutex if no process has a handle on it.
+ * returns a 0 if it is ok for the process to run
+ * returns a -1 if the process can't run do to a conflict with other
+ * slapd processes
+ */
+int
+add_new_slapd_process(int exec_mode, int r_flag, int skip_flag)
+{
+ char mutexName[ MAXPATHLEN + 1 ];
+ char serverMutexName[ MAXPATHLEN + 1 ];
+ char importMutexName[ MAXPATHLEN + 1 ];
+ char exportMutexName[ MAXPATHLEN + 1 ];
+
+ HANDLE mutex;
+ SECURITY_ATTRIBUTES mutexAttributes;
+ PSECURITY_DESCRIPTOR pSD;
+ LPVOID lpMsgBuf;
+
+ int result = 0;
+
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ if (skip_flag) {
+ return 0;
+ }
+
+ /* Create the names for the mutexes */
+ strcpy(mutexName, slapdFrontendConfig->instancedir);
+
+ /* Make sure the name of the mutex is legal. */
+ fix_mutex_name(mutexName);
+
+ sprintf(serverMutexName, "%s/server", mutexName);
+ sprintf(importMutexName, "%s/import", mutexName);
+ sprintf(exportMutexName, "%s/export", mutexName);
+
+ /* Fill in the security crap for the mutex */
+ pSD = (PSECURITY_DESCRIPTOR)slapi_ch_malloc( sizeof( SECURITY_DESCRIPTOR ) );
+ InitializeSecurityDescriptor( pSD, SECURITY_DESCRIPTOR_REVISION );
+ SetSecurityDescriptorDacl( pSD, TRUE, NULL, FALSE );
+ mutexAttributes.nLength = sizeof( mutexAttributes );
+ mutexAttributes.lpSecurityDescriptor = pSD;
+ mutexAttributes.bInheritHandle = FALSE;
+
+ /* Get a handle to the main mutex */
+ if ( ( mutex = CreateMutex( &mutexAttributes, FALSE, mutexName ) ) == NULL ) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ LDAPDebug( LDAP_DEBUG_ANY, CREATE_MUTEX_ERROR, lpMsgBuf, 0, 0 );
+ LocalFree( lpMsgBuf );
+ exit( 1 );
+ }
+
+ /* Lock the main mutex */
+ if ( WaitForSingleObject( mutex, INFINITE ) == WAIT_FAILED ) {
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
+ (LPTSTR) &lpMsgBuf,
+ 0,
+ NULL
+ );
+
+ LDAPDebug( LDAP_DEBUG_ANY, WAIT_ERROR, lpMsgBuf, 0, 0 );
+ LocalFree( lpMsgBuf );
+ exit( 1 );
+ }
+
+
+ switch (exec_mode) {
+ case SLAPD_EXEMODE_SLAPD:
+ if ( mutex_exists( serverMutexName ) ||
+ mutex_exists( importMutexName ) ) {
+ LDAPDebug( LDAP_DEBUG_ANY, NO_SERVER_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ open_mutex = CreateMutex( &mutexAttributes, FALSE, serverMutexName );
+ result = 0;
+ }
+ break;
+ case SLAPD_EXEMODE_DB2LDIF:
+ if (r_flag) {
+ /* When the -r flag is used in db2ldif we need to make sure
+ * we get a consistent snapshot of the server. As a result
+ * it needs to run by itself, so no other slapd process can
+ * change the database while it is running. */
+ if ( mutex_exists( serverMutexName ) ||
+ mutex_exists( importMutexName ) ||
+ mutex_exists( exportMutexName ) ) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_DB2LDIFR_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ CreateMutex( &mutexAttributes, FALSE, exportMutexName );
+ result = 0;
+ }
+ break;
+ }
+ case SLAPD_EXEMODE_DB2ARCHIVE:
+ if ( mutex_exists( importMutexName ) ) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_EXPORT_DUE_TO_IMPORT, 0, 0, 0);
+ result = -1;
+ } else {
+ CreateMutex( &mutexAttributes, FALSE, exportMutexName );
+ result = 0;
+ }
+ break;
+ case SLAPD_EXEMODE_ARCHIVE2DB:
+ case SLAPD_EXEMODE_LDIF2DB:
+ if ( mutex_exists( serverMutexName ) ||
+ mutex_exists( importMutexName ) ||
+ mutex_exists( exportMutexName ) ) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_IMPORT_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ CreateMutex( &mutexAttributes, FALSE, importMutexName );
+ result = 0;
+ }
+ break;
+#if defined(UPGRADEDB)
+ case SLAPD_EXEMODE_UPGRADEDB:
+ if ( mutex_exists( serverMutexName ) ||
+ mutex_exists( importMutexName ) ||
+ mutex_exists( exportMutexName ) ) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_UPGRADEDB_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ CreateMutex( &mutexAttributes, FALSE, importMutexName );
+ result = 0;
+ }
+ break;
+#endif
+ case SLAPD_EXEMODE_DBTEST:
+ if ( mutex_exists( serverMutexName ) ||
+ mutex_exists( importMutexName ) ||
+ mutex_exists( exportMutexName ) ) {
+ LDAPDebug(LDAP_DEBUG_ANY, NO_DBTEST_DUE_TO_USE, 0, 0, 0);
+ result = -1;
+ } else {
+ CreateMutex( &mutexAttributes, FALSE, importMutexName );
+ result = 0;
+ }
+ break;
+ }
+
+ /* release the main mutex */
+ ReleaseMutex( mutex );
+
+ slapi_ch_free((void**)&pSD );
+
+ return( result );
+}
+#endif /* _WIN32 */
+