from .cfg_app import PpCfgAppError, PpConfigApplication
-__version__ = '0.3.2'
+__version__ = '0.3.4'
LOG = logging.getLogger(__name__)
# =============================================================================
class PpLdapApplication(PpConfigApplication):
"""
- Class for configured application objects.
+ Class for a LDAP based configured application objects.
"""
default_ldap_hosts = [
cfg_encoding=cfg_encoding, need_config_file=need_config_file,
)
- pass
-
# -------------------------------------------------------------------------
def perform_config(self):
-
"""
Execute some actions after reading the configuration.
"""
got_host = False
- for section in self.cfg.keys():
+ for section_name in self.cfg.keys():
- if not section.lower() == 'ldap':
+ if not section_name.lower() == 'ldap':
continue
- ldap_section = self.cfg[section]
+ ldap_section = self.cfg[section_name]
+ if self.verbose > 2:
+ LOG.debug("Evaluating config section {n!r}:\n{s}".format(
+ n=section_name, s=pp(ldap_section)))
+
if 'host' in ldap_section:
hosts = self.fs_re.split(ldap_section['host'])
port = int(ldap_section['port'])
except (ValueError, TypeError) as e:
msg = "Invalid LDAP port ({s}/port => {v!r}) found in configuration.".format(
- s=section, v=ldap_section['port'])
+ s=section_name, v=ldap_section['port'])
raise PpLdapAppError(msg)
if port <= 0 or port >= 2 ** 16:
msg = "Invalid LDAP port ({s}/port => {v!r}) found in configuration.".format(
- s=section, v=port)
+ s=section_name, v=port)
raise PpLdapAppError(msg)
self.ldap_port = port
timeout = int(ldap_section['timeout'])
except (ValueError, TypeError) as e:
msg = "Invalid LDAP timeout ({s}/port => {v!r}) found in configuration.".format(
- s=section, v=ldap_section['timeout'])
+ s=section_name, v=ldap_section['timeout'])
LOG.error(msg)
if timeout > 0:
self.ldap_timeout = timeout
MUST be overwritten by descendant classes.
"""
-
- LOG.debug("Executing something ...")
-
- query_filter = (
- '(&'
- '(objectclass=posixAccount)'
- '(objectclass=shadowAccount)'
- '(uid=frank.brehm)'
- ')'
- )
-
- entries = self.ldap_search(query_filter)
-
- print("Found {} LDAP entries.".format(len(entries)))
- i = 0
- for entry in entries:
- i += 1
- print("\n{}".format(entry))
- if i >= 5:
- break
+ LOG.debug("Executing nothing ...")
# -------------------------------------------------------------------------
def ldap_search(
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+@author: Frank Brehm
+@contact: frank.brehm@pixelpark.com
+@copyright: © 2017 by Frank Brehm, Berlin
+@summary: The module for the mk-home application object.
+"""
+from __future__ import absolute_import
+
+# Standard modules
+import sys
+import os
+import logging
+import logging.config
+import re
+import traceback
+import textwrap
+import copy
+
+# Third party modules
+import six
+
+import ldap3
+
+# Own modules
+from .global_version import __version__ as __global_version__
+
+from .errors import FunctionNotImplementedError, PpAppError
+
+from .common import pp, terminal_can_colors, to_bytes, to_bool
+
+from .merge import merge_structure
+
+from .ldap_app import PpLdapAppError, PpLdapApplication
+
+__version__ = '0.1.2'
+LOG = logging.getLogger(__name__)
+
+
+# =============================================================================
+class PpMkHomeError(PpLdapAppError):
+ pass
+
+
+# =============================================================================
+class PpMkHomeApp(PpLdapApplication):
+ """Class for the 'mk-home' application to ensure:
+ * existence of HOME directories for all users in LDAP
+ * all LDAP users having a valid numeric UID (different to 999999999)
+ """
+
+ default_initial_uid = 999999999
+ default_chroot_homedir = os.sep + os.path.join('mnt', 'nfs', 'home')
+
+ # -------------------------------------------------------------------------
+ def __init__(self, appname=None, version=__version__):
+
+ self.initial_uid = self.default_initial_uid
+ self.chroot_homedir = self.default_chroot_homedir
+ self.simulate = False
+
+ description = textwrap.dedent('''\
+ Home Directory and UIDNumber generation - this script will search for
+ Unix Accounts in LDAP and generate the HomeDirectory for Users if it
+ dosen't exists. Also it looks for accounts with the special
+ UIDNumber {} and generate an new for them.
+ ''').strip().format(self.default_initial_uid)
+
+ super(PpMkHomeApp, self).__init__(
+ appname=appname, version=version, description=description,
+ cfg_stems='mk-home'
+ )
+
+ self.initialized = True
+
+ # -------------------------------------------------------------------------
+ def init_arg_parser(self):
+ """
+ Method to initiate the argument parser.
+
+ This method should be explicitely called by all init_arg_parser()
+ methods in descendant classes.
+ """
+
+ super(PpMkHomeApp, self).init_arg_parser()
+
+ self.arg_parser.add_argument(
+ "-s", "--simulate",
+ action='store_true',
+ dest='simulate',
+ help="Simulation af all actions, nothing is really done."
+ )
+
+ # -------------------------------------------------------------------------
+ def perform_arg_parser(self):
+ """
+ Public available method to execute some actions after parsing
+ the command line parameters.
+
+ Descendant classes may override this method.
+ """
+
+ super(PpMkHomeApp, self).perform_arg_parser()
+
+ if self.args.simulate:
+ self.simulate = True
+
+ # -------------------------------------------------------------------------
+ def perform_config(self):
+
+ super(PpMkHomeApp, self).perform_config()
+
+ for section_name in self.cfg.keys():
+
+ if self.verbose > 2:
+ LOG.debug("Checking config section {!r} ...".format(section_name))
+
+ if section_name.lower() not in ('mk-home', 'mk_home', 'mkhome') :
+ continue
+
+ section = self.cfg[section_name]
+ if self.verbose > 2:
+ LOG.debug("Evaluating config section {n!r}:\n{s}".format(
+ n=section_name, s=pp(section)))
+
+ if 'initial_uid' in section:
+ v = section['initial_uid']
+ try:
+ uid = int(v)
+ except (ValueError, TypeError) as e:
+ msg = (
+ "Invalid initial numeric user Id ([{s}]/initial_uid "
+ "=> {v!r}) found in configuration.").format(s=section_name, v=v)
+ raise PpMkHomeError(msg)
+ if uid <= 0:
+ msg = (
+ "Invalid initial numeric user Id ([{s}]/initial_uid "
+ "=> {v!r}) found in configuration.").format(s=section_name, v=v)
+ raise PpMkHomeError(msg)
+ self.initial_uid = uid
+
+ if 'chroot_homedir' in section:
+ v = section['chroot_homedir']
+ if not os.path.isabs(v):
+ msg = (
+ "The chrooted path of the home directories must be an "
+ "absolute pathname (found [{s}]/chroot_homedir "
+ "=> {v!r} in configuration.").format(s=section_name, v=v)
+ raise PpMkHomeError(msg)
+ self.chroot_homedir = v
+
+ # -------------------------------------------------------------------------
+ def pre_run(self):
+ """
+ Dummy function to run before the main routine.
+ Could be overwritten by descendant classes.
+
+ """
+
+ super(PpMkHomeApp, self).pre_run()
+ if os.geteuid():
+ msg = "Only root may execute this application."
+ LOG.error(msg)
+ self.exit(1)
+
+ if not os.path.exists(self.chroot_homedir):
+ msg = "The chrooted path of the home directories {!r} does not exists.".format(
+ self.chroot_homedir)
+ LOG.error(msg)
+ self.exit(1)
+
+ if not os.path.isdir(self.chroot_homedir):
+ msg = "The chrooted path of the home directories {!r} is not a directory.".format(
+ self.chroot_homedir)
+ LOG.error(msg)
+ self.exit(1)
+
+ # -------------------------------------------------------------------------
+ def _run(self):
+
+ LOG.debug("Executing something ...")
+
+ query_filter = (
+ '(&'
+ '(objectclass=posixAccount)'
+ '(objectclass=shadowAccount)'
+ '(uid=frank.brehm)'
+ ')'
+ )
+
+ entries = self.ldap_search(query_filter)
+
+ print("Found {} LDAP entries.".format(len(entries)))
+ i = 0
+ for entry in entries:
+ i += 1
+ print("\n{}".format(entry))
+ if i >= 5:
+ break
+
+
+# =============================================================================
+
+if __name__ == "__main__":
+
+ pass
+
+# =============================================================================
+
+# vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 list