Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package 389-ds for openSUSE:Factory checked 
in at 2022-02-02 22:40:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/389-ds (Old)
 and      /work/SRC/openSUSE:Factory/.389-ds.new.1898 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "389-ds"

Wed Feb  2 22:40:56 2022 rev:52 rq:950581 version:2.0.14~git3.c9226ad90

Changes:
--------
--- /work/SRC/openSUSE:Factory/389-ds/389-ds.changes    2022-01-25 
17:37:24.721779808 +0100
+++ /work/SRC/openSUSE:Factory/.389-ds.new.1898/389-ds.changes  2022-02-02 
22:41:59.403297459 +0100
@@ -1,0 +2,41 @@
+Wed Feb 02 02:33:42 UTC 2022 - william.br...@suse.com
+
+- Update to version 2.0.14~git3.c9226ad90:
+  * Issue 4299 - UI - fix minor issues with ldap editor (table view)
+  * Issue 4299 - UI - fix minor issues with ldap editor
+  * Issue 5103 - UI - Add support for TPR to web console (#5111)
+- Add improvements for suppor config to show certificate usage
+
+-------------------------------------------------------------------
+Tue Feb 01 00:32:18 UTC 2022 - william.br...@suse.com
+
+- Update to version 2.0.14~git0.eccfa2af9:
+  * Bump version to 2.0.14
+  * Issue 5127 - ds_selinux_restorecon.sh: always exit 0
+  * Issue 5037 - in OpenQA changelog trimming can crashes (#5070)
+  * Issue 4992 - BUG - slapd.socket container fix (#4993)
+  * Issue 5079 - BUG - multiple ways to specific primary (#5087)
+  * Issue 5080 - BUG - multiple index types not handled in openldap migration 
(#5094)
+  * Issue 5135 - UI - Disk monitoring threshold does update properly
+
+-------------------------------------------------------------------
+Tue Jan 25 03:13:29 UTC 2022 - William Brown <william.br...@suse.com>
+
+- Update support config to latest version
+
+-------------------------------------------------------------------
+Tue Jan 25 03:03:03 UTC 2022 - william.br...@suse.com
+
+- Update to version 2.0.13~git1.72eb93ac9:
+  * Issue 5129 - BUG - Incorrect fn signature in add_index (#5130)
+  * Bump version to 2.0.13
+  * Issue 5132 - Update Rust crate lru to fix CVE
+  * Issue 3555 - UI - fix audit issue with npm nanoid
+  * Issue 4299 - UI - Add ACI editing features
+  * Issue 4299 - UI LDAP editor - add "edit" and "rename" functionality
+  * Issue 5127 - run restorecon on /dev/shm at server startup
+  * Issue 5124 - dscontainer fails to create an instance
+  * Issue 4312 - fix compiler warning
+  * Issue 5115 -  AttributeError: type object 'build_manpages' has no 
attribute 'build_manpages'
+
+-------------------------------------------------------------------

Old:
----
  389-ds-base-2.0.13~git1.72eb93ac9.tar.xz
  supportutils-plugin-dirsrv-v0.1.0~git0.37cb939.tar.xz

New:
----
  389-ds-base-2.0.14~git3.c9226ad90.tar.xz
  supportutils-plugin-dirsrv-v0.1.0~git2.4c54cf4.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ 389-ds.spec ++++++
--- /var/tmp/diff_new_pack.XuFJha/_old  2022-02-02 22:42:01.139285693 +0100
+++ /var/tmp/diff_new_pack.XuFJha/_new  2022-02-02 22:42:01.143285665 +0100
@@ -33,7 +33,7 @@
 %define svrcorelib libsvrcore0
 
 Name:           389-ds
-Version:        2.0.13~git1.72eb93ac9
+Version:        2.0.14~git3.c9226ad90
 Release:        0
 Summary:        389 Directory Server
 License:        GPL-3.0-or-later AND MPL-2.0
@@ -43,7 +43,7 @@
 Source1:        extra-schema.tgz
 Source2:        LICENSE.openldap
 Source3:        vendor.tar.xz
-Source4:        supportutils-plugin-dirsrv-v0.1.0~git0.37cb939.tar.xz
+Source4:        supportutils-plugin-dirsrv-v0.1.0~git2.4c54cf4.tar.xz
 Source5:        70yast.ldif
 Source9:        %{name}-rpmlintrc
 Source10:       %{user_group}-user.conf

++++++ 389-ds-base-2.0.13~git1.72eb93ac9.tar.xz -> 
389-ds-base-2.0.14~git3.c9226ad90.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/389-ds-base-2.0.13~git1.72eb93ac9/VERSION.sh 
new/389-ds-base-2.0.14~git3.c9226ad90/VERSION.sh
--- old/389-ds-base-2.0.13~git1.72eb93ac9/VERSION.sh    2022-01-25 
01:49:42.000000000 +0100
+++ new/389-ds-base-2.0.14~git3.c9226ad90/VERSION.sh    2022-02-01 
23:35:34.000000000 +0100
@@ -10,7 +10,7 @@
 # PACKAGE_VERSION is constructed from these
 VERSION_MAJOR=2
 VERSION_MINOR=0
-VERSION_MAINT=13
+VERSION_MAINT=14
 # NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
 VERSION_PREREL=
 VERSION_DATE=$(date -u +%Y%m%d)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/dirsrvtests/tests/data/openldap_2_389/1/slapd.d/cn=config/olcDatabase={1}mdb.ldif
 
new/389-ds-base-2.0.14~git3.c9226ad90/dirsrvtests/tests/data/openldap_2_389/1/slapd.d/cn=config/olcDatabase={1}mdb.ldif
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/dirsrvtests/tests/data/openldap_2_389/1/slapd.d/cn=config/olcDatabase={1}mdb.ldif
     2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/dirsrvtests/tests/data/openldap_2_389/1/slapd.d/cn=config/olcDatabase={1}mdb.ldif
     2022-02-01 23:35:34.000000000 +0100
@@ -9,6 +9,7 @@
 olcRootDN: cn=Manager,dc=example,dc=com
 olcRootPW:: c2VjcmV0
 olcDbIndex: objectClass eq
+olcDbIndex: uid eq,pres,sub
 structuralObjectClass: olcMdbConfig
 entryUUID: 401a528e-eaf5-1039-8667-dbfbf2f5e6dd
 creatorsName: cn=config
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/dirsrvtests/tests/suites/openldap_2_389/migrate_test.py
 
new/389-ds-base-2.0.14~git3.c9226ad90/dirsrvtests/tests/suites/openldap_2_389/migrate_test.py
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/dirsrvtests/tests/suites/openldap_2_389/migrate_test.py
       2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/dirsrvtests/tests/suites/openldap_2_389/migrate_test.py
       2022-02-01 23:35:34.000000000 +0100
@@ -39,11 +39,20 @@
 
     # Do we have databases?
     assert len(config.databases) == 2
+    # Check that we unpacked uid eq,pres,sub correctly.
+    assert len(config.databases[0].index) == 4
+    assert ('objectClass', 'eq') in config.databases[0].index
+    assert ('uid', 'eq') in config.databases[0].index
+    assert ('uid', 'pres') in config.databases[0].index
+    assert ('uid', 'sub') in config.databases[0].index
 
     # Did our schema parse?
     assert any(['suseModuleConfiguration' in x.names for x in 
config.schema.classes])
 
 
+
+
+
 @pytest.mark.skipif(ds_is_older('1.4.3'), reason="Not implemented")
 def test_migrate_openldap_slapdd(topology_st):
     """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/ldap/servers/plugins/replication/cl5_api.c
 
new/389-ds-base-2.0.14~git3.c9226ad90/ldap/servers/plugins/replication/cl5_api.c
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/ldap/servers/plugins/replication/cl5_api.c
    2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/ldap/servers/plugins/replication/cl5_api.c
    2022-02-01 23:35:34.000000000 +0100
@@ -125,6 +125,9 @@
     Slapi_Counter *clThreads; /* track threads operating on the changelog */
     pthread_mutex_t clLock; /* controls access to trimming configuration  and 
*/
                             /* lock associated to clVar, used to notify 
threads on close */
+    int32_t trimmingOnGoing; /* it is a flag to indicate that a trimming 
thread is started
+                              * and to prevent another trimming thread to start
+                              */
     pthread_cond_t clCvar; /* Condition Variable used to notify threads on 
close */
     pthread_condattr_t clCAttr; /* the pthread condition attr */
     void *clcrypt_handle;   /* for cl encryption */
@@ -1274,6 +1277,7 @@
     }
     cldb->clThreads = slapi_counter_new();
     cldb->dbState = CL5_STATE_OPEN;
+    cldb->trimmingOnGoing = 0;
 
     if (pthread_mutex_init(&(cldb->stLock), NULL) != 0) {
         slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name_cl,
@@ -2192,13 +2196,33 @@
     struct timespec prev_time = {0};
     Replica *replica = (Replica *)param;
     cldb_Handle *cldb = replica_get_cl_info(replica);
-    int32_t trimInterval = cldb->clConf.trimInterval;
+    int32_t trimInterval;
+
+    if (cldb == NULL) {
+        /* This can happened in race condition
+         * when the cldb_SetReplicaDB is called but the
+         * dispatching of_cl5TrimMain thread is slow.
+         * So trimming could be have been stopped (ruv reload) that
+         * clears the cldb
+         */
+        return 0;
+    }
+    trimInterval = cldb->clConf.trimInterval;
 
     /* Get the initial current time for checking the trim interval */
     clock_gettime(CLOCK_MONOTONIC, &prev_time);
 
     /* Lock the CL state, and bump the thread count */
     pthread_mutex_lock(&(cldb->stLock));
+
+    /* First check that no other trimming thread is running */
+    if (cldb->trimmingOnGoing) {
+        pthread_mutex_unlock(&(cldb->stLock));
+        return 0;
+    }
+
+    /* Now trimming thread can start */
+    cldb->trimmingOnGoing = 1;
     slapi_counter_increment(cldb->clThreads);
 
     while (cldb->dbState == CL5_STATE_OPEN)
@@ -2222,6 +2246,7 @@
         pthread_mutex_lock(&(cldb->stLock));
     }
     slapi_counter_decrement(cldb->clThreads);
+    cldb->trimmingOnGoing = 0;
 
     pthread_mutex_unlock(&(cldb->stLock));
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/ldap/servers/plugins/replication/repl5_agmt.c
 
new/389-ds-base-2.0.14~git3.c9226ad90/ldap/servers/plugins/replication/repl5_agmt.c
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/ldap/servers/plugins/replication/repl5_agmt.c
 2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/ldap/servers/plugins/replication/repl5_agmt.c
 2022-02-01 23:35:34.000000000 +0100
@@ -482,7 +482,9 @@
 
     /* DBDB: review this code */
     if (slapi_entry_attr_hasvalue(e, "objectclass", 
"nsDSWindowsReplicationAgreement")) {
-        if (replica_get_type(replica) == REPLICA_TYPE_PRIMARY) {
+        if (replica_get_type(replica) == REPLICA_TYPE_PRIMARY
+           || (replica_get_type(replica) == REPLICA_TYPE_UPDATABLE && 
replica_is_flag_set(replica, REPLICA_LOG_CHANGES))
+        ) {
             ra->agreement_type = REPLICA_TYPE_WINDOWS;
             windows_init_agreement_from_entry(ra, e);
         } else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/ldap/servers/slapd/libglobs.c 
new/389-ds-base-2.0.14~git3.c9226ad90/ldap/servers/slapd/libglobs.c
--- old/389-ds-base-2.0.13~git1.72eb93ac9/ldap/servers/slapd/libglobs.c 
2022-01-25 01:49:42.000000000 +0100
+++ new/389-ds-base-2.0.14~git3.c9226ad90/ldap/servers/slapd/libglobs.c 
2022-02-01 23:35:34.000000000 +0100
@@ -2178,9 +2178,9 @@
 
     errno = 0;
     threshold = strtoll(value, &endp, 10);
-    if (*endp != '\0' || threshold <= 4096 || errno == ERANGE) {
+    if (*endp != '\0' || threshold < 4096 || errno == ERANGE) {
         slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
-                              "%s: \"%s\" is invalid, threshold must be 
greater than 4096 and less then %lld",
+                              "%s: \"%s\" is invalid, threshold must be 
greater than or equal to 4096 and less then %lld",
                               attrname, value, (long long int)LONG_MAX);
         retVal = LDAP_OPERATIONS_ERROR;
         return retVal;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/LDAPEditor.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/LDAPEditor.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/LDAPEditor.jsx
    2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/LDAPEditor.jsx
    2022-02-01 23:35:34.000000000 +0100
@@ -192,7 +192,8 @@
     handleReload(refresh) {
         const params = {
             serverId: this.props.serverId,
-            baseDn: this.state.baseDN
+            baseDn: this.state.baseDN,
+            addNotification: this.props.addNotification,
         };
 
         this.setState({
@@ -209,7 +210,8 @@
                 const params = {
                     serverId: this.props.serverId,
                     baseDn: suffixDN,
-                    parentId: parentId
+                    parentId: parentId,
+                    addNotification: this.props.addNotification,
                 };
 
                 getRootSuffixEntryDetails(params, 
this.updateTableRootSuffixes);
@@ -305,7 +307,8 @@
             });
             const params = {
                 serverId: this.props.serverId,
-                baseDn: id
+                baseDn: id,
+                addNotification: this.props.addNotification,
             };
             getOneLevelEntries(params, this.processDirectChildren);
         }
@@ -365,18 +368,20 @@
         });
         const params = {
             serverId: this.props.serverId,
-            baseDn: dn
+            baseDn: dn,
+            addNotification: this.props.addNotification,
         };
         getOneLevelEntries(params, this.processDirectChildren);
     }
 
     // Process the entries that are direct children.
-    processDirectChildren = (directChildren) => {
+    processDirectChildren = (directChildren, params) => {
         this.setState({
             loading: true
         });
         const childrenRows = [];
         let rowNumber = 0;
+
         directChildren.map(aChild => {
             const info = JSON.parse(aChild);
             const numSubCellInfo = parseInt(info.numSubordinates) > 0
@@ -647,7 +652,8 @@
                 const params = {
                     serverId: this.props.serverId,
                     baseDn: suffixDN,
-                    parentId: parentId
+                    parentId: parentId,
+                    addNotification: this.props.addNotification,
                 };
                 getRootSuffixEntryDetails(params, 
this.updateTableRootSuffixes);
                 parentId += 2; // The next DN row will be two rows below.
@@ -767,6 +773,7 @@
                     });
                 }
             },
+            /*
             {
                 title: 'Roles ...',
                 isDisabled: true,
@@ -780,6 +787,7 @@
                 title: 'Smart Referrals ...',
                 isDisabled: true
             },
+            */
             {
                 isSeparator: true
             },
@@ -881,22 +889,25 @@
                             onReload={this.handleReload}
                             refreshing={this.state.refreshing}
                             allObjectclasses={this.state.allObjectclasses}
+                            addNotification={this.props.addNotification}
                         />
                     </Tab>
                     <Tab eventKey={1} title={<TabTitleText>Table 
View</TabTitleText>}>
-                        <Breadcrumb className="ds-left-margin 
ds-margin-top-xlg">
-                            {navItems.map(({ id, to, label, active }) => (
-                                <BreadcrumbItem key={id + label} to={to} 
isActive={active} onClick={() => this.onNavItemClick(id, active) }>
-                                    {label}
-                                </BreadcrumbItem>
-                            ))}
-                        </Breadcrumb>
-                        <FontAwesomeIcon
-                            className="ds-left-margin ds-refresh"
-                            icon={faSyncAlt}
-                            title="Refresh"
-                            onClick={this.handleReload}
-                        />
+                        <div className={this.state.searching ? "ds-disabled" : 
""}>
+                            <Breadcrumb className="ds-left-margin 
ds-margin-top-xlg">
+                                {navItems.map(({ id, to, label, active }) => (
+                                    <BreadcrumbItem key={id + label} to={to} 
isActive={active} onClick={() => this.onNavItemClick(id, active) }>
+                                        {label}
+                                    </BreadcrumbItem>
+                                ))}
+                            </Breadcrumb>
+                            <FontAwesomeIcon
+                                className="ds-left-margin ds-refresh"
+                                icon={faSyncAlt}
+                                title="Refresh"
+                                onClick={this.handleReload}
+                            />
+                        </div>
                         <div className={this.state.searching ? 
"ds-margin-top-xlg ds-center" : "ds-hidden"}>
                             <TextContent>
                                 <Text component={TextVariants.h3}>
@@ -920,6 +931,7 @@
                                 onCollapse={this.handleCollapse}
                                 columns={columns}
                                 actionResolver={this.actionResolver}
+                                addNotification={this.props.addNotification}
                             />
                         </div>
                     </Tab>
@@ -931,6 +943,7 @@
                             attributes={this.state.attributes}
                             searchBase={this.state.searchBase}
                             allObjectclasses={this.state.allObjectclasses}
+                            addNotification={this.props.addNotification}
                         />
                     </Tab>
                 </Tabs>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/database/globalPwp.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/database/globalPwp.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/database/globalPwp.jsx
        2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/database/globalPwp.jsx
        2022-02-01 23:35:34.000000000 +0100
@@ -2,9 +2,11 @@
 import React from "react";
 import { log_cmd } from "../tools.jsx";
 import {
+    Alert,
     Button,
     Checkbox,
     Form,
+    FormAlert,
     FormSelect,
     FormSelectOption,
     Grid,
@@ -19,7 +21,7 @@
     TextInput,
     Text,
     TextContent,
-    TextVariants,
+    TextVariants
 } from "@patternfly/react-core";
 import PropTypes from "prop-types";
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
@@ -80,6 +82,12 @@
     "passworddictcheck",
 ];
 
+const tpr_attrs = [
+    "passwordtprmaxuse",
+    "passwordtprdelayexpireat",
+    "passwordtprdelayvalidfrom",
+];
+
 export class GlobalPwPolicy extends React.Component {
     constructor(props) {
         super(props);
@@ -97,6 +105,7 @@
             saveExpDisabled: true,
             saveLockoutDisabled: true,
             saveSyntaxDisabled: true,
+            saveTPRDisabled: true,
             isSelectOpen: false,
         };
 
@@ -115,6 +124,8 @@
         this.saveLockout = this.saveLockout.bind(this);
         this.handleSyntaxChange = this.handleSyntaxChange.bind(this);
         this.saveSyntax = this.saveSyntax.bind(this);
+        this.handleTPRChange = this.handleTPRChange.bind(this);
+        this.saveTPR = this.saveTPR.bind(this);
         this.loadGlobal = this.loadGlobal.bind(this);
         // Select Typeahead
         this.onSelectToggle = this.onSelectToggle.bind(this);
@@ -512,6 +523,76 @@
                 });
     }
 
+    handleTPRChange(e) {
+        const value = e.target.value;
+        const attr = e.target.id;
+        let disableSaveBtn = true;
+
+        // Check if a setting was changed, if so enable the save button
+        for (const tpr_attr of tpr_attrs) {
+            if (attr == tpr_attr && this.state['_' + tpr_attr] != value) {
+                disableSaveBtn = false;
+                break;
+            }
+        }
+
+        // Now check for differences in values that we did not touch
+        for (const tpr_attr of tpr_attrs) {
+            if (attr != tpr_attr && this.state['_' + tpr_attr] != 
this.state[tpr_attr]) {
+                disableSaveBtn = false;
+                break;
+            }
+        }
+
+        this.setState({
+            [attr]: value,
+            saveTPRDisabled: disableSaveBtn,
+        });
+    }
+
+    saveTPR() {
+        this.setState({
+            saving: true
+        });
+
+        const cmd = [
+            'dsconf', '-j', "ldapi://%2fvar%2frun%2fslapd-" + 
this.props.serverId + ".socket",
+            'config', 'replace'
+        ];
+
+        for (const attr of tpr_attrs) {
+            if (this.state['_' + attr] != this.state[attr]) {
+                let val = this.state[attr];
+                cmd.push(attr + "=" + val);
+            }
+        }
+
+        log_cmd("saveTPR", "Saving TPR settings", cmd);
+        cockpit
+                .spawn(cmd, { superuser: true, err: "message" })
+                .done(content => {
+                    this.loadGlobal();
+                    this.setState({
+                        saving: false
+                    });
+                    this.props.addNotification(
+                        "success",
+                        "Successfully updated password policy configuration"
+                    );
+                })
+                .fail(err => {
+                    const errMsg = JSON.parse(err);
+                    this.loadGlobal();
+                    this.setState({
+                        saving: false
+                    });
+                    this.props.addNotification(
+                        "error",
+                        `Error updating password policy configuration - 
${errMsg.desc}`
+                    );
+                });
+    }
+
     loadGlobal() {
         this.setState({
             loading: true
@@ -618,6 +699,7 @@
                             saveExpDisabled: true,
                             saveLockoutDisabled: true,
                             saveSyntaxDisabled: true,
+                            saveTPRDisabled: true,
                             // Settings
                             'nsslapd-pwpolicy-local': pwpLocal,
                             passwordisglobalpolicy: pwIsGlobal,
@@ -659,6 +741,9 @@
                             passwordbadwords: attrs.passwordbadwords[0],
                             passworduserattributes: pwUserAttrs,
                             passwordadmindn: attrs.passwordadmindn[0],
+                            passwordtprmaxuse: attrs.passwordtprmaxuse[0],
+                            passwordtprdelayexpireat: 
attrs.passwordtprdelayexpireat[0],
+                            passwordtprdelayvalidfrom: 
attrs.passwordtprdelayvalidfrom[0],
                             // Record original values
                             '_nsslapd-pwpolicy-local': pwpLocal,
                             _passwordisglobalpolicy: pwIsGlobal,
@@ -700,6 +785,9 @@
                             _passwordbadwords: attrs.passwordbadwords[0],
                             _passworduserattributes: pwUserAttrs,
                             _passwordadmindn: attrs.passwordadmindn[0],
+                            _passwordtprmaxuse: attrs.passwordtprmaxuse[0],
+                            _passwordtprdelayexpireat: 
attrs.passwordtprdelayexpireat[0],
+                            _passwordtprdelayvalidfrom: 
attrs.passwordtprdelayvalidfrom[0],
                         }), this.props.enableTree()
                     );
                 })
@@ -1423,6 +1511,97 @@
                                 isLoading={this.state.saving}
                                 spinnerAriaValueText={this.state.saving ? 
"Saving" : undefined}
                                 {...extraPrimaryProps}
+                            >
+                                {saveBtnName}
+                            </Button>
+                        </Tab>
+                        <Tab eventKey={4} title={<TabTitleText>Temporary 
Password Rules</TabTitleText>}>
+                            <Form className="ds-margin-top ds-margin-left" 
isHorizontal autoComplete="off">
+                                {this.state.passwordmustchange == false && (
+                                <FormAlert>
+                                    <Alert
+                                        variant="info"
+                                        title='"User Must Change Password 
After Reset" must be enabled in General Settings to activate TPR.'
+                                        aria-live="polite"
+                                        isInline
+                                    />
+                                </FormAlert>
+                                 )}
+                                <Grid
+                                    title="Number of times the temporary 
password can be used to authenticate (passwordTPRMaxUse)."
+                                >
+                                    <GridItem className="ds-label" span={3}>
+                                        Password Max Use
+                                    </GridItem>
+                                    <GridItem span={9}>
+                                        <TextInput
+                                            
value={this.state.passwordtprmaxuse}
+                                            type="number"
+                                            id="passwordtprmaxuse"
+                                            
aria-describedby="horizontal-form-name-helper"
+                                            name="passwordtprmaxuse"
+                                            
isDisabled={!this.state.passwordmustchange}
+                                            onChange={(checked, e) => {
+                                                this.handleTPRChange(e);
+                                            }}
+                                        />
+                                    </GridItem>
+                                </Grid>
+                                {pwSyntaxRows}
+                            </Form>
+                            <Form className="ds-margin-top ds-margin-left" 
isHorizontal autoComplete="off">
+                                <Grid
+                                    title="Number of seconds before the 
temporary password expires (passwordTPRDelayExpireAt)."
+                                >
+                                    <GridItem className="ds-label" span={3}>
+                                        Password Expires In
+                                    </GridItem>
+                                    <GridItem span={9}>
+                                        <TextInput
+                                            
value={this.state.passwordtprdelayexpireat}
+                                            type="number"
+                                            id="passwordtprdelayexpireat"
+                                            
aria-describedby="horizontal-form-name-helper"
+                                            name="passwordtprdelayexpireat"
+                                            
isDisabled={!this.state.passwordmustchange}
+                                            onChange={(checked, e) => {
+                                                this.handleTPRChange(e);
+                                            }}
+                                        />
+                                    </GridItem>
+                                </Grid>
+                            </Form>
+                            <Form className="ds-margin-top ds-margin-left" 
isHorizontal autoComplete="off">
+                                <Grid
+                                    title="Number of seconds after which 
temporary password starts to be valid for authentication 
(passwordTPRDelayValidFrom)."
+                                >
+                                    <GridItem className="ds-label" span={3}>
+                                        Password Valid From
+                                    </GridItem>
+                                    <GridItem span={9}>
+                                        <TextInput
+                                            
value={this.state.passwordtprdelayvalidfrom}
+                                            type="number"
+                                            id="passwordtprdelayvalidfrom"
+                                            
aria-describedby="horizontal-form-name-helper"
+                                            name="passwordtprdelayvalidfrom"
+                                            
isDisabled={!this.state.passwordmustchange}
+                                            onChange={(checked, e) => {
+                                                this.handleTPRChange(e);
+                                            }}
+                                        />
+                                    </GridItem>
+                                </Grid>
+                                {pwSyntaxRows}
+                            </Form>
+                            <Button
+                                isDisabled={this.state.saveTPRDisabled}
+                                variant="primary"
+                                className="ds-margin-top-xlg ds-margin-left"
+                                onClick={this.saveTPR}
+                                isLoading={this.state.saving}
+                                spinnerAriaValueText={this.state.saving ? 
"Saving" : undefined}
+                                {...extraPrimaryProps}
                             >
                                 {saveBtnName}
                             </Button>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/database/localPwp.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/database/localPwp.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/database/localPwp.jsx
 2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/database/localPwp.jsx
 2022-02-01 23:35:34.000000000 +0100
@@ -4,10 +4,12 @@
 import { DoubleConfirmModal } from "../notifications.jsx";
 import { PwpTable } from "./databaseTables.jsx";
 import {
+    Alert,
     Button,
     Checkbox,
     ExpandableSection,
     Form,
+    FormAlert,
     FormHelperText,
     FormSelect,
     FormSelectOption,
@@ -81,6 +83,12 @@
     "passworddictcheck",
 ];
 
+const tpr_attrs = [
+    "passwordtprmaxuse",
+    "passwordtprdelayexpireat",
+    "passwordtprdelayvalidfrom",
+];
+
 class CreatePolicy extends React.Component {
     constructor(props) {
         super(props);
@@ -89,6 +97,7 @@
             isGeneralExpanded: false,
             isLockoutExpanded: false,
             isSyntaxExpanded: false,
+            isTPRExpanded: false,
         };
 
         this.onGeneralToggle = (isGeneralExpanded) => {
@@ -111,6 +120,11 @@
                 isSyntaxExpanded
             });
         };
+        this.onTPRToggle = (isTPRExpanded) => {
+            this.setState({
+                isTPRExpanded
+            });
+        };
     }
 
     render() {
@@ -768,6 +782,85 @@
                             </div>
                         </div>
                     </ExpandableSection>
+                    <ExpandableSection
+                        className="ds-margin-top-lg"
+                        toggleText={this.state.isTPRExpanded ? 'Hide Temporary 
Password Settings' : 'Show Temporary Password Settings'}
+                        onToggle={this.onTPRToggle}
+                        isExpanded={this.state.isTPRExpanded}
+                    >
+                        <div className="ds-margin-left">
+                                {this.props.create_passwordmustchange == false 
&& (
+                                <FormAlert>
+                                    <Alert
+                                        variant="info"
+                                        title='"User Must Change Password 
After Reset" must be enabled in General Settings to activate TPR.'
+                                        aria-live="polite"
+                                        isInline
+                                    />
+                                </FormAlert>
+                                 )}
+                            <Grid
+                                title="Number of times the temporary password 
can be used to authenticate (passwordTPRMaxUse)."
+                                className="ds-margin-top"
+                            >
+                                <GridItem className="ds-label" span={3}>
+                                    Password Max Use
+                                </GridItem>
+                                <GridItem span={9}>
+                                    <TextInput
+                                        type="number"
+                                        id="create_passwordtprmaxuse"
+                                        
aria-describedby="horizontal-form-name-helper"
+                                        name="create_passwordtprmaxuse"
+                                        
isDisabled={!this.props.create_passwordmustchange}
+                                        onChange={(checked, e) => {
+                                            this.props.handleChange(e);
+                                        }}
+                                    />
+                                </GridItem>
+                            </Grid>
+                            <Grid
+                                title="Number of seconds before the temporary 
password expires (passwordTPRDelayExpireAt)."
+                                className="ds-margin-top"
+                            >
+                                <GridItem className="ds-label" span={3}>
+                                    Password Expires In
+                                </GridItem>
+                                <GridItem span={9}>
+                                    <TextInput
+                                        type="number"
+                                        id="create_passwordtprdelayexpireat"
+                                        
aria-describedby="horizontal-form-name-helper"
+                                        name="create_passwordtprdelayexpireat"
+                                        
isDisabled={!this.props.create_passwordmustchange}
+                                        onChange={(checked, e) => {
+                                            this.props.handleChange(e);
+                                        }}
+                                    />
+                                </GridItem>
+                            </Grid>
+                            <Grid
+                                title="Number of seconds after which temporary 
password starts to be valid for authentication (passwordTPRDelayValidFrom)."
+                                className="ds-margin-top"
+                            >
+                                <GridItem className="ds-label" span={3}>
+                                    Password Valid From
+                                </GridItem>
+                                <GridItem span={9}>
+                                    <TextInput
+                                        type="number"
+                                        id="create_passwordtprdelayvalidfrom"
+                                        
aria-describedby="horizontal-form-name-helper"
+                                        name="create_passwordtprdelayvalidfrom"
+                                        
isDisabled={!this.props.create_passwordmustchange}
+                                        onChange={(checked, e) => {
+                                            this.props.handleChange(e);
+                                        }}
+                                    />
+                                </GridItem>
+                            </Grid>
+                        </div>
+                    </ExpandableSection>
                 </Form>
                 <Button
                     isDisabled={this.props.createDisabled}
@@ -810,6 +903,7 @@
             saveExpDisabled: true,
             saveLockoutDisabled: true,
             saveSyntaxDisabled: true,
+            saveTPRDisabled: true,
             showDeletePolicy: false,
             // Edit policy
             passwordchange: false,
@@ -847,6 +941,9 @@
             passwordmintokenlength: "0",
             passwordbadwords: "",
             passworduserattributes: [],
+            passwordtprmaxuse: "-1",
+            passwordtprdelayexpireat:  "-1",
+            passwordtprdelayvalidfrom:  "-1",
             _passwordchange: false,
             _passwordmustchange: false,
             _passwordhistory: false,
@@ -882,6 +979,9 @@
             _passwordmintokenlength: "0",
             _passwordbadwords: "",
             _passworduserattributes: [],
+            _passwordtprmaxuse: "-1",
+            _passwordtprdelayexpireat:  "-1",
+            _passwordtprdelayvalidfrom:  "-1",
             // Create policy
             create_passwordchange: false,
             create_passwordmustchange: false,
@@ -918,6 +1018,9 @@
             create_passwordmintokenlength: "0",
             create_passwordbadwords: "",
             create_passworduserattributes: [],
+            create_passwordtprmaxuse: "-1",
+            create_passwordtprdelayexpireat:  "-1",
+            create_passwordtprdelayvalidfrom:  "-1",
             _create_passwordchange: false,
             _create_passwordmustchange: false,
             _create_passwordhistory: false,
@@ -953,6 +1056,9 @@
             _create_passwordmintokenlength: "0",
             _create_passwordbadwords: "",
             _create_passworduserattributes: [],
+            _create_passwordtprmaxuse: "-1",
+            _create_passwordtprdelayexpireat:  "-1",
+            _create_passwordtprdelayvalidfrom:  "-1",
             // Select typeahead
             isUserAttrsCreateOpen: false,
             isUserAttrsEditOpen: false,
@@ -994,6 +1100,9 @@
                 passworduserattributes: "--pwduserattrs",
                 passworddictcheck: "--pwddictcheck",
                 passwordadmindn: "--pwdadmin",
+                passwordtprmaxuse: "--pwptprmaxuse",
+                passwordtprdelayexpireat:  "--pwptprdelayexpireat",
+                passwordtprdelayvalidfrom:  "--pwptprdelayvalidfrom",
             },
         };
 
@@ -1046,6 +1155,7 @@
         this.handleLockoutChange = this.handleLockoutChange.bind(this);
         this.handleModalChange = this.handleModalChange.bind(this);
         this.handleSyntaxChange = this.handleSyntaxChange.bind(this);
+        this.handleTPRChange = this.handleTPRChange.bind(this);
         this.loadLocal = this.loadLocal.bind(this);
         this.loadPolicies = this.loadPolicies.bind(this);
         this.resetTab = this.resetTab.bind(this);
@@ -1053,6 +1163,7 @@
         this.saveGeneral = this.saveGeneral.bind(this);
         this.saveLockout = this.saveLockout.bind(this);
         this.saveSyntax = this.saveSyntax.bind(this);
+        this.saveTPR = this.saveTPR.bind(this);
         this.showDeletePolicy = this.showDeletePolicy.bind(this);
     }
 
@@ -1105,7 +1216,7 @@
         let value;
         let disableSaveBtn = true;
         let invalid_dn = false;
-        const all_attrs = general_attrs.concat(exp_attrs, lockout_attrs, 
syntax_attrs);
+        const all_attrs = general_attrs.concat(exp_attrs, lockout_attrs, 
syntax_attrs, tpr_attrs);
 
         if (selection) {
             attr = "create_passworduserattributes";
@@ -1196,7 +1307,7 @@
     }
 
     createPolicy() {
-        const all_attrs = general_attrs.concat(exp_attrs, lockout_attrs, 
syntax_attrs);
+        const all_attrs = general_attrs.concat(exp_attrs, lockout_attrs, 
syntax_attrs, tpr_attrs);
         let action = "adduser";
 
         this.setState({
@@ -1231,7 +1342,7 @@
                 cmd.push(this.state.attrMap[attr] + "=" + new_val);
             }
         }
-
+      
         log_cmd("createPolicy", "Create a local password policy", cmd);
         cockpit
                 .spawn(cmd, { superuser: true, err: "message" })
@@ -1609,6 +1720,76 @@
                 });
     }
 
+    handleTPRChange(e) {
+        const value = e.target.value;
+        const attr = e.target.id;
+        let disableSaveBtn = true;
+
+        // Check if a setting was changed, if so enable the save button
+        for (const tpr_attr of tpr_attrs) {
+            if (attr == tpr_attr && this.state['_' + tpr_attr] != value) {
+                disableSaveBtn = false;
+                break;
+            }
+        }
+
+        // Now check for differences in values that we did not touch
+        for (const tpr_attr of tpr_attrs) {
+            if (attr != tpr_attr && this.state['_' + tpr_attr] != 
this.state[tpr_attr]) {
+                disableSaveBtn = false;
+                break;
+            }
+        }
+
+        this.setState({
+            [attr]: value,
+            saveTPRDisabled: disableSaveBtn,
+        });
+    }
+
+    saveTPR() {
+        this.setState({
+            saving: true
+        });
+
+        const cmd = [
+            'dsconf', '-j', "ldapi://%2fvar%2frun%2fslapd-" + 
this.props.serverId + ".socket",
+            'localpwp', 'set', this.state.policyName
+        ];
+
+        for (const attr of tpr_attrs) {
+            if (this.state['_' + attr] != this.state[attr]) {
+                let val = this.state[attr];
+                cmd.push(this.state.attrMap[attr] + "=" + val);
+            }
+        }
+
+        log_cmd("saveTPR", "Saving TPR pwpolicy settings", cmd);
+        cockpit
+                .spawn(cmd, { superuser: true, err: "message" })
+                .done(content => {
+                    this.loadLocal(this.state.policyName);
+                    this.setState({
+                        saving: false
+                    });
+                    this.props.addNotification(
+                        "success",
+                        "Successfully updated password policy configuration"
+                    );
+                })
+                .fail(err => {
+                    const errMsg = JSON.parse(err);
+                    this.loadLocal(this.state.policyName);
+                    this.setState({
+                        saving: false
+                    });
+                    this.props.addNotification(
+                        "error",
+                        `Error updating password policy configuration - 
${errMsg.desc}`
+                    );
+                });
+    }
+
     deletePolicy() {
         this.setState({
             loading: true,
@@ -1873,6 +2054,9 @@
                     let pwMaxClassChars = "0";
                     let pwMinCat = "0";
                     let pwMinTokenLen = "0";
+                    let pwTPRMaxUse = "-1";
+                    let pwTPRDelayExpireAt = "-1";
+                    let pwTPRDelayValidFrom = "-1";
 
                     if ('passwordmintokenlength' in attrs) {
                         pwMinTokenLen = attrs.passwordmintokenlength[0];
@@ -1994,6 +2178,15 @@
                             pwUserAttrs = 
attrs.passworduserattributes[0].split(' ');
                         }
                     }
+                    if ('passwordTPRMaxUse' in attrs) {
+                        pwTPRMaxUse = attrs.passwordTPRMaxUse[0];
+                    }
+                    if ('passwordTPRDelayExpireAt' in attrs) {
+                        pwTPRDelayExpireAt = attrs.passwordTPRDelayExpireAt[0];
+                    }
+                    if ('passwordTPRDelayValidFrom' in attrs) {
+                        pwTPRDelayValidFrom = 
attrs.passwordTPRDelayValidFrom[0];
+                    }
 
                     this.setState(() => (
                         {
@@ -2044,6 +2237,9 @@
                             passwordmintokenlength: pwMinTokenLen,
                             passwordbadwords: pwBadWords,
                             passworduserattributes: pwUserAttrs,
+                            passwordtprmaxuse: pwTPRMaxUse,
+                            passwordtprdelayexpireat: pwTPRDelayExpireAt,
+                            passwordtprdelayvalidfrom: pwTPRDelayValidFrom,
                             // Record original values
                             _passwordchange: pwChange,
                             _passwordmustchange: pwMustChange,
@@ -2080,6 +2276,9 @@
                             _passwordmintokenlength: pwMinTokenLen,
                             _passwordbadwords: pwBadWords,
                             _passworduserattributes: pwUserAttrs,
+                            _passwordtprmaxuse: pwTPRMaxUse,
+                            _passwordtprdelayexpireat: pwTPRDelayExpireAt,
+                            _passwordtprdelayvalidfrom: pwTPRDelayValidFrom,
                         })
                     );
                 })
@@ -2752,6 +2951,97 @@
                                 isLoading={this.state.saving}
                                 spinnerAriaValueText={this.state.saving ? 
"Saving" : undefined}
                                 {...extraPrimaryProps}
+                            >
+                                {saveBtnName}
+                            </Button>
+                        </Tab>
+                        <Tab eventKey={4} title={<TabTitleText>Temporary 
Password Rules</TabTitleText>}>
+                            <Form className="ds-margin-top ds-margin-left" 
isHorizontal autoComplete="off">
+                                {this.state.passwordmustchange == false && (
+                                <FormAlert>
+                                    <Alert
+                                        variant="info"
+                                        title='"User Must Change Password 
After Reset" must be enabled in General Settings to activate TPR.'
+                                        aria-live="polite"
+                                        isInline
+                                    />
+                                </FormAlert>
+                                 )}
+                                <Grid
+                                    title="Number of times the temporary 
password can be used to authenticate (passwordTPRMaxUse)."
+                                >
+                                    <GridItem className="ds-label" span={3}>
+                                        Password Max Use
+                                    </GridItem>
+                                    <GridItem span={9}>
+                                        <TextInput
+                                            
value={this.state.passwordtprmaxuse}
+                                            type="number"
+                                            id="passwordtprmaxuse"
+                                            
aria-describedby="horizontal-form-name-helper"
+                                            name="passwordtprmaxuse"
+                                            
isDisabled={!this.state.passwordmustchange}
+                                            onChange={(checked, e) => {
+                                                this.handleTPRChange(e);
+                                            }}
+                                        />
+                                    </GridItem>
+                                </Grid>
+                                {pwSyntaxRows}
+                            </Form>
+                            <Form className="ds-margin-top ds-margin-left" 
isHorizontal autoComplete="off">
+                                <Grid
+                                    title="Number of seconds before the 
temporary password expires (passwordTPRDelayExpireAt)."
+                                >
+                                    <GridItem className="ds-label" span={3}>
+                                        Password Expires In
+                                    </GridItem>
+                                    <GridItem span={9}>
+                                        <TextInput
+                                            
value={this.state.passwordtprdelayexpireat}
+                                            type="number"
+                                            id="passwordtprdelayexpireat"
+                                            
aria-describedby="horizontal-form-name-helper"
+                                            name="passwordtprdelayexpireat"
+                                            
isDisabled={!this.state.passwordmustchange}
+                                            onChange={(checked, e) => {
+                                                this.handleTPRChange(e);
+                                            }}
+                                        />
+                                    </GridItem>
+                                </Grid>
+                            </Form>
+                            <Form className="ds-margin-top ds-margin-left" 
isHorizontal autoComplete="off">
+                                <Grid
+                                    title="Number of seconds after which 
temporary password starts to be valid for authentication 
(passwordTPRDelayValidFrom)."
+                                >
+                                    <GridItem className="ds-label" span={3}>
+                                        Password Valid From
+                                    </GridItem>
+                                    <GridItem span={9}>
+                                        <TextInput
+                                            
value={this.state.passwordtprdelayvalidfrom}
+                                            type="number"
+                                            id="passwordtprdelayvalidfrom"
+                                            
aria-describedby="horizontal-form-name-helper"
+                                            name="passwordtprdelayvalidfrom"
+                                            
isDisabled={!this.state.passwordmustchange}
+                                            onChange={(checked, e) => {
+                                                this.handleTPRChange(e);
+                                            }}
+                                        />
+                                    </GridItem>
+                                </Grid>
+                                {pwSyntaxRows}
+                            </Form>
+                            <Button
+                                isDisabled={this.state.saveTPRDisabled}
+                                variant="primary"
+                                className="ds-margin-top-xlg ds-margin-left"
+                                onClick={this.saveTPR}
+                                isLoading={this.state.saving}
+                                spinnerAriaValueText={this.state.saving ? 
"Saving" : undefined}
+                                {...extraPrimaryProps}
                             >
                                 {saveBtnName}
                             </Button>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/lib/ldapNavigator.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/lib/ldapNavigator.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/lib/ldapNavigator.jsx
     2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/lib/ldapNavigator.jsx
     2022-02-01 23:35:34.000000000 +0100
@@ -5,6 +5,7 @@
     TreeView
 } from '@patternfly/react-core';
 import {
+    ExclamationTriangleIcon,
     FolderIcon,
     FolderOpenIcon,
     ResourcesEmptyIcon
@@ -34,25 +35,7 @@
         };
 
         this.treeOnClick = (evt, treeViewItem, parentItem) => {
-            if (this.state.ldapFailure) {
-                const result = ldapPing(this.props.editorLdapServer,
-                    (res, obj) => {
-                        if (res) {
-                            this.setState({ ldapFailure: false });
-                            console.log('Can reconnect to the LDAP server. 
Continuing...');
-                        } else {
-                            console.log('Cannot contact the LDAP server! 
Aborting...');
-                            console.log(obj);
-                        }
-                    });
-
-                // Once the server is again reachable, a new click will update 
the tree item(s).
-                // Meanwhile give up for this round.
-                return;
-            }
-
             if (treeViewItem.isFakeEntry) {
-                console.log('Clicked on a loading item. Not processing it...');
                 return;
             }
 
@@ -103,6 +86,10 @@
                         const params = {
                             serverId: this.props.editorLdapServer,
                             baseDn: treeViewItem.dn,
+                            name: treeViewItem.name,
+                            fullEntry: treeViewItem.fullEntry,
+                            modTime: treeViewItem.modTime,
+                            addNotification: this.props.addNotification,
                             filter: this.props.skipLeafEntries
                                 ? 
'(|(&(numSubordinates=*)(numSubordinates>=1))(objectClass=organizationalunit)(objectClass=organization))'
                                 : null // getOneLevelEntries() will use its 
default filter '(|(objectClass=*)(objectClass=ldapSubEntry))'
@@ -122,6 +109,31 @@
                 });
         };
 
+        this.updateMyParent = (treeNode, nodeIdObject, nodeChildren, 
removePreviousChildren) => {
+            const res = nodeIdObject.remainingId.indexOf('.');
+            if (res === -1) {
+                const insertionNode = treeNode.find(elt => elt.id === 
nodeIdObject.fullId);
+                insertionNode.children = nodeChildren;
+                insertionNode.loadChildren = false;
+                insertionNode.customBadgeContent = "?";
+            } else {
+                const parentId = nodeIdObject.remainingId.substring(0, res);
+                const startingId = nodeIdObject.startingId === undefined
+                    ? parentId
+                    : `${nodeIdObject.startingId}.${parentId}`;
+
+                const parentNode = treeNode.find(elt => elt.id === startingId);
+                const remainingId = nodeIdObject.remainingId.substring(res + 
1);
+
+                const newNodeIdObject = {
+                    fullId: nodeIdObject.fullId,
+                    remainingId: remainingId,
+                    startingId: startingId
+                }
+                this.updateMyParent(parentNode.children, newNodeIdObject, 
nodeChildren, removePreviousChildren);
+            }
+        };
+
         this.updateMyChildren = (treeNode, nodeIdObject, childArray, 
removePreviousChildren) => {
             const res = nodeIdObject.remainingId.indexOf('.');
             if (res === -1) {
@@ -310,7 +322,11 @@
                     ? Math.max(...idArray)
                     : 0;
                 const mySubId = maxId + 1;
-                const params = { serverId: this.props.editorLdapServer, 
baseDn: nodeDn };
+                const params = {
+                    serverId: this.props.editorLdapServer,
+                    baseDn: nodeDn,
+                    addNotification: this.props.addNotification,
+                };
 
                 // TODO: Change the name of this function to a more generic 
one!!
                 getRootSuffixEntryDetails(params,
@@ -348,7 +364,7 @@
         }
     }
 
-    updateDirectChildren = (potentialChildren, resCode) => {
+    updateDirectChildren = (potentialChildren, params, resCode) => {
         // When leaf entries ( but Organizations and Organization Units ) 
should be skipped
         // run a search with the relevant filter to get the actual number of 
matching grand children
         // ( children of the direct children of the current entry [ the active 
node ]).
@@ -358,25 +374,30 @@
         }
 
         if (potentialChildren === null) {
-            console.log(resCode);
-            // TODO: Show Modal dialog
+            if (resCode.exit_status !== 0) {
+                this.props.addNotification(
+                    "error",
+                    `Error searching database - 
${resCode.msg.split("\n").pop()}`
+                );
+            }
             return;
         }
 
         const updatedChildren = [];
         let nbIterations = 0;
 
-        const params = {
+        const child_params = {
             serverId: this.props.editorLdapServer,
             scope: 'one',
             attributes: '1.1',
+            addNotification: this.props.addNotification,
             filter: 
'(|(&(numSubordinates=*)(numSubordinates>=1))(objectClass=organizationalunit)(objectClass=organization))'
         };
 
         potentialChildren.map(aChild => {
             const info = JSON.parse(aChild);
             params.baseDn = info.dn;
-            runGenericSearch(params, (resArray) => {
+            runGenericSearch(child_params, (resArray) => {
                 if (resArray.length > 0) {
                     info.showChildren = true;
                 }
@@ -385,21 +406,46 @@
                 nbIterations++;
                 if (nbIterations === potentialChildren.length) {
                     // Now process the selected direct children.
-                    this.processDirectChildren(updatedChildren, null);
+                    this.processDirectChildren(updatedChildren, params, null);
                 }
             });
         });
     }
 
     // Process the entries that are direct children.
-    processDirectChildren = (directChildren, resCode) => {
+    processDirectChildren = (directChildren, params, resCode) => {
+        // Retrieve the selected node from ==> this.state.activeItems: 
[treeViewItem, parentItem]
+        const myActiveNode = this.state.activeItems[0];
+        const myChildren = [];
+        let childId = 0; // Used to quickly locate the node in the tree data.
+
         if (directChildren === null) { // There was a failure to connect to 
the LDAP server.
-            // TODO: Show Modal dialog
-            console.log(resCode);
             this.setState({ ldapFailure: true });
-            this.props.handleNodeOnClick(null);
-            if (resCode.msg.endsWith('Can\'t contact LDAP server (-1)')) {
-                this.props.setServerReachabilityStatus(false, resCode.msg);
+            this.props.showTreeLoadingState(false);
+
+            if (resCode.exit_status !== 0) {
+                this.props.addNotification(
+                    "error",
+                    `Error searching database - 
${resCode.msg.split("\n").pop()}`
+                );
+
+                const randomId = Math.random().toString(36).substring(2, 15);
+                let nodeChildren = [{
+                    name: 'Encountered an error, unable to display child 
entries',
+                    id: randomId,
+                    icon: <ExclamationTriangleIcon />,
+                    isFakeEntry: true
+                }];
+
+                const treeAllItems = this.state.allItems;
+                const parentIdObject = {
+                    fullId: myActiveNode.id,
+                    remainingId: myActiveNode.id
+                }
+                this.updateMyParent(treeAllItems, parentIdObject, 
nodeChildren, true);
+                this.setState({
+                    allItems: treeAllItems
+                });
             }
             return;
         } else {
@@ -408,11 +454,6 @@
             this.setState({ ldapFailure: false });
         }
 
-        // Retrieve the selected node from ==> this.state.activeItems: 
[treeViewItem, parentItem]
-        const myActiveNode = this.state.activeItems[0];
-        const myChildren = [];
-        let childId = 0; // Used to quickly locate the node in the tree data.
-
         for (const aChild of directChildren) {
             const info = JSON.parse(aChild);
             const numSubValue = parseInt(info.numSubordinates);
@@ -477,7 +518,7 @@
                         <div>No Databases</div>
                     </Bullseye>
                 }
-                <div className="ds-editor-tree">
+                <div className={this.props.isDisabled ? "ds-disabled 
ds-editor-tree" : "ds-editor-tree"}>
                     <TreeView
                         data={allItems}
                         onSelect={this.treeOnClick}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/lib/options.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/lib/options.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/lib/options.jsx
   2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/lib/options.jsx
   2022-02-01 23:35:34.000000000 +0100
@@ -1,24 +1,23 @@
 // LDAP options.
 const LdapOptions = {
-  sizeLimit: 1000,
-  timeLimit: 5
+    sizeLimit: 2000,
+    timeLimit: 10
 };
+
 // Size limit.
 export function setSizeLimit (limit) {
-  LdapOptions.sizeLimit = limit;
-  console.log(`LdapOptions.sizeLimit = ${LdapOptions.sizeLimit}`);
+    LdapOptions.sizeLimit = limit;
 };
 
 export function getSizeLimit () {
-  return LdapOptions.sizeLimit;
+    return LdapOptions.sizeLimit;
 }
 
 // Time limit.
 export function setTimeLimit (limit) {
-  LdapOptions.timeLimit = limit;
-  console.log(`LdapOptions.timeLimit = ${LdapOptions.timeLimit}`);
+    LdapOptions.timeLimit = limit;
 };
 
 export function getTimeLimit () {
-  return LdapOptions.timeLimit;
+    return LdapOptions.timeLimit;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/lib/utils.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/lib/utils.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/lib/utils.jsx
     2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/lib/utils.jsx
     2022-02-01 23:35:34.000000000 +0100
@@ -238,6 +238,8 @@
     params.searchScope,
     '-l',
     params.timeLimit,
+    '-z',
+    params.sizeLimit,
     params.searchFilter,
     '*',
     '+'
@@ -258,7 +260,10 @@
       if (err.exit_status === 4) {
         console.log('Size limit hit'); // Use the partial data.
         searchResult = data;
-        // TODO: Check other relevant error codes ( 32, 53 ...)
+        params.addNotification(
+            "info",
+            `Size limit of ${params.sizeLimit} was exceeded.  The child 
entries of "${params.searchBase}" have been truncated.`
+        );
       } else {
         searchResult = null;
         resultCallback(null, { status: err.exit_status, msg: err.message });
@@ -515,17 +520,20 @@
       searchResult = data;
     })
     .catch((err, data) => {
-    // .fail(err => {
       console.log('FAIL err.exit_status ==> ' + err.exit_status);
       console.log('FAIL err.message ==> ' + err.message);
       if (err.exit_status === 4) {
-        console.log('Size limit hit');
         // Use the partial data.
         searchResult = data;
-        // TODO: Check other relevant error codes ( 32, 53 ...)
+        const size_limit = getSizeLimit();
+        params.addNotification(
+            "info",
+            `Size limit of ${size_limit} was exceeded.  The child entries of 
"${params.baseDn}" have been truncated.  ` +
+            `Use the "Search" feature if you want to adjust the size limit and 
retrieve more entries`
+        );
       } else {
         searchResult = null;
-        oneLevelCallback(null, { status: err.exit_status, msg: err.message });
+        oneLevelCallback(null, params, { status: err.exit_status, msg: 
err.message });
       }
     })
     .finally(() => {
@@ -568,7 +576,7 @@
         }
       });
       // Process the list of entries.
-      oneLevelCallback(allEntries, null);
+      oneLevelCallback(allEntries, params, null);
     });
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/search.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/search.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/search.jsx
        2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/search.jsx
        2022-02-01 23:35:34.000000000 +0100
@@ -55,10 +55,11 @@
             searchBase: "",
             searchFilter: "",
             searchScope: "sub",
-            sizeLimit: 1000,
+            sizeLimit: 2000,
             timeLimit: 30,
             isExpanded: false,
             searchSuffix: "",
+            baseDN: "",
             searchType: 'Search Text',
             searchText: "",
             getOperationalAttrs: false,
@@ -201,6 +202,7 @@
                 searchScope: this.state.searchScope,
                 sizeLimit: this.state.sizeLimit,
                 timeLimit: this.state.timeLimit,
+                addNotification: this.props.addNotification,
             };
             getSearchEntries(params, this.processResults);
         };
@@ -256,9 +258,17 @@
     componentDidMount() {
         const suffixList =  this.props.suffixList;
         const searchBase = this.props.searchBase;
+        let baseDN = searchBase;  // Drop down list of selected suffix
+        for (const suffix of suffixList) {
+            if (baseDN.includes(suffix)) {
+                baseDN = suffix;
+                break;
+            }
+        }
         this.setState({
             searchBase: searchBase ? searchBase : suffixList.length > 0 ? 
suffixList[0] : "",
             searchSuffix: this.props.suffixList.length > 0 ? 
this.props.suffixList[0] : "",
+            baseDN: baseDN
         });
     }
 
@@ -294,7 +304,7 @@
     }
 
     // Process the entries that are direct children.
-    processResults = (searchResults) => {
+    processResults = (searchResults, resObj) => {
         const resultRows = [];
         let rowNumber = 0;
 
@@ -332,6 +342,13 @@
                 // Increment by 2 the row number.
                 rowNumber += 2;
             });
+        } else {
+            if (resObj.status !== 0) {
+                this.props.addNotification(
+                    "error",
+                    `Error searching the database: ${resObj.msg}`
+                );
+            }
         }
 
         this.setState({
@@ -362,6 +379,7 @@
         this.setState({
             searchSuffix: value,
             searchBase: value,
+            baseDN: value,
         });
     }
 
@@ -541,7 +559,7 @@
                                 <GridItem span={4}>
                                     <FormSelect
                                         id="searchSuffix"
-                                        value={this.state.searchSuffix}
+                                        value={this.state.baseDN}
                                         onChange={(value, event) => {
                                             this.handleSuffixChange(event);
                                         }}
@@ -853,7 +871,7 @@
                     </ExpandableSection>
                 </Form>
                 <div className="ds-indent">
-                    <div className={this.state.searching ? "ds-margin-top-xlg 
ds-center" : "ds-hidden"}>
+                    <div className={this.state.searching ? "ds-margin-top-lg 
ds-center" : "ds-hidden"}>
                         <TextContent>
                             <Text component={TextVariants.h3}>
                                 Searching <i>{this.state.searchBase}</i> ...
@@ -862,6 +880,9 @@
                         <Spinner className="ds-margin-top-lg" size="xl" />
                     </div>
                     <div className={searching ? "ds-hidden" : ""}>
+                        <center>
+                            <p><b>Results:</b> {total}</p>
+                        </center>
                         <EditorTableView
                             key={searching}
                             loading={searching}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/tableView.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/tableView.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/tableView.jsx
     2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/tableView.jsx
     2022-02-01 23:35:34.000000000 +0100
@@ -66,6 +66,7 @@
                            perPage={this.props.perPage}
                            onSetPage={(_evt, value) => 
this.props.onSetPage(value)}
                            onPerPageSelect={(_evt, value) => 
this.props.onPerPageSelect(value)}
+                           dropDirection="up"
                        />
                    }
                </div>;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/treeView.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/treeView.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/ldap_editor/treeView.jsx
      2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/ldap_editor/treeView.jsx
      2022-02-01 23:35:34.000000000 +0100
@@ -117,6 +117,7 @@
                 this.updateEntryRows(treeViewItem);
                 return;
             }
+
             this.setState({
                 searching: true,
             }, () => {
@@ -173,6 +174,12 @@
         }
     }
 
+    showEntryLoading = (isEntryLoading) => {
+        this.setState({
+            searching: isEntryLoading ? true : false
+        });
+    };
+
     showTreeLoadingState = (isTreeLoading) => {
         this.setState({
             isTreeLoading,
@@ -388,10 +395,12 @@
                     });
                 }
             });
+
             // Update the refresh time.
             this.setState({
                 latestEntryRefreshTime: Date.now(),
             });
+            this.showEntryLoading(false);
         });
     };
 
@@ -451,6 +460,7 @@
             >
                 ACIs ...
             </DropdownItem>,
+            /*
             <DropdownItem
                 isDisabled
                 key="tree-view-roles"
@@ -469,6 +479,7 @@
             >
                 Smart Referrals ...
             </DropdownItem>,
+            */
             <DropdownSeparator key="separator-3" />,
             <DropdownItem
                 key="tree-view-delete"
@@ -560,6 +571,8 @@
                                     
showTreeLoadingState={this.showTreeLoadingState}
                                     
refreshButtonTriggerTime={refreshButtonTriggerTime}
                                     handleEntryRefresh={this.refreshEntry}
+                                    
addNotification={this.props.addNotification}
+                                    isDisabled={isTreeLoading}
                                 />
                             }
                         </GridItem>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/server/settings.jsx
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/server/settings.jsx
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/cockpit/389-console/src/lib/server/settings.jsx
   2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/cockpit/389-console/src/lib/server/settings.jsx
   2022-02-01 23:35:34.000000000 +0100
@@ -5,6 +5,7 @@
     Button,
     Checkbox,
     Form,
+    FormHelperText,
     FormSelect,
     FormSelectOption,
     Grid,
@@ -270,6 +271,13 @@
                 valueErr = true;
                 disableSaveBtn = true;
             }
+            if (attr === 'nsslapd-disk-monitoring-threshold') {
+                const numVal = Number(value);
+                if (numVal < 4096) {
+                    valueErr = true;
+                    disableSaveBtn = true;
+                }
+            }
         } else if (nav_tab == "adv") {
             // Handle special cases for anon limit dn
             if (attr == 'nsslapd-anonlimitsdn' && !valid_dn(value)) {
@@ -850,15 +858,17 @@
                                 min={4096}
                                 max={9223372036854775807}
                                 onMinus={() => { 
this.onMinusConfig("nsslapd-disk-monitoring-threshold", "diskmon") }}
-                                onChange={(e) => { this.onConfigChange(e, 
"nsslapd-disk-monitoring-threshold", 4096, 9223372036854775807, "diskmon") }}
+                                onChange={(e) => { this.onConfigChange(e, 
"nsslapd-disk-monitoring-threshold", 1, 9223372036854775807, "diskmon") }}
                                 onPlus={() => { 
this.onPlusConfig("nsslapd-disk-monitoring-threshold", "diskmon") }}
                                 inputName="input"
                                 inputAriaLabel="number input"
                                 minusBtnAriaLabel="minus"
                                 plusBtnAriaLabel="plus"
                                 widthChars={8}
-                                
validated={this.state.errObjDiskMon.diskThreshold ? ValidatedOptions.error : 
ValidatedOptions.default}
                             />
+                            <FormHelperText isError 
isHidden={!this.state.errObjDiskMon['nsslapd-disk-monitoring-threshold']}>
+                                Value must be greater than or equal to 4096
+                            </FormHelperText>
                         </GridItem>
                     </Grid>
                     <Grid
@@ -880,7 +890,6 @@
                                 minusBtnAriaLabel="minus"
                                 plusBtnAriaLabel="plus"
                                 widthChars={8}
-                                
validated={this.state.errObjDiskMon.diskThreshold ? ValidatedOptions.error : 
ValidatedOptions.default}
                             />
                         </GridItem>
                     </Grid>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/lib389/cli/dscontainer 
new/389-ds-base-2.0.14~git3.c9226ad90/src/lib389/cli/dscontainer
--- old/389-ds-base-2.0.13~git1.72eb93ac9/src/lib389/cli/dscontainer    
2022-01-25 01:49:42.000000000 +0100
+++ new/389-ds-base-2.0.14~git3.c9226ad90/src/lib389/cli/dscontainer    
2022-02-01 23:35:34.000000000 +0100
@@ -253,7 +253,7 @@
         s2b.set('ldif_dir', '/data/ldif')
         s2b.set('run_dir', '/data/run')
         s2b.set('lock_dir', '/data/run/lock')
-        s2b.set('ldapi', '/data/run/slapd.socket')
+        s2b.set('ldapi', '/data/run/slapd-localhost.socket')
 
         s2b.set('log_dir', '/data/logs')
         s2b.set('access_log', '/data/logs/access')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/lib389/lib389/migrate/openldap/config.py
 
new/389-ds-base-2.0.14~git3.c9226ad90/src/lib389/lib389/migrate/openldap/config.py
--- 
old/389-ds-base-2.0.13~git1.72eb93ac9/src/lib389/lib389/migrate/openldap/config.py
  2022-01-25 01:49:42.000000000 +0100
+++ 
new/389-ds-base-2.0.14~git3.c9226ad90/src/lib389/lib389/migrate/openldap/config.py
  2022-02-01 23:35:34.000000000 +0100
@@ -113,10 +113,12 @@
         self.idx = name.split('}', 1)[0].split('{', 1)[1]
         self.uuid = ensure_str(self.config[1]['entryUUID'][0])
 
-        self.index = [
-            tuple(ensure_str(x).split(' '))
-            for x in self.config[1]['olcDbIndex']
-        ]
+        self.index = []
+        for x in self.config[1]['olcDbIndex']:
+            (attr, idx_types) = ensure_str(x).split(' ', 1)
+            attr = attr.strip()
+            for idx_type in idx_types.split(','):
+                self.index.append((attr, idx_type.strip()))
 
         self.log.debug(f"settings -> {self.suffix}, {self.idx}, {self.uuid}, 
{self.index}")
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/389-ds-base-2.0.13~git1.72eb93ac9/wrappers/ds_selinux_restorecon.sh.in 
new/389-ds-base-2.0.14~git3.c9226ad90/wrappers/ds_selinux_restorecon.sh.in
--- old/389-ds-base-2.0.13~git1.72eb93ac9/wrappers/ds_selinux_restorecon.sh.in  
2022-01-25 01:49:42.000000000 +0100
+++ new/389-ds-base-2.0.14~git3.c9226ad90/wrappers/ds_selinux_restorecon.sh.in  
2022-02-01 23:35:34.000000000 +0100
@@ -29,5 +29,6 @@
     exit 0
 fi
 
-# Now run restorecon
-restorecon ${DS_HOME_DIR}
+# Now run restorecon, but don't die if it fails (could be that the
+# directory doesn't exist)
+restorecon ${DS_HOME_DIR} || :

++++++ 389-ds-base.obsinfo ++++++
--- /var/tmp/diff_new_pack.XuFJha/_old  2022-02-02 22:42:02.267278047 +0100
+++ /var/tmp/diff_new_pack.XuFJha/_new  2022-02-02 22:42:02.271278020 +0100
@@ -1,5 +1,5 @@
 name: 389-ds-base
-version: 2.0.13~git1.72eb93ac9
-mtime: 1643071782
-commit: 72eb93ac9157e8012fda21834de937c8623aa10e
+version: 2.0.14~git3.c9226ad90
+mtime: 1643754934
+commit: c9226ad90f677a02c63c2cc68061690ea88393a8
 

++++++ _service ++++++
--- /var/tmp/diff_new_pack.XuFJha/_old  2022-02-02 22:42:02.335277586 +0100
+++ /var/tmp/diff_new_pack.XuFJha/_new  2022-02-02 22:42:02.339277559 +0100
@@ -27,8 +27,9 @@
     <param 
name="url">https://github.com/SUSE/supportutils-plugin-dirsrv.git</param>
     <param name="versionformat">@PARENT_TAG@~git@TAG_OFFSET@.%h</param>
     <param name="scm">git</param>
-    <param name="revision">v0.1.0</param>
-    <param name="match-tag">v0.1.0</param>
+    <param name="revision">main</param>
+    <param name="versionrewrite-pattern">(.*)</param>
+    <param name="versionrewrite-replacement">\1</param>
     <param name="changesgenerate">disable</param>
     <param name="without-version">true</param>
   </service>

++++++ supportutils-plugin-dirsrv-v0.1.0~git0.37cb939.tar.xz -> 
supportutils-plugin-dirsrv-v0.1.0~git2.4c54cf4.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/supportutils-plugin-dirsrv-v0.1.0~git0.37cb939/dirsrv 
new/supportutils-plugin-dirsrv-v0.1.0~git2.4c54cf4/dirsrv
--- old/supportutils-plugin-dirsrv-v0.1.0~git0.37cb939/dirsrv   2021-04-07 
04:58:12.000000000 +0200
+++ new/supportutils-plugin-dirsrv-v0.1.0~git2.4c54cf4/dirsrv   2022-02-02 
03:31:48.000000000 +0100
@@ -42,21 +42,26 @@
         self.logfile.write("\n")
 
 
-def run_cmd(cmd, check):
+def run_cmd(cmd, check, shell=False):
     output = subprocess.run(
         cmd,
         check=check,
         stdout=subprocess.PIPE,
         stderr=subprocess.STDOUT,
+        shell=shell
     )
     return output.stdout.decode('UTF-8')
 
-def log_cmd(logfile, cmd, check=True):
+def log_cmd(logfile, cmd, check=True, shell=False):
     logfile.write(COMMAND_HDR)
     logfile.write("%s\n" % " ".join(cmd))
     status = True
     try:
-        output = run_cmd(cmd, check)
+        if shell:
+            cmd = " ".join(cmd)
+            output = run_cmd(cmd, check, shell)
+        else:
+            output = run_cmd(cmd, check, shell)
         logfile.write(output)
     except Exception as e:
         logfile.write("ERROR: subprocess raised error: %s\n" % e.returncode)
@@ -173,6 +178,8 @@
 
     try:
         log_note(logfile, ["Active Server-Cert:"] + 
[tls.display_cert_details(lib389.nss_ssl.CERT_NAME)])
+        log_cmd(logfile, ["certutil", "-V", "-d", inst.ds_paths.cert_dir, 
"-n", lib389.nss_ssl.CERT_NAME, "-u", "V"])
+        log_cmd(logfile, ["certutil", "-L", "-d", inst.ds_paths.cert_dir, 
"-n", lib389.nss_ssl.CERT_NAME, "-a", "|", "openssl", "x509", "-noout", 
"-purpose"], shell=True)
     except:
         log_error(logfile, "Unable to display active Server-Cert information - 
using alternate nickname?")
 

++++++ vendor.tar.xz ++++++
/work/SRC/openSUSE:Factory/389-ds/vendor.tar.xz 
/work/SRC/openSUSE:Factory/.389-ds.new.1898/vendor.tar.xz differ: char 27, line 
1

Reply via email to