[cura-tools] openlmi-tools-lmiwbem: allow root and pegasus members to connect via Unix socket (b96f3ac)
by phatina@fedoraproject.org
Repository : http://git.fedorahosted.org/cgit/cura-tools.git
On branch : openlmi-tools-lmiwbem
>---------------------------------------------------------------
commit b96f3ac9caf4f558922c51a43e1a8c0a9d36eaf7
Author: Peter Hatina <phatina(a)redhat.com>
Date: Fri Jun 27 15:22:26 2014 +0200
allow root and pegasus members to connect via Unix socket
>---------------------------------------------------------------
cli/lmi/shell/LMICIMXMLClient.py | 40 +++++++++------------
cli/lmi/shell/LMIConnection.py | 71 ++++++++++++++++++++++++++------------
cli/lmi/shell/LMIUtil.py | 19 ++++++++++
3 files changed, 85 insertions(+), 45 deletions(-)
diff --git a/cli/lmi/shell/LMICIMXMLClient.py b/cli/lmi/shell/LMICIMXMLClient.py
index ba51b8d..a7c24c0 100644
--- a/cli/lmi/shell/LMICIMXMLClient.py
+++ b/cli/lmi/shell/LMICIMXMLClient.py
@@ -25,6 +25,7 @@ from lmi.shell.LMIUtil import lmi_raise_or_dump_exception
from lmi.shell.LMIUtil import lmi_get_use_exceptions
from lmi.shell.LMIUtil import lmi_set_use_exceptions
from lmi.shell.LMIUtil import lmi_instance_to_path
+from lmi.shell.LMIUtil import lmi_is_localhost
from lmi.shell.LMIDecorators import lmi_process_cim_exceptions
from lmi.shell.LMIDecorators import lmi_process_cim_exceptions_rval
@@ -34,17 +35,6 @@ from lmi.shell.LMIExceptions import ConnectionError
from lmi.shell.LMIExceptions import LMIFilterError
-LOCALHOST_VARIANTS = (
- "localhost",
- "localhost.localdomain",
- "localhost4",
- "localhost4.localdomain4",
- "localhost6",
- "localhost6.localdomain6",
- "127.0.0.1",
- "::1",
-)
-
def filter_kwargs(**kwargs):
return {k: v for k, v in kwargs.iteritems() if v is not None}
@@ -65,16 +55,19 @@ class LMICIMXMLClient(object):
QUERY_LANG_CQL = "DMTF:CQL"
QUERY_LANG_WQL = "WQL"
+ # Unix sockets used by TOG-Pegasus, SFCB or OpenWBEM.
+ PEGASUS_SOCKET = "/var/run/tog-pegasus/cimxml.socket"
+
def __init__(self, uri, username="", password="",
verify_server_cert=True,
key_file=None, cert_file=None):
- if not uri.startswith("http://") and \
- not uri.startswith("https://"):
- uri = "https://" + uri
self._uri = uri
+ if not self._uri.startswith("http://") and \
+ not self._uri.startswith("https://"):
+ self._uri = "https://" + uri
# Parse CIMOM URI
- _, hostname, _, _, username_, password_ = lmi_parse_uri(uri)
+ _, hostname, _, path, username_, password_ = lmi_parse_uri(self._uri)
if username_ is not None:
username = username_
password = password_
@@ -85,14 +78,13 @@ class LMICIMXMLClient(object):
"key_file": key_file
}
- # If we are running as root and the scheme has not been explicitly set,
- # we will use the local UNIX socket for higher performance (and skip
- # authentication).
- connect_locally = os.getuid() == 0 and \
- uri in LOCALHOST_VARIANTS and \
- parse_res.path != "/wsman" and \
- os.path.exists("/var/run/tog-pegasus/cimxml.socket") and \
- not username and not password
+ # If we are connecting to localhost without username or certificate
+ # set, we will use the local UNIX socket for higher performance (and
+ # skip authentication).
+ connect_locally = lmi_is_localhost(uri) and \
+ path != "/wsman" and \
+ not username and not password and \
+ not cert_file and not key_file
if HAVE_LMIWBEM:
# LMIWBEM
@@ -127,6 +119,7 @@ class LMICIMXMLClient(object):
self.disconnect()
del self._cliconn
+ @lmi_process_cim_exceptions(False)
def connect(self):
"""
Connects to CIMOM.
@@ -135,6 +128,7 @@ class LMICIMXMLClient(object):
"""
if HAVE_LMIWBEM:
self._cliconn.connect()
+ return LMIReturnValue(rval=True)
def disconnect(self):
"""
diff --git a/cli/lmi/shell/LMIConnection.py b/cli/lmi/shell/LMIConnection.py
index f763ff9..7ab9e2c 100644
--- a/cli/lmi/shell/LMIConnection.py
+++ b/cli/lmi/shell/LMIConnection.py
@@ -16,6 +16,7 @@
import os
import sys
import atexit
+import getpass
import readline
import urlparse
@@ -41,6 +42,7 @@ from lmi.shell.LMIExceptions import LMINamespaceNotFound
from lmi.shell.LMIShellLogger import lmi_get_logger
from lmi.shell.LMIUtil import lmi_raise_or_dump_exception
+from lmi.shell.LMIUtil import lmi_is_localhost
logger = lmi_get_logger()
@@ -54,38 +56,34 @@ def __lmi_raw_input(prompt, use_echo=True):
:returns: input string
:raises: :py:exc:`EOFError`
"""
- if not sys.stdout.isatty() and sys.stderr.isatty():
+ if not sys.stderr.isatty() and not sys.stdout.isatty():
+ logger.warn(
+ "Both stdout and stderr are detached from terminal, "
+ "using stdout for prompt")
+ elif not sys.stdout.isatty() and sys.stderr.isatty():
# read the input with prompt printed to stderr
- def get_input(prompt):
- sys.stderr.write(prompt)
- return raw_input()
stream = sys.stderr
else:
# read the input with prompt printed to stdout
- # NOTE: raw_input uses stdout only if the readline module is imported
- get_input = raw_input
stream = sys.stdout
- if not sys.stderr.isatty() and not sys.stdout.isatty():
- logger.warn(
- "Both stdout and stderr are detached from terminal, "
- "using stdout for prompt")
- if not use_echo:
- os.system("stty -echo")
+
+ # Define input function
+ if use_echo:
+ def get_input(prompt):
+ return raw_input(prompt)
+ else:
+ def get_input(prompt):
+ return getpass.getpass(prompt, stream)
+
try:
result = get_input(prompt)
except EOFError, e:
- if not use_echo:
- os.system("stty echo")
stream.write("\n")
return None
except KeyboardInterrupt, e:
- if not use_echo:
- os.system("stty echo")
raise e
- if not use_echo:
- os.system("stty echo")
- stream.write("\n")
- if result:
+
+ if result and use_echo:
cur_hist_len = readline.get_current_history_length()
if cur_hist_len > 1:
readline.remove_history_item(cur_hist_len - 1)
@@ -133,6 +131,30 @@ def connect(uri, username="", password="", interactive=False, use_cache=True,
"""
connection = None
+ if lmi_is_localhost(uri) and \
+ not username and not password and \
+ not cert_file and not key_file:
+ try:
+ # Try to get socket's permissions. If we can talk to TOG-Pegasus,
+ # stat() will return stat buf; OSError will be raised otherwise.
+ os.stat("/var/run/tog-pegasus/cimxml.socket")
+
+ connection = LMIConnection(
+ uri, interactive=interactive, use_cache=use_cache)
+
+ # Verify the connection
+ rval, _, errorstr = connection.connect()
+ if not rval:
+ logger.warning("Can't connect via Unix socket")
+ del connection
+ else:
+ logger.info("Connected via Unix socket")
+ return connection
+ except OSError, e:
+ # It is fine not to do anything here. User will be prompted for
+ # necessary credentials, if necessary.
+ pass
+
if interactive and not key_file and not cert_file:
try:
if not username:
@@ -150,6 +172,7 @@ def connect(uri, username="", password="", interactive=False, use_cache=True,
use_cache=use_cache, key_file=key_file, cert_file=cert_file,
verify_server_cert=verify_server_cert)
+ # Verify the connection
rval, _, errorstr = connection.connect()
if not rval:
@@ -336,9 +359,13 @@ class LMIConnection(object):
error string.
:rtype: :py:class:`LMIReturnValue`
"""
- self._client.connect()
+ # Connect to CIMOM. We may fail before the actual "dummy" request is
+ # sent. This only applies for LMIWBEM.
+ rval, _, errorstr = self._client.connect()
+ if not rval:
+ return LMIReturnValue(rval=False, errorstr=errorstr)
- # Perform "dummy" request to check connection and credentials
+ # Perform "dummy" request to check the connection and credentials.
return self._client.dummy()
def disconnect(self):
diff --git a/cli/lmi/shell/LMIUtil.py b/cli/lmi/shell/LMIUtil.py
index 18ad377..ed59851 100644
--- a/cli/lmi/shell/LMIUtil.py
+++ b/cli/lmi/shell/LMIUtil.py
@@ -23,6 +23,17 @@ from lmi.shell import wbem
from lmi.shell.LMIObjectFactory import LMIObjectFactory
+LOCALHOST_VARIANTS = (
+ "localhost",
+ "localhost.localdomain",
+ "localhost4",
+ "localhost4.localdomain4",
+ "localhost6",
+ "localhost6.localdomain6",
+ "127.0.0.1",
+ "::1",
+)
+
# By default, the LMIShell does not use exceptions; LMIReturnValue
# is used instead (with proper error string).
@@ -488,3 +499,11 @@ def lmi_instance_to_path(instance):
return instance.wrapped_object
raise TypeError(
"instance has to be wbem.CIMInstance(Name) or LMIInstance(Name)")
+
+def lmi_is_localhost(uri):
+ """
+ Helper function, which returns True, if URI points to localhost.
+
+ :param str uri: URI to check
+ """
+ return uri in LOCALHOST_VARIANTS