| 23 hours ago | Valery Kharseko | ![]() |
| 23 hours ago | Valery Kharseko | ![]() |
| 23 hours ago | Valery Kharseko | ![]() |
| 23 hours ago | Valery Kharseko | ![]() |
| yesterday | dependabot[bot] | ![]() |
| yesterday | Valery Kharseko | ![]() |
| yesterday | Valery Kharseko | ![]() |
.github/workflows/build.yml
@@ -287,6 +287,21 @@ - name: Test on Windows if: runner.os == 'Windows' run: | # Verify a stop took effect before moving on: wait until the server # releases the exclusive byte-range lock it holds on locks\server.lock. # The explicit Lock(0, 1) probe is required: a byte-range lock does not # prevent opening the file, so a bare Open() would always succeed. function Wait-ServerStopped($lockFile) { $lockFile = Join-Path $PWD $lockFile for ($i = 0; $i -lt 30; $i++) { if (-not (Test-Path $lockFile)) { return } try { $fs = [System.IO.File]::Open($lockFile, 'Open', 'ReadWrite', 'ReadWrite') try { $fs.Lock(0, 1); $fs.Unlock(0, 1); return } finally { $fs.Close() } } catch { Start-Sleep -Seconds 2 } } throw "The server still holds the lock on ${lockFile}: the stop did not take effect" } set OPENDJ_JAVA_ARGS="-server -Xmx512m" opendj-server-legacy\target\package\opendj\setup.bat -h localhost -p 1389 --ldapsPort 1636 --adminConnectorPort 4444 --enableStartTLS --generateSelfSignedCertificate --rootUserDN "cn=Directory Manager" --rootUserPassword password --baseDN dc=example,dc=com --sampleData 5000 --cli --acceptLicense --no-prompt opendj-server-legacy\target\package\opendj\bat\status.bat --hostname localhost --bindDN "cn=Directory Manager" --bindPassword password --trustAll @@ -325,6 +340,8 @@ opendj-server-legacy\target\package\opendj\bat\dsconfig.bat create-backend --hostname localhost --port 4444 --bindDN "cn=Directory Manager" --bindPassword password --backend-name=example2 --type je --set=base-dn:dc=example2,dc=com --set=enabled:true --no-prompt --trustAll opendj-server-legacy\target\package\opendj\bat\makeldif.bat -o test.ldif -c suffix=dc=example2,dc=com opendj-server-legacy\target\package\opendj\config\MakeLDIF\example.template opendj-server-legacy\target\package\opendj\bat\stop-ds.bat if ($LASTEXITCODE -ne 0) { throw "stop-ds.bat failed with exit code $LASTEXITCODE" } Wait-ServerStopped 'opendj-server-legacy\target\package\opendj\locks\server.lock' echo "4.9.9.0" > opendj-server-legacy\target\package\opendj\config\buildinfo opendj-server-legacy\target\package\opendj\upgrade.bat opendj-server-legacy\target\package\opendj\bat\import-ldif.bat --offline --ldifFile test.ldif --backendID=example2 @@ -333,6 +350,8 @@ opendj-server-legacy\target\package\opendj\bat\rebuild-index.bat --bindDN "cn=Directory Manager" --bindPassword password --baseDN "dc=example2,dc=com" --rebuildAll --trustAll opendj-server-legacy\target\package\opendj\bat\ldapsearch.bat --hostname localhost --port 1636 --bindDN "cn=Directory Manager" --bindPassword password --useSsl --trustAll --baseDN "dc=example2,dc=com" --searchScope sub "(uid=user.*)" dn | find /c '"dn:"' | findstr "10000" opendj-server-legacy\target\package\opendj\bat\stop-ds.bat if ($LASTEXITCODE -ne 0) { throw "stop-ds.bat failed with exit code $LASTEXITCODE" } Wait-ServerStopped 'opendj-server-legacy\target\package\opendj\locks\server.lock' opendj-server-legacy\target\package\opendj\bat\windows-service.bat --enableService net start "OpenDJ Server" if ($LASTEXITCODE -ne 0) { throw "net start 'OpenDJ Server' failed with exit code $LASTEXITCODE" } opendj-core/src/main/java/org/forgerock/opendj/ldap/AddressMask.java
@@ -13,6 +13,7 @@ * * Copyright 2006-2009 Sun Microsystems, Inc. * Portions copyright 2011-2014 ForgeRock AS. * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.ldap; @@ -328,7 +329,7 @@ */ private void processHost(final String rule) { // Note that '*' is valid in host rule final String[] s = rule.split("^[0-9a-zA-z-.*]+"); final String[] s = rule.split("^[0-9a-zA-Z_.*-]+"); if (s.length > 0) { throw genericDecodeError(); } @@ -346,7 +347,7 @@ */ private void processHostPattern(final String rule) { // quick check for invalid chars like " " final String[] s = rule.split("^[0-9a-zA-z-.]+"); final String[] s = rule.split("^[0-9a-zA-Z_.-]+"); if (s.length > 0) { throw genericDecodeError(); } opendj-core/src/test/java/org/forgerock/opendj/ldap/AddressMaskTestCase.java
@@ -13,6 +13,7 @@ * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions copyright 2011-2015 ForgeRock AS. * Portions Copyright 2026 3A Systems, LLC. */ package org.forgerock.opendj.ldap; @@ -38,7 +39,9 @@ public Object[][] validData() { return new Object[][] { { "129.34.55.67" }, { "129.*.78.55" }, { ".central.sun.com" }, { "foo.central.sun.com" }, { "foo.*.sun.*" }, { "128.*.*.*" }, { "129.45.23.67/22" }, { "128.33.23.21/32" }, { "*.*.*.*" }, { "129.45.67.34/0" }, { "foo.com" }, { "foo" } }; { "128.33.23.21/32" }, { "*.*.*.*" }, { "129.45.67.34/0" }, { "foo.com" }, { "foo" }, // Underscores appear in real deployments and stay accepted. { "my_host.example.com" }, { ".my_domain.com" } }; } @DataProvider(name = "invalidRules") @@ -47,7 +50,14 @@ { "129.56.78.90/2000" }, { "677.777.AG.BC" }, { "/34" }, { "234.12.12.*/31" }, { "234.12.12.90/" }, { "129.34.56.78/-100" }, { "129" }, { "129.34.-90.67" }, { "129.**.56.67" }, { "foo bar.com" }, { "12foo.example.com" }, { "123.45." }, { ".central.sun day.com" }, { "129.34.45.45/4/3/" } }; { ".central.sun day.com" }, { "129.34.45.45/4/3/" }, /* * The characters between 'Z' and 'a' used to slip through the host and host * pattern validators, which spelled the letter range as A-z instead of A-Z. */ { "foo[bar.com" }, { "foo\\bar.com" }, { "foo]bar.com" }, { "foo^bar.com" }, { "foo`bar.com" }, { ".foo[bar.com" }, { ".foo\\bar.com" }, { ".foo]bar.com" }, { ".foo^bar.com" }, { ".foo`bar.com" } }; } @DataProvider(name = "toStringRule") opendj-server-legacy/pom.xml
@@ -31,20 +31,6 @@ </description> <inceptionYear>2010</inceptionYear> <repositories> <repository> <id>oracle-repository</id> <name>Oracle Maven Repository</name> <url>http://download.oracle.com/maven</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <properties> <!-- General server-wide properties --> <docgen.dir>${project.build.directory}/docgen</docgen.dir> @@ -265,7 +251,7 @@ <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.7.11</version> <version>42.7.12</version> </dependency> <dependency> <groupId>org.testng</groupId> opendj-server-legacy/resource/bin/stop-ds.bat
@@ -14,6 +14,7 @@ rem rem Copyright 2006-2010 Sun Microsystems, Inc. rem Portions Copyright 2011-2014 ForgeRock AS. rem Portions Copyright 2026 3A Systems, LLC. setlocal @@ -93,12 +94,19 @@ :stopUsingSystemCall echo %SCRIPT%: stop using system call >> %LOG% "%INSTALL_ROOT%\lib\winlauncher.exe" stop "%INSTANCE_ROOT%" if not %errorlevel% == 0 ( echo %SCRIPT%: winlauncher stop failed with error %errorlevel% >> %LOG% exit /B %errorlevel% ) goto end :restartUsingSystemCall echo %SCRIPT%: restart using system call >> %LOG% "%INSTALL_ROOT%\lib\winlauncher.exe" stop "%INSTANCE_ROOT%" if not %errorlevel% == 0 goto end if not %errorlevel% == 0 ( echo %SCRIPT%: winlauncher stop failed with error %errorlevel% >> %LOG% exit /B %errorlevel% ) goto startUsingSystemCall :stopUsingProtocol opendj-server-legacy/src/build-tools/windows/service.c
@@ -24,6 +24,13 @@ char *_instanceDir = NULL; HANDLE _eventLog = NULL; char * _logFile = NULL; // The root of the server instance (where logs\server.pid and // locks\server.lock live). _instanceDir is the install root the // service was created with; on split install/instance layouts the // instance root differs and is resolved from the install root's // instance.loc file. Resolved by getInstanceRoot(), normally once // from setInstanceDir(), and released by freeInstanceDir(). static char *_instanceRoot = NULL; // ---------------------------------------------------- // Register a service handler to the service control dispatcher. @@ -417,6 +424,113 @@ } // ---------------------------------------------------- // Returns the root of the server instance whose files the service // must probe. The launching scripts (_script-util.bat) resolve it // from the install root's instance.loc file when that file exists // (split install/instance layouts), resolving a relative content // against the install root, and fall back to the install root // itself. This function performs the same resolution. The result is // cached, except when instance.loc exists but its content cannot be // resolved yet (getCanonicalDirectoryPath requires the directory to // exist, e.g. an instance on a volume that is not mounted yet): // caching the install root then would make isServerRunning() probe // the wrong locks\server.lock for the lifetime of the process, so // that case is reported to the event log and retried on the next // call, probing the install root only for the current call. // ---------------------------------------------------- static char* getInstanceRoot(void) { char locFile[MAX_PATH]; FILE *f; char *resolved = NULL; BOOL unresolvable = FALSE; if (_instanceRoot != NULL) { return _instanceRoot; } if (isSafePath(_instanceDir) && (strlen(_instanceDir) + strlen("\\instance.loc") + 1 < MAX_PATH)) { _snprintf(locFile, MAX_PATH, "%s\\instance.loc", _instanceDir); f = fopen(locFile, "r"); if (f != NULL) { char line[MAX_PATH]; if (fgets(line, MAX_PATH, f) != NULL) { size_t len = strlen(line); while ((len > 0) && ((line[len - 1] == '\n') || (line[len - 1] == '\r') || (line[len - 1] == ' ') || (line[len - 1] == '\t'))) { line[--len] = '\0'; } if (len > 0) { char joined[2 * MAX_PATH]; BOOL isAbsolute = ((len >= 2) && (line[1] == ':')) || ((line[0] == '\\') && (line[1] == '\\')); if (isAbsolute) { _snprintf(joined, sizeof(joined), "%s", line); } else { _snprintf(joined, sizeof(joined), "%s\\%s", _instanceDir, line); } resolved = getCanonicalDirectoryPath(joined); if (resolved == NULL) { unresolvable = TRUE; debugError("Could not resolve the instance root '%s' read from '%s'.", joined, locFile); } else { debug("Instance root resolved from '%s': '%s'.", locFile, resolved); } } } fclose(f); } } if (unresolvable) { static volatile LONG alreadyReported = 0; if (InterlockedCompareExchange(&alreadyReported, 1, 0) == 0) { char msg[2 * MAX_PATH]; const char *logArgs[1]; _snprintf(msg, sizeof(msg), "Could not resolve the OpenDJ instance root from '%s'; probing the install root '%s' until the instance root becomes available.", locFile, _instanceDir); msg[sizeof(msg) - 1] = '\0'; logArgs[0] = msg; if (!reportLogEvent(EVENTLOG_WARNING_TYPE, WIN_EVENT_ID_DEBUG, 1, logArgs)) { // The event log is not registered yet (command-line paths and the // eager call from setInstanceDir): let a later call report it. InterlockedExchange(&alreadyReported, 0); } } return _instanceDir; } if (resolved == NULL) { // No usable instance.loc: the install root is the instance root. _instanceRoot = _instanceDir; } else if (InterlockedCompareExchangePointer((PVOID*)&_instanceRoot, resolved, NULL) != NULL) { // A concurrent first call published its copy: keep that one. free(resolved); } return _instanceRoot; } // getInstanceRoot // ---------------------------------------------------- // Check if the server is running or not. // The functions returns SERVICE_RETURN_OK if we could determine if // the server is running or not and false otherwise. @@ -426,15 +540,16 @@ ServiceReturnCode returnValue; char* relativePath = "\\locks\\server.lock"; char lockFile[MAX_PATH]; char* instanceRoot = getInstanceRoot(); if (mustDebug) { debug("Determining if the server is running."); } if (isSafePath(_instanceDir) && strlen(relativePath)+strlen(_instanceDir)+1 < MAX_PATH) if (isSafePath(instanceRoot) && strlen(relativePath)+strlen(instanceRoot)+1 < MAX_PATH) { int fd; _snprintf(lockFile, MAX_PATH, "%s%s", _instanceDir, relativePath); _snprintf(lockFile, MAX_PATH, "%s%s", instanceRoot, relativePath); if (mustDebug) { debug( @@ -698,22 +813,40 @@ // ---------------------------------------------------- // Stop the application using stop-ds.bat // Stop the application by invoking winlauncher.exe stop directly. // The stop used to go through stop-ds.bat --windowsNetStop, but on // that path two java processes are launched only to end up in the // very same winlauncher.exe stop call, keeping the SCM waiting for // tens of seconds before the stop even begins. // While the stop is in progress the SERVICE_STOP_PENDING status is // re-reported with an incrementing checkPoint through // serviceStatusHandle, as doStartApplication does for the start // (both parameters may be NULL when no reporting is wanted). // The functions returns SERVICE_RETURN_OK if we could stop the server // and SERVICE_RETURN_ERROR otherwise. // ---------------------------------------------------- ServiceReturnCode doStopApplication() ServiceReturnCode doStopApplication(SERVICE_STATUS_HANDLE *serviceStatusHandle, DWORD *checkPoint) { ServiceReturnCode returnValue; // init out params char* relativePath = "\\bat\\stop-ds.bat"; char* relativePath = "\\lib\\winlauncher.exe"; char command[COMMAND_SIZE]; // winlauncher.exe lives under the install root, but the directory it // operates on (logs\server.pid, locks\server.lock) is the instance root. char* instanceRoot = getInstanceRoot(); debug("doStopApplication"); if (strlen(relativePath)+strlen(_instanceDir)+1 < COMMAND_SIZE) if (strlen(relativePath) + strlen(_instanceDir) + strlen(instanceRoot) + strlen("\"\" stop \"\\.\"") + 1 < COMMAND_SIZE) { _snprintf(command, COMMAND_SIZE, "\"%s%s\" --windowsNetStop", _instanceDir, relativePath); // The trailing "\." protects the closing quote from a root that ends // with a backslash (which the command line parser would treat as an // escape); winlauncher.exe removes it again when canonicalizing the path. _snprintf(command, COMMAND_SIZE, "\"%s%s\" stop \"%s\\.\"", _instanceDir, relativePath, instanceRoot); // The stop no longer goes through stop-ds.bat, so this debug log is // the only file trace of the stop: record the command unconditionally. debug("doStopApplication: launching '%s'.", command); // launch the command if (spawn(command, FALSE) != -1) { @@ -723,12 +856,15 @@ debug("doStopApplication: the spawn of the process worked."); // Wait to be able to launch the java process in order it to free the lock // on the file. Sleep(3000); Sleep(1000); while ((nTries > 0) && running) { nTries--; if (serviceStatusHandle != NULL && checkPoint != NULL) { updateServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0, (*checkPoint)++, 10000, serviceStatusHandle); } if (isServerRunning(&running, TRUE) != SERVICE_RETURN_OK) { break; @@ -939,10 +1075,10 @@ // elaborate the commands supported by the service: // - STOP customer has performed a stop-ds (or NET STOP) // - SHUTDOWN the system is rebooting // - INTERROGATE service controler can interrogate the service // - No need to support PAUSE/CONTINUE // // Note: INTERROGATE *must* be supported by the service handler // Note: INTERROGATE has no SERVICE_ACCEPT_ bit: it is always accepted // and *must* be supported by the service handler DWORD controls; SERVICE_STATUS serviceStatus; BOOL success; @@ -961,8 +1097,7 @@ { controls = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN | SERVICE_CONTROL_INTERROGATE; | SERVICE_ACCEPT_SHUTDOWN; } // fill in the status structure @@ -1196,19 +1331,24 @@ else { running = FALSE; // Wait on the termination event rather than sleeping: a completed // stop signals it through doTerminateService, so the process can // exit right away instead of after the next poll plus its // confirmation retries - the window in which a following start // fails with ERROR_SERVICE_ALREADY_RUNNING. if (updatedRunningStatus) { Sleep(5000); returnValue = WaitForSingleObject (_terminationEvent, 5000); } else { returnValue = WaitForSingleObject (_terminationEvent, refreshPeriodSeconds * 1000); if (returnValue == WAIT_OBJECT_0) { debug("The application has exited."); break; } } if (returnValue == WAIT_OBJECT_0) { debug("The application has exited."); break; } code = isServerRunning(&running, FALSE); if (code != SERVICE_RETURN_OK) @@ -1322,31 +1462,25 @@ } // doTerminateService // Set to 1 while a stop is in progress so that repeated STOP/SHUTDOWN // controls do not start a second stop, and the checkpoint counter the // ongoing stop reports SERVICE_STOP_PENDING progress with. static volatile LONG _stopInProgress = 0; static DWORD _stopCheckpoint = CHECKPOINT_FIRST_VALUE; // ---------------------------------------------------- // Stops the service from within the service handler. Shared by the // SERVICE_CONTROL_STOP and SERVICE_CONTROL_SHUTDOWN control codes. // Performs the actual stop of the service: stops the application and // reports the final service status. Runs on the worker thread spawned // by stopServiceFromHandler for SERVICE_CONTROL_STOP and synchronously // for SERVICE_CONTROL_SHUTDOWN. // ---------------------------------------------------- static void stopServiceFromHandler(void) static void stopService(BOOL duringShutdown) { ServiceReturnCode code; DWORD checkpoint; // update service status to STOP_PENDING debug("serviceHandler: stop"); _serviceCurStatus = SERVICE_STOP_PENDING; checkpoint = CHECKPOINT_FIRST_VALUE; updateServiceStatus ( _serviceCurStatus, NO_ERROR, 0, checkpoint++, TIMEOUT_STOP_SERVICE, _serviceStatusHandle ); // let's try to stop the application whatever may be the status above // (best effort mode) code = doStopApplication(); code = doStopApplication(_serviceStatusHandle, &_stopCheckpoint); if (code == SERVICE_RETURN_OK) { WORD argCount = 1; @@ -1375,13 +1509,94 @@ WORD argCount = 1; const char *logArgs[] = {_instanceDir}; debug("serviceHandler: The server could not be stopped."); // We could not stop the server // We could not stop the server. Leaving the service in // SERVICE_STOP_PENDING forever would make the SCM refuse any further // stop or delete request, so report a final state: RUNNING for a // regular stop; during a system shutdown the process is about to be // terminated anyway, so report STOPPED and let serviceMain return. _serviceCurStatus = duringShutdown ? SERVICE_STOPPED : SERVICE_RUNNING; updateServiceStatus ( _serviceCurStatus, NO_ERROR, 0, CHECKPOINT_NO_ONGOING_OPERATION, TIMEOUT_NONE, _serviceStatusHandle ); if (duringShutdown) { doTerminateService (_terminationEvent); } reportLogEvent( EVENTLOG_ERROR_TYPE, WIN_EVENT_ID_SERVER_STOP_FAILED, argCount, logArgs ); } InterlockedExchange(&_stopInProgress, 0); } // stopService // ---------------------------------------------------- // Thread procedure running stopService for SERVICE_CONTROL_STOP. // ---------------------------------------------------- static DWORD WINAPI stopServiceWorker(LPVOID lpParam) { (void)lpParam; stopService(FALSE); return 0; } // stopServiceWorker // ---------------------------------------------------- // Stops the service from within the service handler. Shared by the // SERVICE_CONTROL_STOP and SERVICE_CONTROL_SHUTDOWN control codes. // Reports SERVICE_STOP_PENDING and hands the actual stop over to a // worker thread: the handler must return quickly (the SCM cuts off // ControlService callers after 30 seconds) while a legitimate stop // can take longer. During a system shutdown the stop stays // synchronous: returning from the handler early would only invite the // system to terminate the process sooner. // ---------------------------------------------------- static void stopServiceFromHandler(BOOL duringShutdown) { if (InterlockedCompareExchange(&_stopInProgress, 1, 0) != 0) { // The ongoing stop keeps reporting progress and will set the final // status: nothing to do for this control request. debug("serviceHandler: a stop is already in progress."); return; } // update service status to STOP_PENDING debug("serviceHandler: stop"); _serviceCurStatus = SERVICE_STOP_PENDING; _stopCheckpoint = CHECKPOINT_FIRST_VALUE; updateServiceStatus ( _serviceCurStatus, NO_ERROR, 0, _stopCheckpoint++, TIMEOUT_STOP_SERVICE, _serviceStatusHandle ); if (duringShutdown) { stopService(TRUE); } else { HANDLE stopThread = CreateThread(NULL, 0, stopServiceWorker, NULL, 0, NULL); if (stopThread == NULL) { debugError("Failed to create the stop thread. Last error = %d. Stopping synchronously.", GetLastError()); stopService(FALSE); } else { CloseHandle(stopThread); } } } // stopServiceFromHandler // ---------------------------------------------------- @@ -1399,12 +1614,15 @@ switch (controlCode) { case SERVICE_CONTROL_SHUTDOWN: // If system is shuting down then stop the service // -> no break here // The system is shutting down: stop the service synchronously debug("serviceHandler: shutdown"); stopServiceFromHandler(TRUE); break; case SERVICE_CONTROL_STOP: // update service status to STOP_PENDING and stop the application stopServiceFromHandler(); // from a worker thread stopServiceFromHandler(FALSE); break; @@ -2032,7 +2250,39 @@ } else { Sleep (500); // Wait until the service actually reaches SERVICE_STOPPED so that // DeleteService below performs a clean delete instead of merely // marking a still-running service for deletion. The budget must // exceed the stop worker's own (~61 s); a return to SERVICE_RUNNING // means the stop failed and waiting further is pointless. int nTries = 90; while ((nTries > 0) && (serviceStatus.dwCurrentState != SERVICE_STOPPED) && (serviceStatus.dwCurrentState != SERVICE_RUNNING)) { nTries--; Sleep (1000); if (!QueryServiceStatus (myService, &serviceStatus)) { break; } } if (serviceStatus.dwCurrentState == SERVICE_RUNNING) { // The stop worker reports SERVICE_RUNNING when the stop failed: // deleting the service now would merely mark a still-running // service for deletion and report success while the server keeps // running with no service registration left to retry with. debugError( "The service '%s' is still running after the stop request: not deleting it.", serviceName); returnValue = SERVICE_RETURN_ERROR; } else if (serviceStatus.dwCurrentState != SERVICE_STOPPED) { debugError( "The service '%s' did not reach SERVICE_STOPPED (state=%d): DeleteService will only mark it for deletion.", serviceName, serviceStatus.dwCurrentState); } } } } @@ -2396,14 +2646,24 @@ fprintf(stdout, "The instance dir '%s' is not valid.\n", dir); return FALSE; } // Resolve the instance root before serviceMain's monitor loop and the // stop worker can race on the lazy initialization, and so the resolved // root appears in the debug log at startup. getInstanceRoot(); return TRUE; } // --------------------------------------------------------------- // Frees the _instanceDir global variable allocated by setInstanceDir. // Frees the _instanceDir and _instanceRoot global variables allocated // by setInstanceDir/getInstanceRoot. // --------------------------------------------------------------- static void freeInstanceDir() { if ((_instanceRoot != NULL) && (_instanceRoot != _instanceDir)) { free(_instanceRoot); } _instanceRoot = NULL; free(_instanceDir); _instanceDir = NULL; } opendj-server-legacy/src/build-tools/windows/service.h
@@ -100,6 +100,7 @@ SERVICE_STATUS_HANDLE *serviceStatusHandle ); ServiceReturnCode doStartApplication(SERVICE_STATUS_HANDLE *serviceStatusHandle, DWORD *checkPoint); ServiceReturnCode doStopApplication(SERVICE_STATUS_HANDLE *serviceStatusHandle, DWORD *checkPoint); void serviceHandler(DWORD controlCode); BOOL getServiceStatus(char *serviceName, LPDWORD returnState); opendj-server-legacy/src/build-tools/windows/winlauncher.c
@@ -122,21 +122,26 @@ char pidFile[PATH_SIZE]; FILE *f; char buf[BUF_SIZE]; int read; size_t nRead; debug("Attempting to get the PID for the server rooted at '%s'.", instanceDir); if (getPidFile(instanceDir, pidFile, PATH_SIZE)) { if ((f = fopen(pidFile, "r")) != NULL) { read = fread(buf, 1, sizeof(buf),f); debug("Read '%s' from the PID file '%s'.", buf, pidFile); } if (f != NULL) { nRead = fread(buf, 1, sizeof(buf) - 1, f); fclose(f); returnValue = (int)strtol(buf, (char **)NULL, 10); buf[nRead] = '\0'; if (nRead > 0) { debug("Read '%s' from the PID file '%s'.", buf, pidFile); returnValue = (int)strtol(buf, (char **)NULL, 10); } else { debugError("The PID file '%s' is empty.", pidFile); returnValue = 0; } } else { @@ -177,9 +182,20 @@ if (procHandle == NULL) { debug("The process with pid=%d has already terminated.", pid); // process already dead processDead = TRUE; DWORD lastError = GetLastError(); if (lastError == ERROR_INVALID_PARAMETER) { // no process with this pid exists: it has already terminated debug("The process with pid=%d has already terminated.", pid); processDead = TRUE; } else { // Access denied or any other error: the process may well still be // running, so it must not be reported as stopped. debugError("Failed to open the process (pid=%d) lastError=%d.", pid, lastError); processDead = FALSE; } } else { @@ -246,7 +262,7 @@ // immediately. if ((fopen_s(&f, pidFile, "w") == 0) && (f != NULL)) { fprintf(f, "%d", pid); fprintf(f, "%d\n", pid); fclose (f); returnValue = TRUE; debug("Successfully put pid=%d in the pid file '%s'.", pid, pidFile); @@ -427,6 +443,74 @@ // ---------------------------------------------------- // Waits until the exclusive lock that the server holds on // locks\server.lock has been released, which is the definitive sign // that the server process is gone (the pid in the pid file may be // stale and belong to another process, so the outcome of killProcess // alone is not proof that the server was stopped). // Only a lock conflict (EACCES) is proof that the server still runs: // like isServerRunning in service.c, a lock file that cannot be opened // or an unexpected locking error is not treated as a running server. // Returns TRUE if the server no longer holds the lock (or holding it // cannot be proven) and FALSE if the lock conflict persists after the // bounded retries. // ---------------------------------------------------- BOOL waitForLockRelease(const char* instanceDir) { char lockFile[PATH_SIZE]; char* relativePath = "\\locks\\server.lock"; int nTries = 30; if (!isSafePath(instanceDir) || (strlen(relativePath) + strlen(instanceDir)) >= PATH_SIZE) { debugError("Unable to get the lock file name for instanceDir='%s'.", instanceDir); return FALSE; } _snprintf(lockFile, PATH_SIZE, "%s%s", instanceDir, relativePath); while (nTries > 0) { int fd; int lockingError; if (!fileExists(lockFile)) { debug("Lock file '%s' does not exist, so the server is stopped.", lockFile); return TRUE; } fd = _open(lockFile, _O_RDWR); if (fd == -1) { debug("Could not open the lock file '%s' (errno=%d), so the server is considered stopped.", lockFile, errno); return TRUE; } if (_locking(fd, LK_NBLCK, 1) != -1) { _locking(fd, LK_UNLCK, 1); _close(fd); debug("Acquired the lock on '%s', so the server is stopped.", lockFile); return TRUE; } lockingError = errno; _close(fd); if (lockingError != EACCES) { debugError("Unexpected error locking '%s': %d", lockFile, lockingError); return TRUE; } nTries--; debug("The server still holds the lock on '%s'. Sleeping for 1 second and will try %d more time(s).", lockFile, nTries); Sleep(1000); } debugError("The server did not release the lock on '%s'.", lockFile); return FALSE; } // waitForLockRelease // ---------------------------------------------------- // Function called when we want to stop the server. // This code is called by the stop-ds.bat batch file to stop the server // in windows. @@ -443,13 +527,14 @@ // sets the pid file to be deleted on the exit of the process // the file is not always deleted. // // Returns 0 if the instance could be stopped using the // pid stored in a file of the server installation and // -1 otherwise. // Returns 0 if the server no longer holds the server lock (the process // found in the pid file, if any, was killed and the lock was released) // and -1 otherwise. // ---------------------------------------------------- int stop(const char* instanceDir) { int returnCode = -1; BOOL mayHaveStopped = FALSE; int childPid; @@ -459,15 +544,33 @@ if (childPid != 0) { if (killProcess(childPid)) { returnCode = 0; deletePidFile(instanceDir); } mayHaveStopped = killProcess(childPid); } else { debug("Could not stop the server running at root '%s' because the pid could not be located.", instanceDir); // The pid file is typically missing because the server has already // stopped (or is stopping right now): the lock probe below gives the // definitive answer. debug("Could not locate the pid of the server running at root '%s': relying on the server lock alone.", instanceDir); mayHaveStopped = TRUE; } if (mayHaveStopped) { if (waitForLockRelease(instanceDir)) { returnCode = 0; if (childPid != 0) { deletePidFile(instanceDir); } } else { char * msg = "The server at '%s' is still running: it did not release the server lock.\n"; debugError(msg, instanceDir); fprintf(stderr, msg, instanceDir); } } return returnCode; opendj-server-legacy/src/build-tools/windows/winlauncher.h
@@ -12,11 +12,16 @@ * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2026 3A Systems, LLC. */ #include "common.h" #include <errno.h> #include <fcntl.h> #include <io.h> #include <stdio.h> #include <stdlib.h> #include <sys/locking.h> #include <sys/stat.h> #include <process.h> opendj-server-legacy/src/main/java/org/opends/server/backends/cassandra/Storage.java
@@ -11,7 +11,7 @@ * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2023-2024 3A Systems, LLC. * Copyright 2023-2026 3A Systems, LLC. */ package org.opends.server.backends.cassandra; @@ -147,11 +147,11 @@ } String getKeyspaceName() { return "\""+System.getProperty("keyspace",config.getDBDirectory()).replaceAll("[^a-zA-z0-9_]", "_")+"\""; return "\""+System.getProperty("keyspace",config.getDBDirectory()).replaceAll("[^a-zA-Z0-9_]", "_")+"\""; } String getTableName() { return getKeyspaceName()+".\""+config.getBackendId().replaceAll("[^a-zA-z0-9_]", "_")+"\""; return getKeyspaceName()+".\""+config.getBackendId().replaceAll("[^a-zA-Z0-9_]", "_")+"\""; } @Override opendj-server-legacy/src/main/java/org/opends/server/tools/ConfigureDS.java
@@ -13,6 +13,7 @@ * * Copyright 2006-2009 Sun Microsystems, Inc. * Portions Copyright 2012-2016 ForgeRock AS. * Portions Copyright 2026 3A Systems, LLC. */ package org.opends.server.tools; @@ -1291,10 +1292,12 @@ */ private static String getAlternativeCipher() { // Only OAEP variants belong here: RSA with PKCS#1 v1.5 padding is vulnerable to // Bleichenbacher-style padding oracle attacks and must not be used to wrap the // CryptoManager secret keys. final String[] preferredAlternativeCiphers = { "RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING", "RSA/ECB/PKCS1Padding" "RSA/ECB/OAEPWITHSHA1ANDMGF1PADDING" }; for (final String cipher : preferredAlternativeCiphers) { opendj-server-legacy/src/snmp/src/org/opends/server/snmp/SNMPMonitor.java
@@ -13,7 +13,7 @@ * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2012-2014 ForgeRock AS. * Portions Copyright 2024 3A Systems, LLC. * Portions Copyright 2024-2026 3A Systems, LLC. */ package org.opends.server.snmp; @@ -426,7 +426,7 @@ */ private static long pow(long x, long y) { int j = 1; long j = 1; long k = x; if (y == 0) {