7052679 AI Sparc client gets wanboot.conf error when booting due to restrictive umask
--- a/usr/src/cmd/installadm/dhcp.py Tue Jan 10 14:31:15 2012 -0800
+++ b/usr/src/cmd/installadm/dhcp.py Fri Jan 13 10:23:52 2012 +0100
@@ -499,6 +499,9 @@
in_class = False
seek_bootfile = False
edit_complete = False
+ # dhcpd server runs under dhcpserv user account and needs to be able
+ # to read its config file
+ orig_umask = os.umask(0022)
with open(tmp_cfgfile, "w") as tmp_cfg:
for line in current_lines:
if not edit_complete:
@@ -562,7 +565,7 @@
seek_bootfile = True
# Write each line from the old file to the new as we traverse
tmp_cfg.write(line)
-
+ os.umask(orig_umask)
# Ok, we're done writing lines from the old file to the new. Let's
# ensure we've made our edit. If not, for whatever reason, we should
# inform the enduser that manual DHCP configuration might be required.
@@ -726,7 +729,7 @@
logging.debug("dhcp.control: unexpected service state: %s",
self._state)
raise DHCPServerError(cw(_("DHCP server is in an unexpected "
- "state: action [%s] state [%s]") %
+ "state: action [%s] state [%s]") %
(action, self._state)))
def _add_stanza_to_config_file(self, new_stanza):
@@ -1278,7 +1281,7 @@
cmd = [SVCPROP, "-p", prop, service]
p = Popen.check_call(cmd, stdout=Popen.STORE, stderr=Popen.STORE,
logger='', stderr_loglevel=logging.DEBUG)
-
+
return p.stdout.strip()
@@ -1356,7 +1359,7 @@
# be able to simply use the IP address returned from get_valid_networks().
valid_nets = list(com.get_valid_networks())
if valid_nets:
- ipaddr = valid_nets[0]
+ ipaddr = valid_nets[0]
else:
if verbose:
print >> sys.stderr, cw(_("\nNo networks are currently set to "
--- a/usr/src/cmd/installadm/grub.py Tue Jan 10 14:31:15 2012 -0800
+++ b/usr/src/cmd/installadm/grub.py Fri Jan 13 10:23:52 2012 +0100
@@ -21,7 +21,7 @@
#
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
#
'''
functions supporting creating and modifying menu.lst
@@ -157,6 +157,8 @@
os.remove(media_grub)
# Create a new menu.lst for the AI client to use during boot
+ # menu.lst should be created with right permissions
+ orig_umask = os.umask(0022)
with open(os.path.join(menu_path, MENULST), "w") as menu:
# First setup the the global environment variables
menu.write("default=0\n")
@@ -188,3 +190,4 @@
srv_address))
menu.write("\tmodule$ /%s/platform/i86pc/$ISADIR/boot_archive\n" %
svc_name)
+ os.umask(orig_umask)
--- a/usr/src/cmd/installadm/service_config.py Tue Jan 10 14:31:15 2012 -0800
+++ b/usr/src/cmd/installadm/service_config.py Fri Jan 13 10:23:52 2012 +0100
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
#
'''
This file contains functions to manage the properties of installation
@@ -760,9 +760,15 @@
cfgpath = os.path.join(svcdir, CFGFILE)
logging.log(com.XDEBUG, 'writing config file: %s', cfgpath)
+
+ # .config file should be created with right permissions
+ orig_umask = os.umask(0022)
+
with open(cfgpath, 'w') as cfgfile:
cfg.write(cfgfile)
+ os.umask(orig_umask)
+
def _write_service_config(service_name, props):
'''Writes out the service related info to the .config file
--- a/usr/src/cmd/installadm/setup-sparc.sh Tue Jan 10 14:31:15 2012 -0800
+++ b/usr/src/cmd/installadm/setup-sparc.sh Fri Jan 13 10:23:52 2012 +0100
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
# Description:
# This script sets up the wanboot.conf file which is used
@@ -35,6 +35,9 @@
. /usr/lib/installadm/installadm-common
+# Ensure that we will create files with right permissions
+# umask is shell built-in
+umask 022
WANBOOTCGI="/usr/lib/inet/wanboot/wanboot-cgi"
CGIBIN_WANBOOTCGI="cgi-bin/wanboot-cgi"
--- a/usr/src/cmd/installadm/test/test_create_service.py Tue Jan 10 14:31:15 2012 -0800
+++ b/usr/src/cmd/installadm/test/test_create_service.py Fri Jan 13 10:23:52 2012 +0100
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
#
'''
@@ -29,13 +29,18 @@
'''
-import unittest
+import os
import osol_install.auto_install.create_service as create_service
+import osol_install.auto_install.dhcp as dhcp
+import osol_install.auto_install.grub as grub
import osol_install.auto_install.installadm_common as com
+import shutil
+import tempfile
+import unittest
class ParseOptions(unittest.TestCase):
- '''Tests for parse_options.'''
+ '''Tests for parse_options.'''
@classmethod
def setUpClass(cls):
@@ -43,7 +48,7 @@
We want to sub out the is_multihomed() function from
installadm_common because it calls into the installadm-common.sh
script which is part of the installadm pkg and that pkg may not
- be installed on the system running the unit tests.
+ be installed on the system running the unit tests.
'''
cls.com_ismultihomed = com.is_multihomed
com.is_multihomed = lambda: False
@@ -119,5 +124,106 @@
"pkg:/install-image/solaris-auto-install")
+class CreateTestService(unittest.TestCase):
+ '''Tests for install service set up.'''
+
+ def setUp(self):
+ '''unit test set up'''
+ self.svc_name = 'my-test-service'
+ self.image_path = tempfile.mkdtemp(dir="/tmp")
+ self.image_info = {'image_version': '3.0', 'grub_min_mem64': '0',
+ 'service_name': 'solaris11u1-i386-05',
+ 'grub_do_safe_default': 'true',
+ 'grub_title': 'Oracle Solaris 11',
+ 'image_size': '744619',
+ 'no_install_grub_title': 'Oracle Solaris 11'}
+ self.srv_address = '$serverIP:5555'
+ self.menu_path = self.image_path
+ self.bootargs = ''
+
+ def tearDown(self):
+ '''teardown'''
+ if os.path.exists(self.image_path):
+ shutil.rmtree(self.image_path)
+
+ def test_menu_permissions(self):
+ '''Ensure that menu.lst is created with correct permissions'''
+
+ # save original umask
+ orig_umask = os.umask(0022)
+ # set too restrictive and too open umask
+ for mask in (0066, 0000):
+ os.umask(mask)
+ grub.setup_grub(self.svc_name, self.image_path, self.image_info,
+ self.srv_address, self.menu_path, self.bootargs)
+ mode = os.stat(self.menu_path + '/' + 'menu.lst').st_mode
+ self.assertEqual(mode, 0100644)
+ # return umask to the original value
+ os.umask(orig_umask)
+
+
+class DHCPServerTest(unittest.TestCase):
+ '''Tests for interaction with ISC DHCP server.'''
+
+ def setUp(self):
+ '''Create test instance of dhcp SMF service'''
+
+ # save the original svc name of dhcp SMF service instance
+ self.dhcp_srv_orig = dhcp.DHCP_SERVER_IPV4_SVC
+ self.dhcp_srv = "svc:/network/dhcp/server"
+ # name of our test instance
+ self.instance_name = "ai-unittest"
+ self.dhcp_srv_inst = self.dhcp_srv + ':' + self.instance_name
+ self.dhcp_dir = tempfile.mkdtemp(dir="/tmp")
+
+ # redefine DHCP_SERVER_IPV4_SVC to our test SMF service
+ dhcp.DHCP_SERVER_IPV4_SVC = self.dhcp_srv_inst
+ # construct list of svccfg commands
+ cmds = list()
+ # create new instance of dhcp service
+ cmds.append([dhcp.SVCCFG, "-s", self.dhcp_srv,
+ "add", self.instance_name])
+ svccmd = [dhcp.SVCCFG, "-s", self.dhcp_srv_inst]
+ # add config property group
+ cmds.append(svccmd + ["addpg config application"])
+ # set test config file
+ cmds.append(svccmd + ["setprop config/config_file = astring: " +
+ self.dhcp_dir + "/dhcpd4.conf"])
+ # set lease file
+ cmds.append(svccmd + ["setprop config/lease_file = astring: " +
+ self.dhcp_dir + "/dhcpd4.leases"])
+ # general/complete must be set-up
+ cmds.append(svccmd + ["addpg general framework"])
+ cmds.append(svccmd + ['setprop general/complete = astring: ""'])
+ # disable service
+ cmds.append([dhcp.SVCADM, "disable", self.dhcp_srv_inst])
+
+ for cmd in cmds:
+ Popen.check_call(cmd)
+
+ def tearDown(self):
+ '''Delete test instance of dhcp SMF service'''
+ cmd = [dhcp.SVCCFG, "delete", self.dhcp_srv_inst]
+ Popen.check_call(cmd)
+ dhcp.DHCP_SERVER_IPV4_SVC = self.dhcp_srv_orig
+ if os.path.exists(self.dhcp_dir):
+ shutil.rmtree(self.dhcp_dir)
+
+ def test_permissions(self):
+ '''Test correct permissions of dhcpd4.conf'''
+
+ dhcpsrv = dhcp.DHCPServer()
+ dhcpsrv.add_arch_class('i386', 'some-test-string')
+ # save original umask
+ orig_umask = os.umask(0022)
+ # set too restrictive and too open umask
+ for mask in (0066, 0000):
+ os.umask(mask)
+ dhcpsrv.update_bootfile_for_arch('i386', 'some-other-test-string')
+ mode = os.stat(self.dhcp_dir + '/' + 'dhcpd4.conf').st_mode
+ self.assertEqual(mode, 0100644)
+ # return umask to the original value
+ os.umask(orig_umask)
+
if __name__ == '__main__':
unittest.main()
--- a/usr/src/cmd/installadm/test/test_service_config.py Tue Jan 10 14:31:15 2012 -0800
+++ b/usr/src/cmd/installadm/test/test_service_config.py Fri Jan 13 10:23:52 2012 +0100
@@ -19,7 +19,7 @@
#
# CDDL HEADER END
#
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
#
'''
@@ -37,7 +37,7 @@
class ServiceConfig(unittest.TestCase):
- '''Tests for service_config'''
+ '''Tests for service_config'''
@classmethod
def setUpClass(cls):
@@ -118,8 +118,8 @@
config._write_service_config('s5', props)
services = config.get_all_service_names()
self.assertEqual(len(services), 5)
- self.assertTrue('s1' in services and 's2' in services and
- 's3' in services and 's4' in services and
+ self.assertTrue('s1' in services and 's2' in services and
+ 's3' in services and 's4' in services and
's5' in services)
def test_get_all_service_props(self):
@@ -134,7 +134,7 @@
self.assertEqual(all_props['s1'], {'version': config.CURRENT_VERSION,
'hot': 'fudge'})
self.assertEqual(all_props['s2'], {'version': config.CURRENT_VERSION,
- 'ice': 'cream'})
+ 'ice': 'cream'})
self.assertEqual(all_props['s3'], {'version': config.CURRENT_VERSION,
'apple': 'pie'})
@@ -177,7 +177,6 @@
self.assertRaises(config.ServiceCfgError,
config.verify_key_properties, 's1', props)
-
props = {config.PROP_SERVICE_NAME: 's1',
config.PROP_STATUS: config.STATUS_ON,
config.PROP_TXT_RECORD: 'aiwebserver=ais:5555'}
@@ -208,7 +207,7 @@
self.assertTrue(aliased == ['alias1'])
aliased = config.get_aliased_services('base1', recurse=True)
self.assertTrue(aliased == ['alias1', 'alias2'])
-
+
def test_clients(self):
'''test clients'''
@@ -230,12 +229,28 @@
self.assertEqual(clientdict.keys(), ['01AABBCCDDAABB',
'01AAAAAAAAAAAA'])
self.assertEqual(clientdict['01AAAAAAAAAAAA'][config.FILES],
- ['/tmp/aaa', '/tmp/AAA'] )
+ ['/tmp/aaa', '/tmp/AAA'])
config.remove_client_from_config('s1', '01AABBCCDDAABB')
clientdict = config.get_clients('s1')
self.assertTrue('01AABBCCDDAABB' not in clientdict)
+ def test_configfile_permissions(self):
+ '''test permissions of .config file'''
+
+ svc = 'permtestsvc'
+ props = {'french': 'fries', 'banana': 'split'}
+ # save original umask
+ orig_umask = os.umask(0022)
+ # set too restrictive and too open umask
+ for mask in (0066, 0000):
+ os.umask(mask)
+ config._write_service_config(svc, props)
+ path = config._get_configfile_path(svc)
+ mode = os.stat(path).st_mode
+ self.assertEqual(mode, 0100644)
+ # return umask to the original value
+ os.umask(orig_umask)
if __name__ == '__main__':
unittest.main()