From 749b9f3327f2ffe083c98df41d5cdd378de1c6e9 Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Jun 25 2018 21:39:54 +0000 Subject: Ticket 49471 - Rename dscreate options Description: Changed the names of the two positional arguemnts from "fromfile" --> "install", and "example" --> "create-template" Added option for specifying template file instead of dumping the template to STDOUT Finally added autocomplete arg parsing to the cli tools, and used a unique file name in UI when creating template. https://pagure.io/389-ds-base/issue/49791 Reviewed by: ? --- diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in index d56266b..a75ab78 100644 --- a/rpm/389-ds-base.spec.in +++ b/rpm/389-ds-base.spec.in @@ -286,6 +286,7 @@ Requires: python%{python3_pkgversion}-six Requires: python%{python3_pkgversion}-pyasn1 Requires: python%{python3_pkgversion}-pyasn1-modules Requires: python%{python3_pkgversion}-dateutil +Requires: python%{python3_pkgversion}-argcomplete %{?python_provide:%python_provide python%{python3_pkgversion}-lib389} %description -n python%{python3_pkgversion}-lib389 This module contains tools and libraries for accessing, testing, @@ -437,7 +438,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/libsvrcore.la %if %{use_perl} -# make sure perl scripts have a proper shebang +# make sure perl scripts have a proper shebang sed -i -e 's|#{{PERL-EXEC}}|#!/usr/bin/perl|' $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/script-templates/template-*.pl %endif @@ -573,7 +574,7 @@ for inst in $instances ; do echo restarting instance $inst >> $output 2>&1 || : /bin/systemctl start $inst >> $output 2>&1 || : done -#END UPGRADE +#END UPGRADE %endif exit 0 @@ -960,7 +961,7 @@ exit 0 - bump version to 1.3.0.rc3 - Ticket 549 - DNA plugin no longer reports additional info when range is depleted - Ticket 541 - need to set plugin as off in ldif template -- Ticket 541 - RootDN Access Control plugin is missing after upgrade +- Ticket 541 - RootDN Access Control plugin is missing after upgrade * Fri Dec 14 2012 Noriko Hosoi - 1.3.0-0.2.rc2 - bump version to 1.3.0.rc2 @@ -1028,16 +1029,16 @@ exit 0 * Tue Oct 9 2012 Mark Reynolds - 1.3.0.a1-1 Ticket #28 MOD operations with chained delete/add get back error 53 on backend config Ticket #173 ds-logpipe.py script's man page and script help should be updated for -t option. -Ticket #196 RFE: Interpret IPV6 addresses for ACIs, replication, and chaining -Ticket #218 RFE - Make RIP working with Replicated Entries -Ticket #328 make sure all internal search filters are properly escaped +Ticket #196 RFE: Interpret IPV6 addresses for ACIs, replication, and chaining +Ticket #218 RFE - Make RIP working with Replicated Entries +Ticket #328 make sure all internal search filters are properly escaped Ticket #329 389-admin build fails on F-18 with new apache Ticket #344 deadlock in replica_write_ruv Ticket #351 use betxn plugins by default -Ticket #352 make cos, roles, views betxn aware +Ticket #352 make cos, roles, views betxn aware Ticket #356 logconv.pl - RFE - track bind info -Ticket #365 Audit log - clear text password in user changes -Ticket #370 Opening merge qualifier CoS entry using RHDS console changes the entry. +Ticket #365 Audit log - clear text password in user changes +Ticket #370 Opening merge qualifier CoS entry using RHDS console changes the entry. Ticket #372 Setting nsslapd-listenhost or nsslapd-securelistenhost breaks ACI processing Ticket #386 Overconsumption of memory with large cachememsize and heavy use of ldapmodify Ticket #402 unhashedTicket #userTicket #password in entry extension @@ -1568,7 +1569,7 @@ ice is restarted * Wed Mar 2 2011 Rich Megginson - 1.2.8-0.6.rc1 - 389-ds-base-1.2.8 release candidate 1 - git tag 389-ds-base-1.2.8.rc1 - Bug 518890 - setup-ds-admin.pl - improve hostname validation -- Bug 681015 - RFE: allow fine grained password policy duration attributes in +- Bug 681015 - RFE: allow fine grained password policy duration attributes in - days, hours, minutes, as well - Bug 514190 - setup-ds-admin.pl --debug does not log to file - Bug 680555 - ns-slapd segfaults if I have more than 100 DBs @@ -1621,12 +1622,12 @@ ice is restarted - Bug 151705 - Need to update Console Cipher Preferences with new ciphers - Bug 668862 - init scripts return wrong error code - Bug 670616 - Allow SSF to be set for local (ldapi) connections -- Bug 667935 - DS pipe log script's logregex.py plugin is not redirecting the +- Bug 667935 - DS pipe log script's logregex.py plugin is not redirecting the - log output to the text file - Bug 668619 - slapd stops responding - Bug 624547 - attrcrypt should query the given slot/token for - supported ciphers -- Bug 646381 - Faulty password for nsmultiplexorcredentials does not give any +- Bug 646381 - Faulty password for nsmultiplexorcredentials does not give any - error message in logs * Fri Jan 21 2011 Nathan Kinder - 1.2.8-0.1.a1 @@ -1685,7 +1686,7 @@ erral) * Mon Nov 1 2010 Rich Megginson - 1.2.7-0.5.a4 - 1.2.7.a4 release - git tag 389-ds-base-1.2.7.a4 -- Bug 647932 - multiple memberOf configuration adding memberOf where there is +- Bug 647932 - multiple memberOf configuration adding memberOf where there is no member - Bug 491733 - dbtest crashes - Bug 606545 - core schema should include numSubordinates @@ -2030,7 +2031,7 @@ ions * Tue Jan 09 2007 Dennis Gilmore - 1.1-0.1.cvs20070108 - update to a cvs snapshot -- fedorafy the spec +- fedorafy the spec - create -devel subpackage - apply a patch to use mozldap not mozldap6 - apply a patch to allow --prefix to work correctly diff --git a/src/cockpit/389-console/js/servers.js b/src/cockpit/389-console/js/servers.js index ea2a443..4bebbcd 100644 --- a/src/cockpit/389-console/js/servers.js +++ b/src/cockpit/389-console/js/servers.js @@ -847,42 +847,80 @@ $(document).ready( function() { report_err($("#rootdn-pw"), 'Directory Manager passwords do not match!'); $("#rootdn-pw-confirm").css("border-color", "red"); return; - } else if (root_pw == "" || root_pw_confirm == ""){ + } else if (root_pw == ""){ report_err($("#rootdn-pw"), 'Directory Manager password can not be empty!'); $("#rootdn-pw-confirm").css("border-color", "red"); return; } else { - setup_inf = setup_inf.replace('ROOTPW', 'False'); + setup_inf = setup_inf.replace('ROOTPW', root_pw); } + /* + * Here are steps we take to create the instance + * + * [1] Get FQDN Name for nsslapd-localhost setting in setup file + * [2] Create a file for the inf setup parameters + * [3] Set strict permissions on that file + * [4] Populate the new setup file with settings (including cleartext password) + * [5] Create the instance + * [6] Remove setup file + */ cockpit.spawn(["hostname", "--fqdn"], { superuser: true, "err": "message" }).fail(function(ex) { // Failed to get FQDN popup_err("Failed to get hostname!", ex.message); - }).done(function (data){ - // Set the hostname in inf file + /* + * We have FQDN, so set the hostname in inf file, and create the setup file + */ setup_inf = setup_inf.replace('FQDN', data); - - // Create setup inf file - var cmd = ["/bin/sh", "-c", '/usr/bin/echo -e "' + setup_inf + '" > /tmp/389setup.inf']; - cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) { + 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) { + // Failed to create setup file popup_err("Failed to create installation file!", ex.message); }).done(function (){ - // Next, create the instance - cmd = ['dscreate', 'fromfile', '/tmp/389setup.inf']; - cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) { + /* + * 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) { + // 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 create instance!", ex.message); + popup_err("Failed to set permission on setup file " + setup_file + ": ", ex.message); }).done(function (){ - // Cleanup - $("#create-inst-spinner").hide(); - $("#server-list-menu").attr('disabled', false); - $("#no-instances").hide(); - get_insts(); // Refresh server list - popup_msg("Success!", "Successfully created instance: slapd-" + new_server_id + "", ); - $("#create-inst-form").modal('toggle'); + /* + * 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) { + // Failed to populate setup file + popup_err("Failed to populate installation file!", ex.message); + }).done(function (){ + /* + * Next, create the instance... + */ + cmd = ['dscreate', 'install', setup_file]; + cockpit.spawn(cmd, { superuser: true, "err": "message" }).fail(function(ex) { + // 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); + }).done(function (){ + // Success!!! Now cleanup everything up... + cockpit.spawn(rm_cmd, { superuser: true }); // Remove Inf file with clear text password + $("#create-inst-spinner").hide(); + $("#server-list-menu").attr('disabled', false); + $("#no-instances").hide(); + get_insts(); // Refresh server list + popup_msg("Success!", "Successfully created instance: slapd-" + new_server_id + "", ); + $("#create-inst-form").modal('toggle'); + }); + }); + $("#create-inst-spinner").show(); }); - $("#create-inst-spinner").show(); }); }); }); diff --git a/src/lib389/cli/dsconf b/src/lib389/cli/dsconf index d9110c4..800d42e 100755 --- a/src/lib389/cli/dsconf +++ b/src/lib389/cli/dsconf @@ -7,8 +7,10 @@ # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +# +# PYTHON_ARGCOMPLETE_OK -import argparse +import argparse, argcomplete import logging import ldap import sys @@ -84,7 +86,7 @@ if __name__ == '__main__': cli_whoami.create_parser(subparsers) cli_referint.create_parser(subparsers) cli_automember.create_parser(subparsers) - + argcomplete.autocomplete(parser) args = parser.parse_args() log = reset_get_logger('dsconf', args.verbose) @@ -98,7 +100,6 @@ if __name__ == '__main__': dsrc_inst = dsrc_to_ldap("~/.dsrc", args.instance, log.getChild('dsrc')) # Now combine this with our arguments - dsrc_inst = dsrc_arg_concat(args, dsrc_inst) log.debug("Called with: %s" % args) diff --git a/src/lib389/cli/dscreate b/src/lib389/cli/dscreate index 4e20cfc..1535cc5 100755 --- a/src/lib389/cli/dscreate +++ b/src/lib389/cli/dscreate @@ -1,14 +1,16 @@ #!/usr/bin/python3 # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2018 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +# +# PYTHON_ARGCOMPLETE_OK -import argparse +import argparse, argcomplete import logging import sys @@ -27,22 +29,24 @@ if __name__ == '__main__': subparsers = parser.add_subparsers(help="action") - fromfile_parser = subparsers.add_parser('fromfile', help="Create an instance of Directory Server from an inf answer file") - fromfile_parser.add_argument('file', help="Inf file to use with prepared answers. You can generate an example of this with 'dscreate example'") - fromfile_parser.add_argument('-n', '--dryrun', help="Validate system and configurations only. Do not alter the system.", + install_parser = subparsers.add_parser('install', help="Create an instance of Directory Server from an inf answer file") + install_parser.add_argument('file', help="Inf file to use with prepared answers. You can generate an example of this with 'dscreate create-template'") + install_parser.add_argument('-n', '--dryrun', help="Validate system and configurations only. Do not alter the system.", action='store_true', default=False) - fromfile_parser.add_argument('--IsolemnlyswearthatIamuptonogood', dest="ack", + install_parser.add_argument('--IsolemnlyswearthatIamuptonogood', dest="ack", help="""You are here likely here by mistake! You want setup-ds.pl! By setting this value you acknowledge and take responsibility for the fact this command is UNTESTED and NOT READY. You are ON YOUR OWN! """, action='store_true', default=False) - fromfile_parser.add_argument('-c', '--containerised', help="Indicate to the installer that this is running in a container. Used to disable systemd native components, even if they are installed.", + install_parser.add_argument('-c', '--containerised', help="Indicate to the installer that this is running in a container. Used to disable systemd native components, even if they are installed.", action='store_true', default=False) - fromfile_parser.set_defaults(func=cli_instance.instance_create) + install_parser.set_defaults(func=cli_instance.instance_create) - example_parser = subparsers.add_parser('example', help="Display an example ini answer file, with comments") - example_parser.set_defaults(func=cli_instance.instance_example) + template_parser = subparsers.add_parser('create-template', help="Display an example inf answer file, or provide a file name to write it to disk.") + template_parser.add_argument('template_file', nargs="?", default=None, help="Write example template to this file") + template_parser.set_defaults(func=cli_instance.instance_example) + argcomplete.autocomplete(parser) args = parser.parse_args() log = reset_get_logger("dscreate", args.verbose) diff --git a/src/lib389/cli/dsctl b/src/lib389/cli/dsctl index 83b07c3..f9853d9 100755 --- a/src/lib389/cli/dsctl +++ b/src/lib389/cli/dsctl @@ -7,8 +7,10 @@ # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +# +# PYTHON_ARGCOMPLETE_OK -import argparse +import argparse, argcomplete import logging import sys @@ -36,8 +38,8 @@ if __name__ == '__main__': help="Return result in JSON object", default=False, action='store_true' ) - subparsers = parser.add_subparsers(help="action") + argcomplete.autocomplete(parser) # We stack our needed options in via submodules. diff --git a/src/lib389/cli/dsidm b/src/lib389/cli/dsidm index 8d1a17d..faba91b 100755 --- a/src/lib389/cli/dsidm +++ b/src/lib389/cli/dsidm @@ -7,10 +7,11 @@ # License: GPL (version 3 or any later version). # See LICENSE for details. # --- END COPYRIGHT BLOCK --- +# +# PYTHON_ARGCOMPLETE_OK import ldap -import argparse -# import argcomplete +import argparse, argcomplete import logging import sys @@ -70,8 +71,8 @@ if __name__ == '__main__': cli_ou.create_parser(subparsers) cli_posixgroup.create_parser(subparsers) cli_user.create_parser(subparsers) + argcomplete.autocomplete(parser) - # argcomplete.autocomplete(parser) args = parser.parse_args() log = reset_get_logger('dsidm', args.verbose) diff --git a/src/lib389/lib389/cli_ctl/instance.py b/src/lib389/lib389/cli_ctl/instance.py index 1f35f07..8446e0d 100644 --- a/src/lib389/lib389/cli_ctl/instance.py +++ b/src/lib389/lib389/cli_ctl/instance.py @@ -1,5 +1,5 @@ # --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2016 Red Hat, Inc. +# Copyright (C) 2018 Red Hat, Inc. # All rights reserved. # # License: GPL (version 3 or any later version). @@ -66,17 +66,15 @@ def instance_create(inst, log, args): def instance_example(inst, log, args): - print(""" + gpl_copyright = """ ; --- BEGIN COPYRIGHT BLOCK --- -; Copyright (C) 2015 Red Hat, Inc. +; Copyright (C) 2018 Red Hat, Inc. ; All rights reserved. ; ; License: GPL (version 3 or any later version). ; See LICENSE for details. ; --- END COPYRIGHT BLOCK --- -; Author: firstyear at redhat.com - ; This is a version 2 ds setup inf file. ; It is used by the python versions of setup-ds-* ; Most options map 1 to 1 to the original .inf file. @@ -87,11 +85,29 @@ def instance_example(inst, log, args): ; The special value {instance_name} is substituted at installation time. ; - """) + """ g2b = General2Base(log) s2b = Slapd2Base(log) - print(g2b.collect_help()) - print(s2b.collect_help()) + if args.template_file: + try: + # Create file and set permissions + template_file = open(args.template_file, 'w') + template_file.close() + os.chmod(args.template_file, 0o600) + + # Open file and populate it + template_file = open(args.template_file, 'w') + template_file.write(gpl_copyright) + template_file.write(g2b.collect_help()) + template_file.write(s2b.collect_help()) + template_file.close() + except OSError as e: + log.error("Failed trying to create template file ({}), error: {}".format(args.template_file, str(e))) + return False + else: + print(gpl_copyright) + print(g2b.collect_help()) + print(s2b.collect_help()) return True