# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
#
"""Name Service Switch base classes used by nscfg."""
from .messages import *
from subprocess import *
"""Name Service Switch base class. Represents the common base
class used by the other name service switch classes.
** USE AS BASE CLASS ONLY **"""
# Shared return codes:
# Required class constants and variables.
# LOFS mount constants for read-only root option
# This is a mapping from pre-smf DB names [see nsswitch.conf(4)]
# To SMF db names. Note in SMF, all DBs are singular and there
# is a single consistent mapping. (aka hosts & ipnodes -> host)
#
# This mapping is placed in the base class so that it can be shared
# across multiple subclasses.
'group': 'group',
'hosts': 'host',
'ipnodes': 'host',
'networks': 'network',
'protocols': 'protocol',
'rpc': 'rpc',
'ethers': 'ether',
'netmasks': 'netmask',
'bootparams': 'bootparam',
'publickey': 'publickey',
'netgroup': 'netgroup',
'automount': 'automount',
'aliases': 'alias',
'services': 'service',
'printers': 'printer',
'project': 'project',
'auth_attr': 'auth_attr',
'prof_attr': 'prof_attr',
'tnrhtp': 'tnrhtp',
'tnrhdb': 'tnrhdb',
'sudoers': 'sudoer'}
# This tag is used to determine if a legacy file was previously
# generated by an nscfg export
# This is a shared AUTOGEN header used by multiple subclasses
HEADER = """
#
AUTO_GEN
#
# WARNING: THIS FILE GENERATED FROM SMF DATA.
# DO NOT EDIT THIS FILE. EDITS WILL BE LOST.
"""
DOC = None
# Methods
"""Base class init method. Creates BASE service object.
Collects pg's and properties.
Required: SERVICE, LEGACY"""
"""Disable writing of config or SMF properties."""
"""Set verbose flag."""
try:
dstr = ''
for a in av:
if first:
dstr = _(a)
else:
else:
else:
except:
printStderr(_("Output Error"))
"""Error message output, with a little bit of formatting."""
tag = _("Error in service: %s")
"""Multi line error message output, with a little bit of formatting."""
try:
except:
pass
"""Debugging output. IF debug = True"""
"""Verbose output. IF verbose == True or debug = True"""
"""Reset the service and all existing property information."""
"""Base class delete method."""
#
# Methods that manipulate properties and property groups
#
return True
pass
else:
try:
# Warning SMF magic.
# IF a service has not not imported
# some service properties/pgs may exist (e.g. dependencies)
# but the general pg should not exist
# IF we are at early manifest import, an imported service
# IF we are post early manifest import an imported service
# should have general pg, and may have general_ovr pg
# Therefore IF no general pg, no service
if pg == 'general':
if not fnd_general: # undo any initialization
return
except:
pass
"""Get prop's [first] property value."""
try:
if pg == None:
if prop == None:
return ret[0]
raise ValueError, \
"Multiple values returned, single value expected"
except:
pass # No property found , or no value
return None
"""Get all of the prop's property values as a tuple."""
try:
if pg == None:
if prop == None:
except:
pass
return None
"""Get the list of the service's property groups."""
return None
"""Get the list of the service's properties."""
gprops = []
return gprops
return None
"""Return the name of the 'default' property group."""
"""Return the name of the 'default' property."""
If pg or prop are None, use the default."""
return prop
if pg == None:
if prop == None:
# Validate using libscf APIs directly
# num_retries is ignored.
"""Validate the service properties. Retry num_tries times ignored."""
return False
# Run validate through Nssscf library
try:
except:
output = 'Unable to process libscf validate command\n'
ret = -1
if ret == 0:
return True
return False
If pg is not None, then wait for pg to exist in its most
current form."""
return False
# Run refresh through svccfg, not through Nssscf library
# Collect all error results if they exist for error output.
return False
# Was previously calls to self.svc.refresh() and pgupdate
try:
del io
del p
except:
errout = 'Unable to process svccfg refresh command\n'
ret = -1
return True
return False
"""Add a property group with the given name and type."""
return False
try:
except NssscfError, err:
if ret: # Add value_authorization if it exists
try:
except:
pass
return ret
"""Delete property group with the given name."""
return False
try:
except:
pass
return True
"""Delete property group customizations with the given name."""
return False
try:
except:
pass
return True
return False
try:
except NssscfError, err:
return False
return ret
#
# Methods that manipulate legacy files
#
"""Return the name of the full legacy pathname."""
"""Was the legacy file generated from SMF data?"""
"""Return the name of the lofs mountdir or LEGACYDIR ."""
try:
except:
data = None
if data != None:
for l in data:
try:
except:
continue
if type == 'lofs':
break
"""Return the name of the lofs mount path or legacy_path ."""
"""Return the name of the temp legacy pathname."""
return tmppath
"""Create a new legacy temp file for writing."""
try:
except:
"""Write out header to opened tmpfile.
Modify default '#' comment tag using sep, pre, post."""
return False
if pre != None:
if sep != None:
else:
if sep != None:
else:
if post != None:
"""Create a new legacy temp file for writing."""
try:
except:
pass
return True
try:
except:
return False
return True
"""All-in-one tmp file generation from data string."""
return False
return False
if fd == None: # Unable to create temp file
return False
# Write 'DONT MODIFY' HEADER
if header:
try:
except:
return False
return True
"""Save away an existing legacy file to ${legacy}.orig."""
if altpath != None:
try:
except:
return False # Don't continue (unlink error)
try:
except:
return False # Don't continue (link error)
return True
"""Remove ${legacy}.orig if a legacy file exists."""
if altpath != None:
try:
except:
pass
return True
"""Attempt to remount the legacy file as a lofs mount point.
For this to be successful, there must be a pre-existing mount
fail here mean fallback to the rename file method."""
return False # not a lofs mount candidate
return False # Cannot save away existing legacy
try:
except:
return False
try:
# First clean up old lofs mount
if ret != 0:
del io
del p
return False
# Try to cleanly remount file using lofs
del io
del p
except:
return False
return True
return False
"""Replace legacy config file with tmp config file.
Save away existing legacy file as necessary.
Returns: -1 - Error, 0 - Success, 1 - Unnecessary."""
legdata = None
try:
except:
pass
if legdata != None:
try:
except:
pass
# Try a lofs mount if possible
# Otherwise copy temporary file to legacy file
try:
except:
"""Readlines an existing legacy file. Return a list of lines.
Return: None if no legacy file, [] if empty, or [...]
Note: '\n' are pruned from all lines before return."""
lines = []
try:
for l in ln:
if l.endswith('\n'):
l = l[:-1]
except:
return None
return lines
#
# Service specific methods
#
"""Return True if service is currently enabled."""
return False
try:
except NssscfError, err:
return False
return ret
"""Execute svcadm enable on this service."""
return False
try:
except NssscfError, err:
return False
return ret
"""Execute svcadm disable on this service."""
return False
try:
except NssscfError, err:
return False
return ret
"""Execute svcadm refresh on this service."""
return False
try:
except NssscfError, err:
return False
return ret
"""Execute svcadm restart on this service."""
return False
try:
except NssscfError, err:
return False
return ret
#
# Methods to nss "backend" specific methods
#
"""Return True if this is a class for a nss backend."""
return False
return True
#
# Methods that must be subclassed
#
"""Export from SMF. -1 - Fail, 0 - Success, 1 - Unnecessary.
** Must Subclass **"""
"""Import to SMF. -1 - Fail, 0 - Success, 1 - no config to import.
** Must Subclass **"""
"""Unconfigure SMF. -1 - Fail, 0 - Success.
** Must Subclass **"""
#
# Subclass as needed. The default performs a simple check
# to see that the default PG exists and contains at least
# one property. That may be insufficient.
#
if pgs != None:
if props != None:
if fndprop: # PG and at least 1 prop exist
return True
return False
#
# Check to see if the existing legacy file was generated from SMF data.
# Check for the AUTO_GEN tag as a key.
#
"""Was the legacy file generated from SMF data?"""
return True # and must contain the AUTO_GEN line
return False
#
# Determine if configured or not.
#
"""Is this SMF service configured from SMF data?"""
return True
return True
else:
return True # generated from SMF data
return False
#
# Perform basic typechecking on a value
#
if smftype == 'net_address':
return False # at most 1 net mask
try:
return False # /32 ipv4, /64 ipv6
except:
return False
return False
try:
for d in digs:
x = int(d)
if x >= 0 and x <= 255:
count += 1
if count == 4:
return True # Valid IPv4
except:
pass
return False
for d in digs[:-1]:
return False
d = digs[-1]
return True # Valid IPv6
return False
try:
count = 0
for d in digs:
x = int(d)
if x >= 0 and x <= 255:
count += 1
if count == 4:
return True # Valid IPv6:ipv4
except:
pass
return False
if smftype == 'boolean':
return True # In native format
return True # Legal SMF values
elif smftype == 'integer':
return True # In native format
try:
return True
except:
pass # Fall through
elif smftype == 'hostname':
return True # Only legal DNS name chars
elif smftype == 'net_address':
elif smftype == 'host':
return True
return True # Only legal DNS name chars
elif smftype == 'astring':
return True # In native format
else:
pass # XXX Fail on unknown types
return False