[389-ds-base] branch 389-ds-base-1.4.1 updated: Ticket 50581 - ns-slapd crashes during ldapi search
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
tbordaz pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 776befc Ticket 50581 - ns-slapd crashes during ldapi search
776befc is described below
commit 776befc1dacb85ebca744fbf6ec76397748121bd
Author: Thierry Bordaz <tbordaz(a)redhat.com>
AuthorDate: Mon Sep 2 16:48:45 2019 +0200
Ticket 50581 - ns-slapd crashes during ldapi search
Bug Description:
Using ldapi, if the length of the socket file path exceeds
46 bytes it triggers a buffer overflow while reseting a connection.
Reset happens at open/close/error.
Fix Description:
Use a buffer sized for a PRNetAddr.local.path (~100bytes)
Use of MAXPATHLEN (4kb) is too much.
https://pagure.io/389-ds-base/issue/50581
Reviewed by: William Brown, Alexander Bokovoy, Mark Reynolds, Simon Pichugi
Platforms tested: F30 (thanks !!)
Flag Day: no
Doc impact: no
---
dirsrvtests/tests/suites/basic/basic_test.py | 107 +++++++++++++++++++++++++++
ldap/servers/slapd/connection.c | 39 +++++-----
2 files changed, 129 insertions(+), 17 deletions(-)
diff --git a/dirsrvtests/tests/suites/basic/basic_test.py b/dirsrvtests/tests/suites/basic/basic_test.py
index 8a51f9c..662357f 100644
--- a/dirsrvtests/tests/suites/basic/basic_test.py
+++ b/dirsrvtests/tests/suites/basic/basic_test.py
@@ -12,6 +12,7 @@
"""
from subprocess import check_output, Popen
+from lib389 import DirSrv
from lib389.idm.user import UserAccounts
import pytest
from lib389.tasks import *
@@ -24,6 +25,9 @@ from lib389.topologies import topology_st
from lib389.paths import Paths
from lib389.idm.directorymanager import DirectoryManager
from lib389.config import LDBMConfig
+from lib389.dseldif import DSEldif
+from lib389.rootdse import RootDSE
+
pytestmark = pytest.mark.tier0
@@ -1270,6 +1274,109 @@ sample_entries = yes
request.addfinalizer(fin)
+(a)pytest.fixture(scope="module")
+def dscreate_ldapi_instance(request):
+ template_file = "/tmp/dssetup.inf"
+ longname_serverid = "test_longname_deadbeef_deadbeef_deadbeef_deadbeef_deadbeef"
+ template_text = """[general]
+config_version = 2
+# This invalid hostname ...
+full_machine_name = localhost.localdomain
+# Means we absolutely require this.
+strict_host_checking = False
+# In tests, we can be run in containers, NEVER trust
+# that systemd is there, or functional in any capacity
+systemd = False
+
+[slapd]
+instance_name = %s
+root_dn = cn=directory manager
+root_password = someLongPassword_123
+# We do not have access to high ports in containers,
+# so default to something higher.
+port = 38999
+secure_port = 63699
+
+
+[backend-userroot]
+suffix = dc=example,dc=com
+sample_entries = yes
+""" % longname_serverid
+
+ with open(template_file, "w") as template_fd:
+ template_fd.write(template_text)
+
+ # Unset PYTHONPATH to avoid mixing old CLI tools and new lib389
+ tmp_env = os.environ
+ if "PYTHONPATH" in tmp_env:
+ del tmp_env["PYTHONPATH"]
+ try:
+ subprocess.check_call([
+ 'dscreate',
+ 'from-file',
+ template_file
+ ], env=tmp_env)
+ except subprocess.CalledProcessError as e:
+ log.fatal("dscreate failed! Error ({}) {}".format(e.returncode, e.output))
+ assert False
+
+ inst = DirSrv(verbose=True, external_log=log)
+ dse_ldif = DSEldif(inst,
+ serverid=longname_serverid)
+
+ socket_path = dse_ldif.get("cn=config", "nsslapd-ldapifilepath")
+ inst.local_simple_allocate(
+ serverid=longname_serverid,
+ ldapuri=f"ldapi://{socket_path[0].replace('/', '%2f')}",
+ password="someLongPassword_123"
+ )
+ inst.ldapi_enabled = 'on'
+ inst.ldapi_socket = socket_path
+ inst.ldapi_autobind = 'off'
+ try:
+ inst.open()
+ except:
+ log.fatal("Failed to connect via ldapi to %s instance" % longname_serverid)
+ os.remove(template_file)
+ try:
+ subprocess.check_call(['dsctl', longname_serverid, 'remove', '--do-it'])
+ except subprocess.CalledProcessError as e:
+ log.fatal("Failed to remove test instance Error ({}) {}".format(e.returncode, e.output))
+
+ def fin():
+ os.remove(template_file)
+ try:
+ subprocess.check_call(['dsctl', longname_serverid, 'remove', '--do-it'])
+ except subprocess.CalledProcessError as e:
+ log.fatal("Failed to remove test instance Error ({}) {}".format(e.returncode, e.output))
+
+ request.addfinalizer(fin)
+
+ return inst
+
+
+(a)pytest.mark.skipif(not get_user_is_root() or not default_paths.perl_enabled or ds_is_older('1.4.0.0'),
+ reason="This test is only required with new admin cli, and requires root.")
+(a)pytest.mark.bz1748016
+(a)pytest.mark.ds50581
+def test_dscreate_longname(dscreate_ldapi_instance):
+ """Test that an instance with a long name can
+ handle ldapi connection using a long socket name
+
+ :id: 5d72d955-aff8-4741-8c9a-32c1c707cf1f
+ :setup: None
+ :steps:
+ 1. create an instance with a long serverId name, that open a ldapi connection
+ 2. Connect with ldapi, that hit 50581 and crash the instance
+ :expectedresults:
+ 1. Should succeeds
+ 2. Should succeeds
+ """
+
+ root_dse = RootDSE(dscreate_ldapi_instance)
+ log.info(root_dse.get_supported_ctrls())
+
+
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index e6ce0f01..3600d3d 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -275,6 +275,8 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib
{
char *pTmp = is_SSL ? "SSL " : "";
char *str_ip = NULL, *str_destip;
+ char buf_ldapi[sizeof(from->local.path) + 1] = {0};
+ char buf_destldapi[sizeof(from->local.path) + 1] = {0};
char buf_ip[INET6_ADDRSTRLEN + 1] = {0};
char buf_destip[INET6_ADDRSTRLEN + 1] = {0};
char *str_unknown = "unknown";
@@ -296,18 +298,18 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib
slapi_ch_free((void **)&conn->cin_addr); /* just to be conservative */
if (from->raw.family == PR_AF_LOCAL) { /* ldapi */
conn->cin_addr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
- PL_strncpyz(buf_ip, from->local.path, sizeof(from->local.path));
+ PL_strncpyz(buf_ldapi, from->local.path, sizeof(from->local.path));
memcpy(conn->cin_addr, from, sizeof(PRNetAddr));
- if (!buf_ip[0]) {
+ if (!buf_ldapi[0]) {
PR_GetPeerName(conn->c_prfd, from);
- PL_strncpyz(buf_ip, from->local.path, sizeof(from->local.path));
+ PL_strncpyz(buf_ldapi, from->local.path, sizeof(from->local.path));
memcpy(conn->cin_addr, from, sizeof(PRNetAddr));
- if (!buf_ip[0]) {
+ if (!buf_ldapi[0]) {
/* Cannot derive local address, need something for logging */
- PL_strncpyz(buf_ip, "local", sizeof(buf_ip));
+ PL_strncpyz(buf_ldapi, "local", sizeof(buf_ldapi));
}
}
- str_ip = buf_ip;
+ str_ip = buf_ldapi;
} else if (((from->ipv6.ip.pr_s6_addr32[0] != 0) || /* from contains non zeros */
(from->ipv6.ip.pr_s6_addr32[1] != 0) ||
(from->ipv6.ip.pr_s6_addr32[2] != 0) ||
@@ -362,21 +364,24 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib
memset(conn->cin_destaddr, 0, sizeof(PRNetAddr));
if (PR_GetSockName(conn->c_prfd, conn->cin_destaddr) == 0) {
if (conn->cin_destaddr->raw.family == PR_AF_LOCAL) { /* ldapi */
- PL_strncpyz(buf_destip, conn->cin_destaddr->local.path,
+ PL_strncpyz(buf_destldapi, conn->cin_destaddr->local.path,
sizeof(conn->cin_destaddr->local.path));
- if (!buf_destip[0]) {
- PL_strncpyz(buf_destip, "unknown local file", sizeof(buf_destip));
+ if (!buf_destldapi[0]) {
+ PL_strncpyz(buf_destldapi, "unknown local file", sizeof(buf_destldapi));
}
- } else if (PR_IsNetAddrType(conn->cin_destaddr, PR_IpAddrV4Mapped)) {
- PRNetAddr v4destaddr = {{0}};
- v4destaddr.inet.family = PR_AF_INET;
- v4destaddr.inet.ip = conn->cin_destaddr->ipv6.ip.pr_s6_addr32[3];
- PR_NetAddrToString(&v4destaddr, buf_destip, sizeof(buf_destip));
+ str_destip = buf_destldapi;
} else {
- PR_NetAddrToString(conn->cin_destaddr, buf_destip, sizeof(buf_destip));
+ if (PR_IsNetAddrType(conn->cin_destaddr, PR_IpAddrV4Mapped)) {
+ PRNetAddr v4destaddr = {{0}};
+ v4destaddr.inet.family = PR_AF_INET;
+ v4destaddr.inet.ip = conn->cin_destaddr->ipv6.ip.pr_s6_addr32[3];
+ PR_NetAddrToString(&v4destaddr, buf_destip, sizeof (buf_destip));
+ } else {
+ PR_NetAddrToString(conn->cin_destaddr, buf_destip, sizeof (buf_destip));
+ }
+ buf_destip[sizeof (buf_destip) - 1] = '\0';
+ str_destip = buf_destip;
}
- buf_destip[sizeof(buf_destip) - 1] = '\0';
- str_destip = buf_destip;
} else {
str_destip = str_unknown;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50604 - Fix UI validation
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new f710e6a Issue 50604 - Fix UI validation
f710e6a is described below
commit f710e6a526134598db47fbb502a117cecd4a9bd7
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Mon Sep 16 09:22:38 2019 -0400
Issue 50604 - Fix UI validation
Description:
This issue has been opened to track a series of bugzillas that were filed by our QE group during a massive UI testing day. Here are the issues being addressed in this issue:
- Replication agreement disappears from table after browser refresh
- https://bugzilla.redhat.com/show_bug.cgi?id=1751128
- Fix log rotation time validation
- https://bugzilla.redhat.com/show_bug.cgi?id=1751004
- Check backup/ldif name to see if it already exists
- https://bugzilla.redhat.com/show_bug.cgi?id=1751007
- https://bugzilla.redhat.com/show_bug.cgi?id=1751009
- Root DN should not be editable
- https://bugzilla.redhat.com/show_bug.cgi?id=1751011
- Backup should check if there is a database available
- https://bugzilla.redhat.com/show_bug.cgi?id=1751019
- Also fixed backup duplicate timestamp issue
- Fixed instance creation error handing
- https://bugzilla.redhat.com/show_bug.cgi?id=1751026
- Fixed export/inout issues. Check for existing back or ldif
- https://bugzilla.redhat.com/show_bug.cgi?id=1751019
- Validate SSL version min and max
- https://bugzilla.redhat.com/show_bug.cgi?id=1751072
- Can not promte/demote replica
- https://bugzilla.redhat.com/show_bug.cgi?id=1751145
- Database link creation and deletion issue
- https://bugzilla.redhat.com/show_bug.cgi?id=1751157
- Agreement name validation during creation
- https://bugzilla.redhat.com/show_bug.cgi?id=1751165
- Validate referral port
- https://bugzilla.redhat.com/show_bug.cgi?id=1751173
- Fix deleteion of config attributes
- https://bugzilla.redhat.com/show_bug.cgi?id=1751190
There was an overall improvement when creating suffixes/databases on how to initialize them
relates: https://pagure.io/389-ds-base/issue/50604
Reviewed by: spichugi(Thanks!)
(cherry picked from commit c403a39c8db68243524bd0cc50529167ac0d9fb2)
---
src/cockpit/389-console/src/css/ds.css | 8 ++
src/cockpit/389-console/src/database.jsx | 104 +++++++++++++++----
src/cockpit/389-console/src/ds.js | 10 +-
src/cockpit/389-console/src/index.html | 59 ++++++-----
.../389-console/src/lib/database/backups.jsx | 78 ++++++++++++--
.../389-console/src/lib/database/databaseModal.jsx | 29 +++++-
.../389-console/src/lib/database/referrals.jsx | 9 +-
.../389-console/src/lib/database/suffix.jsx | 39 ++++++-
.../389-console/src/lib/security/ciphers.jsx | 2 +-
src/cockpit/389-console/src/lib/tools.jsx | 11 ++
src/cockpit/389-console/src/replication.js | 15 ++-
src/cockpit/389-console/src/security.jsx | 58 ++++++++---
src/cockpit/389-console/src/servers.html | 22 ++--
src/cockpit/389-console/src/servers.js | 112 +++++++++++++++------
src/lib389/lib389/__init__.py | 7 +-
src/lib389/lib389/_mapped_object.py | 2 +-
src/lib389/lib389/chaining.py | 2 +-
src/lib389/lib389/cli_conf/backend.py | 31 ++++++
src/lib389/lib389/cli_conf/security.py | 5 +-
src/lib389/lib389/configurations/sample.py | 53 ++++++++++
src/lib389/lib389/replica.py | 8 +-
21 files changed, 535 insertions(+), 129 deletions(-)
diff --git a/src/cockpit/389-console/src/css/ds.css b/src/cockpit/389-console/src/css/ds.css
index 6da4b9d..f5b1e4f 100644
--- a/src/cockpit/389-console/src/css/ds.css
+++ b/src/cockpit/389-console/src/css/ds.css
@@ -76,6 +76,10 @@
font-size: 13px !important;
}
+.ds-switch {
+ margin-top: 2px;
+}
+
.ds-refresh:hover {
color: DarkGray;
background-color: white;
@@ -741,6 +745,10 @@ option {
width: 100%;
}
+.ds-inst-indent {
+ margin-left: 240px;
+}
+
.ds-left-margin {
margin-left: 10px !important;
}
diff --git a/src/cockpit/389-console/src/database.jsx b/src/cockpit/389-console/src/database.jsx
index e5adf79..36b38be 100644
--- a/src/cockpit/389-console/src/database.jsx
+++ b/src/cockpit/389-console/src/database.jsx
@@ -13,9 +13,13 @@ import {
Modal,
Icon,
Form,
+ Row,
+ Col,
+ ControlLabel,
Button,
noop,
TreeView,
+ Radio,
Spinner
} from "patternfly-react";
import PropTypes from "prop-types";
@@ -41,7 +45,10 @@ export class Database extends React.Component {
showSuffixModal: false,
createSuffix: "",
createBeName: "",
- createRootNode: false,
+ createSuffixEntry: false,
+ createSampleEntries: false,
+ noSuffixInit: true,
+
// DB config
globalDBConfig: {},
configUpdated: 0,
@@ -67,6 +74,7 @@ export class Database extends React.Component {
this.removeNotification = this.removeNotification.bind(this);
this.addNotification = this.addNotification.bind(this);
this.handleChange = this.handleChange.bind(this);
+ this.handleRadioChange = this.handleRadioChange.bind(this);
this.loadGlobalConfig = this.loadGlobalConfig.bind(this);
this.loadLDIFs = this.loadLDIFs.bind(this);
this.loadBackups = this.loadBackups.bind(this);
@@ -541,10 +549,32 @@ export class Database extends React.Component {
showSuffixModal () {
this.setState({
showSuffixModal: true,
+ createSuffixEntry: false,
+ createSampleEntries: false,
+ noSuffixInit: true,
errObj: {},
});
}
+ handleRadioChange(e) {
+ // Handle the create suffix init option radio button group
+ let noInit = false;
+ let addSuffix = false;
+ let addSample = false;
+ if (e.target.id == "noSuffixInit") {
+ noInit = true;
+ } else if (e.target.id == "createSuffixEntry") {
+ addSuffix = true;
+ } else { // createSampleEntries
+ addSample = true;
+ }
+ this.setState({
+ noSuffixInit: noInit,
+ createSuffixEntry: addSuffix,
+ createSampleEntries: addSample
+ });
+ }
+
handleChange(e) {
const value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
let valueErr = false;
@@ -570,7 +600,7 @@ export class Database extends React.Component {
let errors = false;
let missingArgs = {
createSuffix: false,
- createBeName: false
+ createBeName: false,
};
if (this.state.createSuffix == "") {
@@ -601,9 +631,12 @@ export class Database extends React.Component {
"dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
"backend", "create", "--be-name", this.state.createBeName, '--suffix', this.state.createSuffix,
];
- if (this.state.createSampleEntries == true) {
+ if (this.state.createSampleEntries) {
cmd.push('--create-entries');
}
+ if (this.state.createSuffixEntry) {
+ cmd.push('--create-suffix');
+ }
log_cmd("createSuffix", "Create a new backend", cmd);
cockpit
@@ -616,6 +649,7 @@ export class Database extends React.Component {
);
// Refresh tree
this.loadSuffixTree(false);
+ this.loadSuffixList();
})
.fail(err => {
let errMsg = JSON.parse(err);
@@ -1133,7 +1167,11 @@ export class Database extends React.Component {
showModal={this.state.showSuffixModal}
closeHandler={this.closeSuffixModal}
handleChange={this.handleChange}
+ handleRadioChange={this.handleRadioChange}
saveHandler={this.createSuffix}
+ noInit={this.state.noSuffixInit}
+ addSuffix={this.state.createSuffixEntry}
+ addSample={this.state.createSampleEntries}
error={this.state.errObj}
/>
</div>
@@ -1147,7 +1185,11 @@ class CreateSuffixModal extends React.Component {
showModal,
closeHandler,
handleChange,
+ handleRadioChange,
saveHandler,
+ noInit,
+ addSuffix,
+ addSample,
error
} = this.props;
@@ -1169,20 +1211,40 @@ class CreateSuffixModal extends React.Component {
</Modal.Header>
<Modal.Body>
<Form horizontal autoComplete="off">
- <div className="ds-inline">
- <div>
- <label htmlFor="createSuffix" className="ds-config-label" title="Database Suffix DN (nsslapd-suffix)">
- Suffix DN</label><input onChange={handleChange} className={error.createSuffix ? "ds-input-bad" : "ds-input"} type="text" id="createSuffix" size="40" />
- </div>
- <div>
- <label htmlFor="createBeName" className="ds-config-label" title="Database backend name (nsslapd-backend)">
- Backend Name</label><input onChange={handleChange} className={error.createBeName ? "ds-input-bad" : "ds-input"} type="text" id="createBeName" size="40" />
- </div>
- <div>
- <p />
- <input type="checkbox" className="ds-config-checkbox" id="createSampleEntries" onChange={handleChange} /><label
- htmlFor="createSampleEntries" className="ds-label" title="Create the datbase with sample entries"> Create Sample Entries</label>
- </div>
+ <Row title="Database suffix, like 'dc=example,dc=com'. The suffix must be a valid LDAP Distiguished Name (DN)">
+ <Col sm={3}>
+ <ControlLabel>Suffix DN</ControlLabel>
+ </Col>
+ <Col sm={5}>
+ <input onChange={handleChange} className={error.createSuffix ? "ds-input-bad" : "ds-input"} type="text" id="createSuffix" size="40" />
+ </Col>
+ </Row>
+ <p />
+ <Row title="The name for the backend database, like 'userroot'. The name can be a combination of alphanumeric characters, dashes (-), and underscores (_). No other characters are allowed, and the name must be unique across all backends.">
+ <Col sm={3}>
+ <ControlLabel>Database Name</ControlLabel>
+ </Col>
+ <Col sm={5}>
+ <input onChange={handleChange} className={error.createBeName ? "ds-input-bad" : "ds-input"} type="text" id="createBeName" size="40" />
+ </Col>
+ </Row>
+ <hr />
+ <div>
+ <Row className="ds-indent">
+ <Radio name="radioGroup" id="noSuffixInit" onChange={handleRadioChange} checked={noInit} inline>
+ Do Not Initialize Database
+ </Radio>
+ </Row>
+ <Row className="ds-indent">
+ <Radio name="radioGroup" id="createSuffixEntry" onChange={handleRadioChange} checked={addSuffix} inline>
+ Create The Top Suffix Entry
+ </Radio>
+ </Row>
+ <Row className="ds-indent">
+ <Radio name="radioGroup" id="createSampleEntries" onChange={handleRadioChange} checked={addSample} inline>
+ Add Sample Entries
+ </Radio>
+ </Row>
</div>
</Form>
</Modal.Body>
@@ -1221,7 +1283,11 @@ CreateSuffixModal.propTypes = {
showModal: PropTypes.bool,
closeHandler: PropTypes.func,
handleChange: PropTypes.func,
+ handleRadioChange: PropTypes.func,
saveHandler: PropTypes.func,
+ noInit: PropTypes.bool,
+ addSuffix: PropTypes.bool,
+ addSample: PropTypes.bool,
error: PropTypes.object,
};
@@ -1229,6 +1295,10 @@ CreateSuffixModal.defaultProps = {
showModal: false,
closeHandler: noop,
handleChange: noop,
+ handleRadioChange: noop,
saveHandler: noop,
+ noInit: true,
+ addSuffix: false,
+ addSample: false,
error: {},
};
diff --git a/src/cockpit/389-console/src/ds.js b/src/cockpit/389-console/src/ds.js
index 702ff88..1274b3f 100644
--- a/src/cockpit/389-console/src/ds.js
+++ b/src/cockpit/389-console/src/ds.js
@@ -76,6 +76,12 @@ function valid_dn (dn){
}
function valid_num (val){
+ // Validate value is a number
+ let result = !isNaN(val);
+ return result;
+}
+
+function valid_port (val){
// Validate value is a number and between 1 and 65535
let result = !isNaN(val);
if (result) {
@@ -366,6 +372,8 @@ function load_repl_suffix_dropdowns() {
$("#" + repl_dropdowns[list]).append('<option value="' + obj['items'][idx] + '" selected="selected">' + obj['items'][idx] +'</option>');
}
}
+ get_and_set_repl_agmts();
+ get_and_set_repl_winsync_agmts();
if (obj['items'].length == 0){
// Disable create agmt buttons
$("#create-agmt").prop("disabled", true);
@@ -443,8 +451,6 @@ function load_config (refresh){
// Replication page
get_and_set_repl_config();
- get_and_set_repl_agmts();
- get_and_set_repl_winsync_agmts();
get_and_set_cleanallruv();
update_progress();
diff --git a/src/cockpit/389-console/src/index.html b/src/cockpit/389-console/src/index.html
index 91993cc..3eef2a7 100644
--- a/src/cockpit/389-console/src/index.html
+++ b/src/cockpit/389-console/src/index.html
@@ -386,47 +386,56 @@
<p class="ds-modal-error"></p>
<div class="ds-inline">
<div>
- <label for="create-inst-serverid" class="ds-config-label" title="The instance name, this is what gets appended to 'slapi-'. The instance name can only contain letters, numbers, and: # % : - _">
- Instance Name</label><input class="ds-input ds-inst-input" size="40" type="text" id="create-inst-serverid" placeholder="Your_Instance_Name" required />
+ <label for="create-inst-serverid" class="ds-config-label ds-input-right" title="The instance name, this is what gets appended to 'slapi-'. The instance name can only contain letters, numbers, and: # % : - _">
+ Instance Name</label><input class="ds-input ds-inst-input ds-left-margin" size="40" type="text" id="create-inst-serverid" placeholder="Your_Instance_Name" required />
</div>
<div>
- <label for="create-inst-port" class="ds-config-label" title="The server port number">
- Port</label><input class="ds-input ds-inst-input" size="40" type="text" value="389" id="create-inst-port" required />
+ <label for="create-inst-port" class="ds-config-label ds-input-right" title="The server port number">
+ Port</label><input class="ds-input ds-inst-input ds-left-margin" size="40" type="text" value="389" id="create-inst-port" required />
</div>
<div>
- <label for="create-inst-secureport" class="ds-config-label" title="The secure port number for TLS connections">
- Secure Port</label><input class="ds-input ds-inst-input" size="40" type="text" value="636" id="create-inst-secureport" required />
+ <label for="create-inst-secureport" class="ds-config-label ds-input-right" title="The secure port number for TLS connections">
+ Secure Port</label><input class="ds-input ds-inst-input ds-left-margin" size="40" type="text" value="636" id="create-inst-secureport" required />
</div>
- <div>
- <label for="create-inst-rootdn" class="ds-config-label" title="The DN for the unrestricted user">
- Directory Manager DN</label><input class="ds-input ds-inst-input" size="40" autocomplete="username" value="cn=Directory Manager" type="text" id="create-inst-rootdn" required />
+ <div class="ds-inst-indent">
+ <input type="checkbox" class="ds-config-checkbox" id="create-inst-tls" checked><label
+ for="create-inst-tls" class="ds-label" title="Create a self-signed certificate database">Create Self-Signed TLS Certificate DB</label>
</div>
<div>
- <label for="rootdn-pw" class="ds-config-label" title="Directory Manager password.">Directory Manager Password</label><input
- class="ds-input ds-inst-input" size="40" type="password" autocomplete="new-password" placeholder="Enter password" id="rootdn-pw" name="name" required>
+ <label for="create-inst-rootdn" class="ds-config-label ds-input-right" title="The DN for the unrestricted user">
+ Directory Manager DN</label><input class="ds-input ds-inst-input ds-left-margin" size="40" autocomplete="username" value="cn=Directory Manager" type="text" id="create-inst-rootdn" required />
</div>
<div>
- <label for="rootdn-pw-confirm" class="ds-config-label" title="Confirm password">Confirm Password</label><input
- class="ds-input ds-inst-input" size="40" type="password" autocomplete="new-password" placeholder="Confirm password" id="rootdn-pw-confirm" name="name" required>
+ <label for="rootdn-pw" class="ds-config-label ds-input-right" title="Directory Manager password.">Directory Manager Password</label><input
+ class="ds-input ds-inst-input ds-left-margin" size="40" type="password" autocomplete="new-password" placeholder="Enter password" id="rootdn-pw" name="name" required>
</div>
- <hr>
<div>
- <label for="backend-suffix" class="ds-config-label" title="Database suffix, like 'dc=example,dc=com'. The suffix must be a valid LDAP Distiguished Name (DN)">Database Suffix</label><input
- class="ds-input ds-inst-input" size="40" placeholder="e.g. dc=example,dc=com" type="text" id="backend-suffix">
+ <label for="rootdn-pw-confirm" class="ds-config-label ds-input-right" title="Confirm password">Confirm Password</label><input
+ class="ds-input ds-inst-input ds-left-margin" size="40" type="password" autocomplete="new-password" placeholder="Confirm password" id="rootdn-pw-confirm" name="name" required>
</div>
+ <hr>
+ <h5 class="ds-center">Optional Database Settings</h5>
<div>
- <label for="backend-name" class="ds-config-label" title="The name for the backend database, like 'userroot'. The name can be a combination of alphanumeric characters, dashes (-), and underscores (_). No other characters are allowed.">Database Name</label><input
- class="ds-input ds-inst-input" placeholder="e.g. userRoot" size="40" type="text" id="backend-name">
+ <label for="backend-suffix" class="ds-config-label ds-input-right" title="Database suffix, like 'dc=example,dc=com'. The suffix must be a valid LDAP Distiguished Name (DN)">Database Suffix</label><input
+ class="ds-input ds-inst-input ds-left-margin" size="40" placeholder="e.g. dc=example,dc=com" type="text" id="backend-suffix">
</div>
-
<div>
- <label for="create-sample-entries" class="ds-config-label" title="Create sample entries in the suffix">Create Sample Entries </label><input
- type="checkbox" class="ds-input ds-config-checkbox" id="create-sample-entries">
+ <label for="backend-name" class="ds-config-label ds-input-right" title="The name for the backend database, like 'userroot'. The name can be a combination of alphanumeric characters, dashes (-), and underscores (_). No other characters are allowed, and the name must be unique across all backends.">Database Name</label><input
+ class="ds-input ds-inst-input ds-left-margin" placeholder="e.g. userRoot" size="40" type="text" id="backend-name">
</div>
- <hr>
- <div>
- <input type="checkbox" class="ds-config-checkbox" id="create-inst-tls" checked><label
- for="create-inst-tls" class="ds-label" title="Create a self-signed certificate database">Create Self Signed Certificate DB</label>
+ <div class="ds-inst-indent ds-margin-top">
+ <div>
+ <input type="radio" name="ds-radio-group" id="no-init" checked /><label class="ds-left-margin" for="no-init"
+ title="Do not initialize the backend database"> Do Not Initialize Database</label>
+ </div>
+ <div>
+ <input type="radio" name="ds-radio-group" id="create-suffix-entry" /><label class="ds-left-margin" for="create-suffix-entry"
+ title="Create the suffix entry with a basic READ ACI"> Create Suffix Entry</label>
+ </div>
+ <div>
+ <input type="radio" name="ds-radio-group" id="create-sample-entries" /><label class="ds-left-margin" for="create-sample-entries"
+ title="Create sample entries under the suffix"> Create Suffix Entry And Add Sample Entries</label>
+ </div>
</div>
<div id="create-inst-spinner" class="ds-center" hidden>
<hr>
diff --git a/src/cockpit/389-console/src/lib/database/backups.jsx b/src/cockpit/389-console/src/lib/database/backups.jsx
index 96d6e97..f04c348 100644
--- a/src/cockpit/389-console/src/lib/database/backups.jsx
+++ b/src/cockpit/389-console/src/lib/database/backups.jsx
@@ -30,7 +30,8 @@ export class Backups extends React.Component {
activeKey: 1,
showConfirmBackupDelete: false,
showConfirmBackup: false,
- showConfirmRestore: false,
+ showConfirmRestoreReplace: false,
+ showConfirmLDIFReplace: false,
showRestoreSpinningModal: false,
showDelBackupSpinningModal: false,
showBackupModal: false,
@@ -40,6 +41,7 @@ export class Backups extends React.Component {
// LDIF
showConfirmLDIFDelete: false,
showConfirmLDIFImport: false,
+ showConfirmRestore: false,
showLDIFSpinningModal: false,
showLDIFDeleteSpinningModal: false,
showExportModal: false,
@@ -68,6 +70,8 @@ export class Backups extends React.Component {
this.closeRestoreSpinningModal = this.closeRestoreSpinningModal.bind(this);
this.showDelBackupSpinningModal = this.showDelBackupSpinningModal.bind(this);
this.closeDelBackupSpinningModal = this.closeDelBackupSpinningModal.bind(this);
+ this.validateBackup = this.validateBackup.bind(this);
+ this.closeConfirmRestoreReplace = this.closeConfirmRestoreReplace.bind(this);
// LDIFS
this.importLDIF = this.importLDIF.bind(this);
this.deleteLDIF = this.deleteLDIF.bind(this);
@@ -80,6 +84,8 @@ export class Backups extends React.Component {
this.doExport = this.doExport.bind(this);
this.showExportModal = this.showExportModal.bind(this);
this.closeExportModal = this.closeExportModal.bind(this);
+ this.validateLDIF = this.validateLDIF.bind(this);
+ this.closeConfirmLDIFReplace = this.closeConfirmLDIFReplace.bind(this);
}
showExportModal () {
@@ -97,6 +103,12 @@ export class Backups extends React.Component {
});
}
+ closeConfirmLDIFReplace () {
+ this.setState({
+ showConfirmLDIFReplace: false
+ });
+ }
+
showLDIFSpinningModal () {
this.setState({
showLDIFSpinningModal: true
@@ -233,6 +245,12 @@ export class Backups extends React.Component {
});
}
+ closeConfirmRestoreReplace () {
+ this.setState({
+ showConfirmRestoreReplace: false,
+ });
+ }
+
importLDIF() {
this.showLDIFSpinningModal();
@@ -288,12 +306,23 @@ export class Backups extends React.Component {
});
}
+ validateBackup() {
+ for (let i = 0; i < this.props.backups.length; i++) {
+ if (this.state.backupName == this.props.backups[i]['name']) {
+ this.setState({
+ showConfirmRestoreReplace: true
+ });
+ return;
+ }
+ }
+ this.doBackup();
+ }
+
doBackup () {
let cmd = [
"dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
"backup", "create"
];
-
if (this.state.backupName != "") {
if (bad_file_name(this.state.backupName)) {
this.props.addNotification(
@@ -332,8 +361,15 @@ export class Backups extends React.Component {
}
restoreBackup () {
- this.showRestoreSpinningModal();
+ if (this.props.suffixes.length == 0) {
+ this.props.addNotification(
+ "error",
+ `There are no databases defined to restore`
+ );
+ return;
+ }
+ this.showRestoreSpinningModal();
const cmd = [
"dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
"backup", "restore", this.state.backupName
@@ -405,6 +441,23 @@ export class Backups extends React.Component {
});
}
+ validateLDIF() {
+ let ldifname = this.state.ldifName;
+ if (!ldifname.endsWith(".ldif")) {
+ // dsconf/dsctl adds ".ldif" if not set, so that's what we need to check
+ ldifname = ldifname + ".ldif";
+ }
+ for (let i = 0; i < this.props.ldifs.length; i++) {
+ if (ldifname == this.props.ldifs[i]['name']) {
+ this.setState({
+ showConfirmLDIFReplace: true
+ });
+ return;
+ }
+ }
+ this.doExport();
+ }
+
doExport() {
let missingArgs = {ldifName: false};
if (this.state.ldifName == "") {
@@ -525,7 +578,7 @@ export class Backups extends React.Component {
showModal={this.state.showExportModal}
closeHandler={this.closeExportModal}
handleChange={this.handleChange}
- saveHandler={this.doExport}
+ saveHandler={this.validateLDIF}
spinning={this.state.exportSpinner}
error={this.state.errObj}
suffixes={this.props.suffixes}
@@ -534,7 +587,7 @@ export class Backups extends React.Component {
showModal={this.state.showBackupModal}
closeHandler={this.closeBackupModal}
handleChange={this.handleChange}
- saveHandler={this.doBackup}
+ saveHandler={this.validateBackup}
spinning={this.state.backupSpinning}
error={this.state.errObj}
/>
@@ -590,7 +643,20 @@ export class Backups extends React.Component {
msg="Are you sure you want to delete this backup?"
msgContent={this.state.backupName}
/>
-
+ <ConfirmPopup
+ showModal={this.state.showConfirmRestoreReplace}
+ closeHandler={this.closeConfirmRestoreReplace}
+ actionFunc={this.doBackup}
+ msg="Replace Existing Backup"
+ msgContent="A backup already eixsts with the same name, do you want to replace it?"
+ />
+ <ConfirmPopup
+ showModal={this.state.showConfirmLDIFReplace}
+ closeHandler={this.closeConfirmLDIFReplace}
+ actionFunc={this.doExport}
+ msg="Replace Existing LDIF File"
+ msgContent="A LDIF file already eixsts with the same name, do you want to replace it?"
+ />
</div>
);
}
diff --git a/src/cockpit/389-console/src/lib/database/databaseModal.jsx b/src/cockpit/389-console/src/lib/database/databaseModal.jsx
index 01db9bb..092f22d 100644
--- a/src/cockpit/389-console/src/lib/database/databaseModal.jsx
+++ b/src/cockpit/389-console/src/lib/database/databaseModal.jsx
@@ -4,6 +4,7 @@ import {
Row,
Col,
ControlLabel,
+ Radio,
Icon,
Button,
Form,
@@ -110,8 +111,12 @@ class CreateSubSuffixModal extends React.Component {
showModal,
closeHandler,
handleChange,
+ handleRadioChange,
saveHandler,
suffix,
+ noInit,
+ addSuffix,
+ addSample,
error
} = this.props;
@@ -133,7 +138,7 @@ class CreateSubSuffixModal extends React.Component {
</Modal.Header>
<Modal.Body>
<Form horizontal autoComplete="off">
- <Row title="Database Suffix DN (nsslapd-suffix)">
+ <Row title="Database suffix, like 'dc=example,dc=com'. The suffix must be a valid LDAP Distiguished Name (DN)">
<Col sm={3}>
<ControlLabel>Sub-Suffix DN</ControlLabel>
</Col>
@@ -150,9 +155,9 @@ class CreateSubSuffixModal extends React.Component {
</Col>
</Row>
<p />
- <Row title="Database backend name (nsslapd-backend)">
+ <Row title="The name for the backend database, like 'userroot'. The name can be a combination of alphanumeric characters, dashes (-), and underscores (_). No other characters are allowed, and the name must be unique across all backends.">
<Col sm={3}>
- <ControlLabel>Backend Name</ControlLabel>
+ <ControlLabel>Database Name</ControlLabel>
</Col>
<Col sm={9}>
<FormControl
@@ -163,6 +168,24 @@ class CreateSubSuffixModal extends React.Component {
/>
</Col>
</Row>
+ <hr />
+ <div>
+ <Row className="ds-indent">
+ <Radio name="radioGroup" id="noSuffixInit" onChange={handleRadioChange} checked={noInit} inline>
+ Do Not Initialize Database
+ </Radio>
+ </Row>
+ <Row className="ds-indent">
+ <Radio name="radioGroup" id="createSuffixEntry" onChange={handleRadioChange} checked={addSuffix} inline>
+ Create The Top Sub-Suffix Entry
+ </Radio>
+ </Row>
+ <Row className="ds-indent">
+ <Radio name="radioGroup" id="createSampleEntries" onChange={handleRadioChange} checked={addSample} inline>
+ Add Sample Entries
+ </Radio>
+ </Row>
+ </div>
</Form>
</Modal.Body>
<Modal.Footer>
diff --git a/src/cockpit/389-console/src/lib/database/referrals.jsx b/src/cockpit/389-console/src/lib/database/referrals.jsx
index 22f9c50..a44569b 100644
--- a/src/cockpit/389-console/src/lib/database/referrals.jsx
+++ b/src/cockpit/389-console/src/lib/database/referrals.jsx
@@ -12,7 +12,7 @@ import {
Form,
noop
} from "patternfly-react";
-import { log_cmd } from "../tools.jsx";
+import { log_cmd, valid_port } from "../tools.jsx";
import PropTypes from "prop-types";
import "../../css/ds.css";
@@ -122,6 +122,13 @@ export class SuffixReferrals extends React.Component {
);
missingArgs.refPort = true;
errors = true;
+ } else if (!valid_port(this.state.refPort)) {
+ this.props.addNotification(
+ "error",
+ `Invalid port number, please use a number between 1 and 65535`
+ );
+ missingArgs.refPort = true;
+ errors = true;
}
if (errors) {
this.setState({
diff --git a/src/cockpit/389-console/src/lib/database/suffix.jsx b/src/cockpit/389-console/src/lib/database/suffix.jsx
index 4366c19..8413799 100644
--- a/src/cockpit/389-console/src/lib/database/suffix.jsx
+++ b/src/cockpit/389-console/src/lib/database/suffix.jsx
@@ -79,6 +79,10 @@ export class Suffix extends React.Component {
showSubSuffixModal: false,
subSuffixValue: "",
subSuffixBeName: "",
+ createSuffixEntry: false,
+ noSuffixInit: true,
+ createSampleEntries: false,
+
// Create Link
showLinkModal: false,
createLinkSuffix: "",
@@ -100,6 +104,7 @@ export class Suffix extends React.Component {
this.showImportModal = this.showImportModal.bind(this);
this.closeImportModal = this.closeImportModal.bind(this);
this.handleChange = this.handleChange.bind(this);
+ this.handleRadioChange = this.handleRadioChange.bind(this);
this.doImport = this.doImport.bind(this);
this.importLDIF = this.importLDIF.bind(this);
this.showConfirmLDIFImport = this.showConfirmLDIFImport.bind(this);
@@ -411,13 +416,20 @@ export class Suffix extends React.Component {
}
// Create a new suffix
- const cmd = [
+ let cmd = [
"dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
"backend", "create", "--be-name", this.state.subSuffixBeName,
"--suffix=" + this.state.subSuffixValue + "," + this.props.suffix,
"--parent-suffix=" + this.props.suffix
];
+ if (this.state.createSampleEntries) {
+ cmd.push('--create-entries');
+ }
+ if (this.state.createSuffixEntry) {
+ cmd.push('--create-suffix');
+ }
+
log_cmd("createSubSuffix", "Create a sub suffix", cmd);
cockpit
.spawn(cmd, { superuser: true, err: "message" })
@@ -539,7 +551,7 @@ export class Suffix extends React.Component {
this.state.createLinkName
];
if (this.state.createUseStartTLS) {
- cmd.push("--use-starttls");
+ cmd.push("--use-starttls=on");
}
log_cmd("createLink", "Create database link", cmd);
cockpit
@@ -588,6 +600,25 @@ export class Suffix extends React.Component {
}, this.checkPasswords);
}
+ handleRadioChange(e) {
+ // Handle the create suffix init option radio button group
+ let noInit = false;
+ let addSuffix = false;
+ let addSample = false;
+ if (e.target.id == "noSuffixInit") {
+ noInit = true;
+ } else if (e.target.id == "createSuffixEntry") {
+ addSuffix = true;
+ } else { // createSampleEntries
+ addSample = true;
+ }
+ this.setState({
+ noSuffixInit: noInit,
+ createSuffixEntry: addSuffix,
+ createSampleEntries: addSample
+ });
+ }
+
//
// Delete suffix
//
@@ -847,8 +878,12 @@ export class Suffix extends React.Component {
showModal={this.state.showSubSuffixModal}
closeHandler={this.closeSubSuffixModal}
handleChange={this.handleChange}
+ handleRadioChange={this.handleRadioChange}
saveHandler={this.createSubSuffix}
suffix={this.props.suffix}
+ noInit={this.state.noSuffixInit}
+ addSuffix={this.state.createSuffixEntry}
+ addSample={this.state.createSampleEntries}
error={this.state.errObj}
/>
<ImportModal
diff --git a/src/cockpit/389-console/src/lib/security/ciphers.jsx b/src/cockpit/389-console/src/lib/security/ciphers.jsx
index 4714fcb..c07c0dc 100644
--- a/src/cockpit/389-console/src/lib/security/ciphers.jsx
+++ b/src/cockpit/389-console/src/lib/security/ciphers.jsx
@@ -89,7 +89,7 @@ export class Ciphers extends React.Component {
.done(() => {
this.props.addNotification(
"success",
- `Successfully set cipher preferences. You must restart the server for these changes to take effect.`
+ `Successfully set cipher preferences. You must restart the Directory Server for these changes to take effect.`
);
this.setState({
saving: false,
diff --git a/src/cockpit/389-console/src/lib/tools.jsx b/src/cockpit/389-console/src/lib/tools.jsx
index eb0a67c..dc8a701 100644
--- a/src/cockpit/389-console/src/lib/tools.jsx
+++ b/src/cockpit/389-console/src/lib/tools.jsx
@@ -111,3 +111,14 @@ export function bad_file_name(file_name) {
}
return false;
}
+
+export function valid_port (val) {
+ // Validate value is a number and between 1 and 65535
+ let result = !isNaN(val);
+ if (result) {
+ if (val < 1 || val > 65535) {
+ result = false;
+ }
+ }
+ return result;
+}
diff --git a/src/cockpit/389-console/src/replication.js b/src/cockpit/389-console/src/replication.js
index e28d175..92566ad 100644
--- a/src/cockpit/389-console/src/replication.js
+++ b/src/cockpit/389-console/src/replication.js
@@ -271,7 +271,6 @@ function get_and_set_repl_agmts () {
* Get the replication agreements for the selected suffix
*/
var suffix = $("#select-repl-agmt-suffix").val();
-
if (suffix) {
console.log("Loading replication agreements...");
var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','repl-agmt', 'list', '--suffix=' + suffix ];
@@ -1133,6 +1132,13 @@ $(document).ready( function() {
$("#nsds5replicabinddn").css("border-color", "initial");
cmd_args.push('--bind-dn=' + agmt_bind);
}
+ if (agmt_name == "") {
+ $("#agmt-cn").css("border-color", "red");
+ param_err = true;
+ } else {
+ $("#agmt-cn").css("border-color", "initial");
+ cmd_args.push('"' + agmt_name + '"');
+ }
if (param_err ){
popup_msg("Error", "Missing required parameters");
return;
@@ -1265,13 +1271,6 @@ $(document).ready( function() {
if (agmt_init == "online-init") {
init_replica = true;
}
- if ( agmt_name == "") {
- $("#agmt-cn").css("border-color", "red");
- param_err = true;
- } else {
- $("#agmt-cn").css("border-color", "initial");
- cmd_args.push('"' + agmt_name + '"');
- }
// Create agreement in DS
if ( editing ) {
diff --git a/src/cockpit/389-console/src/security.jsx b/src/cockpit/389-console/src/security.jsx
index 77b25f9..fd681e2 100644
--- a/src/cockpit/389-console/src/security.jsx
+++ b/src/cockpit/389-console/src/security.jsx
@@ -2,7 +2,7 @@ import cockpit from "cockpit";
import React from "react";
import Switch from "react-switch";
import { NotificationController, ConfirmPopup } from "./lib/notifications.jsx";
-import { log_cmd } from "./lib/tools.jsx";
+import { log_cmd, valid_port } from "./lib/tools.jsx";
import { Typeahead } from "react-bootstrap-typeahead";
import { CertificateManagement } from "./lib/security/certificateManagement.jsx";
import { SecurityEnableModal } from "./lib/security/securityModals.jsx";
@@ -18,6 +18,7 @@ import {
ControlLabel,
Button,
Checkbox,
+ Icon,
Spinner
} from "patternfly-react";
import PropTypes from "prop-types";
@@ -475,6 +476,26 @@ export class Security extends React.Component {
}
saveSecurityConfig () {
+ // Validate some setting first
+ let sslMin = this.state._sslVersionMin;
+ let sslMax = this.state._sslVersionMax;
+ if (this.state._sslVersionMin != this.state.sslVersionMin) {
+ sslMin = this.state.sslVersionMin;
+ }
+ if (this.state._sslVersionMax != this.state.sslVersionMax) {
+ sslMax = this.state.sslVersionMax;
+ }
+
+ if (sslMin > sslMax) {
+ this.addNotification(
+ "error",
+ `The TLS minimum version but be less than or equal to the TLS maximum version`
+ );
+ // Reset page
+ this.loadSecurityConfig();
+ return;
+ }
+
let cmd = [
'dsconf', '-j', 'ldapi://%2fvar%2frun%2fslapd-' + this.props.serverId + '.socket',
'security', 'set'
@@ -493,6 +514,15 @@ export class Security extends React.Component {
cmd.push("--tls-client-auth=" + this.state.clientAuth);
}
if (this.state._securePort != this.state.securePort) {
+ if (!valid_port(this.state.securePort)) {
+ this.addNotification(
+ "error",
+ `The Secure Port is invalid, it must be a number between 1 and 65535`
+ );
+ // Reset page
+ this.loadSecurityConfig();
+ return;
+ }
cmd.push("--secure-port=" + this.state.securePort);
}
if (this.state._secureListenhost != this.state.secureListenhost) {
@@ -522,7 +552,7 @@ export class Security extends React.Component {
if (cmd.length > 5) {
log_cmd("saveSecurityConfig", "Applying security config change", cmd);
- let msg = "Successfully updated security configuration. You must restart the server for these changes to take effect.";
+ let msg = "Successfully updated security configuration. You must restart the Directory Server for these changes to take effect.";
this.setState({
// Start the spinner
@@ -592,7 +622,6 @@ export class Security extends React.Component {
render() {
let securityPage = "";
let serverCert = [this.state.nssslpersonalityssl];
-
if (this.state.loaded && !this.state.saving) {
let configPage = "";
if (this.state.securityEnabled) {
@@ -603,7 +632,7 @@ export class Security extends React.Component {
Server Secure Port
</Col>
<Col sm={4}>
- <input id="securePort" className="ds-input-auto" onChange={this.handleChange} type="text" defaultValue={this.state.securePort} />
+ <input id="securePort" className="ds-input-auto" onChange={this.handleChange} type="text" value={this.state.securePort} />
</Col>
</Row>
<Row className="ds-margin-top" title="This parameter can be used to restrict the Directory Server instance to a single IP interface (hostname, or IP address). This parameter specifically sets what interface to use for TLS traffic. Requires restart. (nsslapd-securelistenhost).">
@@ -611,7 +640,7 @@ export class Security extends React.Component {
Secure Listen Host
</Col>
<Col sm={4}>
- <input id="secureListenhost" className="ds-input-auto" type="text" onChange={this.handleChange} defaultValue={this.state.secureListenhost} />
+ <input id="secureListenhost" className="ds-input-auto" type="text" onChange={this.handleChange} value={this.state.secureListenhost} />
</Col>
</Row>
<Row className="ds-margin-top" title="The name, or nickname, of the server certificate inthe NSS datgabase the server should use (nsSSLPersonalitySSL).">
@@ -635,8 +664,7 @@ export class Security extends React.Component {
Minimum TLS Version
</Col>
<Col sm={4}>
- <select id="sslVersionMin" className="btn btn-default dropdown ds-select" onChange={this.handleChange} defaultValue={this.state.sslVersionMin}>
- <option />
+ <select id="sslVersionMin" className="btn btn-default dropdown ds-select" onChange={this.handleChange} value={this.state.sslVersionMin}>
<option>TLS1.3</option>
<option>TLS1.2</option>
<option>TLS1.1</option>
@@ -650,8 +678,7 @@ export class Security extends React.Component {
Maximum TLS Version
</Col>
<Col sm={4}>
- <select id="sslVersionMax" className="btn btn-default dropdown ds-select" onChange={this.handleChange} defaultValue={this.state.sslVersionMax}>
- <option />
+ <select id="sslVersionMax" className="btn btn-default dropdown ds-select" onChange={this.handleChange} value={this.state.sslVersionMax}>
<option>TLS1.3</option>
<option>TLS1.2</option>
<option>TLS1.1</option>
@@ -665,7 +692,7 @@ export class Security extends React.Component {
Client Authentication
</Col>
<Col sm={4}>
- <select id="clientAuth" className="btn btn-default dropdown ds-select" onChange={this.handleChange} defaultValue={this.state.clientAuth}>
+ <select id="clientAuth" className="btn btn-default dropdown ds-select" onChange={this.handleChange} value={this.state.clientAuth}>
<option>off</option>
<option>allowed</option>
<option>required</option>
@@ -677,7 +704,7 @@ export class Security extends React.Component {
Validate Certificate
</Col>
<Col sm={4}>
- <select id="validateCert" className="btn btn-default dropdown ds-select" onChange={this.handleChange} defaultValue={this.state.validateCert}>
+ <select id="validateCert" className="btn btn-default dropdown ds-select" onChange={this.handleChange} value={this.state.validateCert}>
<option>warn</option>
<option>on</option>
<option>off</option>
@@ -761,13 +788,20 @@ export class Security extends React.Component {
<Col componentClass={ControlLabel} sm={2}>
Security Enabled
</Col>
- <Col sm={2}>
+ <Col sm={1}>
<Switch
+ className="ds-switch"
onChange={this.handleSwitchChange}
checked={this.state.securityEnabled}
height={20}
/>
</Col>
+ <Col>
+ <Icon className="ds-left-margin ds-refresh"
+ type="fa" name="refresh" title="Refresh security settings"
+ onClick={this.loadSecurityConfig}
+ />
+ </Col>
</Row>
<hr />
{configPage}
diff --git a/src/cockpit/389-console/src/servers.html b/src/cockpit/389-console/src/servers.html
index 04678e8..1d17872 100644
--- a/src/cockpit/389-console/src/servers.html
+++ b/src/cockpit/389-console/src/servers.html
@@ -136,15 +136,15 @@
<form>
<div>
<label for="nsslapd-rootdn" class="ds-config-label" title="The DN of the unrestricted directory manager (nsslapd-rootdn).">Directory Manager DN</label><input
- class="ds-input" type="text" autocomplete="username" id="nsslapd-rootdn" placeholder="cn=directory manager" value="cn=Directory Manager" size="40"/>
+ class="ds-input" type="text" readonly id="nsslapd-rootdn" value="cn=Directory Manager" size="40"/>
</div>
<div>
<label for="nsslapd-rootpw" class="ds-config-label" title="The Directory Manager password (nsslapd-rootpw).">Directory Manager Password</label><input
- class="ds-input" type="password" autocomplete="new-password" id="nsslapd-rootpw" size="40"/>
+ class="ds-input" type="password" id="nsslapd-rootpw" size="40"/>
</div>
<div>
<label for="nsslapd-rootpw-confirm" class="ds-config-label" title="Confirm directory manager password.">Confirm Password</label><input
- class="ds-input" type="password" autocomplete="new-password" id="nsslapd-rootpw-confirm" size="40"/>
+ class="ds-input" type="password" id="nsslapd-rootpw-confirm" size="40"/>
</div>
<div>
<label for="nsslapd-rootpwstoragescheme" class="ds-config-label" title="Set the Directory Manager password storage scheme (nsslapd-rootpwstoragescheme).">Password Storage Scheme</label><select
@@ -525,8 +525,8 @@
<option>day</option>
<option>week</option>
<option>month</option>
- </select> at <input class="ds-input" type="text" title="Hour" id="nsslapd-accesslog-logrotationsynchour" placeholder="0" size="1"/> : <input class="ds-input" type="text" placeholder="0"
- title="Minute" id="nsslapd-accesslog-logrotationsyncminute" size="1"/>
+ </select> at <input class="ds-input" type="text" title="Hour" id="nsslapd-accesslog-logrotationsynchour" placeholder="0" size="1"/> : <input class="ds-input" type="text" placeholder="0"
+ title="Minute" id="nsslapd-accesslog-logrotationsyncmin" size="1"/>
</div>
</div>
<p></p>
@@ -615,7 +615,7 @@
<option>week</option>
<option>month</option>
</select> at <input class="ds-input" type="text" title="Hour" id="nsslapd-auditlog-logrotationsynchour" placeholder="0" size="1"/> : <input class="ds-input" type="text" placeholder="0"
- title="Minute" id="nsslapd-auditlog-logrotationsyncminute" size="1"/>
+ title="Minute" id="nsslapd-auditlog-logrotationsyncmin" size="1"/>
</div>
</div>
<p></p>
@@ -674,7 +674,7 @@
<option>week</option>
<option>month</option>
</select> at <input class="ds-input" type="text" title="Hour" id="nsslapd-auditfaillog-logrotationsynchour" placeholder="0" size="1"/> : <input class="ds-input" type="text" placeholder="0"
- title="Minute" id="nsslapd-auditfaillog-logrotationsyncminute" size="1"/>
+ title="Minute" id="nsslapd-auditfaillog-logrotationsyncmin" size="1"/>
</div>
</div>
<h4 class="ds-sub-header">Deletion Policy</h4>
@@ -731,7 +731,7 @@
<option>week</option>
<option>month</option>
</select> at <input class="ds-input" type="text" title="Hour" id="nsslapd-errorlog-logrotationsynchour" placeholder="0" size="1"/> : <input class="ds-input" type="text" placeholder="0"
- title="Minute" id="nsslapd-errorlog-logrotationsyncminute" size="1"/>
+ title="Minute" id="nsslapd-errorlog-logrotationsyncmin" size="1"/>
</div>
</div>
@@ -950,14 +950,14 @@
<h3 class="ds-config-header">LDAPI & Autobind Settings</h3>
<div class="ldapi-attrs ds-inline" hidden>
<div>
- <label for="nsslapd-ldapifilepath" class="ds-config-label" title="The Unix socket file (nsslapd-ldapifilepath).">LDAPI Socket File Path</label><input
+ <label for="nsslapd-ldapifilepath" class="ds-config-label" title="The Unix socket file (nsslapd-ldapifilepath). The UI requires this exact path so it is a read-only setting.">LDAPI Socket File Path</label><input
class="ds-input" type="text" id="nsslapd-ldapifilepath" size="35" readonly/>
</div>
<div class="ds-inline">
<div class="autobind-attrs">
<div>
- <label for="nsslapd-ldapimaprootdn" class="ds-config-label" title="Map the Unix root entry to this Directory Manager DN (nsslapd-ldapimaprootdn).">DN to map "root" To</label><input
- class="ds-input" type="text" id="nsslapd-ldapimaprootdn" placeholder="e.g. cn=Directory Manager" size="35"/>
+ <label for="nsslapd-ldapimaprootdn" class="ds-config-label" title="Map the Unix root entry to this Directory Manager DN (nsslapd-ldapimaprootdn). The UI requires this to be set to the current root DN so it is a read-only setting">DN to map "root" To</label><input
+ class="ds-input" type="text" id="nsslapd-ldapimaprootdn" readonly size="35"/>
</div>
<div>
<p></p>
diff --git a/src/cockpit/389-console/src/servers.js b/src/cockpit/389-console/src/servers.js
index b2a4b0f..7e34a5a 100644
--- a/src/cockpit/389-console/src/servers.js
+++ b/src/cockpit/389-console/src/servers.js
@@ -211,7 +211,7 @@ function get_and_set_config () {
config_loaded = 1;
check_inst_alive();
}).fail(function(data) {
- popup_err("Error", "Failed to set config\n" + data.message);
+ popup_err("Error", "Failed to get config\n" + data.message);
check_inst_alive(1);
});
}
@@ -311,34 +311,56 @@ function get_and_set_sasl () {
}
function apply_mods(mods) {
- var mod = mods.pop();
+ let mod = mods.pop();
- if (!mod){
- popup_success("Successfully updated configuration");
- return; /* all done*/
+ if (!mod) {
+ return 0; /* all done*/
}
- var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','config', 'replace'];
+ let cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'config', 'replace'];
cmd.push(mod.attr + "=" + mod.val);
cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).then(function() {
config_values[mod.attr] = mod.val;
// Continue with next mods (if any))
apply_mods(mods);
- }, function(ex) {
- popup_err("Failed to update attribute: " + mod.attr, ex.message);
+ }, function(ex, data) {
+ popup_err("Failed to update attribute: " + mod.attr, data);
// Reset HTML for remaining values that have not been processed
$("#" + mod.attr).val(config_values[mod.attr]);
for (remaining in mods) {
$("#" + remaining.attr).val(config_values[remaining.attr]);
}
check_inst_alive(0);
- return; // Stop on error
+ return -1; // Stop on error
+ });
+}
+
+function delete_mods(mods) {
+ let mod = mods.pop();
+
+ if (!mod) {
+ return 0; /* all done*/
+ }
+ var cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket', 'config', 'delete', mod.attr];
+ cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).then(function() {
+ config_values[mod.attr] = "";
+ // Continue with next mods (if any))
+ delete_mods(mods);
+ }, function(ex, data) {
+ popup_err("Failed to delete attribute: " + mod.attr, data);
+ // Reset HTML for remaining values that have not been processed
+ $("#" + mod.attr).val(config_values[mod.attr]);
+ for (remaining in mods) {
+ $("#" + remaining.attr).val(config_values[remaining.attr]);
+ }
+ check_inst_alive(0);
+ return -1; // Stop on error
});
}
function save_config() {
// Loop over current config_values check for differences
- var mod_list = [];
-
+ let mod_list = [];
+ let del_list = [];
for (var attr in config_values) {
var mod = {};
if ( $("#" + attr).is(':checkbox')) {
@@ -360,7 +382,6 @@ function save_config() {
} else {
// Normal input
var val = $("#" + attr).val();
-
// But first check for rootdn-pw changes and check confirm input matches
if (attr == "nsslapd-rootpw") {
if (val != config_values[attr] || val != $("#nsslapd-rootpw-confirm").val()) {
@@ -379,16 +400,34 @@ function save_config() {
}
if (attr == "nsslapd-port") {
- if (!valid_num(config_values[attr])) {
+ if (!valid_port(val)) {
popup_msg("Port number is not valid");
$("#nsslapd-port").val(config_values[attr]);
}
}
- if ( val && val != config_values[attr]) {
+ if (attr.indexOf("logrotationsynchour") != -1) {
+ if (!valid_num(val) || val < 0 || val > 23) {
+ popup_msg("Invalid value", "You must use a number between 0 - 23 for: " + attr);
+ $("#" + attr).val(config_values[attr])
+ return;
+ }
+ }
+ if (attr.indexOf("logrotationsyncmin") != -1) {
+ if (!valid_num(val) || val < 0 || val > 59){
+ popup_msg("Invalid value", "You must use a number between 0 - 59 for: " + attr);
+ $("#" + attr).val(config_values[attr])
+ return;
+ }
+ }
+
+ if (val && val != config_values[attr]) {
mod['attr'] = attr;
mod['val'] = val;
mod_list.push(mod);
+ } else if (val == "" && val != config_values[attr]) {
+ mod['attr'] = attr;
+ del_list.push(mod);
}
}
}
@@ -434,8 +473,19 @@ function save_config() {
}
// Build dsconf commands to apply all the mods
- if (mod_list.length) {
- apply_mods(mod_list);
+ if (mod_list.length || del_list.length) {
+ let err = 0;
+ if (mod_list.length) {
+ if (apply_mods(mod_list) == -1) {
+ return;
+ }
+ }
+ if (del_list.length) {
+ if (delete_mods(del_list) == -1) {
+ return;
+ }
+ }
+ popup_success("Successfully updated configuration");
} else {
// No changes to save, log msg? popup_msg()
}
@@ -1500,7 +1550,7 @@ $(document).ready( function() {
report_err($("#create-inst-port"), 'You must provide a port number');
$("#create-inst-port").css("border-color", "red");
return;
- } else if (!valid_num(server_port)) {
+ } else if (!valid_port(server_port)) {
report_err($("#create-inst-port"), 'Port must be a number between 1 and 65534!');
$("#create-inst-port").css("border-color", "red");
return;
@@ -1514,7 +1564,7 @@ $(document).ready( function() {
report_err($("#create-inst-secureport"), 'You must provide a secure port number');
$("#create-inst-secureport").css("border-color", "red");
return;
- } else if (!valid_num(secure_port)) {
+ } else if (!valid_port(secure_port)) {
report_err($("#create-inst-secureport"), 'Secure port must be a number!');
$("#create-inst-secureport").css("border-color", "red");
return;
@@ -1584,8 +1634,8 @@ $(document).ready( function() {
}
if ( $("#create-sample-entries").is(":checked") ) {
setup_inf += '\nsample_entries = yes\n';
- } else {
- setup_inf += '\nsample_entries = no\n';
+ } else if ( $("#create-suffix-entry").is(":checked") ) {
+ setup_inf += '\ncreate_suffix_entry = yes\n';
}
}
@@ -1599,9 +1649,9 @@ $(document).ready( function() {
* [5] Create the instance
* [6] Remove setup file
*/
- cockpit.spawn(["hostname", "--fqdn"], { superuser: true, "err": "message" }).fail(function(ex) {
+ cockpit.spawn(["hostname", "--fqdn"], { superuser: true, "err": "message" }).fail(function(ex, data) {
// Failed to get FQDN
- popup_err("Failed to get hostname!", ex.message);
+ popup_err("Failed to get hostname!", data);
}).done(function (data){
/*
* We have FQDN, so set the hostname in inf file, and create the setup file
@@ -1610,38 +1660,38 @@ $(document).ready( function() {
var setup_file = "/tmp/389-setup-" + (new Date).getTime() + ".inf";
var rm_cmd = ['rm', setup_file];
var create_file_cmd = ['touch', setup_file];
- cockpit.spawn(create_file_cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+ cockpit.spawn(create_file_cmd, { superuser: true, "err": "message" }).fail(function(ex, data) {
// Failed to create setup file
- popup_err("Failed to create installation file!", ex.message);
+ popup_err("Failed to create installation file!", data);
}).done(function (){
/*
* We have our new setup file, now set permissions on that setup file before we add sensitive data
*/
var chmod_cmd = ['chmod', '600', setup_file];
- cockpit.spawn(chmod_cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+ cockpit.spawn(chmod_cmd, { superuser: true, "err": "message" }).fail(function(ex, data) {
// Failed to set permissions on setup file
cockpit.spawn(rm_cmd, { superuser: true }); // Remove Inf file with clear text password
$("#create-inst-spinner").hide();
- popup_err("Failed to set permission on setup file " + setup_file + ": ", ex.message);
+ popup_err("Failed to set permission on setup file " + setup_file + ": ", data);
}).done(function (){
/*
* Success we have our setup file and it has the correct permissions.
* Now populate the setup file...
*/
- var cmd = ["/bin/sh", "-c", '/usr/bin/echo -e "' + setup_inf + '" >> ' + setup_file];
- cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) {
+ let cmd = ["/bin/sh", "-c", '/usr/bin/echo -e "' + setup_inf + '" >> ' + setup_file];
+ cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex, data) {
// Failed to populate setup file
- popup_err("Failed to populate installation file!", ex.message);
+ popup_err("Failed to populate installation file!", data);
}).done(function (){
/*
* Next, create the instance...
*/
cmd = [DSCREATE, 'from-file', setup_file];
- cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV] }).fail(function(ex) {
+ cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV] }).fail(function(ex, data) {
// Failed to create the new instance!
cockpit.spawn(rm_cmd, { superuser: true }); // Remove Inf file with clear text password
$("#create-inst-spinner").hide();
- popup_err("Failed to create instance!", ex.message);
+ popup_err("Failed to create instance!", data);
}).done(function (){
// Success!!! Now cleanup everything up...
cockpit.spawn(rm_cmd, { superuser: true }); // Remove Inf file with clear text password
diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py
index 8e6eb66..0ff4335 100644
--- a/src/lib389/lib389/__init__.py
+++ b/src/lib389/lib389/__init__.py
@@ -2940,7 +2940,7 @@ class DirSrv(SimpleLDAPObject, object):
json_result = {'type': 'list', 'items': []}
for backup in dirlist:
bak = bakdir + "/" + backup
- bak_date = os.path.getctime(bak)
+ bak_date = os.path.getmtime(bak)
bak_date = datetime.fromtimestamp(bak_date).strftime('%Y-%m-%d %H:%M:%S')
bak_size = subprocess.check_output(['du', '-sh', bak]).split()[0].decode('utf-8')
if use_json:
@@ -2980,12 +2980,13 @@ class DirSrv(SimpleLDAPObject, object):
json_result = {'type': 'list', 'items': []}
for ldif in dirlist:
fullpath = ldifdir + "/" + ldif
- ldif_date = os.path.getctime(fullpath)
+ ldif_date = os.path.getmtime(fullpath)
ldif_date = datetime.fromtimestamp(ldif_date).strftime('%Y-%m-%d %H:%M:%S')
ldif_size = subprocess.check_output(['du', '-sh', fullpath]).split()[0].decode('utf-8')
ldif_suffix = self.getLDIFSuffix(fullpath)
if ldif_suffix == "":
- ldif_suffix = "???"
+ # This is not a valid LDIF file
+ ldif_suffix = "Invalid LDIF"
if use_json:
json_item = [ldif, ldif_date, ldif_size, ldif_suffix]
json_result['items'].append(json_item)
diff --git a/src/lib389/lib389/_mapped_object.py b/src/lib389/lib389/_mapped_object.py
index 36ddc2e..010d964 100644
--- a/src/lib389/lib389/_mapped_object.py
+++ b/src/lib389/lib389/_mapped_object.py
@@ -282,7 +282,7 @@ class DSLdapObject(DSLogging):
mods = []
for arg in args:
- if isinstance(arg[1], list):
+ if isinstance(arg[1], list) or isinstance(arg[1], tuple):
value = ensure_list_bytes(arg[1])
else:
value = [ensure_bytes(arg[1])]
diff --git a/src/lib389/lib389/chaining.py b/src/lib389/lib389/chaining.py
index a25bbb6..7a0401e 100644
--- a/src/lib389/lib389/chaining.py
+++ b/src/lib389/lib389/chaining.py
@@ -124,7 +124,7 @@ class ChainingLink(DSLdapObject):
pass
# Delete the monitoring entry
- monitor = self.get_monitor(rdn)
+ monitor = self.get_monitor()
monitor.delete()
# Delete the link
diff --git a/src/lib389/lib389/cli_conf/backend.py b/src/lib389/lib389/cli_conf/backend.py
index 36e32ec..0b55ba4 100644
--- a/src/lib389/lib389/cli_conf/backend.py
+++ b/src/lib389/lib389/cli_conf/backend.py
@@ -8,6 +8,12 @@
# --- END COPYRIGHT BLOCK ---
from lib389.backend import Backend, Backends, DatabaseConfig
+from lib389.configurations.sample import (
+ create_base_domain,
+ create_base_org,
+ create_base_orgunit,
+ create_base_cn,
+ )
from lib389.chaining import (ChainingLinks)
from lib389.index import Index, VLVIndex, VLVSearches
from lib389.monitor import MonitorLDBM
@@ -172,6 +178,29 @@ def backend_create(inst, basedn, log, args):
be = Backend(inst)
be.create(properties=props)
+ if args.create_suffix and not args.create_entries:
+ # Set basic ACIs (taken from instance/setup.py)
+ o_aci = '(targetattr="o || description || objectClass")(targetfilter="(objectClass=organization)")(version 3.0; acl "Enable anyone o read"; allow (read, search, compare)(userdn="ldap:///anyone");)'
+ dc_aci = '(targetattr="dc || description || objectClass")(targetfilter="(objectClass=domain)")(version 3.0; acl "Enable anyone domain read"; allow (read, search, compare)(userdn="ldap:///anyone");)',
+ ou_aci = '(targetattr="ou || description || objectClass")(targetfilter="(objectClass=organizationalUnit)")(version 3.0; acl "Enable anyone ou read"; allow (read, search, compare)(userdn="ldap:///anyone");)'
+ cn_aci = '(targetattr="cn || description || objectClass")(targetfilter="(objectClass=nscontainer)")(version 3.0; acl "Enable anyone cn read"; allow (read, search, compare)(userdn="ldap:///anyone");)'
+ suffix_rdn_attr = args.suffix.split('=')[0].lower()
+ if suffix_rdn_attr == 'dc':
+ domain = create_base_domain(inst, args.suffix)
+ domain.add('aci', dc-aci)
+ elif suffix_rdn_attr == 'o':
+ org = create_base_org(inst, args.suffix)
+ org.add('aci', o_aci)
+ elif suffix_rdn_attr == 'ou':
+ orgunit = create_base_orgunit(inst, args.suffix)
+ orgunit.add('aci', ou_aci)
+ elif suffix_rdn_attr == 'cn':
+ cn = create_base_cn(inst, args.suffix)
+ cn.add('aci', cn_aci)
+ else:
+ # Unsupported rdn
+ raise ValueError("Suffix RDN is not supported for creating suffix object. Only 'dc', 'o', 'ou', and 'cn' are supported.")
+
print("The database was sucessfully created")
@@ -1052,6 +1081,8 @@ def create_parser(subparsers):
create_parser.add_argument('--suffix', required=True, help='The database suffix DN, for example "dc=example,dc=com"')
create_parser.add_argument('--be-name', required=True, help='The database backend name, for example "userroot"')
create_parser.add_argument('--create-entries', action='store_true', help='Create sample entries in the database')
+ create_parser.add_argument('--create-suffix', action='store_true',
+ help="Create the suffix object entry in the database. Only suffixes using the attributes 'dc', 'o', 'ou', or 'cn' are supported in this feature")
#######################################################
# Delete backend
diff --git a/src/lib389/lib389/cli_conf/security.py b/src/lib389/lib389/cli_conf/security.py
index 20f2574..0273817 100644
--- a/src/lib389/lib389/cli_conf/security.py
+++ b/src/lib389/lib389/cli_conf/security.py
@@ -91,7 +91,10 @@ def _security_generic_set(inst, basedn, logs, args, attrs_map):
if arg is None:
continue
dsobj = props.cls(inst)
- dsobj.replace(props.attr, arg)
+ if arg != "":
+ dsobj.replace(props.attr, arg)
+ else:
+ dsobj.remove_all(props.attr)
def _security_generic_get_parser(parent, attrs_map, help):
diff --git a/src/lib389/lib389/configurations/sample.py b/src/lib389/lib389/configurations/sample.py
index 25a1b32..f30b8d6 100644
--- a/src/lib389/lib389/configurations/sample.py
+++ b/src/lib389/lib389/configurations/sample.py
@@ -9,6 +9,9 @@
from ldap import dn
from lib389.idm.domain import Domain
+from lib389.idm.organization import Organization
+from lib389.idm.organizationalunit import OrganizationalUnit
+from lib389.idm.nscontainer import nsContainer
from lib389.utils import ensure_str
@@ -42,3 +45,53 @@ def create_base_domain(instance, basedn):
return domain
+
+def create_base_org(instance, basedn):
+ """Create the base organization object"""
+
+ org = Organization(instance, dn=basedn)
+ # Explode the dn to get the first bit.
+ avas = dn.str2dn(basedn)
+ o_ava = avas[0][0][1]
+
+ org.create(properties={
+ # I think in python 2 this forces unicode return ...
+ 'o': o_ava,
+ 'description': basedn,
+ })
+
+ return org
+
+
+def create_base_orgunit(instance, basedn):
+ """Create the base org unit object for a org unit"""
+
+ orgunit = OrganizationalUnit(instance, dn=basedn)
+ # Explode the dn to get the first bit.
+ avas = dn.str2dn(basedn)
+ ou_ava = avas[0][0][1]
+
+ orgunit.create(properties={
+ # I think in python 2 this forces unicode return ...
+ 'ou': ou_ava,
+ 'description': basedn,
+ })
+
+ return orgunit
+
+
+def create_base_cn(instance, basedn):
+ """Create the base nsContainer object"""
+
+ cn = nsContainer(instance, dn=basedn)
+ # Explode the dn to get the first bit.
+ avas = dn.str2dn(basedn)
+ cn_ava = avas[0][0][1]
+
+ cn.create(properties={
+ # I think in python 2 this forces unicode return ...
+ 'cn': cn_ava,
+ 'description': basedn,
+ })
+
+ return cn
diff --git a/src/lib389/lib389/replica.py b/src/lib389/lib389/replica.py
index 21c1ada..48a14cf 100644
--- a/src/lib389/lib389/replica.py
+++ b/src/lib389/lib389/replica.py
@@ -1264,15 +1264,15 @@ class Replica(DSLdapObject):
raise ValueError('Failed to update replica: ' + str(e))
elif replicarole == ReplicaRole.CONSUMER and newrole == ReplicaRole.MASTER:
try:
- self.replace_many([(REPL_TYPE, str(REPLICA_RDWR_TYPE)),
+ self.replace_many((REPL_TYPE, str(REPLICA_RDWR_TYPE)),
(REPL_FLAGS, str(REPLICA_FLAGS_WRITE)),
- (REPL_ID, str(rid))])
+ (REPL_ID, str(rid)))
except ldap.LDAPError as e:
raise ValueError('Failed to update replica: ' + str(e))
elif replicarole == ReplicaRole.HUB and newrole == ReplicaRole.MASTER:
try:
- self.replace_many([(REPL_TYPE, str(REPLICA_RDWR_TYPE)),
- (REPL_ID, str(rid))])
+ self.replace_many((REPL_TYPE, str(REPLICA_RDWR_TYPE)),
+ (REPL_ID, str(rid)))
except ldap.LDAPError as e:
raise ValueError('Failed to update replica: ' + str(e))
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] 02/02: Ticket 50593 Investigate URP handling on standalone instance
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
lkrispen pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
commit 1ab768e21de737f1b3abba2ce97f66a9c101aa81
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
AuthorDate: Thu Sep 12 09:42:31 2019 +0200
Ticket 50593 Investigate URP handling on standalone instance
Bug: If the MMR plugin is enabled (on by default)
even if no replica was configured the MMR plugins were called
and eventually tried to generate cenotaphs for modrdn ops-
Fix: Check early if the operation affects a backend without replication
and return
---
ldap/servers/plugins/replication/repl5_plugins.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
index abb3e68..e6b2fdb 100644
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -575,6 +575,10 @@ multimaster_mmr_preop (Slapi_PBlock *pb, int flags)
{
int rc= SLAPI_PLUGIN_SUCCESS;
+ if (!is_mmr_replica(pb)) {
+ return rc;
+ }
+
switch (flags)
{
case SLAPI_PLUGIN_BE_PRE_ADD_FN:
@@ -598,6 +602,10 @@ multimaster_mmr_postop (Slapi_PBlock *pb, int flags)
{
int rc= SLAPI_PLUGIN_SUCCESS;
+ if (!is_mmr_replica(pb)) {
+ return rc;
+ }
+
switch (flags)
{
case SLAPI_PLUGIN_BE_TXN_POST_ADD_FN:
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] 01/02: Issue 50506 - Fix regression for relication stripattrs
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
lkrispen pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
commit 9597dddc0169032c12b381a09657c11f6bf883be
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
AuthorDate: Thu Sep 12 13:42:39 2019 +0200
Issue 50506 - Fix regression for relication stripattrs
Bug: When parsing the provided attribute value, a reference was used
and modified, the original attribute was corrupted
Fix: Use a copy for parsing
Reviewed by: ?
---
ldap/servers/plugins/replication/repl5_agmt.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index f2f16f5..2948270 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -530,9 +530,10 @@ agmt_new_from_entry(Slapi_Entry *e)
* Extract the attributes to strip for "empty" mods
*/
ra->attrs_to_strip = NULL;
- tmpstr = (char *)slapi_entry_attr_get_ref(e, type_nsds5ReplicaStripAttrs);
+ tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaStripAttrs);
if (NULL != tmpstr) {
ra->attrs_to_strip = slapi_str2charray_ext(tmpstr, " ", 0);
+ slapi_ch_free_string(&tmpstr);
}
if (!agmt_is_valid(ra)) {
@@ -2954,7 +2955,7 @@ agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e)
{
char *tmpstr = NULL;
- tmpstr = (char *)slapi_entry_attr_get_ref(e, type_nsds5ReplicaStripAttrs);
+ tmpstr = slapi_entry_attr_get_charptr(e, type_nsds5ReplicaStripAttrs);
PR_Lock(ra->lock);
if (ra->attrs_to_strip) {
@@ -2964,6 +2965,7 @@ agmt_set_attrs_to_strip(Repl_Agmt *ra, Slapi_Entry *e)
ra->attrs_to_strip = NULL;
} else {
ra->attrs_to_strip = slapi_str2charray_ext(tmpstr, " ", 0);
+ slapi_ch_free_string(&tmpstr);
}
PR_Unlock(ra->lock);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50546 - fix more UI issues(part 2)
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 7ee2626 Issue 50546 - fix more UI issues(part 2)
7ee2626 is described below
commit 7ee262688bed38a0d5e2130a89c0e99e21b43d26
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Sep 10 15:13:38 2019 -0400
Issue 50546 - fix more UI issues(part 2)
Description: Fixed minor issues not fully addressed from the last commit
relates: https://pagure.io/389-ds-base/issue/50546
Reviewed by: mreynolds (one line commit rule)
---
src/cockpit/389-console/src/ds.js | 22 +---------------
src/cockpit/389-console/src/index.html | 9 ++++---
src/cockpit/389-console/src/schema.html | 6 ++---
src/cockpit/389-console/src/servers.html | 17 +++---------
src/cockpit/389-console/src/servers.js | 45 +++-----------------------------
5 files changed, 16 insertions(+), 83 deletions(-)
diff --git a/src/cockpit/389-console/src/ds.js b/src/cockpit/389-console/src/ds.js
index efe337c..702ff88 100644
--- a/src/cockpit/389-console/src/ds.js
+++ b/src/cockpit/389-console/src/ds.js
@@ -346,27 +346,7 @@ function popup_success(msg) {
// This is called when any Save button is clicked on the main page. We call
// all the save functions for all the pages here. This is not used for modal forms
function save_all () {
- if ("nsslapd-ldapilisten" in config_values || "nsslapd-ldapiautobind" in config_values) {
- if ( (!$("#nsslapd-ldapilisten").is(":checked") && config_values["nsslapd-ldapilisten"] == "on") ||
- (!$("#nsslapd-ldapiautobind").is(":checked") && config_values["nsslapd-ldapiautobind"] == "on") )
- {
- // Okay we are disabling some form of LDAPI that will break the UI, warn the user
- popup_confirm("Disabling LDAPI or LDAPI Autobind will make the UI unusable. Are you sure you want to proceed",
- "Confirmation", function (yes)
- {
- if (yes) {
- save_config();
- } else {
- // No, reset config
- get_and_set_config();
- }
- });
- } else {
- save_config();
- }
- } else {
- save_config();
- }
+ save_config(); // Server Config Page
}
function load_repl_suffix_dropdowns() {
diff --git a/src/cockpit/389-console/src/index.html b/src/cockpit/389-console/src/index.html
index 1a42c97..91993cc 100644
--- a/src/cockpit/389-console/src/index.html
+++ b/src/cockpit/389-console/src/index.html
@@ -411,13 +411,14 @@
</div>
<hr>
<div>
- <label for="backend-name" class="ds-config-label" title="The name for the backend database, like 'userroot'">Backend Name (optional)</label><input
- class="ds-input ds-inst-input" placeholder="e.g. userRoot" size="40" type="text" id="backend-name">
+ <label for="backend-suffix" class="ds-config-label" title="Database suffix, like 'dc=example,dc=com'. The suffix must be a valid LDAP Distiguished Name (DN)">Database Suffix</label><input
+ class="ds-input ds-inst-input" size="40" placeholder="e.g. dc=example,dc=com" type="text" id="backend-suffix">
</div>
<div>
- <label for="backend-suffix" class="ds-config-label" title="Database suffix, like 'dc=example,dc=com'">Backend Suffix (optional)</label><input
- class="ds-input ds-inst-input" size="40" placeholder="e.g. dc=example,dc=com" type="text" id="backend-suffix">
+ <label for="backend-name" class="ds-config-label" title="The name for the backend database, like 'userroot'. The name can be a combination of alphanumeric characters, dashes (-), and underscores (_). No other characters are allowed.">Database Name</label><input
+ class="ds-input ds-inst-input" placeholder="e.g. userRoot" size="40" type="text" id="backend-name">
</div>
+
<div>
<label for="create-sample-entries" class="ds-config-label" title="Create sample entries in the suffix">Create Sample Entries </label><input
type="checkbox" class="ds-input ds-config-checkbox" id="create-sample-entries">
diff --git a/src/cockpit/389-console/src/schema.html b/src/cockpit/389-console/src/schema.html
index 872abab..36f61be 100644
--- a/src/cockpit/389-console/src/schema.html
+++ b/src/cockpit/389-console/src/schema.html
@@ -102,11 +102,11 @@
class="ds-input" type="text" id="attr-usage-view" size="40" readonly />
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="attr-multivalued-view" readonly /><label
+ <input type="checkbox" class="ds-config-checkbox" id="attr-multivalued-view" disabled="disabled" /><label
for="attr-multivalued-view" class="ds-label"> Attribute Multi-Valued </label>
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="attr-no-user-mod-view" readonly /><label
+ <input type="checkbox" class="ds-config-checkbox" id="attr-no-user-mod-view" disabled="disabled" /><label
for="attr-no-user-mod-view" class="ds-label"> Read-only (NO-USER-MODIFICATION flag) </label>
</div>
<div>
@@ -330,7 +330,7 @@
<hr>
<div class="ds-container">
<div name="available-attrs">
- <label class="ds-config-label" for="schema-list" title="The available attributes to choose from."><b>Available Attributes</b></label>
+ <label for="schema-list" title="The available attributes to choose from."><b>Available Attributes</b></label>
<select id="schema-list" class="ds-oc-form-list" name="availattrs" multiple>
</select>
</div>
diff --git a/src/cockpit/389-console/src/servers.html b/src/cockpit/389-console/src/servers.html
index 02e39ab..04678e8 100644
--- a/src/cockpit/389-console/src/servers.html
+++ b/src/cockpit/389-console/src/servers.html
@@ -948,24 +948,15 @@
-->
<div id="server-ldapi" class="all-pages ds-margin-left" hidden>
<h3 class="ds-config-header">LDAPI & Autobind Settings</h3>
- <div>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-ldapilisten" checked><label
- for="nsslapd-ldapilisten" class="ds-label" title="Enable LDAPI (nsslapd-ldapilisten)."> Enable LDAPI</label>
- </div>
<div class="ldapi-attrs ds-inline" hidden>
<div>
- <label for="nsslapd-ldapifilepath" class="ds-config-indent-sm-label" title="The Unix socket file (nsslapd-ldapifilepath).">LDAPI Socket File Path</label><input
- class="ds-input" type="text" id="nsslapd-ldapifilepath" size="35"/>
- </div>
- <div>
- <p></p>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-ldapiautobind"><label
- for="nsslapd-ldapiautobind" class="ds-label" title="Enable autobind (nsslapd-ldapiautobind)."> Enable Autobind</label>
+ <label for="nsslapd-ldapifilepath" class="ds-config-label" title="The Unix socket file (nsslapd-ldapifilepath).">LDAPI Socket File Path</label><input
+ class="ds-input" type="text" id="nsslapd-ldapifilepath" size="35" readonly/>
</div>
<div class="ds-inline">
- <div class="autobind-attrs" hidden>
+ <div class="autobind-attrs">
<div>
- <label for="nsslapd-ldapimaprootdn" class="ds-config-indent-sm-label" title="Map the Unix root entry to this Directory Manager DN (nsslapd-ldapimaprootdn).">DN to map "root" To</label><input
+ <label for="nsslapd-ldapimaprootdn" class="ds-config-label" title="Map the Unix root entry to this Directory Manager DN (nsslapd-ldapimaprootdn).">DN to map "root" To</label><input
class="ds-input" type="text" id="nsslapd-ldapimaprootdn" placeholder="e.g. cn=Directory Manager" size="35"/>
</div>
<div>
diff --git a/src/cockpit/389-console/src/servers.js b/src/cockpit/389-console/src/servers.js
index 3d1c4fa..b2a4b0f 100644
--- a/src/cockpit/389-console/src/servers.js
+++ b/src/cockpit/389-console/src/servers.js
@@ -115,8 +115,8 @@ function clear_inst_form() {
$("#create-inst-rootdn").val("cn=Directory Manager");
$("#rootdn-pw").val("");
$("#rootdn-pw-confirm").val("");
- $("#backend-suffix").val("");
- $("#backend-name").val("");
+ $("#backend-suffix").val("dc=example,dc=com");
+ $("#backend-name").val("userRoot");
$("#create-sample-entries").prop('checked', false);
$("#create-inst-tls").prop('checked', true);
$(".ds-inst-input").css("border-color", "initial");
@@ -963,45 +963,6 @@ $(document).ready( function() {
});
// LDAPI form control
- $("#nsslapd-ldapilisten").change(function() {
- if(this.checked) {
- $('.ldapi-attrs').show();
- if ( $("#nsslapd-ldapiautobind").is(":checked") ){
- $(".autobind-attrs").show();
- if ( $("#nsslapd-ldapimaptoentries").is(":checked") ){
- $(".autobind-entry-attrs").show();
- } else {
- $(".autobind-entry-attrs").hide();
- }
- } else {
- $(".autobind-attrs").hide();
- $(".autobind-entry-attrs").hide();
- $("#nsslapd-ldapimaptoentries").prop("checked", false );
- }
- } else {
- $('.ldapi-attrs').hide();
- $(".autobind-attrs").hide();
- $(".autobind-entry-attrs").hide();
- $("#nsslapd-ldapiautobind").prop("checked", false );
- $("#nsslapd-ldapimaptoentries").prop("checked", false );
- }
- });
-
- $("#nsslapd-ldapiautobind").change(function() {
- if (this.checked){
- $(".autobind-attrs").show();
- if ( $("#nsslapd-ldapimaptoentries").is(":checked") ){
- $(".autobind-entry-attrs").show();
- } else {
- $(".autobind-entry-attrs").hide();
- }
- } else {
- $(".autobind-attrs").hide();
- $(".autobind-entry-attrs").hide();
- $("#nsslapd-ldapimaptoentries").prop("checked", false );
- }
- });
-
$("#nsslapd-ldapimaptoentries").change(function() {
if (this.checked){
$(".autobind-entry-attrs").show();
@@ -1524,7 +1485,7 @@ $(document).ready( function() {
$("#create-inst-serverid").css("border-color", "red");
return;
}
- if (new_server_id.match(/^[#%:-A-Za-z0-9_]+$/g)) {
+ if (new_server_id.match(/^[#%:A-Za-z0-9_\-]+$/g)) {
setup_inf = setup_inf.replace('INST_NAME', new_server_id);
} else {
report_err($("#create-inst-serverid"), 'Instance name can only contain letters, numbers, and: # % : - _');
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch master updated: Issue 50546 - fix more UI issues(part 2)
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new db876c6 Issue 50546 - fix more UI issues(part 2)
db876c6 is described below
commit db876c62309810e9c5ac14a553e5c1135af55bd7
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Tue Sep 10 15:13:38 2019 -0400
Issue 50546 - fix more UI issues(part 2)
Description: Fixed minor issues not fully addressed from the last commit
relates: https://pagure.io/389-ds-base/issue/50546
Reviewed by: mreynolds (one line commit rule)
---
src/cockpit/389-console/src/ds.js | 22 +---------------
src/cockpit/389-console/src/index.html | 9 ++++---
src/cockpit/389-console/src/schema.html | 6 ++---
src/cockpit/389-console/src/servers.html | 17 +++---------
src/cockpit/389-console/src/servers.js | 45 +++-----------------------------
5 files changed, 16 insertions(+), 83 deletions(-)
diff --git a/src/cockpit/389-console/src/ds.js b/src/cockpit/389-console/src/ds.js
index efe337c..702ff88 100644
--- a/src/cockpit/389-console/src/ds.js
+++ b/src/cockpit/389-console/src/ds.js
@@ -346,27 +346,7 @@ function popup_success(msg) {
// This is called when any Save button is clicked on the main page. We call
// all the save functions for all the pages here. This is not used for modal forms
function save_all () {
- if ("nsslapd-ldapilisten" in config_values || "nsslapd-ldapiautobind" in config_values) {
- if ( (!$("#nsslapd-ldapilisten").is(":checked") && config_values["nsslapd-ldapilisten"] == "on") ||
- (!$("#nsslapd-ldapiautobind").is(":checked") && config_values["nsslapd-ldapiautobind"] == "on") )
- {
- // Okay we are disabling some form of LDAPI that will break the UI, warn the user
- popup_confirm("Disabling LDAPI or LDAPI Autobind will make the UI unusable. Are you sure you want to proceed",
- "Confirmation", function (yes)
- {
- if (yes) {
- save_config();
- } else {
- // No, reset config
- get_and_set_config();
- }
- });
- } else {
- save_config();
- }
- } else {
- save_config();
- }
+ save_config(); // Server Config Page
}
function load_repl_suffix_dropdowns() {
diff --git a/src/cockpit/389-console/src/index.html b/src/cockpit/389-console/src/index.html
index 1a42c97..91993cc 100644
--- a/src/cockpit/389-console/src/index.html
+++ b/src/cockpit/389-console/src/index.html
@@ -411,13 +411,14 @@
</div>
<hr>
<div>
- <label for="backend-name" class="ds-config-label" title="The name for the backend database, like 'userroot'">Backend Name (optional)</label><input
- class="ds-input ds-inst-input" placeholder="e.g. userRoot" size="40" type="text" id="backend-name">
+ <label for="backend-suffix" class="ds-config-label" title="Database suffix, like 'dc=example,dc=com'. The suffix must be a valid LDAP Distiguished Name (DN)">Database Suffix</label><input
+ class="ds-input ds-inst-input" size="40" placeholder="e.g. dc=example,dc=com" type="text" id="backend-suffix">
</div>
<div>
- <label for="backend-suffix" class="ds-config-label" title="Database suffix, like 'dc=example,dc=com'">Backend Suffix (optional)</label><input
- class="ds-input ds-inst-input" size="40" placeholder="e.g. dc=example,dc=com" type="text" id="backend-suffix">
+ <label for="backend-name" class="ds-config-label" title="The name for the backend database, like 'userroot'. The name can be a combination of alphanumeric characters, dashes (-), and underscores (_). No other characters are allowed.">Database Name</label><input
+ class="ds-input ds-inst-input" placeholder="e.g. userRoot" size="40" type="text" id="backend-name">
</div>
+
<div>
<label for="create-sample-entries" class="ds-config-label" title="Create sample entries in the suffix">Create Sample Entries </label><input
type="checkbox" class="ds-input ds-config-checkbox" id="create-sample-entries">
diff --git a/src/cockpit/389-console/src/schema.html b/src/cockpit/389-console/src/schema.html
index 872abab..36f61be 100644
--- a/src/cockpit/389-console/src/schema.html
+++ b/src/cockpit/389-console/src/schema.html
@@ -102,11 +102,11 @@
class="ds-input" type="text" id="attr-usage-view" size="40" readonly />
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="attr-multivalued-view" readonly /><label
+ <input type="checkbox" class="ds-config-checkbox" id="attr-multivalued-view" disabled="disabled" /><label
for="attr-multivalued-view" class="ds-label"> Attribute Multi-Valued </label>
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="attr-no-user-mod-view" readonly /><label
+ <input type="checkbox" class="ds-config-checkbox" id="attr-no-user-mod-view" disabled="disabled" /><label
for="attr-no-user-mod-view" class="ds-label"> Read-only (NO-USER-MODIFICATION flag) </label>
</div>
<div>
@@ -330,7 +330,7 @@
<hr>
<div class="ds-container">
<div name="available-attrs">
- <label class="ds-config-label" for="schema-list" title="The available attributes to choose from."><b>Available Attributes</b></label>
+ <label for="schema-list" title="The available attributes to choose from."><b>Available Attributes</b></label>
<select id="schema-list" class="ds-oc-form-list" name="availattrs" multiple>
</select>
</div>
diff --git a/src/cockpit/389-console/src/servers.html b/src/cockpit/389-console/src/servers.html
index 02e39ab..04678e8 100644
--- a/src/cockpit/389-console/src/servers.html
+++ b/src/cockpit/389-console/src/servers.html
@@ -948,24 +948,15 @@
-->
<div id="server-ldapi" class="all-pages ds-margin-left" hidden>
<h3 class="ds-config-header">LDAPI & Autobind Settings</h3>
- <div>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-ldapilisten" checked><label
- for="nsslapd-ldapilisten" class="ds-label" title="Enable LDAPI (nsslapd-ldapilisten)."> Enable LDAPI</label>
- </div>
<div class="ldapi-attrs ds-inline" hidden>
<div>
- <label for="nsslapd-ldapifilepath" class="ds-config-indent-sm-label" title="The Unix socket file (nsslapd-ldapifilepath).">LDAPI Socket File Path</label><input
- class="ds-input" type="text" id="nsslapd-ldapifilepath" size="35"/>
- </div>
- <div>
- <p></p>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-ldapiautobind"><label
- for="nsslapd-ldapiautobind" class="ds-label" title="Enable autobind (nsslapd-ldapiautobind)."> Enable Autobind</label>
+ <label for="nsslapd-ldapifilepath" class="ds-config-label" title="The Unix socket file (nsslapd-ldapifilepath).">LDAPI Socket File Path</label><input
+ class="ds-input" type="text" id="nsslapd-ldapifilepath" size="35" readonly/>
</div>
<div class="ds-inline">
- <div class="autobind-attrs" hidden>
+ <div class="autobind-attrs">
<div>
- <label for="nsslapd-ldapimaprootdn" class="ds-config-indent-sm-label" title="Map the Unix root entry to this Directory Manager DN (nsslapd-ldapimaprootdn).">DN to map "root" To</label><input
+ <label for="nsslapd-ldapimaprootdn" class="ds-config-label" title="Map the Unix root entry to this Directory Manager DN (nsslapd-ldapimaprootdn).">DN to map "root" To</label><input
class="ds-input" type="text" id="nsslapd-ldapimaprootdn" placeholder="e.g. cn=Directory Manager" size="35"/>
</div>
<div>
diff --git a/src/cockpit/389-console/src/servers.js b/src/cockpit/389-console/src/servers.js
index 3d1c4fa..b2a4b0f 100644
--- a/src/cockpit/389-console/src/servers.js
+++ b/src/cockpit/389-console/src/servers.js
@@ -115,8 +115,8 @@ function clear_inst_form() {
$("#create-inst-rootdn").val("cn=Directory Manager");
$("#rootdn-pw").val("");
$("#rootdn-pw-confirm").val("");
- $("#backend-suffix").val("");
- $("#backend-name").val("");
+ $("#backend-suffix").val("dc=example,dc=com");
+ $("#backend-name").val("userRoot");
$("#create-sample-entries").prop('checked', false);
$("#create-inst-tls").prop('checked', true);
$(".ds-inst-input").css("border-color", "initial");
@@ -963,45 +963,6 @@ $(document).ready( function() {
});
// LDAPI form control
- $("#nsslapd-ldapilisten").change(function() {
- if(this.checked) {
- $('.ldapi-attrs').show();
- if ( $("#nsslapd-ldapiautobind").is(":checked") ){
- $(".autobind-attrs").show();
- if ( $("#nsslapd-ldapimaptoentries").is(":checked") ){
- $(".autobind-entry-attrs").show();
- } else {
- $(".autobind-entry-attrs").hide();
- }
- } else {
- $(".autobind-attrs").hide();
- $(".autobind-entry-attrs").hide();
- $("#nsslapd-ldapimaptoentries").prop("checked", false );
- }
- } else {
- $('.ldapi-attrs').hide();
- $(".autobind-attrs").hide();
- $(".autobind-entry-attrs").hide();
- $("#nsslapd-ldapiautobind").prop("checked", false );
- $("#nsslapd-ldapimaptoentries").prop("checked", false );
- }
- });
-
- $("#nsslapd-ldapiautobind").change(function() {
- if (this.checked){
- $(".autobind-attrs").show();
- if ( $("#nsslapd-ldapimaptoentries").is(":checked") ){
- $(".autobind-entry-attrs").show();
- } else {
- $(".autobind-entry-attrs").hide();
- }
- } else {
- $(".autobind-attrs").hide();
- $(".autobind-entry-attrs").hide();
- $("#nsslapd-ldapimaptoentries").prop("checked", false );
- }
- });
-
$("#nsslapd-ldapimaptoentries").change(function() {
if (this.checked){
$(".autobind-entry-attrs").show();
@@ -1524,7 +1485,7 @@ $(document).ready( function() {
$("#create-inst-serverid").css("border-color", "red");
return;
}
- if (new_server_id.match(/^[#%:-A-Za-z0-9_]+$/g)) {
+ if (new_server_id.match(/^[#%:A-Za-z0-9_\-]+$/g)) {
setup_inf = setup_inf.replace('INST_NAME', new_server_id);
} else {
report_err($("#create-inst-serverid"), 'Instance name can only contain letters, numbers, and: # % : - _');
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50546 - fix more UI issues
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new f8752be Issue 50546 - fix more UI issues
f8752be is described below
commit f8752be0d448cd63cc8ca15ff402333162207c00
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Mon Sep 9 16:36:20 2019 -0400
Issue 50546 - fix more UI issues
Description: In schema.js do not reset "ds-input" class's border. In FF
it makes all the field ugly. Also fixed the plugin forms
to be nicer and easier to read
relates: https://pagure.io/389-ds-base/issue/50546
Reviewed by: mreynolds (one line commit rule)
(cherry picked from commit 041f71c2f56f326b691bd7b678065fc6c74eed45)
---
src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx | 3 ++-
src/cockpit/389-console/src/schema.js | 2 --
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx b/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
index ae97dca..b0e4a21 100644
--- a/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
+++ b/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
@@ -186,7 +186,7 @@ class PluginBasicConfig extends React.Component {
<div>
<Form inline>
<Row>
- <Col sm={6}>
+ <Col sm={6} className="ds-margin-top">
<h3>
<ControlLabel className="ds-plugin-tab-header">
{this.props.pluginName}
@@ -216,6 +216,7 @@ class PluginBasicConfig extends React.Component {
)}
</Row>
</Form>
+ <p />
{this.props.children}
<CustomCollapse>
<Row>
diff --git a/src/cockpit/389-console/src/schema.js b/src/cockpit/389-console/src/schema.js
index 618c555..ea6159b 100644
--- a/src/cockpit/389-console/src/schema.js
+++ b/src/cockpit/389-console/src/schema.js
@@ -76,7 +76,6 @@ function clear_oc_form() {
$(".ds-modal-error").hide();
$("#oc-name").attr('disabled', false);
$("#oc-name").val("");
- $(".ds-input").css("border-color", "initial");
$("#oc-oid").val("");
$("#oc-kind").prop('selectedIndex',0);
$("#oc-desc").val("");
@@ -93,7 +92,6 @@ function clear_attr_form() {
$(".ds-modal-error").hide();
$("#attr-name").attr('disabled', false);
$("#attr-name").val("");
- $(".ds-input").css("border-color", "initial");
$("#attr-syntax").val("");
$("#attr-desc").val("");
$("#attr-parent").prop('selectedIndex',0);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch master updated: Issue 50546 - fix more UI issues
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new 041f71c Issue 50546 - fix more UI issues
041f71c is described below
commit 041f71c2f56f326b691bd7b678065fc6c74eed45
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Mon Sep 9 16:36:20 2019 -0400
Issue 50546 - fix more UI issues
Description: In schema.js do not reset "ds-input" class's border. In FF
it makes all the field ugly. Also fixed the plugin forms
to be nicer and easier to read
relates: https://pagure.io/389-ds-base/issue/50546
Reviewed by: mreynolds (one line commit rule)
---
src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx | 3 ++-
src/cockpit/389-console/src/schema.js | 2 --
2 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx b/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
index ae97dca..b0e4a21 100644
--- a/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
+++ b/src/cockpit/389-console/src/lib/plugins/pluginBasicConfig.jsx
@@ -186,7 +186,7 @@ class PluginBasicConfig extends React.Component {
<div>
<Form inline>
<Row>
- <Col sm={6}>
+ <Col sm={6} className="ds-margin-top">
<h3>
<ControlLabel className="ds-plugin-tab-header">
{this.props.pluginName}
@@ -216,6 +216,7 @@ class PluginBasicConfig extends React.Component {
)}
</Row>
</Form>
+ <p />
{this.props.children}
<CustomCollapse>
<Row>
diff --git a/src/cockpit/389-console/src/schema.js b/src/cockpit/389-console/src/schema.js
index 618c555..ea6159b 100644
--- a/src/cockpit/389-console/src/schema.js
+++ b/src/cockpit/389-console/src/schema.js
@@ -76,7 +76,6 @@ function clear_oc_form() {
$(".ds-modal-error").hide();
$("#oc-name").attr('disabled', false);
$("#oc-name").val("");
- $(".ds-input").css("border-color", "initial");
$("#oc-oid").val("");
$("#oc-kind").prop('selectedIndex',0);
$("#oc-desc").val("");
@@ -93,7 +92,6 @@ function clear_attr_form() {
$(".ds-modal-error").hide();
$("#attr-name").attr('disabled', false);
$("#attr-name").val("");
- $(".ds-input").css("border-color", "initial");
$("#attr-syntax").val("");
$("#attr-desc").val("");
$("#attr-parent").prop('selectedIndex',0);
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch 389-ds-base-1.4.1 updated: Issue 50546 - Fix various issues in UI
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch 389-ds-base-1.4.1
in repository 389-ds-base.
The following commit(s) were added to refs/heads/389-ds-base-1.4.1 by this push:
new 9b9c7a4 Issue 50546 - Fix various issues in UI
9b9c7a4 is described below
commit 9b9c7a40b81c063a9f095e4e854045319801d1f2
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri Sep 6 16:37:26 2019 -0400
Issue 50546 - Fix various issues in UI
Description: This patch addresses several issues:
- #50546 - Exports from Cockpit can be stored outside of /var/lib/dirsrv/slapd-instance_name/ldif/
- #50418 - dsctl remove does not cleanup /etc/tmpfiles.d
- #50554 - Cockpit incorrectly shows that a server is in read-only mode
- #49856 - Changing port should adjust selinux labels
- This also enforces a minimum password length for root DN
- Added confirmation modal is you disable LDAPI(and UI)
- Added port verification
- Created new "view" modals for schema instead oi reusing edit forms
- Improved instance creation form validation
- Added a progress bar for doing the initial load of configuration
relates: https://pagure.io/389-ds-base/issue/50546
Reviewed by: spichugi(Thanks!)
---
src/cockpit/389-console/src/css/ds.css | 16 +-
src/cockpit/389-console/src/ds.js | 49 +++++-
src/cockpit/389-console/src/index.html | 25 +++-
.../389-console/src/lib/database/backups.jsx | 34 ++++-
.../389-console/src/lib/database/suffix.jsx | 19 ++-
.../389-console/src/lib/monitor/serverMonitor.jsx | 28 ++--
src/cockpit/389-console/src/lib/tools.jsx | 8 +
src/cockpit/389-console/src/replication.html | 42 +++---
src/cockpit/389-console/src/replication.js | 6 +-
src/cockpit/389-console/src/schema.html | 165 +++++++++++++++++++--
src/cockpit/389-console/src/schema.js | 99 +++++++++++--
src/cockpit/389-console/src/security.jsx | 14 +-
src/cockpit/389-console/src/servers.html | 12 +-
src/cockpit/389-console/src/servers.js | 91 ++++++++++--
src/lib389/lib389/config.py | 2 +-
src/lib389/lib389/instance/options.py | 5 +-
src/lib389/lib389/instance/remove.py | 5 +-
src/lib389/lib389/instance/setup.py | 15 +-
18 files changed, 511 insertions(+), 124 deletions(-)
diff --git a/src/cockpit/389-console/src/css/ds.css b/src/cockpit/389-console/src/css/ds.css
index 3481db8..6da4b9d 100644
--- a/src/cockpit/389-console/src/css/ds.css
+++ b/src/cockpit/389-console/src/css/ds.css
@@ -317,6 +317,7 @@ td {
width: 875px !important;
min-width: 875px !important;
vertical-align: middle;
+ margin-left: -100px !important;
}
.ds-button-right {
@@ -686,6 +687,10 @@ option {
text-align: center;
}
+.modal {
+ overflow-y:auto;
+}
+
/* wizard accordions are narrower */
.ds-wiz-accordion {
margin-top: 20px;
@@ -826,6 +831,13 @@ option {
transform: translate(-25%, -50%);
}
+.ds-loading {
+ position: fixed;
+ top: 25%;
+ left: 35%;
+ transform: translate(-25%, -35%);
+}
+
.ds-popup {
min-width: 350px !important;
}
@@ -885,10 +897,6 @@ option {
}
}
-.control-label {
- text-align: left !important;
-}
-
.rbt-token {
background-color: #ededed;
color: #363636;
diff --git a/src/cockpit/389-console/src/ds.js b/src/cockpit/389-console/src/ds.js
index 47247e6..efe337c 100644
--- a/src/cockpit/389-console/src/ds.js
+++ b/src/cockpit/389-console/src/ds.js
@@ -76,8 +76,14 @@ function valid_dn (dn){
}
function valid_num (val){
- // Validate value is a number
- return !isNaN(val);
+ // Validate value is a number and between 1 and 65535
+ let result = !isNaN(val);
+ if (result) {
+ if (val < 1 || val > 65535) {
+ result = false;
+ }
+ }
+ return result;
}
function tableize (val) {
@@ -340,7 +346,27 @@ function popup_success(msg) {
// This is called when any Save button is clicked on the main page. We call
// all the save functions for all the pages here. This is not used for modal forms
function save_all () {
- save_config(); // Server Config Page
+ if ("nsslapd-ldapilisten" in config_values || "nsslapd-ldapiautobind" in config_values) {
+ if ( (!$("#nsslapd-ldapilisten").is(":checked") && config_values["nsslapd-ldapilisten"] == "on") ||
+ (!$("#nsslapd-ldapiautobind").is(":checked") && config_values["nsslapd-ldapiautobind"] == "on") )
+ {
+ // Okay we are disabling some form of LDAPI that will break the UI, warn the user
+ popup_confirm("Disabling LDAPI or LDAPI Autobind will make the UI unusable. Are you sure you want to proceed",
+ "Confirmation", function (yes)
+ {
+ if (yes) {
+ save_config();
+ } else {
+ // No, reset config
+ get_and_set_config();
+ }
+ });
+ } else {
+ save_config();
+ }
+ } else {
+ save_config();
+ }
}
function load_repl_suffix_dropdowns() {
@@ -374,6 +400,18 @@ function load_repl_suffix_dropdowns() {
});
}
+var progress = 10;
+
+function update_progress () {
+ progress += 10;
+ if (progress > 100) {
+ progress = 100;
+ }
+ $("#ds-progress-label").text(progress + "%");
+ $("#ds-progress-bar").attr("aria-valuenow", progress);
+ $("#ds-progress-bar").css("width", progress + "%");
+}
+
var loading_cfg = 0;
function load_config (refresh){
@@ -382,6 +420,8 @@ function load_config (refresh){
return;
}
loading_cfg = 1;
+ progress = 10;
+ update_progress();
// Load the configuration for all the pages.
var dropdowns = ['local-pwp-suffix', 'select-repl-cfg-suffix'];
@@ -415,15 +455,18 @@ function load_config (refresh){
get_and_set_config();
get_and_set_sasl();
get_and_set_localpwp();
+ update_progress();
// Schema page
get_and_set_schema_tables();
+ update_progress();
// Replication page
get_and_set_repl_config();
get_and_set_repl_agmts();
get_and_set_repl_winsync_agmts();
get_and_set_cleanallruv();
+ update_progress();
// Initialize the tabs
$(".ds-tab-list").css( 'color', '#777');
diff --git a/src/cockpit/389-console/src/index.html b/src/cockpit/389-console/src/index.html
index eb7ea4a..1a42c97 100644
--- a/src/cockpit/389-console/src/index.html
+++ b/src/cockpit/389-console/src/index.html
@@ -33,9 +33,20 @@
<body>
<div id="reload-page" hidden></div>
- <div id="loading-page" class="ds-center ds-loading-spinner" hidden>
+ <div id="loading-page" class="ds-center ds-loading" hidden>
<h4 id="loading-msg">Loading Directory Server Configuration...</h4>
<p><span class="spinner spinner-lg spinner-inline"></span></p>
+
+ <div class="progress">
+ <div class="progress-bar" role="progressbar" id="ds-progress-bar"
+ aria-valuenow="20" aria-valuemin="0"
+ aria-valuemax="100" style="width: 20%;"
+ >
+ <span id="ds-progress-label">20%</span>
+ </div>
+ </div>
+
+
</div>
<div id="everything" hidden>
<div class="ds-nav-bar">
@@ -375,7 +386,7 @@
<p class="ds-modal-error"></p>
<div class="ds-inline">
<div>
- <label for="create-inst-serverid" class="ds-config-label" title="The instance name, this is what gets appended to \"slapi-\"">
+ <label for="create-inst-serverid" class="ds-config-label" title="The instance name, this is what gets appended to 'slapi-'. The instance name can only contain letters, numbers, and: # % : - _">
Instance Name</label><input class="ds-input ds-inst-input" size="40" type="text" id="create-inst-serverid" placeholder="Your_Instance_Name" required />
</div>
<div>
@@ -400,12 +411,12 @@
</div>
<hr>
<div>
- <label for="backend-name" class="ds-config-label" title="The backend name, like 'userroot'">Backend Name (optional)</label><input
- class="ds-input ds-inst-input" size="40" type="text" id="backend-name">
+ <label for="backend-name" class="ds-config-label" title="The name for the backend database, like 'userroot'">Backend Name (optional)</label><input
+ class="ds-input ds-inst-input" placeholder="e.g. userRoot" size="40" type="text" id="backend-name">
</div>
<div>
<label for="backend-suffix" class="ds-config-label" title="Database suffix, like 'dc=example,dc=com'">Backend Suffix (optional)</label><input
- class="ds-input ds-inst-input" size="40" type="text" id="backend-suffix">
+ class="ds-input ds-inst-input" size="40" placeholder="e.g. dc=example,dc=com" type="text" id="backend-suffix">
</div>
<div>
<label for="create-sample-entries" class="ds-config-label" title="Create sample entries in the suffix">Create Sample Entries </label><input
@@ -445,8 +456,8 @@
</div>
<div class="modal-body">
<form class="form-horizontal">
- <label for="backup-name" title="Enter a directory name for the backup">
- Backup Name:</label><input class="ds-input-auto" type="text" id="backup-name"/>
+ <label for="backup-name" title="Enter a name for the backup subdirectory located under the server's backup directory (nsslapd-bakdir)">
+ Name For The Backup</label><input class="ds-input-auto" type="text" id="backup-name"/>
</form>
<div id="backup-spinner" class="ds-center" hidden>
<p></p>
diff --git a/src/cockpit/389-console/src/lib/database/backups.jsx b/src/cockpit/389-console/src/lib/database/backups.jsx
index 9a9f6bb..96d6e97 100644
--- a/src/cockpit/389-console/src/lib/database/backups.jsx
+++ b/src/cockpit/389-console/src/lib/database/backups.jsx
@@ -19,7 +19,7 @@ import {
Row,
noop
} from "patternfly-react";
-import { log_cmd } from "../tools.jsx";
+import { log_cmd, bad_file_name } from "../tools.jsx";
import PropTypes from "prop-types";
import "../../css/ds.css";
@@ -289,19 +289,26 @@ export class Backups extends React.Component {
}
doBackup () {
- this.setState({
- backupSpinning: true
- });
-
let cmd = [
"dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
"backup", "create"
];
if (this.state.backupName != "") {
+ if (bad_file_name(this.state.backupName)) {
+ this.props.addNotification(
+ "warning",
+ `Backup name should not be a path. All backups are stored in the server's backup directory`
+ );
+ return;
+ }
cmd.push(this.state.backupName);
}
+ this.setState({
+ backupSpinning: true
+ });
+
log_cmd("doBackup", "Add backup task", cmd);
cockpit
.spawn(cmd, { superuser: true, err: "message" })
@@ -399,12 +406,25 @@ export class Backups extends React.Component {
}
doExport() {
- let missingArgs = {ldifLocation: false};
- if (this.state.ldifLocation == "") {
+ let missingArgs = {ldifName: false};
+ if (this.state.ldifName == "") {
this.props.addNotification(
"warning",
`LDIF name is empty`
);
+ missingArgs.ldifName = true;
+ this.setState({
+ errObj: missingArgs
+ });
+ return;
+ }
+
+ // Must not be a path
+ if (bad_file_name(this.state.ldifName)) {
+ this.props.addNotification(
+ "warning",
+ `LDIF name should not be a path. All export files are stored in the server's LDIF directory`
+ );
missingArgs.ldifLocation = true;
this.setState({
errObj: missingArgs
diff --git a/src/cockpit/389-console/src/lib/database/suffix.jsx b/src/cockpit/389-console/src/lib/database/suffix.jsx
index 8d58da9..4366c19 100644
--- a/src/cockpit/389-console/src/lib/database/suffix.jsx
+++ b/src/cockpit/389-console/src/lib/database/suffix.jsx
@@ -6,7 +6,7 @@ import { SuffixConfig } from "./suffixConfig.jsx";
import { SuffixReferrals } from "./referrals.jsx";
import { SuffixIndexes } from "./indexes.jsx";
import { VLVIndexes } from "./vlvIndexes.jsx";
-import { log_cmd } from "../tools.jsx";
+import { log_cmd, bad_file_name } from "../tools.jsx";
import {
ImportModal,
ExportModal,
@@ -260,7 +260,20 @@ export class Suffix extends React.Component {
return;
}
- // Do import
+ // Must not be a path
+ if (bad_file_name(this.state.ldifLocation)) {
+ this.props.addNotification(
+ "warning",
+ `LDIF name should not be a path. All export files are stored in the server's LDIF directory`
+ );
+ missingArgs.ldifLocation = true;
+ this.setState({
+ errObj: missingArgs
+ });
+ return;
+ }
+
+ // Do Export
let export_cmd = [
"dsconf", "-j", "ldapi://%2fvar%2frun%2fslapd-" + this.props.serverId + ".socket",
"backend", "export", this.props.suffix, "--ldif=" + this.state.ldifLocation
@@ -289,7 +302,7 @@ export class Suffix extends React.Component {
})
.fail(err => {
let errMsg = JSON.parse(err);
- this.loadLDIFs();
+ this.props.reloadLDIFs();
this.props.addNotification(
"error",
`Error exporting database - ${errMsg.desc}`
diff --git a/src/cockpit/389-console/src/lib/monitor/serverMonitor.jsx b/src/cockpit/389-console/src/lib/monitor/serverMonitor.jsx
index 0169f39..93c2aef 100644
--- a/src/cockpit/389-console/src/lib/monitor/serverMonitor.jsx
+++ b/src/cockpit/389-console/src/lib/monitor/serverMonitor.jsx
@@ -67,7 +67,7 @@ export class ServerMonitor extends React.Component {
<TabPane eventKey={1}>
<div className="ds-margin-top-lg">
<Row>
- <Col componentClass={ControlLabel} sm={3}>
+ <Col componentClass={ControlLabel} sm={4}>
Server Instance
</Col>
<Col sm={8}>
@@ -75,7 +75,7 @@ export class ServerMonitor extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top">
- <Col componentClass={ControlLabel} sm={3}>
+ <Col componentClass={ControlLabel} sm={4}>
Version
</Col>
<Col sm={8}>
@@ -83,7 +83,7 @@ export class ServerMonitor extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top">
- <Col componentClass={ControlLabel} sm={3}>
+ <Col componentClass={ControlLabel} sm={4}>
Server Started
</Col>
<Col sm={8}>
@@ -91,7 +91,7 @@ export class ServerMonitor extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top">
- <Col componentClass={ControlLabel} sm={3}>
+ <Col componentClass={ControlLabel} sm={4}>
Server Uptime
</Col>
<Col sm={8}>
@@ -105,7 +105,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Worker Threads
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-threads" value={this.props.data.threads} readOnly />
</Col>
</Row>
@@ -113,7 +113,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Threads Waiting To Read
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-readwaiters" value={this.props.data.readwaiters} readOnly />
</Col>
</Row>
@@ -121,7 +121,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Conns At Max Threads
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-currentconnectionsatmaxthreads" value={this.props.data.currentconnectionsatmaxthreads} readOnly />
</Col>
</Row>
@@ -129,7 +129,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Conns Exceeded Max Threads
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-maxthreadsperconnhits" value={this.props.data.maxthreadsperconnhits} readOnly />
</Col>
</Row>
@@ -137,7 +137,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Total Connections
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-totalconnections" value={this.props.data.totalconnections} readOnly />
</Col>
</Row>
@@ -145,7 +145,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Current Conections
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-currentconnections" value={this.props.data.currentconnections} readOnly />
</Col>
</Row>
@@ -153,7 +153,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Operations Started
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-opsinitiated" value={this.props.data.opsinitiated} readOnly />
</Col>
</Row>
@@ -161,7 +161,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Operations Completed
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-opscompleted" value={this.props.data.opscompleted} readOnly />
</Col>
</Row>
@@ -169,7 +169,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Entries Returned To Clients
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-entriessent" value={this.props.data.entriessent} readOnly />
</Col>
</Row>
@@ -177,7 +177,7 @@ export class ServerMonitor extends React.Component {
<Col componentClass={ControlLabel} sm={4}>
Bytes Sent to Clients
</Col>
- <Col sm={7}>
+ <Col sm={8}>
<input type="text" className="ds-input-auto" id="monitor-server-bytessent" value={this.props.data.bytessent} readOnly />
</Col>
</Row>
diff --git a/src/cockpit/389-console/src/lib/tools.jsx b/src/cockpit/389-console/src/lib/tools.jsx
index b3e7573..eb0a67c 100644
--- a/src/cockpit/389-console/src/lib/tools.jsx
+++ b/src/cockpit/389-console/src/lib/tools.jsx
@@ -103,3 +103,11 @@ export function get_date_diff(start, end) {
return `${days} days, ${hours} hours, ${minutes} minutes, and ${seconds} seconds`;
}
+
+export function bad_file_name(file_name) {
+ // file_name must be a string, and not a location/directory
+ if (file_name.includes("/")) {
+ return true;
+ }
+ return false;
+}
diff --git a/src/cockpit/389-console/src/replication.html b/src/cockpit/389-console/src/replication.html
index 9d65107..af9fca4 100644
--- a/src/cockpit/389-console/src/replication.html
+++ b/src/cockpit/389-console/src/replication.html
@@ -257,27 +257,27 @@ CleanAllRUV Tasks
<div class="ds-inline">
<div>
<label for="agmt-cn" class="ds-config-label" title="Agreement name (cn).">Agreement Name</label><input
- class="ds-input agmt-form-input" type="text" placeholder="Agreement name" id="agmt-cn" name="name" size="35" required>
+ class="ds-input agmt-form-input" type="text" placeholder="Agreement name" id="agmt-cn" name="name" size="40" required>
</div>
<div>
<label for="nsds5replicahost" class="ds-config-label" title="Agreement name (nsDS5ReplicaHost).">Consumer Host</label><input
- class="ds-input agmt-form-input" type="text" placeholder="Consumer hostname" id="nsds5replicahost" name="port" size="35" required>
+ class="ds-input agmt-form-input" type="text" placeholder="Consumer hostname" id="nsds5replicahost" name="port" size="40" required>
</div>
<div>
<label for="nsds5replicaport" class="ds-config-label" title="Agreement name (nsDS5ReplicaPort).">Consumer Port</label><input
- class="ds-input agmt-form-input" type="text" placeholder="Consumer port number" id="nsds5replicaport" name="name" size="35" required>
+ class="ds-input agmt-form-input" type="text" placeholder="Consumer port number" id="nsds5replicaport" name="name" size="40" required>
</div>
<div>
<label for="nsds5replicabinddn" class="ds-config-label" title="Replication Bind DN (nsDS5ReplicaBindDN).">Replication Bind DN</label><input
- class="ds-input agmt-form-input" type="text" autocomplete="username" placeholder="Bind DN" id="nsds5replicabinddn" name="name" size="35" required>
+ class="ds-input agmt-form-input" type="text" autocomplete="username" placeholder="Bind DN" id="nsds5replicabinddn" name="name" size="40" required>
</div>
<div>
- <label for="nsds5replicacredentials" class="ds-config-label" title="Replication Bind DN (nsDS5ReplicaCredentials).">Replication Bind DN Credentials</label><input
- class="ds-input agmt-form-input" type="password" autocomplete="new-password" placeholder="Enter password" id="nsds5replicacredentials" name="name" size="35" required>
+ <label for="nsds5replicacredentials" class="ds-config-label" title="Replication Bind DN (nsDS5ReplicaCredentials).">Bind DN Password</label><input
+ class="ds-input agmt-form-input" type="password" autocomplete="new-password" placeholder="Enter password" id="nsds5replicacredentials" name="name" size="40" required>
</div>
<div>
<label for="nsds5replicacredentials-confirm" class="ds-config-label" title="Confirm password">Confirm Password</label><input
- class="ds-input agmt-form-input" type="password" autocomplete="new-password" placeholder="Confirm password" id="nsds5replicacredentials-confirm" name="name" size="35" required>
+ class="ds-input agmt-form-input" type="password" autocomplete="new-password" placeholder="Confirm password" id="nsds5replicacredentials-confirm" name="name" size="40" required>
</div>
<div>
<label for="nsds5replicatransportinfo" class="ds-config-label" title="The protocol used to connect to the replica (nsDS5ReplicaTransportInfo).">Connection Protocol</label><select
@@ -448,7 +448,7 @@ CleanAllRUV Tasks
<!-- Winsync Agreement Wizard -->
<div class="modal fade" id="winsync-agmt-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="winsync-agmt-wizard-title" aria-hidden="true">
- <div class="modal-dialog ds-modal-wide">
+ <div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">
@@ -462,27 +462,27 @@ CleanAllRUV Tasks
<div class="ds-inline">
<div>
<label for="winsync-agmt-cn" class="ds-config-label" title="Agreement name (cn).">Agreement Name</label><input
- class="ds-input" type="text" placeholder="Agreement name" id="winsync-agmt-cn" name="name" required>
+ class="ds-input" type="text" placeholder="Agreement name" id="winsync-agmt-cn" name="name" size="40" required>
</div>
<div>
<label for="winsync-nsds7windowsdomain" class="ds-config-label" title="Agreement name (nsds7WindowsDomain).">Windows Domain Name</label><input
- class="ds-input" type="text" placeholder="Windows Domain Name, example: mydomain.com" id="winsync-nsds7windowsdomain" name="name" required>
+ class="ds-input" type="text" placeholder="Windows Domain Name, example: mydomain.com" id="winsync-nsds7windowsdomain" size="40" name="name" required>
</div>
<div>
<label for="winsync-nsds5replicahost" class="ds-config-label" title="Agreement name (nsDS5ReplicaHost).">Windows Host</label><input
- class="ds-input" type="text" placeholder="Windows hostname" id="winsync-nsds5replicahost" name="port" required>
+ class="ds-input" type="text" placeholder="Windows hostname" id="winsync-nsds5replicahost" name="port" size="40" required>
</div>
<div>
<label for="winsync-nsds5replicaport" class="ds-config-label" title="Agreement name (nsDS5ReplicaPort).">Windows Port</label><input
- class="ds-input" type="text" placeholder="Windows server port number" id="winsync-nsds5replicaport" name="name" required>
+ class="ds-input" type="text" placeholder="Windows server port number" id="winsync-nsds5replicaport" name="name" size="40" required>
</div>
<div>
<label for="winsync-nsds7windowsreplicasubtree" class="ds-config-label" title="Agreement name (nsds7WindowsReplicaSubtree).">Windows Subtree</label><input
- class="ds-input" type="text" placeholder="Active Directory subtree" id="winsync-nsds7windowsreplicasubtree" name="name" required>
+ class="ds-input" type="text" placeholder="Active Directory subtree" id="winsync-nsds7windowsreplicasubtree" name="name" size="40" required>
</div>
<div>
<label for="winsync-nsds7directoryreplicasubtree" class="ds-config-label" title="Agreement name (nsds7DirectoryReplicaSubtree).">Directory Server Subtree</label><input
- class="ds-input" type="text" placeholder="The local Directory Server subtree" id="winsync-nsds7directoryreplicasubtree" name="name" required>
+ class="ds-input" type="text" placeholder="The local Directory Server subtree" id="winsync-nsds7directoryreplicasubtree" name="name" size="40" required>
</div>
<div>
<input type="checkbox" class="ds-config-checkbox" id="winsync-nsds7newwinusersyncenabled-checkbox" checked><label
@@ -502,15 +502,15 @@ CleanAllRUV Tasks
<div>
<hr class="ds-hr">
<label for="winsync-nsds5replicabinddn" class="ds-config-label" title="Replication Bind DN (nsDS5ReplicaBindDN).">Replication Bind DN</label><input
- class="ds-input" type="text" autocomplete="username" placeholder="Bind DN" id="winsync-nsds5replicabinddn" name="name" required>
+ class="ds-input" type="text" autocomplete="username" placeholder="Bind DN" id="winsync-nsds5replicabinddn" name="name" size="40" required>
</div>
<div>
- <label for="winsync-nsds5replicacredentials" class="ds-config-label" title="Replication Bind DN (nsDS5ReplicaCredentials).">Replication Bind DN Credentials</label><input
- class="ds-input" type="password" autocomplete="new-password" placeholder="Enter password" id="winsync-nsds5replicacredentials" name="name" required>
+ <label for="winsync-nsds5replicacredentials" class="ds-config-label" title="Replication Bind DN (nsDS5ReplicaCredentials).">Bind DN Password</label><input
+ class="ds-input" type="password" autocomplete="new-password" placeholder="Enter password" id="winsync-nsds5replicacredentials" name="name" size="40" required>
</div>
<div>
<label for="winsync-nsds5replicacredentials-confirm" class="ds-config-label" title="Confirm password">Confirm Password</label><input
- class="ds-input" type="password"autocomplete="new-password" placeholder="Confirm password" id="winsync-nsds5replicacredentials-confirm" name="name" required>
+ class="ds-input" type="password"autocomplete="new-password" placeholder="Confirm password" id="winsync-nsds5replicacredentials-confirm" name="name" size="40" required>
</div>
<div>
<label for="winsync-nsds5replicatransportinfo" class="ds-config-label" title="The protocol used to connect to the replica (nsDS5ReplicaTransportInfo).">Connection Protocol</label><select
@@ -581,7 +581,7 @@ CleanAllRUV Tasks
<!-- Add replication manager Form -->
<div class="modal fade" id="add-repl-mgr-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="repl-mgr-label" aria-hidden="true">
- <div class="modal-dialog ds-modal-wide">
+ <div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">
@@ -594,7 +594,7 @@ CleanAllRUV Tasks
<div class="ds-inline">
<div>
<label for="add-repl-mgr-dn" class="" title=
- "The DN of the replication manager. The entry should use 'cn' for RDN, and the entry should be under 'cn=config'. (nsds5replicabinddn)">
+ "The DN of the replication manager. The entry should use 'cn' for the RDN, and the entry should be under 'cn=config'. (nsds5replicabinddn)">
Replication Manager DN</label>
</div>
<div>
@@ -689,7 +689,7 @@ CleanAllRUV Tasks
<label for="enable-repl-mgr-dn" class="ds-label-sm" title=
"The DN of the replication manager. The DN should use 'cn' for the RDN, 'cn=replication manager,cn=config' (nsds5replicabinddn)">Replication Manager DN</label><input
type="text" title="The DN of the replication manager entry. It must use the RDN attribute 'cn', and it must be located under 'cn=config'. For example: cn=replication manager,cn=config"
- id="enable-repl-mgr-dn" size="40" class="ds-left-margin" />
+ id="enable-repl-mgr-dn" value="cn=replication manager,cn=config" size="40" class="ds-left-margin" />
<p></p>
</div>
<div>
diff --git a/src/cockpit/389-console/src/replication.js b/src/cockpit/389-console/src/replication.js
index 58f9b4b..e28d175 100644
--- a/src/cockpit/389-console/src/replication.js
+++ b/src/cockpit/389-console/src/replication.js
@@ -109,7 +109,7 @@ function clear_enable_repl_form () {
$("#select-enable-repl-role").prop("selectedIndex", 0);
$("#enable-repl-pw").val("");
$("#enable-repl-pw-confirm").val("");
- $("#enable-repl-mgr-dn").val("");
+ $("#enable-repl-mgr-dn").val("cn=replication manager,cn=config");
$("#enable-repl-mgr-checkbox").prop('checked', false);
$("#enable-repl-mgr-passwd").hide();
}
@@ -203,6 +203,7 @@ function get_and_set_repl_winsync_agmts() {
log_cmd('get_and_set_repl_winsync_agmts', 'Get the winsync agmts', cmd);
cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {
var obj = JSON.parse(data);
+ update_progress();
for (var idx in obj['items']) {
var state = "Enabled";
var con_host = "";
@@ -278,6 +279,7 @@ function get_and_set_repl_agmts () {
cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {
repl_agmt_table.clear().draw();
var obj = JSON.parse(data);
+ update_progress();
for (var idx in obj['items']) {
agmt_attrs = obj['items'][idx]['attrs'];
var agmt_name = agmt_attrs['cn'][0];
@@ -351,6 +353,7 @@ function get_and_set_cleanallruv() {
log_cmd('get_and_set_cleanallruv', 'Get the cleanAllRUV tasks', cmd);
cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {
var tasks = JSON.parse(data);
+ update_progress();
repl_clean_table.clear().draw();
for (var idx in tasks['items']) {
task_attrs = tasks['items'][idx]['attrs'];
@@ -394,6 +397,7 @@ function get_and_set_repl_config () {
$('#repl-mgr-table').find("tr:gt(0)").remove();
$(".ds-cfg").val("");
$("#nsds5replicaprecisetombstonepurging").prop('checked', false);
+ update_progress();
// Set configuration and the repl manager table
for (var attr in repl['attrs']) {
diff --git a/src/cockpit/389-console/src/schema.html b/src/cockpit/389-console/src/schema.html
index 10bdabe..872abab 100644
--- a/src/cockpit/389-console/src/schema.html
+++ b/src/cockpit/389-console/src/schema.html
@@ -65,6 +65,80 @@
<!-- Modals/Popups/Wizards -->
+ <!-- View Attribute modal -->
+ <div class="modal fade" id="view-attr-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="view-attr-header" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">
+ <span class="pficon pficon-close"></span>
+ </button>
+ <h4 class="modal-title">View Attribute</h4>
+ </div>
+ <div class="modal-body">
+ <div class="ds-inline">
+ <div>
+ <label for="attr-name-view" class="ds-config-label-lrg" title="The attribute name"><b
+ >Attribute Name</b></label><input class="ds-input" type="text" id="attr-name-view" size="40" readonly />
+ </div>
+ <div>
+ <label for="attr-desc-view" class="ds-config-label-lrg" title="The attribute description"><b
+ >Description</b></label><input class="ds-input" type="text" id="attr-desc-view" size="40" readonly />
+ </div>
+ <div>
+ <label for="attr-oid-view" class="ds-config-label-lrg" title="The attribute name"><b
+ >OID</b></label><input class="ds-input" type="text" id="attr-oid-view" size="40" readonly />
+ </div>
+ <div>
+ <label for="attr-parent-view" class="ds-config-label-lrg" title="The parent attribute"><b>Parent Attribute</b></label><input
+ class="ds-input" type="text" id="attr-parent-view" size="40" readonly />
+ </div>
+ <div>
+ <label for="attr-syntax-view" class="ds-config-label-lrg" title="The attribute syntax"><b>Attribute Syntax</b></label><input
+ class="ds-input" type="text" id="attr-syntax-view" size="40" readonly />
+ </div>
+ <div>
+ <label for="attr-usage-view" class="ds-config-label-lrg" title="The parent attribute"><b>Attribute Usage</b></label><input
+ class="ds-input" type="text" id="attr-usage-view" size="40" readonly />
+ </div>
+ <div>
+ <input type="checkbox" class="ds-config-checkbox" id="attr-multivalued-view" readonly /><label
+ for="attr-multivalued-view" class="ds-label"> Attribute Multi-Valued </label>
+ </div>
+ <div>
+ <input type="checkbox" class="ds-config-checkbox" id="attr-no-user-mod-view" readonly /><label
+ for="attr-no-user-mod-view" class="ds-label"> Read-only (NO-USER-MODIFICATION flag) </label>
+ </div>
+ <div>
+ <label for="attr-alias-view" class="ds-config-label-lrg" title="The attribute alias list separated by space"><b
+ >Attribute Aliases</b></label><input class="ds-input" type="text" id="attr-alias-view" size="40" readonly />
+ </div>
+ <div class="panel panel-default ds-margin-top">
+ <div class="panel-heading"><strong>Matching rules</strong></div>
+ <div class="panel-body">
+ <div>
+ <label for="attr-eq-mr-select-view" class="ds-config-label-lrg"><b>Equality</b></label><input
+ class="ds-input" type="text" id="attr-eq-mr-select-view" size="35" readonly />
+ </div>
+ <div>
+ <label for="attr-order-mr-select-view" class="ds-config-label-lrg"><b>Ordering</b></label><input
+ class="ds-input" type="text" id="attr-order-mr-select-view" size="35" readonly />
+ </div>
+ <div>
+ <label for="attr-sub-mr-select-view" class="ds-config-label-lrg"><b>Substring</b></label><input
+ class="ds-input" type="text" id="attr-sub-mr-select-view" size="35" readonly />
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
<!-- Add/edit Attribute modal -->
<div class="modal fade" id="add-edit-attr-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="add-edit-attr-header" aria-hidden="true">
<div class="modal-dialog">
@@ -79,22 +153,22 @@
<div class="ds-inline">
<p class="ds-modal-error"></p>
<div>
- <label for="attr-parent" class="ds-config-label-lrg" title="The parent attribute"><b>Parent Attribute</b></label><select
- class="btn btn-default dropdown ds-oc-dropdown" id="attr-parent">
- <option value=""></option>
- </select>
- </div>
- <div>
<label for="attr-name" class="ds-config-label-lrg" title="The attribute name"><b
>Attribute Name</b></label><input class="ds-input" type="text" id="attr-name" size="40"/>
</div>
<div>
<label for="attr-desc" class="ds-config-label-lrg" title="The attribute description"><b
- >Attribute Description</b></label><input class="ds-input" type="text" id="attr-desc" size="40"/>
+ >Description</b></label><input class="ds-input" type="text" id="attr-desc" size="40"/>
</div>
<div>
<label for="attr-oid" class="ds-config-label-lrg" title="The attribute name"><b
- >Attribute OID</b></label><input class="ds-input" type="text" id="attr-oid" size="40"/>
+ >OID</b></label><input class="ds-input" type="text" id="attr-oid" size="40"/>
+ </div>
+ <div>
+ <label for="attr-parent" class="ds-config-label-lrg" title="The parent attribute"><b>Parent Attribute</b></label><select
+ class="btn btn-default dropdown ds-oc-dropdown" id="attr-parent">
+ <option value=""></option>
+ </select>
</div>
<div>
<label for="attr-syntax" class="ds-config-label-lrg" title="The attribute syntax"><b>Attribute Syntax</b></label><select
@@ -119,7 +193,7 @@
<label for="attr-alias" class="ds-config-label-lrg" title="The attribute alias list separated by space"><b
>Attribute Aliases</b></label><input class="ds-input" type="text" id="attr-alias" size="40"/>
</div>
- <div class="panel panel-default">
+ <div class="panel panel-default ds-margin-top">
<div class="panel-heading"><strong>Matching rules</strong></div>
<div class="panel-body">
<div>
@@ -157,6 +231,65 @@
</div>
+ <!-- View Objectclass -->
+ <div class="modal fade" id="view-objectclass-form" aria-labelledby="view-objectclass-form" data-backdrop="static" tabindex="-1" role="dialog" aria-hidden="true">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close" data-dismiss="modal" aria-hidden="true" aria-label="Close">
+ <span class="pficon pficon-close"></span>
+ </button>
+ <h4 class="modal-title">View Objectclass</h4>
+ </div>
+ <div class="modal-body">
+ <form class="form-horizontal">
+ <div class="ds-inline">
+ <div>
+ <label for="oc-name-view" class="ds-config-label-lrg" title="The objectclass name"><b
+ >Objectclass Name</b></label><input class="ds-input" type="text" id="oc-name-view" size="40" readonly />
+ </div>
+ <div>
+ <label for="oc-desc-view" class="ds-config-label-lrg" title="The objectClass description"><b
+ >Description</b></label><input class="ds-input" type="text" id="oc-desc-view" size="40" readonly/>
+ </div>
+ <div>
+ <label for="oc-oid-view" class="ds-config-label-lrg" title="Objectclass OID (optional)"><b
+ >OID (optional)</b></label><input class="ds-input" value="" type="text" id="oc-oid-view" size="40" readonly/>
+ </div>
+ <div>
+ <label for="oc-parent-view" class="ds-config-label-lrg" title="The parent objectclass"><b>Parent Objectclass</b></label><input
+ class="ds-input" value="" type="text" id="oc-parent-view" size="40" readonly />
+ </div>
+ <div>
+ <label for="oc-kind-view" class="ds-config-label-lrg" title="The parent objectclass"><b>Objectclass Kind</b></label><input
+ class="ds-input" value="" type="text" id="oc-kind-view" size="40" readonly />
+ </div>
+ <hr>
+ <div class="ds-container">
+ <div>
+ <label class="ds-config-label" for="oc-required-list-view" title=
+ "Attributes allowed by the objectclass"><b>Required Attributes</b></label>
+ <select id="oc-required-list-view" class="ds-may-must-list" multiple>
+ </select>
+ </div>
+ <div class="ds-divider"></div>
+ <div>
+ <label class="ds-config-label" for="oc-allowed-list-view" title=
+ "Attributes allowed by the objectclass"><b>Allowed Attributes</b></label>
+ <select id="oc-allowed-list-view" class="ds-may-must-list" multiple>
+ </select>
+ </div>
+ </div>
+ </div>
+ </form>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
<!-- Add/Edit Objectclass -->
<div class="modal fade" id="add-edit-oc-form" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="add-edit-oc-header" aria-hidden="true">
<div class="modal-dialog">
@@ -172,27 +305,27 @@
<div class="ds-inline">
<p class="ds-modal-error"></p>
<div>
- <label for="oc-parent" class="ds-config-label-lrg" title="The parent objectclass"><b>Parent Objectclass</b></label><select
- class="btn btn-default dropdown ds-oc-dropdown" id="oc-parent">
- </select>
- </div>
- <div>
<label for="oc-name" class="ds-config-label-lrg" title="The objectclass name"><b
>Objectclass Name</b></label><input class="ds-input" type="text" id="oc-name" size="40" required />
</div>
<div>
<label for="oc-desc" class="ds-config-label-lrg" title="The objectClass description"><b
- >ObjectClass Description</b></label><input class="ds-input" type="text" id="oc-desc" size="40"/>
+ >Description</b></label><input class="ds-input" type="text" id="oc-desc" size="40"/>
</div>
<div>
<label for="oc-oid" class="ds-config-label-lrg" title="Objectclass OID (optional)"><b
>OID (optional)</b></label><input class="ds-input" value="" type="text" id="oc-oid" size="40"/>
</div>
<div>
+ <label for="oc-parent" class="ds-config-label-lrg" title="The parent objectclass"><b>Parent Objectclass</b></label><select
+ class="btn btn-default dropdown ds-oc-dropdown" id="oc-parent">
+ </select>
+ </div>
+ <div>
<label for="oc-kind" class="ds-config-label-lrg" title="The parent objectclass"><b>Objectclass Kind</b></label><select
class="btn btn-default dropdown ds-oc-dropdown" id="oc-kind">
<option value=""></option>
- </select>
+ </select>
</div>
<hr>
<div class="ds-container">
diff --git a/src/cockpit/389-console/src/schema.js b/src/cockpit/389-console/src/schema.js
index a31e74a..618c555 100644
--- a/src/cockpit/389-console/src/schema.js
+++ b/src/cockpit/389-console/src/schema.js
@@ -251,7 +251,7 @@ function get_and_set_schema_tables() {
}
$.each(syntax_list, function (i, syntax) {
if (syntax.id === item.syntax) {
- syntax_name = '<div title="' + syntax.id + '">' + syntax.name + '</div>';
+ syntax_name = '<div title="' + syntax.name + '">' + syntax.name + '</div>';
}
});
// If attribute is user defined them the action button is enabled
@@ -326,6 +326,7 @@ function get_and_set_schema_tables() {
"visible": false
}]
});
+ update_progress();
}).fail(function(syntax_data) {
console.log("Get syntaxes failed: " + syntax_data.message);
check_inst_alive(1);
@@ -353,6 +354,7 @@ function get_and_set_schema_tables() {
});
console.log("Finished loading schema.");
+ update_progress();
}).fail(function(oc_data) {
console.log("Get all schema objects failed: " + oc_data.message);
check_inst_alive(1);
@@ -738,13 +740,50 @@ $(document).ready( function() {
$("#add-edit-attr-form").modal('toggle');
}
+ function load_view_attr_form(element) {
+ clear_attr_form();
+ var data = schema_at_table.row(element.parents('tr') ).data();
+ var edit_attr_name = data[0];
+ var edit_attr_oid = data[1];
+ var edit_attr_syntax = $.parseHTML(data[2])[0].title;
+ var edit_attr_multivalued = data[3];
+ var edit_attr_desc = data[5];
+ var edit_attr_aliases = data[6];
+ var edit_attr_x_origin = data[7];
+ var edit_attr_usage = data[8];
+ var edit_attr_no_user_mod = data[9];
+ var edit_attr_parent = data[10];
+ var edit_attr_eq_mr = data[11];
+ var edit_attr_order_mr = data[12];
+ var edit_attr_sub_mr = data[13];
+
+ $("#attr-name-view").val(edit_attr_name);
+ $("#attr-oid-view").val(edit_attr_oid);
+ $("#attr-usage-view")[0].value = edit_attr_usage;
+ $("#attr-parent-view")[0].value = edit_attr_parent;
+ $("#attr-desc-view").val(edit_attr_desc);
+ if (edit_attr_aliases) {
+ $("#attr-alias-view").val(edit_attr_aliases.join(" "));
+ }
+ $("#attr-syntax-view").val(edit_attr_syntax);
+ $("#attr-multivalued-view").prop('checked', false);
+ if (edit_attr_multivalued == "yes") {
+ $("#attr-multivalued-view").prop('checked', true);
+ }
+ $("#attr-no-user-mod-view").prop('checked', false);
+ if (edit_attr_no_user_mod) {
+ $("#attr-no-user-mod-view").prop('checked', true);
+ }
+ $("#attr-eq-mr-select-view").val(edit_attr_eq_mr);
+ $("#attr-order-mr-select-view").val(edit_attr_order_mr);
+ $("#attr-sub-mr-select-view").val(edit_attr_sub_mr);
+
+ $("#view-attr-form").modal('toggle');
+ }
+
$(document).on('click', '.attr-view-btn', function(e) {
e.preventDefault();
- load_attr_form($(this));
- var edit_attr_name = schema_at_table.row($(this).parents('tr') ).data()[0];
- $("#add-edit-attr-header").html('View Attribute: ' + edit_attr_name);
- $("#save-attr-button").attr('title', 'Only user-defined attributes can be modified');
- $("#save-attr-button").attr('disabled', true);
+ load_view_attr_form($(this));
});
$(document).on('click', '.attr-edit-btn', function(e) {
@@ -772,6 +811,44 @@ $(document).ready( function() {
});
});
+ function load_view_oc_form(element) {
+ clear_oc_form();
+ var data = schema_oc_table.row(element.parents('tr') ).data();
+ var edit_oc_name = data[0];
+ var edit_oc_oid = data[1];
+ var edit_oc_required = data[2].split(" ");
+ var edit_oc_allowed = data[3].split(" ");
+ var edit_oc_x_origin = data[5];
+ var edit_oc_kind = data[6];
+ var edit_oc_desc = data[7];
+ var edit_oc_parent = data[8];
+
+ $("#oc-name-view").val(edit_oc_name);
+ $("#oc-oid-view").val(edit_oc_oid);
+ $("#oc-kind-view")[0].value = edit_oc_kind;
+ $("#oc-desc-view").val(edit_oc_desc);
+ $("#oc-parent-view")[0].value = edit_oc_parent;
+ $.each(edit_oc_required, function (i, item) {
+ if (item) {
+ $("#oc-required-list-view").append($('<option>', {
+ value: item,
+ text : item
+ }));
+ }
+ });
+ $.each(edit_oc_allowed, function (i, item) {
+ if (item) {
+ $("#oc-allowed-list-view").append($('<option>', {
+ value: item,
+ text : item
+ }));
+ }
+ });
+
+ // Update modal html header and fields and show()
+ $("#view-objectclass-form").modal('toggle');
+ }
+
function load_oc_form(element) {
clear_oc_form();
var data = schema_oc_table.row(element.parents('tr') ).data();
@@ -789,9 +866,9 @@ $(document).ready( function() {
$("#oc-name").attr('disabled', true);
$("#oc-name").val(edit_oc_name);
$("#oc-oid").val(edit_oc_oid);
- $("#oc-kind")[0].value = edit_oc_kind;
+ $("#oc-kind").val(edit_oc_kind);
$("#oc-desc").val(edit_oc_desc);
- $("#oc-parent")[0].value = edit_oc_parent;
+ $("#oc-parent").val(edit_oc_parent);
$.each(edit_oc_required, function (i, item) {
if (item) {
$("#oc-required-list").append($('<option>', {
@@ -816,11 +893,7 @@ $(document).ready( function() {
$(document).on('click', '.oc-view-btn', function(e) {
e.preventDefault();
- load_oc_form($(this));
- var edit_oc_name = schema_oc_table.row($(this).parents('tr') ).data()[0];
- $("#add-edit-oc-header").html('View Objectclass: ' + edit_oc_name);
- $("#save-oc-button").attr('title', 'Only user-defined objectClasses can be modified');
- $("#save-oc-button").attr('disabled', true);
+ load_view_oc_form($(this));
});
$(document).on('click', '.oc-edit-btn', function(e) {
diff --git a/src/cockpit/389-console/src/security.jsx b/src/cockpit/389-console/src/security.jsx
index 43edf49..77b25f9 100644
--- a/src/cockpit/389-console/src/security.jsx
+++ b/src/cockpit/389-console/src/security.jsx
@@ -599,7 +599,7 @@ export class Security extends React.Component {
configPage =
<div>
<Row className="ds-margin-top" title="The server's secure port number (nsslapd-secureport).">
- <Col componentClass={ControlLabel} sm={2}>
+ <Col componentClass={ControlLabel} sm={3}>
Server Secure Port
</Col>
<Col sm={4}>
@@ -607,7 +607,7 @@ export class Security extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top" title="This parameter can be used to restrict the Directory Server instance to a single IP interface (hostname, or IP address). This parameter specifically sets what interface to use for TLS traffic. Requires restart. (nsslapd-securelistenhost).">
- <Col componentClass={ControlLabel} sm={2}>
+ <Col componentClass={ControlLabel} sm={3}>
Secure Listen Host
</Col>
<Col sm={4}>
@@ -615,7 +615,7 @@ export class Security extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top" title="The name, or nickname, of the server certificate inthe NSS datgabase the server should use (nsSSLPersonalitySSL).">
- <Col className="ds-no-padding" sm={2}>
+ <Col className="ds-no-padding" sm={3}>
<ControlLabel>Server Certificate Name</ControlLabel>
</Col>
<Col sm={4}>
@@ -631,7 +631,7 @@ export class Security extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top" title="The minimum SSL/TLS version the server will accept (sslversionmin).">
- <Col componentClass={ControlLabel} sm={2}>
+ <Col componentClass={ControlLabel} sm={3}>
Minimum TLS Version
</Col>
<Col sm={4}>
@@ -646,7 +646,7 @@ export class Security extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top" title="The maximum SSL/TLS version the server will accept (sslversionmax).">
- <Col componentClass={ControlLabel} sm={2}>
+ <Col componentClass={ControlLabel} sm={3}>
Maximum TLS Version
</Col>
<Col sm={4}>
@@ -661,7 +661,7 @@ export class Security extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top" title="Sets how the Directory Server enforces TLS client authentication (nsSSLClientAuth).">
- <Col componentClass={ControlLabel} sm={2}>
+ <Col componentClass={ControlLabel} sm={3}>
Client Authentication
</Col>
<Col sm={4}>
@@ -673,7 +673,7 @@ export class Security extends React.Component {
</Col>
</Row>
<Row className="ds-margin-top" title="Validate server's certificate expiration date (nsslapd-validate-cert).">
- <Col componentClass={ControlLabel} sm={2}>
+ <Col componentClass={ControlLabel} sm={3}>
Validate Certificate
</Col>
<Col sm={4}>
diff --git a/src/cockpit/389-console/src/servers.html b/src/cockpit/389-console/src/servers.html
index e8171c0..02e39ab 100644
--- a/src/cockpit/389-console/src/servers.html
+++ b/src/cockpit/389-console/src/servers.html
@@ -95,24 +95,24 @@
<div class="ds-divider"></div>
<div class="ds-inline">
<div>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-attribute-name-exceptions" checked><label
+ <input type="checkbox" class="ds-config-checkbox" id="nsslapd-attribute-name-exceptions"><label
for="nsslapd-attribute-name-exceptions" class="ds-label" title="Allows non-standard characters in attribute names to be used for backwards compatibility with older servers"> Allow Attribute Naming Exceptions </label>
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-dn-validate-strict" checked><label
+ <input type="checkbox" class="ds-config-checkbox" id="nsslapd-dn-validate-strict"><label
for="nsslapd-dn-validate-strict" class="ds-label" title="Enables strict syntax validation for DNs, according to section 3 in RFC 4514 (nsslapd-dn-validate-strict)."> Enable Strict DN Syntax Validation</label>
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-entryusn-global" checked><label
+ <input type="checkbox" class="ds-config-checkbox" id="nsslapd-entryusn-global"><label
for="nsslapd-entryusn-global" class="ds-label" title="For USN plugin - maintain unique USNs across all back end databases (nsslapd-entryusn-global)."> Enable Unique USNs Across All Backends</label>
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-ignore-time-skew" checked><label
+ <input type="checkbox" class="ds-config-checkbox" id="nsslapd-ignore-time-skew"><label
for="nsslapd-ignore-time-skew" class="ds-label" title="Ignore time skew when generating CSNs"> Ignore CSN Time Skew</label>
</div>
<div>
- <input type="checkbox" class="ds-config-checkbox" id="nsslapd-readonly-server" checked><label
- for="nsslapd-readonly-server" class="ds-label" title="Make entire server read-only (nsslapd-readonly)"> Server Read-Only</label>
+ <input type="checkbox" class="ds-config-checkbox" id="nsslapd-readonly"><label
+ for="nsslapd-readonly" class="ds-label" title="Make entire server read-only (nsslapd-readonly)"> Server Read-Only</label>
</div>
</div>
diff --git a/src/cockpit/389-console/src/servers.js b/src/cockpit/389-console/src/servers.js
index d3e285d..3d1c4fa 100644
--- a/src/cockpit/389-console/src/servers.js
+++ b/src/cockpit/389-console/src/servers.js
@@ -165,6 +165,7 @@ function get_and_set_config () {
$(".ds-accesslog-table").prop('checked', false);
$(".ds-errorlog-table").prop('checked', false);
config_values = {};
+ update_progress();
for (var attr in obj['attrs']) {
var val = obj['attrs'][attr][0];
@@ -189,6 +190,7 @@ function get_and_set_config () {
// Do the log level tables
if (attr == "nsslapd-accesslog-level") {
+ config_values[attr] = val;
var level_val = parseInt(val);
for ( var level in accesslog_levels ) {
if (level_val & accesslog_levels[level]) {
@@ -196,6 +198,7 @@ function get_and_set_config () {
}
}
} else if (attr == "nsslapd-errorlog-level") {
+ config_values[attr] = val;
var level_val = parseInt(val);
for ( var level in errorlog_levels ) {
if (level_val & errorlog_levels[level]) {
@@ -232,6 +235,7 @@ function update_suffix_dropdowns () {
$("#" + dropdowns[list]).append('<option value="' + obj['items'][idx] + '" selected="selected">' + obj['items'][idx] +'</option>');
}
}
+ update_progress();
}).fail(function(data) {
if (quiet === undefined) {
popup_err("Error", "Failed to get backend suffix list\n" + data.message);
@@ -251,6 +255,7 @@ function get_and_set_localpwp (quiet) {
log_cmd('get_and_set_localpwp', 'Get local password policies', cmd);
cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {
var obj = JSON.parse(data);
+ update_progress();
// Empty table
pwp_table.clear().draw();
@@ -276,13 +281,13 @@ function get_and_set_sasl () {
log_cmd('get_and_set_sasl', 'Get SASL mappings', cmd);
cockpit.spawn(cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {
var obj = JSON.parse(data);
+ update_progress();
sasl_table.clear().draw();
for (var idx in obj['items']) {
var map_cmd = [DSCONF, '-j', 'ldapi://%2fvar%2frun%2f' + server_id + '.socket','sasl', 'get', obj['items'][idx] ];
log_cmd('get_and_set_sasl', 'Get SASL mapping', map_cmd);
cockpit.spawn(map_cmd, { superuser: true, "err": "message", "environ": [ENV]}).done(function(data) {
var map_obj = JSON.parse(data);
-
// Update html table
var sasl_priority = '100';
if ( map_obj['attrs'].hasOwnProperty('nssaslmappriority') ){
@@ -357,14 +362,29 @@ function save_config() {
var val = $("#" + attr).val();
// But first check for rootdn-pw changes and check confirm input matches
- if (attr == "nsslapd-rootpw" && (val != config_values[attr] || val != $("#nsslapd-rootpw-confirm").val())) {
- // Password change, make sure passwords match
- if (val != $("#nsslapd-rootpw-confirm").val()){
- popup_msg("Passwords do not match!", "The Directory Manager passwords do not match, please correct before saving again.");
- return;
+ if (attr == "nsslapd-rootpw") {
+ if (val != config_values[attr] || val != $("#nsslapd-rootpw-confirm").val()) {
+ // Password change, make sure passwords match
+ if (val != $("#nsslapd-rootpw-confirm").val()){
+ popup_msg("Passwords do not match!", "The Directory Manager passwords do not match, please correct before saving again.");
+ return;
+ }
+ }
+ if (val.length < 8) {
+ popup_msg("Password is too short!", "The Directory Manager password must be at least 8 characters long.");
+ $("#nsslapd-rootpw").val(config_values[attr]);
+ $("#nsslapd-rootpw-confirm").val(config_values[attr]);
+ return;
}
}
+ if (attr == "nsslapd-port") {
+ if (!valid_num(config_values[attr])) {
+ popup_msg("Port number is not valid");
+ $("#nsslapd-port").val(config_values[attr]);
+ }
+ }
+
if ( val && val != config_values[attr]) {
mod['attr'] = attr;
mod['val'] = val;
@@ -382,10 +402,15 @@ function save_config() {
access_log_level += val;
}
});
- mod = {}
- mod['attr'] = "nsslapd-accesslog-level";
- mod['val'] = access_log_level;
- mod_list.push(mod);
+ if (config_values["nsslapd-accesslog-level"] === undefined) {
+ config_values["nsslapd-accesslog-level"] = "256";
+ }
+ if (config_values["nsslapd-accesslog-level"] != access_log_level) {
+ mod = {}
+ mod['attr'] = "nsslapd-accesslog-level";
+ mod['val'] = access_log_level;
+ mod_list.push(mod);
+ }
// Save error log levels
var error_log_level = 0;
@@ -396,10 +421,17 @@ function save_config() {
error_log_level += val;
}
});
- mod = {}
- mod['attr'] = "nsslapd-errorlog-level";
- mod['val'] = error_log_level;
- mod_list.push(mod);
+ if (config_values["nsslapd-errorlog-level"] === undefined ||
+ config_values["nsslapd-errorlog-level"] == "16384")
+ {
+ config_values["nsslapd-errorlog-level"] = "0";
+ }
+ if (config_values["nsslapd-errorlog-level"] != error_log_level) {
+ mod = {}
+ mod['attr'] = "nsslapd-errorlog-level";
+ mod['val'] = error_log_level;
+ mod_list.push(mod);
+ }
// Build dsconf commands to apply all the mods
if (mod_list.length) {
@@ -1007,6 +1039,10 @@ $(document).ready( function() {
* Get all the current values from the form.
*/
var policy_name = $("#local-entry-dn").val();
+ if (policy_name == "" || !valid_dn(policy_name)) {
+ popup_msg("Error", "You must enter a valid DN for the local password policy");
+ return;
+ }
var pwp_track = "off";
if ( $("#local-passwordtrackupdatetime").is(":checked") ) {
pwp_track = "on";
@@ -1479,19 +1515,33 @@ $(document).ready( function() {
var new_server_id = $("#create-inst-serverid").val();
if (new_server_id == ""){
report_err($("#create-inst-serverid"), 'You must provide an Instance name');
+ $("#create-inst-serverid").css("border-color", "red");
return;
} else {
new_server_id = new_server_id.replace(/^slapd-/i, ""); // strip "slapd-"
- setup_inf = setup_inf.replace('INST_NAME', new_server_id);
+ if (new_server_id.length > 128) {
+ report_err($("#create-inst-serverid"), 'Instance name is too long, it must not exceed 128 characters');
+ $("#create-inst-serverid").css("border-color", "red");
+ return;
+ }
+ if (new_server_id.match(/^[#%:-A-Za-z0-9_]+$/g)) {
+ setup_inf = setup_inf.replace('INST_NAME', new_server_id);
+ } else {
+ report_err($("#create-inst-serverid"), 'Instance name can only contain letters, numbers, and: # % : - _');
+ $("#create-inst-serverid").css("border-color", "red");
+ return;
+ }
}
// Port
var server_port = $("#create-inst-port").val();
if (server_port == ""){
report_err($("#create-inst-port"), 'You must provide a port number');
+ $("#create-inst-port").css("border-color", "red");
return;
} else if (!valid_num(server_port)) {
- report_err($("#create-inst-port"), 'Port must be a number!');
+ report_err($("#create-inst-port"), 'Port must be a number between 1 and 65534!');
+ $("#create-inst-port").css("border-color", "red");
return;
} else {
setup_inf = setup_inf.replace('PORT', server_port);
@@ -1501,9 +1551,11 @@ $(document).ready( function() {
var secure_port = $("#create-inst-secureport").val();
if (secure_port == ""){
report_err($("#create-inst-secureport"), 'You must provide a secure port number');
+ $("#create-inst-secureport").css("border-color", "red");
return;
} else if (!valid_num(secure_port)) {
report_err($("#create-inst-secureport"), 'Secure port must be a number!');
+ $("#create-inst-secureport").css("border-color", "red");
return;
} else {
setup_inf = setup_inf.replace('SECURE_PORT', secure_port);
@@ -1513,6 +1565,7 @@ $(document).ready( function() {
var server_rootdn = $("#create-inst-rootdn").val();
if (server_rootdn == ""){
report_err($("#create-inst-rootdn"), 'You must provide a Directory Manager DN');
+ $("#create-inst-rootdn").css("border-color", "red");
return;
} else {
setup_inf = setup_inf.replace('ROOTDN', server_rootdn);
@@ -1536,6 +1589,10 @@ $(document).ready( function() {
report_err($("#rootdn-pw"), 'Directory Manager password can not be empty!');
$("#rootdn-pw-confirm").css("border-color", "red");
return;
+ } else if (root_pw.length < 8) {
+ report_err($("#rootdn-pw"), 'Directory Manager password must have at least 8 characters');
+ $("#rootdn-pw-confirm").css("border-color", "red");
+ return;
} else {
setup_inf = setup_inf.replace('ROOTPW', root_pw);
}
@@ -1546,9 +1603,11 @@ $(document).ready( function() {
if ( (backend_name != "" && backend_suffix == "") || (backend_name == "" && backend_suffix != "") ) {
if (backend_name == ""){
report_err($("#backend-name"), 'If you specify a backend suffix, you must also specify a backend name');
+ $("#backend-name").css("border-color", "red");
return;
} else {
report_err($("#backend-suffix"), 'If you specify a backend name, you must also specify a backend suffix');
+ $("#backend-suffix").css("border-color", "red");
return;
}
}
diff --git a/src/lib389/lib389/config.py b/src/lib389/lib389/config.py
index 23ab9f2..53f1b16 100644
--- a/src/lib389/lib389/config.py
+++ b/src/lib389/lib389/config.py
@@ -64,7 +64,7 @@ class Config(DSLdapObject):
return DN_CONFIG
def replace(self, key, value):
- if key.lower() == 'nsslapd-secureport' and selinux_present():
+ if selinux_present() and (key.lower() == 'nsslapd-secureport' or key.lower() == 'nsslapd-port'):
# Get old port and remove label
old_port = self.get_attr_val_utf8(key)
self.log.debug("Removing old port's selinux label...")
diff --git a/src/lib389/lib389/instance/options.py b/src/lib389/lib389/instance/options.py
index 702b60a..dcc7f63 100644
--- a/src/lib389/lib389/instance/options.py
+++ b/src/lib389/lib389/instance/options.py
@@ -166,8 +166,9 @@ class Slapd2Base(Options2):
self._helptext['root_password'] = ("Sets the password of the account specified in the \"root_dn\" parameter. " +
"You can either set this parameter to a plain text password dscreate hashes " +
"during the installation or to a \"{algorithm}hash\" string generated by the " +
- "pwdhash utility. Note that setting a plain text password can be a security " +
- "risk if unprivileged users can read this INF file!")
+ "pwdhash utility. The password must be at least 8 characters long. Note " +
+ "that setting a plain text password can be a security risk if unprivileged " +
+ "users can read this INF file!")
self._options['prefix'] = ds_paths.prefix
self._type['prefix'] = str
diff --git a/src/lib389/lib389/instance/remove.py b/src/lib389/lib389/instance/remove.py
index 1f15b46..c9a872e 100644
--- a/src/lib389/lib389/instance/remove.py
+++ b/src/lib389/lib389/instance/remove.py
@@ -105,7 +105,10 @@ def remove_ds_instance(dirsrv, force=False):
_log.debug(f"CMD: {' '.join(result.args)} ; STDOUT: {result.stdout} ; STDERR: {result.stderr}")
_log.debug("Removing %s" % tmpfiles_d_path)
- shutil.rmtree(tmpfiles_d_path, ignore_errors=True)
+ try:
+ os.remove(tmpfiles_d_path)
+ except OSError as e:
+ _log.debug("Failed to remove tmpfile: " + str(e))
# Nor can we assume we have selinux. Try docker sometime ;)
if dirsrv.ds_paths.with_selinux:
diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py
index 58012b3..bb0ff32 100644
--- a/src/lib389/lib389/instance/setup.py
+++ b/src/lib389/lib389/instance/setup.py
@@ -243,8 +243,11 @@ class SetupDs(object):
print('===========================================')
# Set the defaults
- general = {'config_version': 2, 'full_machine_name': socket.getfqdn(),
- 'strict_host_checking': False, 'selinux': True, 'systemd': ds_paths.with_systemd,
+ general = {'config_version': 2,
+ 'full_machine_name': socket.getfqdn(),
+ 'strict_host_checking': False,
+ 'selinux': True,
+ 'systemd': ds_paths.with_systemd,
'defaults': '999999999', 'start': True}
slapd = {'self_sign_cert_valid_months': 24,
@@ -394,6 +397,11 @@ class SetupDs(object):
print('Password can not be empty')
continue
+ if len(rootpw1) < 8:
+ print('Password must be at least 8 characters long')
+ continue
+
+
rootpw2 = getpass.getpass('Confirm the Directory Manager Password: ').rstrip()
if rootpw1 != rootpw2:
print('Passwords do not match')
@@ -568,6 +576,9 @@ class SetupDs(object):
assert_c(is_a_dn(slapd['root_dn']), "root_dn in section [slapd] is not a well formed LDAP DN")
assert_c(slapd['root_password'] is not None and slapd['root_password'] != '',
"Configuration attribute 'root_password' in section [slapd] not found")
+ if len(slapd['root_password']) < 8:
+ raise ValueError("root_password must be at least 8 characters long")
+
# Check if pre-hashed or not.
# !!!!!!!!!!!!!!
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months
[389-ds-base] branch master updated: Bump version to 1.4.2.0
by pagure@pagure.io
This is an automated email from the git hooks/post-receive script.
mreynolds pushed a commit to branch master
in repository 389-ds-base.
The following commit(s) were added to refs/heads/master by this push:
new a096b07 Bump version to 1.4.2.0
a096b07 is described below
commit a096b07cc92adbe385d0c5cb7288d4e86b496042
Author: Mark Reynolds <mreynolds(a)redhat.com>
AuthorDate: Fri Sep 6 15:42:04 2019 -0400
Bump version to 1.4.2.0
---
VERSION.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION.sh b/VERSION.sh
index 9a7d5ca..3d8b8d9 100644
--- a/VERSION.sh
+++ b/VERSION.sh
@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
-VERSION_MAINT=1.6
+VERSION_MAINT=2.0
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
3 years, 6 months