diff --git a/CHANGELOG.md b/CHANGELOG.md index dbcfbc7..43f6e01 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # NetSUS Changelog +## 5.0.1 +* Fixed a bug with SUS URL validation, when using SSL +* Fixed an issue with LDAP proxy install in some RHEL-based installations +* Fixed a bug with NetBoot shares not being browsable on macOS 10.14 +* Updated to the latest version of Reposado +* Updated appliance build scripts for latest Operating Systems +* Fixed a security issue, relating to a LFI vulnerability from the Logs page +* Added macOS 10.15 SUS catalog options +* Added the ability to select the NetBoot engine (pybsdp/DHCP) +* Added (experimental) support for RHEL 8 +* Defaults to Active Directory login, if it is configured +* Appliance Operating System is now Ubuntu 16.04.6 +* Will preserve a Kinobi installation if detected during the Installation + ## 5.0 * Updated user interface to align with Jamf Pro UI diff --git a/CreateNetSUSInstaller.sh b/CreateNetSUSInstaller.sh index 20ccaa5..9a5d4e0 100755 --- a/CreateNetSUSInstaller.sh +++ b/CreateNetSUSInstaller.sh @@ -29,11 +29,11 @@ cp -R NetBoot/netbootInstall.sh temp/installer/install-netboot.sh cp -R NetBoot/etc/init.d/pybsdp temp/installer/resources/pybsdp.ubuntu cp -R NetBoot/etc/rc.d/init.d/pybsdp temp/installer/resources/pybsdp.rhel cp -R NetBoot/usr/local/lib temp/installer/resources/lib -# cp -R NetBoot/usr/local/sbin temp/installer/resources/dhcp -# rm -f NetBoot/usr/local/sbin temp/installer/resources/dhcp/pybsdp +cp -R NetBoot/usr/local/sbin temp/installer/resources/dhcp +rm -f temp/installer/resources/dhcp/pybsdp cp -R NetBoot/usr/local/sbin/pybsdp temp/installer/resources/pybsdp -# cp -R NetBoot/var/appliance/conf/dhcpd.conf temp/installer/resources/dhcpd.conf -# cp -R NetBoot/var/appliance/configurefornetboot temp/installer/resources/configurefornetboot +cp -R NetBoot/var/appliance/conf/dhcpd.conf temp/installer/resources/dhcpd.conf +cp -R NetBoot/var/appliance/configurefornetboot temp/installer/resources/configurefornetboot cp -R NetBoot/var/appliance/libdb4-4.8.30-21.fc26.x86_64.rpm temp/installer/resources/libdb4-4.8.30-21.fc26.x86_64.rpm cp -R NetBoot/var/appliance/nbi_settings.py temp/installer/resources/nbi_settings.py cp -R NetBoot/var/appliance/netatalk-2.2.0-2.el6.x86_64.rpm temp/installer/resources/netatalk-2.2.0-2.el6.x86_64.rpm diff --git a/NetBoot/netbootInstall.sh b/NetBoot/netbootInstall.sh index 54a3cb0..01e414a 100644 --- a/NetBoot/netbootInstall.sh +++ b/NetBoot/netbootInstall.sh @@ -33,6 +33,7 @@ if [[ $(which apt-get 2>&-) != "" ]]; then apt_install netatalk apt_install nfs-kernel-server apt_install python-configparser + apt_install libxml-xpath-perl elif [[ $(which yum 2>&-) != "" ]]; then yum_install avahi yum_install samba @@ -58,6 +59,7 @@ elif [[ $(which yum 2>&-) != "" ]]; then fi yum_install nfs-utils yum_install vim-common + yum_install perl-XML-XPath chkconfig messagebus on >> $logFile 2>&1 chkconfig avahi-daemon on >> $logFile 2>&1 chkconfig rpcbind on >> $logFile 2>&1 @@ -252,18 +254,18 @@ fi cp ./resources/nbi_settings.py /var/appliance/ >> $logFile # Install and configure dhcp -# killall dhcpd >> $logFile 2>&1 -# if [ ! -d "/var/appliance/conf" ]; then -# mkdir -p /var/appliance/conf -# fi -# cp ./resources/dhcpd.conf /var/appliance/conf/ >> $logFile -# cp ./resources/configurefornetboot /var/appliance/ >> $logFile +killall dhcpd >> $logFile 2>&1 +if [ ! -d "/var/appliance/conf" ]; then +mkdir -p /var/appliance/conf +fi +cp ./resources/dhcpd.conf /var/appliance/conf/ >> $logFile +cp ./resources/configurefornetboot /var/appliance/ >> $logFile -# if [ ! -d "/var/db" ]; then -# mkdir /var/db -# fi -# touch /var/db/dhcpd.leases -# cp ./resources/dhcp/* /usr/local/sbin/ >> $logFile +if [ ! -d "/var/db" ]; then + mkdir /var/db +fi +touch /var/db/dhcpd.leases +cp ./resources/dhcp/* /usr/local/sbin/ >> $logFile # Update netatalk configuration if [ -f "/etc/default/netatalk" ]; then diff --git a/NetBoot/usr/local/sbin/DHCP_LICENSE b/NetBoot/usr/local/sbin/DHCP_LICENSE new file mode 100644 index 0000000..242473e --- /dev/null +++ b/NetBoot/usr/local/sbin/DHCP_LICENSE @@ -0,0 +1,20 @@ +# Copyright (c) 2004-2012 by Internet Systems Consortium, Inc. ("ISC") +# Copyright (c) 1995-2003 by Internet Software Consortium +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT +# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +# Internet Systems Consortium, Inc. +# 950 Charter Street +# Redwood City, CA 94063 +# +# https://www.isc.org/ diff --git a/NetBoot/usr/local/sbin/dhcp-4.2.4-P1_dhcp.c.patch b/NetBoot/usr/local/sbin/dhcp-4.2.4-P1_dhcp.c.patch new file mode 100644 index 0000000..7422aba --- /dev/null +++ b/NetBoot/usr/local/sbin/dhcp-4.2.4-P1_dhcp.c.patch @@ -0,0 +1,72 @@ +--- /Users/eric.krause/Desktop/dhcp/dhcp-4.2.4-P1/server/dhcp.c 2012-07-13 01:18:05.000000000 -0500 ++++ /Users/eric.krause/Desktop/dhcp/dhcp-4.2.4-P1 patched/server/dhcp.c 2012-08-01 13:41:56.000000000 -0500 +@@ -624,10 +624,9 @@ + RENEWING client, so we can punt on this issue. */ + + if (!packet -> shared_network || +- (packet -> raw -> ciaddr.s_addr && ++ (packet -> raw -> ciaddr.s_addr && + packet -> raw -> giaddr.s_addr) || + (have_requested_addr && !packet -> raw -> ciaddr.s_addr)) { +- + /* If we don't know where it came from but we do know + where it claims to have come from, it didn't come + from there. */ +@@ -1024,7 +1023,7 @@ + return; + } + } +- ++#if 0 + /* We don't respond to DHCPINFORM packets if we're not authoritative. + It would be nice if a per-host value could override this, but + there's overhead involved in checking this, so let's see how people +@@ -1049,7 +1048,7 @@ + subnet_dereference (&subnet, MDL); + return; + } +- ++#endif + option_state_allocate (&options, MDL); + memset (&outgoing, 0, sizeof outgoing); + memset (&raw, 0, sizeof raw); +@@ -1301,7 +1300,16 @@ + } else { + gip.len = 0; + memcpy(&to.sin_addr, cip.iabuf, 4); +- to.sin_port = remote_port; ++ log_info ("JAMF-DHCP change"); ++ if (ntohs(packet->client_port) != 68 && ntohs(packet->client_port) != 67) { ++ log_info ("System Prefs Port"); ++ log_info ("%d", ntohs(packet->client_port)); ++ to.sin_port = packet->client_port; ++ } else { ++ log_info ("N Key or encapsulated"); ++ log_info ("%d", ntohs(remote_port)); ++ to.sin_port = remote_port; ++ } + } + + /* Report what we're sending. */ +@@ -1466,7 +1474,6 @@ + to.sin_port = local_port; + else + to.sin_port = remote_port; /* for testing. */ +- + if (fallback_interface) { + result = send_packet(fallback_interface, packet, &raw, + outgoing.packet_length, from, &to, +@@ -1482,7 +1489,7 @@ + } + } else { + to.sin_addr = limited_broadcast; +- to.sin_port = remote_port; ++ to.sin_port = remote_port; + } + + errno = 0; +@@ -4506,3 +4513,4 @@ + options->universe_count = agent_universe.index + 1; + } + } ++ diff --git a/NetBoot/usr/local/sbin/dhcpd b/NetBoot/usr/local/sbin/dhcpd new file mode 100755 index 0000000..f92033e Binary files /dev/null and b/NetBoot/usr/local/sbin/dhcpd differ diff --git a/NetBoot/var/appliance/configurefornetboot b/NetBoot/var/appliance/configurefornetboot index 49cbf68..731475b 100755 --- a/NetBoot/var/appliance/configurefornetboot +++ b/NetBoot/var/appliance/configurefornetboot @@ -7,7 +7,7 @@ # # This program is distributed "as is" by JAMF Software, LLC. For more information or support for the appliance, please utilize the following resources: # -# https://jamfnation.jamfsoftware.com/ +# https://jamfnation.jamfsoftware.com/ # # Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: # @@ -20,7 +20,16 @@ # THIS SOFTWARE IS PROVIDED BY JAMF SOFTWARE, LLC "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JAMF SOFTWARE, LLC BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -ip=`ip addr show to 0.0.0.0/0 scope global | awk '/[[:space:]]inet / { print gensub("/.*","","g",$2) }'` +if [ "$(xpath 2>&1 | grep options)" != '' ]; then + iface=`xpath -e "//netbootiface/text()" /var/appliance/conf/appliance.conf.xml 2>/dev/null` +else + iface=`xpath /var/appliance/conf/appliance.conf.xml "//netbootiface/text()" 2>/dev/null` +fi +if [ "${iface}" != '' ]; then + ip=`ip addr show ${iface} | grep -w inet | awk '{print $2}' | cut -d / -f 1` +else + ip=`ip addr show to 0.0.0.0/0 scope global | awk '/[[:space:]]inet / { print gensub("/.*","","g",$2) }'` +fi ipdec=`awk -v dec=${ip} 'BEGIN{n=split(dec,d,".");for(i=1;i<=n;i++) printf ":%02X",d[i];print ""}'` imageid=`grep 'FF:FF:07:04' /etc/dhcpd.conf | sed 's/.*FF:FF:07:04://g' | cut -c1-11` curafp=`grep "01:01:02:08:04:.*.:80" /etc/dhcpd.conf | sed 's/option vendor-encapsulated-options 01:01:02:08:04:.*.:80:.*:61:66:70:75:73:65:72:3A://g' | awk -F40 '{print $1}' | tr -d ' ' | sed 's/\(.*\)./\1/'` diff --git a/README.md b/README.md index 2663ff4..c93b39b 100755 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ # NetSUS Downloads Installer: -[https://github.com/jamf/NetSUS/releases/download/5.0/NetSUSLPInstaller_5.0.run](https://github.com/jamf/NetSUS/releases/download/5.0/NetSUSLPInstaller_5.0.run) +[https://github.com/jamf/NetSUS/releases/download/5.0.1/NetSUSLPInstaller_5.0.1.run](https://github.com/jamf/NetSUS/releases/download/5.0.1/NetSUSLPInstaller_5.0.1.run) OVA: -[https://github.com/jamf/NetSUS/releases/download/5.0/NetSUSLP_5.0.ova](https://github.com/jamf/NetSUS/releases/download/5.0/NetSUSLP_5.0.ova) +[https://github.com/jamf/NetSUS/releases/download/5.0.1/NetSUSLP_5.0.1.ova](https://github.com/jamf/NetSUS/releases/download/5.0.1/NetSUSLP_5.0.1.ova) # What is NetSUS? @@ -53,7 +53,7 @@ For a getting started guide and step-by-step walkthroughs check out the **[docum #### If you are running a Kinobi Patch Server: -* Kinobi 1.0 is incompatible with NetSUS 5.0. You will need to install Kinobi 1.1 after upgrading to NetSUS 5.0, available from: - +* Kinobi 1.0 is incompatible with NetSUS 5.0.1. You will need to install Kinobi 1.1 or later (1.2 is recommended) after upgrading to NetSUS 5.0.1, available from: + **Only Intel-based Macs can use a NetBoot server hosted by the NetSUSLP.** diff --git a/SUS/var/lib/reposado/repo_sync b/SUS/var/lib/reposado/repo_sync index 3a5226c..3d995ea 100755 --- a/SUS/var/lib/reposado/repo_sync +++ b/SUS/var/lib/reposado/repo_sync @@ -296,6 +296,7 @@ def curl(url, destinationpath, onlyifnewer=False, etag=None, resume=False): print >> fileobj, 'dump-header -' # dump headers to stdout print >> fileobj, 'speed-time = 30' # give up if too slow d/l print >> fileobj, 'tlsv1' # use only TLS 1.x + print >> fileobj, 'http1.1' # disable http2 print >> fileobj, 'url = "%s"' % url # add additional options from our prefs @@ -345,11 +346,17 @@ def curl(url, destinationpath, onlyifnewer=False, etag=None, resume=False): line = line_stripped if line.startswith('HTTP/'): - header['http_result_code'] = line.split(None, 2)[1] - header['http_result_description'] = line.split(None, 2)[2] + header['http_result_code'] = '' + header['http_result_description'] = '' + try: + part = line.split(None, 2) + header['http_result_code'] = part[1] + header['http_result_description'] = part[2] + except IndexError: + pass elif ': ' in line: - part = line.split(None, 1) - fieldname = part[0].rstrip(':').lower() + part = line.split(': ', 1) + fieldname = part[0].lower() header[fieldname] = part[1] else: # "empty" line, but not end of output. likely end of headers @@ -712,6 +719,16 @@ def sync(fast_scan=False, download_packages=True): 'Could not replicate %s: %s', package['MetadataURL'], err) continue + if 'IntegrityDataURL' in package: + try: + unused_path = replicateURLtoFilesystem( + package['IntegrityDataURL'], + copy_only_if_missing=fast_scan) + except ReplicationError, err: + reposadocommon.print_stderr( + 'Could not replicate %s: %s', + package['IntegrityDataURL'], err) + continue # calculate total size size = 0 diff --git a/SUS/var/lib/reposado/reposadolib/reposadocommon.py b/SUS/var/lib/reposado/reposadolib/reposadocommon.py index 3d24f3a..099f3c8 100755 --- a/SUS/var/lib/reposado/reposadolib/reposadocommon.py +++ b/SUS/var/lib/reposado/reposadolib/reposadocommon.py @@ -39,6 +39,8 @@ Created by Greg Neagle on 2011-03-03. """ +from __future__ import absolute_import +from __future__ import print_function import sys import os import imp @@ -98,6 +100,9 @@ def pref(prefname): ('https://swscan.apple.com/content/catalogs/others/' 'index-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-' 'snowleopard-leopard.merged-1.sucatalog'), + ('https://swscan.apple.com/content/catalogs/others/' + 'index-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-' + 'snowleopard-leopard.merged-1.sucatalog'), ], 'PreferredLocalizations': ['English', 'en'], 'CurlPath': '/usr/bin/curl' @@ -208,7 +213,7 @@ def log(msg): try: fileobj = open(LOGFILE, mode='a', buffering=1) try: - print >> fileobj, time.strftime(formatstr), msg.encode('UTF-8') + print(time.strftime(formatstr), msg.encode('UTF-8'), file=fileobj) except (OSError, IOError): pass fileobj.close() @@ -224,7 +229,7 @@ def print_stdout(msg, *args): if LOGFILE: log(output) else: - print output + print(output) sys.stdout.flush() @@ -236,7 +241,7 @@ def print_stderr(msg, *args): if LOGFILE: log(output) else: - print >> sys.stderr, concat_message(msg, *args) + print(concat_message(msg, *args), file=sys.stderr) def humanReadable(size_in_bytes): @@ -259,14 +264,14 @@ def writeDataToPlist(data, filename): if not os.path.exists(metadata_dir): try: os.makedirs(metadata_dir) - except OSError, errmsg: + except OSError as errmsg: print_stderr( 'Could not create missing %s because %s', metadata_dir, errmsg) try: plistlib.writePlist(data, os.path.join(metadata_dir, filename)) - except (IOError, OSError, TypeError), errmsg: + except (IOError, OSError, TypeError) as errmsg: print_stderr( 'Could not write %s because %s', filename, errmsg) @@ -351,6 +356,9 @@ def rewriteURLsForProduct(product): if 'MetadataURL' in package: package['MetadataURL'] = rewriteOneURL( package['MetadataURL']) + if 'IntegrityDataURL' in package: + package['IntegrityDataURL'] = rewriteOneURL( + package['IntegrityDataURL']) # workaround for 10.8.2 issue where client ignores local pkg # and prefers Apple's URL. Need to revisit as we better understand this # issue @@ -416,9 +424,9 @@ def writeBranchCatalogs(localcatalogpath): catalog['Products'][product_key] = \ downloaded_products[product_key] elif pref('LocalCatalogURLBase') and product_key in product_info: - # Product has probably been deprecated by Apple, - # so we're using cached product info - # First check to see if this product was ever in this + # Product might have been deprecated by Apple, + # so we check cached product info + # Check to see if this product was ever in this # catalog original_catalogs = product_info[product_key].get( 'OriginalAppleCatalogs', []) @@ -440,17 +448,11 @@ def writeBranchCatalogs(localcatalogpath): catalog['Products'][product_key] = catalog_entry continue else: - if pref('LocalCatalogURLBase'): - print_stderr( - 'WARNING: Product %s not added to branch %s of %s. ' - 'It is not in the corresponding Apple catalogs ' - 'and is not in the ProductInfo cache.', - product_key, branch, localcatalogname) - else: - print_stderr( - 'WARNING: Product %s not added to branch %s of %s. ' - 'It is not in the corresponding Apple catalog.', - product_key, branch, localcatalogname) + # item is not listed in the main catalog and we don't have a + # local cache of product info. It either was never in this + # catalog or has been removed by Apple. In either case, we just + # skip the item -- we can't add it to the catalog. + pass plistlib.writePlist(catalog, branchcatalogpath) @@ -508,7 +510,7 @@ def readXMLfile(filename): print_stderr( 'Invalid XML in %s', filename) return None - except IOError, err: + except IOError as err: print_stderr( 'Error reading %s: %s', filename, err) return None @@ -520,7 +522,7 @@ def writeXMLtoFile(node, path): xml_string = node.toxml('utf-8') try: fileobject = open(path, mode='w') - print >> fileobject, xml_string + print(xml_string, file=fileobject) fileobject.close() except (OSError, IOError): print_stderr('Couldn\'t write XML to %s' % path) diff --git a/appliance/setup-centos-7.json b/appliance/setup-centos-7.json index 4d5ea1c..f5a4907 100755 --- a/appliance/setup-centos-7.json +++ b/appliance/setup-centos-7.json @@ -80,11 +80,11 @@ "disk_size": 512000, "guest_additions_mode": "disable", "iso_urls": [ - "iso/CentOS-7-x86_64-Everything-1804.iso", - "http://mirror.optus.net/centos/7.5.1804/isos/x86_64/CentOS-7-x86_64-Everything-1804.iso" + "iso/CentOS-7-x86_64-Everything-1810.iso", + "http://mirror.optus.net/centos/7.6.1810/isos/x86_64/CentOS-7-x86_64-Everything-1810.iso" ], "iso_checksum_type": "sha256", - "iso_checksum": "99723c8b87dcec21df8aed23de1eb810346d42cfd2a3fafafe70a68296053417", + "iso_checksum": "918975cdf947e858c9a0c77d6b90a9a56d9977f3a4496a56437f46f46200cf71", "http_directory": "http", "http_port_min": 9001, "http_port_max": 9001, diff --git a/appliance/setup-ubuntu-14.04.json b/appliance/setup-ubuntu-14.04.json index bcaa828..417ce9f 100644 --- a/appliance/setup-ubuntu-14.04.json +++ b/appliance/setup-ubuntu-14.04.json @@ -111,11 +111,11 @@ "disk_size": 512000, "guest_additions_mode": "disable", "iso_urls": [ - "iso/ubuntu-14.04.5-server-amd64.iso", - "http://releases.ubuntu.com/trusty/ubuntu-14.04.5-server-amd64.iso" + "iso/ubuntu-14.04.6-server-amd64.iso", + "http://releases.ubuntu.com/trusty/ubuntu-14.04.6-server-amd64.iso" ], "iso_checksum_type": "sha256", - "iso_checksum": "dde07d37647a1d2d9247e33f14e91acb10445a97578384896b4e1d985f754cc1", + "iso_checksum": "b17d7c1e9d0321ad5810ba77b69aef43f0f29a5422b08120e6ee0576c4527c0e", "http_directory": "http", "http_port_min": 9001, "http_port_max": 9001, diff --git a/appliance/setup-ubuntu-16.04.json b/appliance/setup-ubuntu-16.04.json index e535e80..e67d717 100644 --- a/appliance/setup-ubuntu-16.04.json +++ b/appliance/setup-ubuntu-16.04.json @@ -123,11 +123,11 @@ "disk_size": 512000, "guest_additions_mode": "disable", "iso_urls": [ - "iso/ubuntu-16.04.5-server-amd64.iso", - "http://releases.ubuntu.com/16.04/ubuntu-16.04.5-server-amd64.iso" + "iso/ubuntu-16.04.6-server-amd64.iso", + "http://releases.ubuntu.com/16.04/ubuntu-16.04.6-server-amd64.iso" ], "iso_checksum_type": "sha256", - "iso_checksum": "c94de1cc2e10160f325eb54638a5b5aa38f181d60ee33dae9578d96d932ee5f8", + "iso_checksum": "16afb1375372c57471ea5e29803a89a5a6bd1f6aabea2e5e34ac1ab7eb9786ac", "http_directory": "http", "http_port_min": 9001, "http_port_max": 9001, diff --git a/appliance/setup-ubuntu-18.04.json b/appliance/setup-ubuntu-18.04.json index 6663247..32b339d 100644 --- a/appliance/setup-ubuntu-18.04.json +++ b/appliance/setup-ubuntu-18.04.json @@ -122,11 +122,11 @@ "disk_size": 512000, "guest_additions_mode": "disable", "iso_urls": [ - "iso/ubuntu-18.04.1-server-amd64.iso", - "http://cdimage.ubuntu.com/ubuntu/releases/bionic/release/ubuntu-18.04.1-server-amd64.iso" + "iso/ubuntu-18.04.2-server-amd64.iso", + "http://cdimage.ubuntu.com/ubuntu/releases/bionic/release/ubuntu-18.04.2-server-amd64.iso" ], "iso_checksum_type": "sha256", - "iso_checksum": "a5b0ea5918f850124f3d72ef4b85bda82f0fcd02ec721be19c1a6952791c8ee8", + "iso_checksum": "a2cb36dc010d98ad9253ea5ad5a07fd6b409e3412c48f1860536970b073c98f5", "http_directory": "http", "http_port_min": 9001, "http_port_max": 9001, diff --git a/base/testOSRequirements.sh b/base/testOSRequirements.sh index 4f21f01..2a19364 100755 --- a/base/testOSRequirements.sh +++ b/base/testOSRequirements.sh @@ -22,7 +22,7 @@ case $NAME in fi exit 0 else - log "Error: $NAME version must be 14.04 or 16.04 (Detected $VERSION_ID)." + log "Error: $NAME version must be 14.04, 16.04 or 18.04 (Detected $VERSION_ID)." exit 1 fi ;; @@ -32,6 +32,9 @@ case $NAME in unset IFS if [[ ${VERSION_ARR[0]} -eq 6 ]] && [[ ${VERSION_ARR[1]} -gt 3 ]] || [[ ${VERSION_ARR[0]} -gt 6 ]] ; then log "$PRETTY_NAME found" + if [[ ${VERSION_ARR[0]} -eq 8 ]] ; then + log "Warning: $NAME $VERSION_ID support is currently experimental, proceed with caution." + fi exit 0 else log "Error: $NAME version must be 6.4 or later (Detected $VERSION_ID)." @@ -44,7 +47,7 @@ case $NAME in ;; *) release=$(rpm -q --queryformat '%{RELEASE}' rpm | cut -d '.' -f 2) - if [[ $release == "el6" ]] || [[ $release == "el7" ]] ; then + if [[ $release == "el6" ]] || [[ $release == "el7" ]] || [[ $release == "el8" ]] ; then IFS='.' VERSION_ARR=( $VERSION_ID ) unset IFS diff --git a/docs/netboot.md b/docs/netboot.md index 6d3111d..c546a9f 100755 --- a/docs/netboot.md +++ b/docs/netboot.md @@ -16,6 +16,14 @@ To set up a NetBoot server, you need a NetBoot image (.nbi folder). For more inf 4. In the top-right corner of the page, click the toggle so it displays .\ All related services will automatically start. +5. Select the engine (BSDP/DHCP) you wish to use to broadcast the NetBoot image information.\ + **Note**: BSDP supports multiple images, but will not broadcast across subnets.\ + **Note**: DHCP broadcasts across subnets, but only supports a single image. + +6. **Optional**: If using DHCP, specify the network interface you wish to use to broadcast the NetBoot image information.\ + **Note**: The subnet definition for the selected network interface is automatically added. + +6. **Optional**: If using DHCP, add additional subnet definitions for the networks you wish to enable NetBoot on. ## Uploading a NetBoot Image diff --git a/docs/sus.md b/docs/sus.md index f1488d5..8dbca04 100755 --- a/docs/sus.md +++ b/docs/sus.md @@ -3,6 +3,8 @@ The SUS hosted by the NetSUSLP uses Reposado, an open source software update application. Unlike a standard SUS, you can divide the SUS hosted by the NetSUSLP into branches and enable different software updates on each branch. This gives you more control over which updates should be installed on each computer in your organization. +**Note**: NetSUS uses [Reposado](https://github.com/wdas/reposado) to provide software updates, refer to the [Reposado Wiki](https://github.com/wdas/reposado/wiki) for detailed documentation. + ## Setting Up the SUS 1. Log in to the NetSUSLP web application. @@ -14,7 +16,7 @@ Unlike a standard SUS, you can divide the SUS hosted by the NetSUSLP into branch 4. In the top-right corner of the page, click the toggle so it displays . 5. Enter the Base URL for the software update service and tab out of the field.\ - **Note**: NetSUSLP 5.0 allows for HTTPS to be used for the Base URL. + **Note**: NetSUSLP 5.0.1 allows for HTTPS to be used for the Base URL. @@ -191,6 +193,10 @@ The actual Branch URLs vary depending on the operating system of enrolled comput https://sus.mycompany.corp/content/catalogs/others/index-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1_.sucatalog +**macOS v10.15** + + https://sus.mycompany.corp/content/catalogs/others/index-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1_.sucatalog + ### Running Software Update on Computers For instructions on using Jamf Pro to run Software Update on computers that are managed by the Jamf Pro Server, see the “Running Software Update” section in the Jamf Pro Administrator’s Guide. diff --git a/webadmin/var/www/webadmin/about.php b/webadmin/var/www/webadmin/about.php index ce577a3..38fc33f 100644 --- a/webadmin/var/www/webadmin/about.php +++ b/webadmin/var/www/webadmin/about.php @@ -51,6 +51,9 @@

DataTables

https://datatables.net/

+

ISC DHCP

+

https://www.isc.org/dhcp/

+

jQuery

https://jquery.com/

diff --git a/webadmin/var/www/webadmin/dashboard.php b/webadmin/var/www/webadmin/dashboard.php index e7910fd..0a0a9af 100644 --- a/webadmin/var/www/webadmin/dashboard.php +++ b/webadmin/var/www/webadmin/dashboard.php @@ -260,10 +260,6 @@ function netbootExec($cmd) { } $dhcp_running = (trim(netbootExec("getdhcpstatus")) === "true"); -if ($dhcp_running) { - netbootExec("stopdhcp"); - netbootExec("startbsdp"); -} $bsdp_running = (trim(netbootExec("getbsdpstatus")) === "true"); $netbootusage = trim(suExec("getDirSize /srv/NetBoot/NetBootSP0")); @@ -273,12 +269,22 @@ function netbootExec($cmd) { $shadowusage = (formatSize($shadowusage*1024, 0)); if ($conf->getSetting("netboot") == "") { - if ($dhcp_running) { + if ($dhcp_running || $bsdp_running) { $conf->setSetting("netboot", "enabled"); } else { $conf->setSetting("netboot", "disabled"); } } + +$nbengine = $conf->getSetting("netbootengine"); +if (empty($nbengine)) { + if ($dhcp_running) { + $nbengine = "dhcpd"; + } else { + $nbengine = "pybsdp"; + } + $conf->setSetting("netbootengine", $nbengine); +} ?>
@@ -293,10 +299,14 @@ function netbootExec($cmd) {
-
+
">
BSDP Status
+
"> +
DHCP Status
+ +
diff --git a/webadmin/var/www/webadmin/inc/functions.php b/webadmin/var/www/webadmin/inc/functions.php index 3163ae8..a4ecd97 100755 --- a/webadmin/var/www/webadmin/inc/functions.php +++ b/webadmin/var/www/webadmin/inc/functions.php @@ -21,6 +21,11 @@ function getCurrentWebUser() { return $admin_username; } +function getNetAddress($ip, $mask) +{ + return long2ip(ip2long($ip) & ip2long($mask)); +} + function getSSHstatus() { if (trim(suExec("getSSHstatus")) == "true") { return true; diff --git a/webadmin/var/www/webadmin/inc/header.php b/webadmin/var/www/webadmin/inc/header.php index 225eb62..7800818 100644 --- a/webadmin/var/www/webadmin/inc/header.php +++ b/webadmin/var/www/webadmin/inc/header.php @@ -54,7 +54,7 @@ - + diff --git a/webadmin/var/www/webadmin/logs.php b/webadmin/var/www/webadmin/logs.php index d3210f5..2b607dd 100755 --- a/webadmin/var/www/webadmin/logs.php +++ b/webadmin/var/www/webadmin/logs.php @@ -14,8 +14,15 @@ function formatSize($size, $precision = 1) { return round(pow(1024, $base - floor($base)), $precision) .' '. $suffixes[floor($base)]; } +$display_log_str = trim(suExec("displayLogList")); +$display_log_list = explode(" ", $display_log_str); +/* +$flush_log_str = trim(suExec("flushLogList")); +$flush_log_list = explode(" ", $flush_log_str); +*/ + $log_content = ""; -if (isset($_POST['display_log'])) { +if (isset($_POST['display_log']) && in_array($_POST['display_file'], $display_log_list, TRUE)) { $log_content = suExec("displayLog ".$_POST['display_file']." ".$_POST['display_lines']); $log_size = formatSize(strlen($log_content)); } @@ -29,12 +36,6 @@ function formatSize($size, $precision = 1) { // #################################################################### if (empty($log_content)) { - $display_log_str = trim(suExec("displayLogList")); - $display_log_list = explode(" ", $display_log_str); -/* - $flush_log_str = trim(suExec("flushLogList")); - $flush_log_list = explode(" ", $flush_log_str); -*/ ?>

+ +
+
NetBoot Engine Service used to provide NetBoot information to clients.
+
+ > + +
+
+ > + +
+
+ +
+ +
+ +
+
Network Interface Network Interface to use for NetBoot Images (HTTP/NFS).
+ +
+ +
+ +
+ +
+ +
+
"> +
+
Unable to update dhcpd.conf.
+
+
+ + +
+ +
+ + + + + + + + + + \ No newline at end of file diff --git a/webadmin/var/www/webadmin/susSettings.php b/webadmin/var/www/webadmin/susSettings.php index cec42bb..872f4fc 100644 --- a/webadmin/var/www/webadmin/susSettings.php +++ b/webadmin/var/www/webadmin/susSettings.php @@ -39,6 +39,9 @@ function susExec($cmd) { array("default" => true, "name" => "10.14", "url" => "https://swscan.apple.com/content/catalogs/others/index-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog"), array("default" => false, "name" => "10.14beta", "url" => "https://swscan.apple.com/content/catalogs/others/index-10.14beta-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog"), array("default" => false, "name" => "10.14seed", "url" => "https://swscan.apple.com/content/catalogs/others/index-10.14seed-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog"), + array("default" => true, "name" => "10.15", "url" => "https://swscan.apple.com/content/catalogs/others/index-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog"), + array("default" => false, "name" => "10.15beta", "url" => "https://swscan.apple.com/content/catalogs/others/index-10.15beta-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog"), + array("default" => false, "name" => "10.15seed", "url" => "https://swscan.apple.com/content/catalogs/others/index-10.15seed-10.15-10.14-10.13-10.12-10.11-10.10-10.9-mountainlion-lion-snowleopard-leopard.merged-1.sucatalog"), ); $default_catalog_urls = array(); foreach ($default_catalog_map as $array) { @@ -151,7 +154,7 @@ function hideSuccess(element) { function validBaseUrl(element, labelId = false) { hideSuccess(element); - if (/^http(s)?:\/\/(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9][\/]|[1-9][0-9]|[1-9][0-9][\/]|1[0-9]{2}|1[0-9]{2}[\/]|2[0-4][0-9]|2[0-4][0-9][\/]|25[0-5]|25[0-5][\/])$|^http(s)?:\/\/(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][\/]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9][\/])$/.test(element.value)) { + if (/^http(s)?:\/\/(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]|[1-9][0-9]|[1-9][0-9]|1[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|2[0-4][0-9]|25[0-5]|25[0-5])\/$|^http(s)?:\/\/(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])\/$/.test(element.value)) { hideError(element, labelId); } else { showError(element, labelId); @@ -159,7 +162,7 @@ function validBaseUrl(element, labelId = false) { } function updateBaseUrl(element, offset = false) { - if (/^http(s)?:\/\/(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9][\/]|[1-9][0-9]|[1-9][0-9][\/]|1[0-9]{2}|1[0-9]{2}[\/]|2[0-4][0-9]|2[0-4][0-9][\/]|25[0-5]|25[0-5][\/])$|^http(s)?:\/\/(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z][\/]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9][\/])$/.test(element.value)) { + if (/^http(s)?:\/\/(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[0-9]|[1-9][0-9]|[1-9][0-9]|1[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|2[0-4][0-9]|25[0-5]|25[0-5])\/$|^http(s)?:\/\/(([a-zA-Z]|[a-zA-Z][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z]|[A-Za-z]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9]|[A-Za-z][A-Za-z0-9\-]*[A-Za-z0-9])\/$/.test(element.value)) { ajaxPost('susCtl.php', 'baseurl='+element.value); showSuccess(element); } @@ -278,7 +281,7 @@ function toggleDashboard() {
-
Base URL Base URL for the software update server (e.g. "http://sus.mycompany.corp").
+
Base URL Base URL for the software update server (e.g. "http://sus.mycompany.corp/").
diff --git a/webadmin/webadminInstall.sh b/webadmin/webadminInstall.sh index 480f52f..33ec81d 100755 --- a/webadmin/webadminInstall.sh +++ b/webadmin/webadminInstall.sh @@ -58,6 +58,7 @@ elif [[ $(which yum 2>&-) != "" ]]; then yum_install ntpdate yum_install mod_ssl yum_install php + yum_install php-json yum_install php-xml yum_install php-ldap chkconfig httpd on >> $logFile 2>&1 @@ -208,6 +209,222 @@ rm -f /var/www/html/index.html # Install the webadmin interface cp -R ./resources/html/* /var/www/html/ >> $logFile +# Add Patch Server Components, if detected +if [ -f '/var/www/html/webadmin/patchTitles.php' ]; then + # Menu + sed -i '/$pageURI == "sharing.php"/i\ +
  • ">Patch Definitions
  • ' /var/www/html/webadmin/inc/header.php + + # Dashboard + if [ -f '/var/www/html/webadmin/scripts/patchHelper.sh' ]; then + sed -i '1,/panel panel-default panel-main/ {/panel panel-default panel-main/i\ +
    ">\ +
    \ + Patch Definitions\ +
    \ +query("SELECT COUNT(id) FROM titles")->fetchColumn();\ +}\ +\ +function patchExec($cmd) {\ + return shell_exec("sudo /bin/sh scripts/patchHelper.sh ".escapeshellcmd($cmd)." 2>&1");\ +}\ +\ +if ($conf->getSetting("kinobi_url") != "" && $conf->getSetting("kinobi_token") != "") {\ + $ch = curl_init();\ + curl_setopt($ch, CURLOPT_URL, $conf->getSetting("kinobi_url"));\ + curl_setopt($ch, CURLOPT_POST, true);\ + curl_setopt($ch, CURLOPT_POSTFIELDS, "token=".$conf->getSetting("kinobi_token"));\ + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ + $result = curl_exec($ch);\ + curl_close ($ch);\ + $token = json_decode($result, true);\ +}\ +?>\ +\ +
    \ +
    \ + \ +
    \ + \ +

    Patch Management

    \ +
    \ +
    \ + \ +\ + \ +
    \ +
    \ +
    SSL Enabled
    \ + \ +
    \ +
    \ + \ +\ + \ +
    \ +
    \ +
    Hostname
    \ + \ +
    \ +
    \ + \ +\ +
    \ +\ + \ +
    \ + \ +\ + \ +
    \ +
    \ +
    Number of Titles
    \ + \ +
    \ +
    \ + \ +\ +\ + \ +
    \ +
    \ +
    Subscription Expires
    \ + \ +
    \ +
    \ + \ +\ +
    \ + \ +
    \ +
    \ + +}' /var/www/html/webadmin/dashboard.php + else + sed -i '1,/panel panel-default panel-main/ {/panel panel-default panel-main/i\ +
    ">\ +
    \ + Patch Definitions\ +
    \ +query("SELECT COUNT(id) FROM titles WHERE enabled = 1")->fetchColumn();\ +}\ +\ +// Suscription\ +$subs = $kinobi->getSetting("subscription");\ +if (!empty($subs["url"]) && !empty($subs["token"])) {\ + $subs_resp = fetchJsonArray($subs["url"], $subs["token"]);\ +}\ +?>\ +\ +
    \ +
    \ +getSetting("patch") == "enabled") { ?>\ + \ +
    \ + \ +

    Patch Management

    \ +
    \ +
    \ + \ +\ + \ +
    \ +
    \ +
    SSL Enabled
    \ + \ +
    \ +
    \ + \ +\ + \ +
    \ +
    \ +
    Hostname
    \ + \ +
    \ +
    \ + \ +\ +
    \ +\ + \ +
    \ + \ +\ + \ +
    \ +
    \ +
    Number of Titles
    \ + \ +
    \ +
    \ + \ +\ +\ + \ +
    \ +
    \ +
    Subscription Expires
    \ + \ +
    \ +
    \ + \ +\ + \ +
    \ + \ +

    Patch Management

    \ +
    \ +
    \ + \ +\ + \ +
    \ +
    \ +
    Configure Patch Definitions to provide an external patch source for Jamf Pro.
    \ + \ +
    \ +
    \ + \ +\ +
    \ + \ +
    \ +
    \ + +}' /var/www/html/webadmin/dashboard.php + fi + + # Settings + sed -i '//i\ + \ +

    Patch Definitions

    \ +

    Patch Definitions

    \ +
    \ +
    \ + \ + \ +
    ' /var/www/html/webadmin/settings.php +fi + # Prevent writes to the webadmin's helper script chown root:root /var/www/html/webadmin/scripts/adminHelper.sh >> $logFile chmod a-wr /var/www/html/webadmin/scripts/adminHelper.sh >> $logFile