diff --git a/base/lshell/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch b/base/lshell/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch deleted file mode 100644 index 39947ee08..000000000 --- a/base/lshell/centos/meta_patches/0001-Update-package-versioning-for-TIS-format.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 30a087a13a78b77537a969db2a30b531246b0bd7 Mon Sep 17 00:00:00 2001 -From: Don Penney -Date: Mon, 26 Sep 2016 17:39:58 -0400 -Subject: [PATCH] Update package versioning for TIS format - ---- - SPECS/lshell.spec | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/SPECS/lshell.spec b/SPECS/lshell.spec -index 0fd4d17..e5f1317 100644 ---- a/SPECS/lshell.spec -+++ b/SPECS/lshell.spec -@@ -2,7 +2,7 @@ - - Name: lshell - Version: 0.9.16 --Release: 6%{?dist} -+Release: 5.el7%{?_tis_dist}.%{tis_patch_ver} - Summary: A Python-based limited shell - - License: GPLv3+ --- -1.8.3.1 - diff --git a/base/lshell/centos/meta_patches/PATCH_ORDER b/base/lshell/centos/meta_patches/PATCH_ORDER deleted file mode 100644 index dece91c62..000000000 --- a/base/lshell/centos/meta_patches/PATCH_ORDER +++ /dev/null @@ -1,3 +0,0 @@ -spec-include-TiS-changes.patch -spec-update-lshell-conf-allowed-list.patch -0001-Update-package-versioning-for-TIS-format.patch diff --git a/base/lshell/centos/meta_patches/spec-include-TiS-changes.patch b/base/lshell/centos/meta_patches/spec-include-TiS-changes.patch deleted file mode 100644 index 89cf3b557..000000000 --- a/base/lshell/centos/meta_patches/spec-include-TiS-changes.patch +++ /dev/null @@ -1,87 +0,0 @@ -lshell.spec: to include Titanium Cloud changes - -To include the Titanium Cloud specific changes from: - -stx/stx-integ/base/lshell - -diff -u b/SPECS/lshell.spec b/SPECS/lshell.spec ---- b/SPECS/lshell.spec -+++ b/SPECS/lshell.spec -@@ -1,3 +1,5 @@ -+%define WRSROOT_P cBglipPpsKwBQ -+ - Name: lshell - Version: 0.9.16 - Release: 5%{?dist} -@@ -6,6 +8,15 @@ - License: GPLv3+ - URL: https://github.com/ghantoos/lshell - Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.gz -+Source1: cgcs_cli -+Source2: lshell.conf -+Source3: wrs.sudo -+Source4: lshell_env_setup -+Patch1: lshell_cgcs.patch -+Patch2: lshell-source-support.patch -+Patch3: lshell-prompt-change-support.patch -+Patch4: lshell-newline-escape-character-support.patch -+Patch5: lshell-shell-escape-check.patch - BuildArch: noarch - - BuildRequires: python2-devel -@@ -20,6 +31,11 @@ - %setup -q - #Fix permission - chmod -x CHANGES -+%patch1 -p1 -+%patch2 -p1 -+%patch3 -p1 -+%patch4 -p1 -+%patch5 -p1 - - %build - %{__python2} setup.py build -@@ -27,10 +43,25 @@ - %install - %{__python2} setup.py install -O1 --skip-build --root=%{buildroot} - # Doc files at the wrong place --rm %{buildroot}%{_defaultdocdir}/lshell/{CHANGES,COPYING,README} -+rm -f %{buildroot}%{_defaultdocdir}/lshell/{CHANGES,COPYING,README} -+mkdir -p ${RPM_BUILD_ROOT}/usr/local/bin -+install -m 755 ${RPM_SOURCE_DIR}/cgcs_cli ${RPM_BUILD_ROOT}/usr/local/bin/cgcs_cli -+install -m 755 ${RPM_SOURCE_DIR}/lshell_env_setup ${RPM_BUILD_ROOT}/usr/local/bin/lshell_env_setup -+install -d ${RPM_BUILD_ROOT}/etc -+install -m 644 ${RPM_SOURCE_DIR}/lshell.conf ${RPM_BUILD_ROOT}/etc/lshell.conf -+install -d ${RPM_BUILD_ROOT}/etc/sudoers.d -+cp ${RPM_SOURCE_DIR}/wrs.sudo wrs.sudo -+echo 'Defaults passprompt="Password: "' >> wrs.sudo -+install -m 440 wrs.sudo ${RPM_BUILD_ROOT}/etc/sudoers.d/wrs - - %pre - getent group lshell >/dev/null || groupadd -r lshell -+getent group wrs >/dev/null || groupadd -r wrs -+getent group wrs_protected >/dev/null || groupadd -f -g 345 wrs_protected -+getent passwd wrsroot > /dev/null || \ -+useradd -m -g wrs -G root,wrs_protected \ -+ -d /home/wrsroot -p %{WRSROOT_P} \ -+ -s /bin/sh wrsroot 2> /dev/null || : - - %post - grep -q '^%{_bindir}/%{name}$' %{_sysconfdir}/shells || \ -@@ -42,13 +73,13 @@ - fi - - %files --%doc CHANGES COPYING README --%{_mandir}/man*/*.* - %{_bindir}/%{name} - %config(noreplace) %{_sysconfdir}/%{name}.conf --%config(noreplace) %{_sysconfdir}/logrotate.d/%{name} -+%config(noreplace) %{_sysconfdir}/sudoers.d/wrs - %{python_sitelib}/lshell/ - %{python_sitelib}/%{name}*.egg-info -+/usr/local/bin/cgcs_cli -+/usr/local/bin/lshell_env_setup - - %changelog - * Wed Jun 17 2015 Fedora Release Engineering - 0.9.16-5 diff --git a/base/lshell/centos/meta_patches/spec-update-lshell-conf-allowed-list.patch b/base/lshell/centos/meta_patches/spec-update-lshell-conf-allowed-list.patch deleted file mode 100644 index 0e601f9dc..000000000 --- a/base/lshell/centos/meta_patches/spec-update-lshell-conf-allowed-list.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- - lshell.spec | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/SPECS/lshell.spec -+++ b/SPECS/lshell.spec -@@ -2,7 +2,7 @@ - - Name: lshell - Version: 0.9.16 --Release: 5%{?dist} -+Release: 6%{?dist} - Summary: A Python-based limited shell - - License: GPLv3+ diff --git a/base/lshell/centos/srpm_path b/base/lshell/centos/srpm_path deleted file mode 100644 index 8e04439b3..000000000 --- a/base/lshell/centos/srpm_path +++ /dev/null @@ -1 +0,0 @@ -mirror:Source/lshell-0.9.16-5.el7.src.rpm diff --git a/base/lshell/files/cgcs_cli b/base/lshell/files/cgcs_cli deleted file mode 100755 index 98f6e6631..000000000 --- a/base/lshell/files/cgcs_cli +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -/usr/bin/lshell diff --git a/base/lshell/files/lshell-newline-escape-character-support.patch b/base/lshell/files/lshell-newline-escape-character-support.patch deleted file mode 100644 index 6e1b00b3a..000000000 --- a/base/lshell/files/lshell-newline-escape-character-support.patch +++ /dev/null @@ -1,53 +0,0 @@ ---- - lshell/shellcmd.py | 26 +++++++++++++++++++++++++- - 1 file changed, 25 insertions(+), 1 deletion(-) - ---- a/lshell/shellcmd.py -+++ b/lshell/shellcmd.py -@@ -74,6 +74,7 @@ class ShellCmd(cmd.Cmd, object): - self.promptbase = getuser() - - self.prompt = '%s:~$ ' % self.promptbase -+ self.prompt2 = '> ' # PS2 prompt - - self.intro = self.conf['intro'] - -@@ -670,6 +671,12 @@ class ShellCmd(cmd.Cmd, object): - self.stdout.write("%s\n" % self.intro) - if self.conf['login_script']: - self.loginCmdParse(self.conf['login_script']) -+ -+ # for long commands, a user may escape the new line -+ # by giving a bash like '\' character at the end of -+ # the line. cmdloop() needs to recognize that and -+ # create an appended line before sending it to onecmd() -+ partial_line = "" - stop = None - while not stop: - if self.cmdqueue: -@@ -691,7 +698,24 @@ class ShellCmd(cmd.Cmd, object): - line = 'EOF' - else: - line = line[:-1] # chop \n -- line = self.precmd(line) -+ -+ if len(line) > 1 and line.startswith('\\'): -+ # implying previous partial line -+ line = line[:1].replace('\\', '', 1) -+ if partial_line: -+ line = partial_line + line -+ if line.endswith('\\'): -+ # continuation character. First partial line. -+ # We shall expect the command to continue in -+ # a new line. Change to bash like PS2 prompt to -+ # indicate this continuation to the user -+ partial_line = line.strip('\\') -+ self.prompt = self.prompt2 # switching to PS2 -+ continue -+ partial_line = "" -+ -+ self.updateprompt(os.getcwd()) -+ line = self.precmd(line) - stop = self.onecmd(line) - stop = self.postcmd(stop, line) - self.postloop() diff --git a/base/lshell/files/lshell-prompt-change-support.patch b/base/lshell/files/lshell-prompt-change-support.patch deleted file mode 100644 index 5613a0739..000000000 --- a/base/lshell/files/lshell-prompt-change-support.patch +++ /dev/null @@ -1,139 +0,0 @@ ---- - lshell/shellcmd.py | 77 ++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 71 insertions(+), 6 deletions(-) - ---- a/lshell/shellcmd.py -+++ b/lshell/shellcmd.py -@@ -28,6 +28,7 @@ import readline - import glob - import subprocess - -+from time import gmtime, strftime - from utils import get_aliases - - -@@ -50,6 +51,9 @@ class ShellCmd(cmd.Cmd, object): - else: - self.stderr = stderr - -+ # create a devnull device -+ self.devnull = open(os.devnull, 'w') -+ - self.args = args - self.conf = userconf - self.log = self.conf['logpath'] -@@ -145,13 +149,63 @@ class ShellCmd(cmd.Cmd, object): - self.g_cmd, self.g_arg, self.g_line = ['', '', ''] - return object.__getattribute__(self, attr) - -+ def check_prompt(self, var, value): -+ """ check if user is attempting to -+ modify shell prompt and if so then -+ update the prompt -+ """ -+ if 'PS' in var: -+ if 'PS1' in var: -+ # update prompt -+ self.promptbase = self.setprompt( -+ {'prompt' : value.strip('\n').strip('\r')}) -+ self.updateprompt(os.getcwd()) -+ else: -+ self.log.critical("*** forbidden %s prompt change requested. " -+ "Only PS1 changes permissible" % var) -+ -+ - def setprompt(self, conf): - """ set prompt used by the shell - """ - if conf.has_key('prompt'): - promptbase = conf['prompt'] -- promptbase = promptbase.replace('%u', getuser()) -- promptbase = promptbase.replace('%h', os.uname()[1].split('.')[0]) -+ # Recognize shell name control command -+ promptbase = re.sub(r'\\s', 'lshell', -+ promptbase) -+ # Recognize username control command -+ promptbase = re.sub(r'\\u|%u', getuser(), -+ promptbase) -+ # Recognize hostname control command -+ promptbase = re.sub(r'\\h|%h', os.uname()[1].split('.')[0], -+ promptbase) -+ # Recognize full hostname control command -+ promptbase = re.sub(r'\\H', os.uname()[1], -+ promptbase) -+ # Recognize time control commands -+ promptbase = re.sub(r'\\t', strftime("%H:%M:%S", gmtime()), -+ promptbase) -+ promptbase = re.sub(r'\\T', strftime("%I:%M:%S", gmtime()), -+ promptbase) -+ promptbase = re.sub(r'\\A', strftime("%H:%M", gmtime()), -+ promptbase) -+ promptbase = re.sub(r'\\@', strftime("%I:%M:%S%p", gmtime()), -+ promptbase) -+ promptbase = re.sub(r'\\d', strftime("%a %b %d", gmtime()), -+ promptbase) -+ ######################################################## -+ # The following control commands are not supported: # -+ # v - the shell version # -+ # V - the shell release version # -+ # w - Complete path of current working directory # -+ # W - the basename of the current working directory # -+ # ! - the history number of this command # -+ # # - the command number of this command # -+ # $? - status of the last command # -+ # $() - any command executions # -+ ######################################################## -+ promptbase = re.sub(r'\\v|\\V|\\w|\\W|\\!|\\#|\\\$\?|\\\$\(.*\)|\\\$', '', -+ promptbase) - else: - promptbase = getuser() - -@@ -199,7 +253,7 @@ class ShellCmd(cmd.Cmd, object): - def export(self): - """ export environment variables """ - # if command contains at least 1 space -- if self.g_line.count(' '): -+ if self.g_line.count(' '): - env = self.g_line.split(" ", 1)[1] - # if it conatins the equal sign, consider only the first one - if env.count('='): -@@ -216,6 +270,10 @@ class ShellCmd(cmd.Cmd, object): - cin, cout = os.popen2('`which echo` %s' % value) - value = cout.readlines()[0] - -+ # check if new exported environment -+ # is a prompt change command -+ self.check_prompt(var, value) -+ - os.environ.update({var: value.rstrip()}) - - def source(self): -@@ -485,11 +543,14 @@ class ShellCmd(cmd.Cmd, object): - p = subprocess.Popen( "`which echo` %s" % item, - shell=True, - stdin=subprocess.PIPE, -- stdout=subprocess.PIPE ) -+ stdout=subprocess.PIPE, -+ stderr = self.devnull ) - (cin, cout) = (p.stdin, p.stdout) - except ImportError: -- cin, cout = os.popen2('`which echo` %s' % item) -- item = cout.readlines()[0].split(' ')[0].strip() -+ cin, cout = os.popen2('`which echo` %s 2>/dev/null' % item) -+ shellresponse = cout.readlines() -+ if shellresponse: -+ item = shellresponse[0].split(' ')[0].strip() - item = os.path.expandvars(item) - tomatch = os.path.realpath(item) - if os.path.isdir(tomatch) and tomatch[-1] != '/': tomatch += '/' -@@ -559,6 +620,10 @@ class ShellCmd(cmd.Cmd, object): - if len(env) is not 2: - continue - newenv.update(dict([env])) -+ # check if the new environment includes -+ # any Shell prompt change commands -+ self.check_prompt(env[0], env[1]) -+ - os.environ.update(newenv) - - def loginCmdParse(self, script): diff --git a/base/lshell/files/lshell-shell-escape-check.patch b/base/lshell/files/lshell-shell-escape-check.patch deleted file mode 100644 index d1749f7db..000000000 --- a/base/lshell/files/lshell-shell-escape-check.patch +++ /dev/null @@ -1,121 +0,0 @@ ---- - lshell/shellcmd.py | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 77 insertions(+), 3 deletions(-) - ---- a/lshell/shellcmd.py -+++ b/lshell/shellcmd.py -@@ -30,7 +30,7 @@ import subprocess - - from time import gmtime, strftime - from utils import get_aliases -- -+from distutils.spawn import find_executable - - class ShellCmd(cmd.Cmd, object): - """ Main lshell CLI class -@@ -337,6 +337,44 @@ class ShellCmd(cmd.Cmd, object): - # strip all spaces/tabs - line = " ".join(line.split()) - -+ # Expand all variables -+ line = os.path.expandvars(line) -+ -+ # *** AWK HOOK *** # -+ # Before we begin, check if user is trying -+ # to pass an awk script to the awk interpreter -+ # and disallow that option. -+ # -+ # Also disallow inline vars in awk since an attacker -+ # may use that to scramble a forbidden cmd -+ # such as the following shell escape: -+ # (awk -v X=ba -v Y=ash 'BEGIN { system("/bin/"X Y) }' -+ # -+ # In an ideal world we should parse the awk script -+ # and inline vars for forbidden paths and commands -+ # but that will require some gnarly regexes (esp for -+ # the inline vars). Deferring this as TODO -+ if re.match(r'\s*awk.*-f\s*[\w/~]+', line): -+ return self.warn_count('awk script option', oline, strict, ssh) -+ if re.match(r'\s*awk.*-v\s*\w+=', line): -+ return self.warn_count('awk inline variable option', oline, strict, ssh) -+ -+ -+ # process all quoted text seperately -+ # This logic is kept crudely simple on purpose. -+ # At most we might match the same stanza twice -+ # (for e.g. "'a'", 'a') but the converse would -+ # require detecting single quotation stanzas -+ # nested within double quotes and vice versa -+ relist = re.findall(r'[^=]\"(.+)\"',line) -+ relist2 = re.findall(r'[^=]\'(.+)\'',line) -+ relist = relist + relist2 -+ for item in relist: -+ if self.check_secure(item, strict = strict): -+ return 1 -+ if self.check_path(item, strict = strict): -+ return 1 -+ - # ignore quoted text - line = re.sub(r'\"(.+?)\"', '', line) - line = re.sub(r'\'(.+?)\'', '', line) -@@ -438,7 +476,8 @@ class ShellCmd(cmd.Cmd, object): - new_cmd_line = 'export ' + oline - self.g_line = new_cmd_line - self.check_secure(new_cmd_line, strict = strict) -- else: -+ # filter out macros, text or constructs that got picked up as commands -+ elif command.islower() and find_executable(command): - return self.warn_count('command', oline, strict, ssh, command) - return 0 - -@@ -499,6 +538,7 @@ class ShellCmd(cmd.Cmd, object): - %(self.conf['warning_counter'])) - self.stderr.write('This incident has been reported.\n') - -+ - def check_path(self, line, completion=None, ssh=None, strict=None): - """ Check if a path is entered in the line. If so, it checks if user \ - are allowed to see this path. If user is not allowed, it calls \ -@@ -594,7 +634,41 @@ class ShellCmd(cmd.Cmd, object): - detect the new environment and then use that to update the \ - environ of the lshell process. - """ -- pipe = subprocess.Popen("%s; env -0" % script, -+ try: -+ script_path = os.path.expanduser(script.\ -+ strip("source").split()[0]) -+ script_path = os.path.expandvars(script_path) -+ with open (script_path) as fd: -+ content = fd.readlines() -+ content = [line.strip('\n') for line in content] -+ -+ # Although rare in a normal cases, an attacker -+ # may attempt to bypass line validation by -+ # scrambling commands via line continuations -+ partial_line = "" -+ for i,line in enumerate(content): -+ if line.startswith('#'): -+ continue -+ if len(line) > 1 and line.startswith('\\'): -+ # implying previous partial line -+ content[i] = line[:1].replace('\\', '', 1) -+ if partial_line: -+ content[i] = partial_line + line -+ if line.endswith('\\'): -+ # continuation character. First partial line. -+ # We shall expect the command to continue in -+ # a new line. -+ partial_line = content[i].strip('\\') -+ continue -+ partial_line = "" -+ if self.check_secure(content[i]): -+ return -+ if self.check_path(content[i]): -+ return -+ except: -+ pass -+ -+ pipe = subprocess.Popen("%s; env -0" % script, - bufsize=1, - stdout=subprocess.PIPE, - shell=True) diff --git a/base/lshell/files/lshell-source-support.patch b/base/lshell/files/lshell-source-support.patch deleted file mode 100644 index 050f62d4d..000000000 --- a/base/lshell/files/lshell-source-support.patch +++ /dev/null @@ -1,106 +0,0 @@ ---- - lshell/shellcmd.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 64 insertions(+), 1 deletion(-) - ---- a/lshell/shellcmd.py -+++ b/lshell/shellcmd.py -@@ -26,6 +26,7 @@ import re - import signal - import readline - import glob -+import subprocess - - from utils import get_aliases - -@@ -128,6 +129,9 @@ class ShellCmd(cmd.Cmd, object): - # builtin export function - elif self.g_cmd == 'export': - self.export() -+ # builtin source function -+ elif self.g_cmd == 'source': -+ self.source() - # case 'cd' is in an alias e.g. {'toto':'cd /var/tmp'} - elif self.g_line[0:2] == 'cd': - self.g_cmd = self.g_line.split()[0] -@@ -214,6 +218,14 @@ class ShellCmd(cmd.Cmd, object): - - os.environ.update({var: value.rstrip()}) - -+ def source(self): -+ """ implementation of the "source" command -+ """ -+ # ensure if command contains at least 1 space -+ if self.g_line.count(' '): -+ source_script = self.g_line -+ self.sourceShell(source_script) -+ - def cd(self): - """ implementation of the "cd" command - """ -@@ -515,6 +527,57 @@ class ShellCmd(cmd.Cmd, object): - else: - self.prompt = '%s:%s$ ' % (self.promptbase, path) - -+ def sourceShell(self, script): -+ """Source the shell script and call env when done in order to \ -+ detect the new environment and then use that to update the \ -+ environ of the lshell process. -+ """ -+ pipe = subprocess.Popen("%s; env -0" % script, -+ bufsize=1, -+ stdout=subprocess.PIPE, -+ shell=True) -+ -+ iterator = iter(pipe.stdout.readline, b'') -+ outputlist = list(iterator) -+ output = '' -+ for i, line in enumerate(outputlist): -+ if i == (len(outputlist) -1): -+ output = line -+ else: -+ sys.stdout.write(line) -+ -+ # output may pick up some echos at the end of script and merge -+ # with the first line in env. Test for this and echo those to stdout -+ envList = output.split('\0') -+ firstenv = re.findall('^\S+=\S+$', envList[0], re.MULTILINE) -+ if firstenv: -+ print envList[0].strip(firstenv[0]) -+ envList[0] = firstenv[0] -+ newenv = {} -+ for line in envList: -+ env = line.split("=", 1) -+ if len(env) is not 2: -+ continue -+ newenv.update(dict([env])) -+ os.environ.update(newenv) -+ -+ def loginCmdParse(self, script): -+ """Parse the login command specified in login_script. \ -+ If login_script or a sub script sources a bash config \ -+ then call shell_source() -+ """ -+ # if multiple commands are chained together, execute -+ # them individually. We will not support conditional -+ # chaining (&& or ||) since that would required the -+ # additional complexity of checking the retcode of -+ # the previous command -+ cmds = script.split(";") -+ for cmd in cmds: -+ if "source" in cmd: -+ self.sourceShell(cmd) -+ else: -+ os.system(cmd) -+ - def cmdloop(self, intro=None): - """Repeatedly issue a prompt, accept input, parse an initial prefix \ - off the received input, and dispatch to action methods, passing them \ -@@ -541,7 +604,7 @@ class ShellCmd(cmd.Cmd, object): - if self.intro and isinstance(self.intro, str): - self.stdout.write("%s\n" % self.intro) - if self.conf['login_script']: -- os.system(self.conf['login_script']) -+ self.loginCmdParse(self.conf['login_script']) - stop = None - while not stop: - if self.cmdqueue: diff --git a/base/lshell/files/lshell.conf b/base/lshell/files/lshell.conf deleted file mode 100644 index e3e1da037..000000000 --- a/base/lshell/files/lshell.conf +++ /dev/null @@ -1,94 +0,0 @@ -# lshell.py configuration file -# -# $Id: lshell.conf,v 1.27 2010-10-18 19:05:17 ghantoos Exp $ - -[global] -## log directory (default /var/log/lshell/ ) -logpath : /var/log/lshell/ -## set log level to 0, 1, 2, 3 or 4 (0: no logs, 1: least verbose, -## 4: log all commands) -loglevel : 2 -## configure log file name (default is %u i.e. username.log) -#logfilename : %y%m%d-%u -#logfilename : syslog - -## in case you are using syslog, you can choose your logname -#syslogname : myapp - -[default] -## a list of the allowed commands or 'all' to allow all commands in user's PATH -allowed : ['source','vim','awk','cut','grep','cat','env','export', 'read', 'pwd','ls','echo','cd','ll','less','cp','scp','sftp','mv','rm','nova','system','neutron','cinder','glance','ceilometer','heat','keystone','passwd','openstack'] - -## a list of forbidden character or commands -- deny vim, as it allows to escape lshell -#forbidden : [';', '&', '|','`','>','<', '$(', '${'] -forbidden : [';', '&', '>','<', '$('] - -## a list of allowed command to use with sudo(8) -#sudo_commands : ['ls', 'more'] - -## number of warnings when user enters a forbidden value before getting -## exited from lshell, set to -1 to disable. -warning_counter : 2 - -## command aliases list (similar to bash’s alias directive) -aliases : {'ll':'ls -l', 'vim':'rvim'} - -## introduction text to print (when entering lshell) -#intro : "== My personal intro ==\nWelcome to lshell\nType '?' or 'help' to get the list of allowed commands" - -## configure your promt using %u or %h (default: username) -prompt : "%u@%h" - -## set sort prompt current directory update (default: 0) -#prompt_short : 0 - -## a value in seconds for the session timer -timer : 900 - -## list of path to restrict the user "geographicaly" -#path : ['/home/bla/','/etc'] - -## set the home folder of your user. If not specified the home_path is set to -## the $HOME environment variable -#home_path : '/home/bla/' - -## update the environment variable $PATH of the user -#env_path : ':/usr/local/bin:/usr/sbin' - -## a list of path; all executable files inside these path will be allowed -#allowed_cmd_path: ['/home/bla/bin','/home/bla/stuff/libexec'] - -## add environment variables -#env_vars : {'foo':1, 'bar':'helloworld'} -env_vars : {'OPENRC_TEMPLATE':'/etc/nova/ldap_openrc_template'} -## allow or forbid the use of scp (set to 1 or 0) -#scp : 1 - -## forbid scp upload -#scp_upload : 0 - -## forbid scp download -#scp_download : 0 - -## allow of forbid the use of sftp (set to 1 or 0) -#sftp : 1 - -## list of command allowed to execute over ssh (e.g. rsync, rdiff-backup, etc.) -#overssh : ['ls', 'rsync'] - -## logging strictness. If set to 1, any unknown command is considered as -## forbidden, and user's warning counter is decreased. If set to 0, command is -## considered as unknown, and user is only warned (i.e. *** unknown synthax) -strict : 0 - -## force files sent through scp to a specific directory -#scpforce : '/home/bla/uploads/' - -## history file maximum size -history_size : 100 - -## set history file name (default is /home/%u/.lhistory) -#history_file : "/home/%u/.lshell_history" - -## define the script to run at user login -login_script : "source /usr/local/bin/lshell_env_setup --mute; install -m 0500 /usr/local/bin/lshell_env_setup ~/" diff --git a/base/lshell/files/lshell_cgcs.patch b/base/lshell/files/lshell_cgcs.patch deleted file mode 100644 index 80d35267f..000000000 --- a/base/lshell/files/lshell_cgcs.patch +++ /dev/null @@ -1,54 +0,0 @@ -Index: lshell-0.9.16/setup.py -=================================================================== ---- lshell-0.9.16.orig/setup.py -+++ lshell-0.9.16/setup.py -@@ -40,10 +40,7 @@ choose a list of allowed commands for ev - scripts = ['bin/lshell'], - package_dir = {'lshell':'lshell'}, - packages = ['lshell'], -- data_files = [('/etc', ['etc/lshell.conf']), -- ('/etc/logrotate.d', ['etc/logrotate.d/lshell']), -- ('share/doc/lshell',['README', 'COPYING', 'CHANGES']), -- ('share/man/man1/', ['man/lshell.1']) ], -+ data_files = [], - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console' -Index: lshell-0.9.16/lshell/shellcmd.py -=================================================================== ---- lshell-0.9.16.orig/lshell/shellcmd.py -+++ lshell-0.9.16/lshell/shellcmd.py -@@ -199,7 +199,7 @@ class ShellCmd(cmd.Cmd, object): - env = self.g_line.split(" ", 1)[1] - # if it conatins the equal sign, consider only the first one - if env.count('='): -- var, value = env.split(' ')[0].split('=')[0:2] -+ var, value = env.split('=', 1) - # expand values, if variable is surcharged by other variables - try: - import subprocess -@@ -212,7 +212,7 @@ class ShellCmd(cmd.Cmd, object): - cin, cout = os.popen2('`which echo` %s' % value) - value = cout.readlines()[0] - -- os.environ.update({var: value}) -+ os.environ.update({var: value.rstrip()}) - - def cd(self): - """ implementation of the "cd" command -@@ -361,7 +361,14 @@ class ShellCmd(cmd.Cmd, object): - - # for all other commands check in allowed list - if command not in self.conf['allowed'] and command: -- return self.warn_count('command', oline, strict, ssh, command) -+ export_pattern = re.compile('^[a-zA-Z0-9\-\_]*=') -+ if export_pattern.match(oline): -+ self.g_cmd = 'export' -+ new_cmd_line = 'export ' + oline -+ self.g_line = new_cmd_line -+ self.check_secure(new_cmd_line, strict = strict) -+ else: -+ return self.warn_count('command', oline, strict, ssh, command) - return 0 - - def warn_count(self, messagetype, line=None, strict=None, ssh=None, command=None): diff --git a/base/lshell/files/lshell_env_setup b/base/lshell/files/lshell_env_setup deleted file mode 100755 index ce0687db8..000000000 --- a/base/lshell/files/lshell_env_setup +++ /dev/null @@ -1,100 +0,0 @@ -#!/bin/bash -MAX_OPENRC_LEN=100 -read -p "Pre-store Keystone user credentials for this session? (y/N): " confirm -confirm=${confirm,,} - -if [ "$confirm" == "y" ] || [ "$confirm" = "yes" ]; then - if [ -z "$OPENRC_TEMPLATE" ] || [ ! -f `echo $OPENRC_TEMPLATE` ]; then - read -p "env[OPENRC_TEMPLATE] not set. -Hints will not be available for certain options. Continue anyways? (Y/n): " confirm - confirm=${confirm,,} - ([ "$confirm" == "n" ] || [ "$confirm" == "no" ]) && exit 0 - else - # Check if we are to run Muted - [ "$1" = "--mute" ] && MUTE=1 - - # Load default values for System URL, Region and Keystone URL - defEnv=( $(cat $OPENRC_TEMPLATE) ) - defEnvLen=${#defEnv[@]} - [ "$defEnvLen" -gt "$MAX_OPENRC_LEN" ] && \ - defEnvLen="$MAX_OPENRC_LEN" - for (( i=0; i<$defEnvLen; i++)); - do - if [[ ${defEnv[$i]} =~ OS_AUTH_URL=(.*)$ ]]; then - def_os_auth_url=${BASH_REMATCH[1]} - elif [[ ${defEnv[$i]} =~ OS_REGION_NAME=(.*)$ ]]; then - def_os_region_name=${BASH_REMATCH[1]} - elif [[ ${defEnv[$i]} =~ OS_PROJECT_NAME=(.*)$ ]]; then - def_os_project_name=${BASH_REMATCH[1]} - elif [[ ${defEnv[$i]} =~ OS_USER_DOMAIN_NAME=(.*)$ ]]; then - def_os_user_domain_name=${BASH_REMATCH[1]} - elif [[ ${defEnv[$i]} =~ OS_PROJECT_DOMAIN_NAME=(.*)$ ]]; then - def_os_project_domain_name=${BASH_REMATCH[1]} - fi - done - fi - - read -p "Enter Keystone username [$USER]: " os_user - [ -z "$os_user" ] && os_user="$USER" - - read -p "Enter Keystone user domain name: " os_user_domain_name - [ -z "$os_user_domain_name" ] && os_user_domain_name="$def_os_user_domain_name" - - read -p "Enter Project name: " os_project_name - [ -z "$os_project_name" ] && os_project_name="$def_os_project_name" - - read -p "Enter Project domain name: " os_project_domain_name - [ -z "$os_project_domain_name" ] && os_project_domain_name="$def_os_project_domain_name" - - read -s -p "Enter Keystone password: " os_pass - [ -z "$os_pass" ] && \ - echo -n "Invalid password entry. Aborting!" && exit 1 - - # if we are not in mute mode then ask for these - # from user as input - if [ -z "$MUTE" ]; then - if [ -z "$def_os_region_name" ]; then - read -p "\n\nEnter Keystone Region Name: " os_region - else - read -p "Enter Keystone Region Name [$def_os_region_name]: " os_region - [ -z "$os_region" ] && os_region="$def_os_region_name" - fi - - if [ -z "$def_os_auth_url" ]; then - read -p "Enter Keystone Authentication URL: " os_auth_url - else - read -p "Enter Keystone Authentication URL [$def_os_auth_url]: " os_auth_url - [ -z "$os_auth_url" ] && os_auth_url="$def_os_auth_url" - fi - else - # In MUTE mode - os_region="$def_os_region_name" - echo ""; echo "" - echo "Using default Openstack Region Name: $os_region" - os_auth_url="$def_os_auth_url" - echo "Using default Openstack Authentication URL: $os_auth_url" - echo "To set these to non-default, run \"source ~/$(basename $BASH_SOURCE)\" in your shell" - fi - - - # set user environment which will be valid for - # the duration of this session - # Since lshell is running for internal clients - # move OS ENDPOINT TYPE to internalURL - export OS_ENDPOINT_TYPE="internalURL" - export CINDER_ENDPOINT_TYPE="internalURL" - export OS_INTERFACE="internal" - export OS_USERNAME="$os_user" - export OS_PASSWORD="$os_pass" - export OS_PROJECT_NAME="$os_project_name" - export OS_USER_DOMAIN_NAME="$os_user_domain_name" - export OS_PROJECT_DOMAIN_NAME="$os_project_domain_name" - export OS_AUTH_URL="$os_auth_url" - export OS_IDENTITY_API_VERSION=3 - export OS_REGION_NAME="$os_region" - # modify PS1 prompt - newprompt="[\u@\h \W($os_user)]\$ " - export PS1="$newprompt" - echo "" - echo "Keystone credentials preloaded!" -fi diff --git a/centos_iso_image.inc b/centos_iso_image.inc index 1f77defa3..3bc9a0ca5 100644 --- a/centos_iso_image.inc +++ b/centos_iso_image.inc @@ -169,9 +169,6 @@ initscripts # setup setup -# lshell -lshell - # nss-pam-ldapd nss-pam-ldapd @@ -232,6 +229,9 @@ novnc # sudo sudo +# config files +sudo-config + # net-snmp net-snmp-utils net-snmp-libs diff --git a/centos_pkg_dirs b/centos_pkg_dirs index ac553c576..105282e19 100644 --- a/centos_pkg_dirs +++ b/centos_pkg_dirs @@ -2,7 +2,6 @@ tools/vm-topology base/initscripts base/util-linux base/setup -base/lshell utilities/namespace-utils ldap/nss-pam-ldapd base/centos-release @@ -103,6 +102,7 @@ logging/logmgmt filesystem/filesystem-scripts utilities/branding config-files/io-scheduler +config-files/sudo-config tools/collector grub/grubby utilities/platform-util diff --git a/base/lshell/centos/build_srpm.data b/config-files/sudo-config/centos/build_srpm.data similarity index 55% rename from base/lshell/centos/build_srpm.data rename to config-files/sudo-config/centos/build_srpm.data index d6df555cd..7e7b60ef4 100644 --- a/base/lshell/centos/build_srpm.data +++ b/config-files/sudo-config/centos/build_srpm.data @@ -1,2 +1,2 @@ COPY_LIST="files/*" -TIS_PATCH_VER=4 +TIS_PATCH_VER=0 diff --git a/config-files/sudo-config/centos/sudo-config.spec b/config-files/sudo-config/centos/sudo-config.spec new file mode 100644 index 000000000..e1c2f8e1c --- /dev/null +++ b/config-files/sudo-config/centos/sudo-config.spec @@ -0,0 +1,32 @@ +Summary: StarlingX Sudo Configuration File +Name: sudo-config +Version: 1.0 +Release: %{tis_patch_ver}%{?_tis_dist} +License: Apache-2.0 +Group: base +Packager: StarlingX +URL: unknown + +Source0: wrs.sudo +Source1: LICENSE + +%define WRSROOT_P cBglipPpsKwBQ + +%description +StarlingX sudo configuration file + +%install +install -d %{buildroot}/%{_sysconfdir}/sudoers.d +install -m 440 %{SOURCE0} %{buildroot}/%{_sysconfdir}/sudoers.d/wrs + +%pre +getent group wrs >/dev/null || groupadd -r wrs +getent group wrs_protected >/dev/null || groupadd -f -g 345 wrs_protected +getent passwd wrsroot > /dev/null || \ +useradd -m -g wrs -G root,wrs_protected \ + -d /home/wrsroot -p %{WRSROOT_P} \ + -s /bin/sh wrsroot 2> /dev/null || : + +%files +%license ../SOURCES/LICENSE +%config(noreplace) %{_sysconfdir}/sudoers.d/wrs diff --git a/config-files/sudo-config/files/LICENSE b/config-files/sudo-config/files/LICENSE new file mode 100644 index 000000000..d64569567 --- /dev/null +++ b/config-files/sudo-config/files/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/base/lshell/files/wrs.sudo b/config-files/sudo-config/files/wrs.sudo similarity index 92% rename from base/lshell/files/wrs.sudo rename to config-files/sudo-config/files/wrs.sudo index 2924050ef..bf51703a8 100644 --- a/base/lshell/files/wrs.sudo +++ b/config-files/sudo-config/files/wrs.sudo @@ -9,3 +9,4 @@ wrsroot ALL=(root) NOPASSWD: /usr/bin/config_management wrsroot ALL=(root) NOPASSWD: /usr/local/sbin/collect Defaults lecture=never, secure_path=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin +Defaults passprompt="Password: " diff --git a/ldap/ldapscripts/centos/ldapscripts.spec b/ldap/ldapscripts/centos/ldapscripts.spec index 263e38d3c..480c7867c 100644 --- a/ldap/ldapscripts/centos/ldapscripts.spec +++ b/ldap/ldapscripts/centos/ldapscripts.spec @@ -19,9 +19,7 @@ Patch0: sudo-support.patch Patch1: sudo-delete-support.patch Patch2: log_timestamp.patch Patch3: ldap-user-setup-support.patch -Patch4: ldap-user-setup-support-input-validation.patch -Patch5: ldap-user-setup-noninteractive-mode-fix.patch -Patch6: allow-anonymous-bind-for-ldap-search.patch +Patch4: allow-anonymous-bind-for-ldap-search.patch %define debug_package %{nil} @@ -31,7 +29,6 @@ Patch6: allow-anonymous-bind-for-ldap-search.patch %description Shell scripts that allow to manage POSIX accounts (users, groups, machines) in an LDAP directory. - %prep %setup -q %patch0 -p1 @@ -39,20 +36,16 @@ Shell scripts that allow to manage POSIX accounts (users, groups, machines) in a %patch2 -p1 %patch3 -p1 %patch4 -p1 -%patch5 -p1 -%patch6 -p1 - %build - %install make install DESTDIR=%{buildroot} rm -Rf %{buildroot}/usr/local/man rm -f %{buildroot}/usr/local/sbin/*machine* rm -f %{buildroot}/usr/local/etc/ldapscripts/ldapaddmachine.template.sample -install -d ldroot}}/usr/local/etc/ +install -d %{buildroot}/usr/local/etc/ install -m 644 %{SOURCE1} %{buildroot}/usr/local/etc/ldapscripts/ldapscripts.conf install -m 644 %{SOURCE2} %{buildroot}/usr/local/etc/ldapscripts/ldapadduser.template.cgcs install -m 644 %{SOURCE3} %{buildroot}/usr/local/etc/ldapscripts/ldapaddgroup.template.cgcs diff --git a/ldap/ldapscripts/files/ldap-user-setup-noninteractive-mode-fix.patch b/ldap/ldapscripts/files/ldap-user-setup-noninteractive-mode-fix.patch deleted file mode 100644 index da3b20f4a..000000000 --- a/ldap/ldapscripts/files/ldap-user-setup-noninteractive-mode-fix.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- - sbin/ldapusersetup | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/sbin/ldapusersetup -+++ b/sbin/ldapusersetup -@@ -105,7 +105,7 @@ LdapAddLoginShell () { - ;; - esac - else -- shellopn=${$2,,} -+ shellopn=${2,,} - case $shellopn in - "bash") _SHELL="/bin/sh";; - "lshell") _SHELL="$_DEFAULTLSHELL";; diff --git a/ldap/ldapscripts/files/ldap-user-setup-support-input-validation.patch b/ldap/ldapscripts/files/ldap-user-setup-support-input-validation.patch deleted file mode 100644 index 91caf1a65..000000000 --- a/ldap/ldapscripts/files/ldap-user-setup-support-input-validation.patch +++ /dev/null @@ -1,87 +0,0 @@ ---- - sbin/ldapusersetup | 45 ++++++++++++++++++++++++++++++++++----------- - 1 file changed, 34 insertions(+), 11 deletions(-) - ---- a/sbin/ldapusersetup -+++ b/sbin/ldapusersetup -@@ -44,6 +44,29 @@ _SHELL="" - - ### Helper functions ### - -+# Gets input from user and validates it. -+# Will only return if input meets validation -+# criteria otherwise will just sit there. -+# -+# Input : input string ($1), valid output options ($2) -+# Output: the validated input -+# Note : the validation list must be an array -+LdapUserInput () { -+declare -a optionAry=("${!2}") -+while true; do -+ read -p "$1" _output -+ # convert to lower case -+ _output2=${_output,,} -+ # check if output is a valid option -+ if [[ "${optionAry[@]}" =~ "$_output2" ]]; then -+ break -+ else -+ echo "Invalid input \"$_output\". Allowed options: ${optionAry[@]}" >&2 -+ fi -+done -+ echo "$_output2" -+} -+ - # Delete an ldap user if it exists - # and exit with error - # Input : username ($1), exit msg ($2) -@@ -67,10 +90,12 @@ LdapAddUser() { - LdapAddLoginShell () { - if [ -z "$2" ]; then - # Ask the user for the login shell -- echo "Select Login Shell option # [2]: -+ shellInput="Select Login Shell option # [2]: - 1) Bash --2) Lshell" -- read opn -+2) Lshell -+" -+ options=( 1, 2 ) -+ opn=`LdapUserInput "$shellInput" options[@]` - case $opn in - 1) _SHELL="/bin/sh";; - 2) _SHELL="$_DEFAULTLSHELL";; -@@ -139,7 +164,6 @@ LdapUpdateShadowWarning () { - echo "Updating password expiry to $_newWarning days" - } - -- - # Since this setup script is meant to be a - # wrapper on top of existing ldap scripts, - # it share invoke those... we could have achieved -@@ -170,10 +194,9 @@ if [ "$#" -eq 0 ]; then - # prompt for sudo permissions - if [ "$_SHELL" != "$_DEFAULTLSHELL" ]; then - # Should sudo be activated for this user -- echo -n "Add $_username to sudoer list? (yes/NO): " -- read CONFIRM -- CONFIRM=${CONFIRM,,} -- -+ shellInput="Add $_username to sudoer list? (yes/NO): " -+ options=( "yes", "no" ) -+ CONFIRM=`LdapUserInput "$shellInput" options[@]` - if is_yes $CONFIRM - then - LdapAddSudo "$_username" -@@ -181,9 +204,9 @@ if [ "$#" -eq 0 ]; then - fi - - # Add to secondary user group -- echo -n "Add $_username to secondary user group? (yes/NO): " -- read CONFIRM -- CONFIRM=${CONFIRM,,} -+ shellInput="Add $_username to secondary user group? (yes/NO): " -+ options=( "yes", "no" ) -+ CONFIRM=`LdapUserInput "$shellInput" options[@]` - if is_yes $CONFIRM - then - echo -n "Secondary group to add user to? [$_DEFAULTGRP2]: " diff --git a/ldap/ldapscripts/files/ldap-user-setup-support.patch b/ldap/ldapscripts/files/ldap-user-setup-support.patch index c24576fe5..11102226b 100644 --- a/ldap/ldapscripts/files/ldap-user-setup-support.patch +++ b/ldap/ldapscripts/files/ldap-user-setup-support.patch @@ -1,12 +1,17 @@ --- - Makefile | 5 - man/man1/ldapusersetup.1 | 61 ++++++++++ - sbin/ldapusersetup | 263 +++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 327 insertions(+), 2 deletions(-) + Makefile | 5 +- + man/man1/ldapusersetup.1 | 60 +++++++++++ + sbin/ldapusersetup | 254 +++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 317 insertions(+), 2 deletions(-) + create mode 100644 man/man1/ldapusersetup.1 + create mode 100644 sbin/ldapusersetup +diff --git a/sbin/ldapusersetup b/sbin/ldapusersetup +new file mode 100644 +index 0000000..27d12dc --- /dev/null +++ b/sbin/ldapusersetup -@@ -0,0 +1,263 @@ +@@ -0,0 +1,254 @@ +#!/bin/sh + +# ldapusersetup : interactive setup for adding users to LDAP @@ -33,7 +38,6 @@ + echo "Usage : $0 [-u ] +where accepted field(s) are as follows: +--sudo : whether to add this user to sudoer list -+--shell <\"bash\"|\"lshell\"> : choose the shell for this user (default is lshell) +--secondgroup : the secondary group to add this user to +--passmax : the shadowMax value for this user +--passwarning : the shadowWarning value for this user" @@ -46,13 +50,36 @@ + +# runtime defaults +_DEFAULTGRP2="wrs_protected" -+_DEFAULTLSHELL="/usr/local/bin/cgcs_cli" ++_BASHSHELL="/bin/bash" +_DEFAULTSHADOWMAX="90" +_DEFAULTSHADOWWARNING="2" +_SHELL="" + +### Helper functions ### + ++# Gets input from user and validates it. ++# Will only return if input meets validation ++# criteria otherwise will just sit there. ++# ++# Input : input string ($1), valid output options ($2) ++# Output: the validated input ++# Note : the validation list must be an array ++LdapUserInput () { ++declare -a optionAry=("${!2}") ++while true; do ++ read -p "$1" _output ++ # convert to lower case ++ _output2=${_output,,} ++ # check if output is a valid option ++ if [[ "${optionAry[@]}" =~ "$_output2" ]]; then ++ break ++ else ++ echo "Invalid input \"$_output\". Allowed options: ${optionAry[@]}" >&2 ++ fi ++done ++ echo "$_output2" ++} ++ +# Delete an ldap user if it exists +# and exit with error +# Input : username ($1), exit msg ($2) @@ -74,30 +101,8 @@ +# Input : username ($1), shell to set ($2) +# Output : none +LdapAddLoginShell () { -+ if [ -z "$2" ]; then -+ # Ask the user for the login shell -+ echo "Select Login Shell option # [2]: -+1) Bash -+2) Lshell" -+ read opn -+ case $opn in -+ 1) _SHELL="/bin/sh";; -+ 2) _SHELL="$_DEFAULTLSHELL";; -+ *) -+ [ ! -z "$opn" ] && echo "Invalid option. Selecting Lshell" -+ _SHELL="$_DEFAULTLSHELL" -+ ;; -+ esac -+ else -+ shellopn=${$2,,} -+ case $shellopn in -+ "bash") _SHELL="/bin/sh";; -+ "lshell") _SHELL="$_DEFAULTLSHELL";; -+ *) -+ echo "Invalid option($2). Selecting Lshell"; _SHELL="$_DEFAULTLSHELL" -+ ;; -+ esac -+ fi ++ # Support bash only now. ++ _SHELL="$_BASHSHELL" + # Replace the login shell + ldapmodifyuser $1 replace loginShell $_SHELL &> /dev/null + [ $? -eq 0 ] || LdapRollback $1 "Critical setup error: cannot set login shell" @@ -148,14 +153,13 @@ + echo "Updating password expiry to $_newWarning days" +} + -+ +# Since this setup script is meant to be a +# wrapper on top of existing ldap scripts, +# it share invoke those... we could have achieved +# loose coupling by not relying on helpers but +# at the expense of massively redundant code +# duplication. -+declare -a helper_scripts=("ldapadduser" "ldapaddsudo" "ldapmodifyuser" "ldapaddusertogroup" "$_DEFAULTLSHELL") ++declare -a helper_scripts=("ldapadduser" "ldapaddsudo" "ldapmodifyuser" "ldapaddusertogroup" "$_BASHSHELL") + +# Do some quick sanity tests to make sure +# helper scripts are present @@ -172,27 +176,23 @@ + read _username + LdapAddUser "$_username" + -+ # Replace the login shell. We will prompt the user for this ++ # Replace the login shell. Only bash is supported now. + LdapAddLoginShell "$_username" + -+ # If login shell is NOT the default limited shell then -+ # prompt for sudo permissions -+ if [ "$_SHELL" != "$_DEFAULTLSHELL" ]; then -+ # Should sudo be activated for this user -+ echo -n "Add $_username to sudoer list? (yes/NO): " -+ read CONFIRM -+ CONFIRM=${CONFIRM,,} ++ # Should sudo be activated for this user ++ echo -n "Add $_username to sudoer list? (yes/NO): " ++ read CONFIRM ++ CONFIRM=${CONFIRM,,} + -+ if is_yes $CONFIRM -+ then -+ LdapAddSudo "$_username" -+ fi ++ if is_yes $CONFIRM ++ then ++ LdapAddSudo "$_username" + fi + + # Add to secondary user group -+ echo -n "Add $_username to secondary user group? (yes/NO): " -+ read CONFIRM -+ CONFIRM=${CONFIRM,,} ++ shellInput="Add $_username to secondary user group? (yes/NO): " ++ options=( "yes", "no" ) ++ CONFIRM=`LdapUserInput "$shellInput" options[@]` + if is_yes $CONFIRM + then + echo -n "Secondary group to add user to? [$_DEFAULTGRP2]: " @@ -226,10 +226,6 @@ + --sudo) # optional + _sudo="yes" + ;; -+ --shell) # optional -+ _loginshell="$2" -+ shift -+ ;; + --passmax) # optional + _shadowMax="$2" + shift @@ -270,9 +266,11 @@ + LdapUpdateShadowMax $_username $_shadowMax + LdapUpdateShadowWarning $_username $_shadowWarning +fi +diff --git a/Makefile b/Makefile +index f81c272..6e5b193 100644 --- a/Makefile +++ b/Makefile -@@ -41,12 +41,13 @@ SBINFILES = ldapdeletemachine ldapmodify +@@ -41,12 +41,13 @@ SBINFILES = ldapdeletemachine ldapmodifygroup ldapsetpasswd lsldap ldapadduser l ldapdeleteuser ldapsetprimarygroup ldapfinger ldapid ldapgid ldapmodifymachine \ ldaprenamegroup ldapaddgroup ldapaddusertogroup ldapdeleteuserfromgroup \ ldapinit ldapmodifyuser ldaprenamemachine ldapaddmachine ldapdeletegroup \ @@ -288,9 +286,12 @@ MAN5FILES = ldapscripts.5 TMPLFILES = ldapaddgroup.template.sample ldapaddmachine.template.sample \ ldapadduser.template.sample +diff --git a/man/man1/ldapusersetup.1 b/man/man1/ldapusersetup.1 +new file mode 100644 +index 0000000..9b3129b --- /dev/null +++ b/man/man1/ldapusersetup.1 -@@ -0,0 +1,61 @@ +@@ -0,0 +1,60 @@ +.\" Copyright (c) 2015 Wind River Systems, Inc. +.\" +.\" This program is free software; you can redistribute it and/or @@ -337,7 +338,6 @@ +The name or uid of the user to modify. +The following fields are available as long format options: +--sudo : whether to add this user to sudoer list -+--shell : which login shell to use (default is lshell) +--secondgroup : the secondary group to add this user to +--passmax : the shadowMax value for this user +--passwarning : the shadowWarning value for this user"