diff --git a/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/modules/univention/admincli/admin.py b/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/modules/univention/admincli/admin.py index 1607760..b87c5e6 100755 --- a/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/modules/univention/admincli/admin.py +++ b/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/modules/univention/admincli/admin.py @@ -30,1067 +30,1119 @@ # /usr/share/common-licenses/AGPL-3; if not, see # . - +from argparse import ArgumentParser +from textwrap import dedent +import sys import getopt import re -import string import base64 import os import subprocess import traceback -import univention.debug +import univention.debug as ud -import univention.admin.uexceptions +import univention.admin.uexceptions as uex import univention.admin.uldap import univention.admin.modules import univention.admin.objects -from univention.admin.layout import Tab, Group -import univention.config_registry +from univention.admin.layout import Group +from univention.config_registry import ConfigRegistry import univention.admin.ipaddress + univention.admin.modules.update() # update choices-lists which are defined in LDAP univention.admin.syntax.update_choices() -# usage information -def usage(): - out=[] - out.append('univention-directory-manager: command line interface for managing UCS') - out.append('copyright (c) 2001-@%@copyright_lastyear@%@ Univention GmbH, Germany') - out.append('') - out.append('Syntax:') - out.append(' univention-directory-manager module action [options]') - out.append(' univention-directory-manager [--help] [--version]') - out.append('') - out.append('actions:') - out.append(' %-32s %s' % ('create:', 'Create a new object')) - out.append(' %-32s %s' % ('modify:', 'Modify an existing object')) - out.append(' %-32s %s' % ('remove:', 'Remove an existing object')) - out.append(' %-32s %s' % ('list:', 'List objects')) - out.append(' %-32s %s' % ('move:', 'Move object in directory tree')) - out.append('') - out.append(' %-32s %s' % ('-h | --help | -?:', 'print this usage message')) - out.append(' %-32s %s' % ('--version:', 'print version information')) - out.append('') - out.append('general options:') - out.append(' --%-30s %s' % ('logfile', 'path and name of the logfile to be used')) - out.append('') - out.append('create options:') - out.append(' --%-30s %s' % ('binddn', 'bind DN')) - out.append(' --%-30s %s' % ('bindpwd', 'bind password')) - out.append(' --%-30s %s' % ('bindpwdfile', 'file containing bind password')) - out.append(' --%-30s %s' % ('position', 'Set position in tree')) - out.append(' --%-30s %s' % ('set', 'Set variable to value, e.g. foo=bar')) - out.append(' --%-30s %s' % ('superordinate', 'Use superordinate module')) - out.append(' --%-30s %s' % ('option', 'Use only given module options')) - out.append(' --%-30s %s' % ('customattribute', 'Set custom attribute foo=bar')) - out.append(' --%-30s %s' % ('policy-reference', 'Reference to policy given by DN')) - out.append(' --%-30s %s' % ('tls', '0 (no); 1 (try); 2 (must)')) - out.append(' --%-30s ' % ('ignore_exists')) - out.append('') - out.append('modify options:') - out.append(' --%-30s %s' % ('binddn', 'bind DN')) - out.append(' --%-30s %s' % ('bindpwd', 'bind password')) - out.append(' --%-30s %s' % ('bindpwdfile', 'file containing bind password')) - out.append(' --%-30s %s' % ('dn', 'Edit object with DN')) - out.append(' --%-30s %s' % ('arg', 'Edit object with ARG')) - out.append(' --%-30s %s' % ('set', 'Set variable to value, e.g. foo=bar')) - out.append(' --%-30s %s' % ('append', 'Append value to variable, e.g. foo=bar')) - out.append(' --%-30s %s' % ('remove', 'Remove value from variable, e.g. foo=bar')) - out.append(' --%-30s %s' % ('option', 'Use only given module options')) - out.append(' --%-30s %s' % ('append-option', 'Append the module options')) - out.append(' --%-30s %s' % ('customattribute', 'Set custom attribute foo=bar')) - out.append(' --%-30s %s' % ('customattribute-remove', 'Remove custom attribute')) - out.append(' --%-30s %s' % ('policy-reference', 'Reference to policy given by DN')) - out.append(' --%-30s %s' % ('policy-dereference', 'Remove reference to policy given by DN')) - out.append(' --%-30s %s' % ('tls', '0 (no); 1 (try); 2 (must)')) - out.append('') - out.append('remove options:') - out.append(' --%-30s %s' % ('binddn', 'bind DN')) - out.append(' --%-30s %s' % ('bindpwd', 'bind password')) - out.append(' --%-30s %s' % ('bindpwdfile', 'file containing bind password')) - out.append(' --%-30s %s' % ('dn', 'Remove object with DN')) - out.append(' --%-30s %s' % ('superordinate', 'Use superordinate module')) - out.append(' --%-30s %s' % ('arg', 'Remove object with ARG')) - out.append(' --%-30s %s' % ('filter', 'Lookup filter e.g. foo=bar')) - out.append(' --%-30s %s' % ('tls', '0 (no); 1 (try); 2 (must)')) - out.append(' --%-30s %s' % ('remove_referring', 'remove referring objects')) - out.append('') - out.append('list options:') - out.append(' --%-30s %s' % ('filter', 'Lookup filter e.g. foo=bar')) - out.append(' --%-30s %s' % ('policies', 'List policy-based settings:')) - out.append(' %-30s %s' % ('', '0:short, 1:long (with policy-DN)')) - out.append('') - out.append('move options:') - out.append(' --%-30s %s' % ('binddn', 'bind DN')) - out.append(' --%-30s %s' % ('bindpwd', 'bind password')) - out.append(' --%-30s %s' % ('bindpwdfile', 'file containing bind password')) - out.append(' --%-30s %s' % ('dn', 'Move object with DN')) - out.append(' --%-30s %s' % ('position', 'Move to position in tree')) - out.append('') - out.append('Description:') - out.append(' univention-directory-manager is a tool to handle the configuration for UCS') - out.append(' on command line level.') - out.append(' Use "univention-directory-manager modules" for a list of available modules.') - out.append('') - return out - -def version(): - o=[] - o.append('univention-directory-manager @%@package_version@%@') - return o - -def _print_property( module, action, name, output ): - property = module.property_descriptions.get( name ) + +class Failed(Exception): + def __str__(self): + return "OPERATION FAILED" + + +def parse_commandline(): + usage = dedent("""\ + %(prog)s module action [arguments] + %(prog)s [--help] [--version] + """) + description = dedent("""\ + univention-directory-manager is a tool to handle the configuration for UCS + on command line level. + Use "univention-directory-manager modules" for a list of available modules. + """) + version = "%(prog)s @%@package_version@%@" + parser = ArgumentParser( + usage=usage, + description=description, + prog="univention-directory-manager") + parser.add_argument("-?", action="help") + parser.add_argument("--version", action="version", version=version) + + general_opt = parser.add_argument_group("General options") + general_opt.add_argument( + "--logfile", + dest="logfile", + default='/var/log/univention/directory-manager-cmd.log', + help="path and name of the logfile to be used") + general_opt.add_argument( + "--binddn", + dest="binddn", + help="bind DN") + general_opt.add_argument( + "--bindpwd", + dest="bindpwd", + help="bind password") + general_opt.add_argument( + "--bindpwdfile", + dest="bindpwdfile", + help="file containing bind password") + general_opt.add_argument( + "--tls", + dest="tls", type=int, + default=2, choices=range(3), + help="0 (no); 1 (try); 2 (must)") + + subparsers = parser.add_subparsers( + title="sub-commands", + description="valid subcommands", + help="additional help") + + create_opt = subparsers.add_parser("modules", help="List available modules") + + create_opt = subparsers.add_parser("create", help="Create a new object") + create_opt.add_argument( + "--position", + dest="position", + help="Set position in tree") + create_opt.add_argument( + "--set", + action="append", dest="set", required=True, + help="Set variable to value, e.g. foo=bar") + create_opt.add_argument( + "--superordinate", + dest="superordinate", + help="Use superordinate module") + create_opt.add_argument( + "--option", + action="append", dest="option", + help="Use only given module options") + create_opt.add_argument( + "--policy-reference", + action="append", dest="policy_reference", + help="Reference to policy given by DN") + create_opt.add_argument( + "--ignore_exists", + action="store_true", dest="ignore_exists", + help="Ignore already existing object") + + modify_opt = subparsers.add_parser("modify", help="Modify an existing object") + modify_opt.add_argument( + "--dn", + dest="dn", required=True, + help="Edit object with DN") + modify_opt.add_argument( + "--set", + action="append", dest="set", + help="Set variable to value, e.g. foo=bar") + modify_opt.add_argument( + "--append", + action="append", dest="append", + help="Append value to variable, e.g. foo=bar") + modify_opt.add_argument( + "--remove", + action="append", dest="remove", + help="Remove value from variable, e.g. foo=bar") + modify_opt.add_argument( + "--option", + action="append", dest="option", + help="Append the module options") + modify_opt.add_argument( + "--policy-reference", + action="append", dest="policy_reference", + help="Reference to policy given by DN") + modify_opt.add_argument( + "--policy-dereference", + action="append", dest="policy_dereference", + help="Remove reference to policy given by DN") + + remove_opt = subparsers.add_parser("remove", help="Remove an existing object") + remove_opt.add_argument( + "--dn", + dest="dn", + help="Remove object with DN") + remove_opt.add_argument( + "--superordinate", + dest="superordinate", + help="Use superordinate module") + remove_opt.add_argument( + "--filter", + dest="filter", + help="Lookup filter e.g. foo=bar") + remove_opt.add_argument( + "--remove_referring", + action="store_true", dest="remove_referring", + help="Remove referring objects") + + list_opt = subparsers.add_parser("list", help="List objects") + list_opt.add_argument( + "--filter", + dest="filter", + help="Lookup filter e.g. foo=bar") + list_opt.add_argument( + "--policies", + dest="policies", type=int, choices=range(2), + help="List policy-based settings: 0:short, 1:long (with policy-DN)") + + move_opt = subparsers.add_parser("move", help="Move object in directory tree") + move_opt.add_argument( + "--dn", + dest="dn", required=True, + help="Move object with DN") + move_opt.add_argument( + "--position", + dest="position", required=True, + help="Move to position in tree") + + args = parser.parse_args() + return args + + +def usage(out=sys.stdout): + print >> out, dedent("""\ + %(prog)s command line interface for managing UCS + copyright (c) 2001-%(year)s Univention GmbH, Germany + + Syntax: + %(prog)s module action [options] + %(prog)s [--help] [--version] + + actions: + create: Create a new object + modify: Modify an existing object + remove: Remove an existing object + list: List objects + move: Move object in directory tree + + -h | --help | -?: Print this usage message + --version: Print version information + + general options: + --logfile Path and name of the logfile to be used + --binddn Bind DN + --bindpwd Bind password + --bindpwdfile file containing bind password + --tls 0 (no); 1 (try); 2 (must) + + create options: + --position Set position in tree + --set Set variable to value, e.g. foo=bar + --superordinate Use superordinate module + --option Use only given module options + --policy-reference Reference to policy given by DN + --ignore_exists + + modify options: + --dn Edit object with DN + --set Set variable to value, e.g. foo=bar + --append Append value to variable, e.g. foo=bar + --remove Remove value from variable, e.g. foo=bar + --option Use only given module options + --append-option Append the module options + --policy-reference Reference to policy given by DN + --policy-dereference Remove reference to policy given by DN + + remove options: + --dn Remove object with DN + --superordinate Use superordinate module + --filter Lookup filter e.g. foo=bar + --remove_referring Remove referring objects + + list options: + --filter Lookup filter e.g. foo=bar + --policies List policy-based settings: + 0:short, 1:long (with policy-DN) + + move options: + --dn Move object with DN + --position Move to position in tree + + Description: + %(prog)s is a tool to handle the configuration for UCS + on command line level. + Use "%(prog)s modules" for a list of available modules. + """) % { + "prog": "univention-directory-manager", + "year": "@%@copyright_lastyear@%@", + } + + +def version(out=sys.stdout): + print >> out, 'univention-directory-manager @%@package_version@%@' + + +def _print_property(module, action, name, out=sys.stdout): + property = module.property_descriptions.get(name) if property is None: - output.append( 'E: unknown property %s of module %s' % ( name, univention.admin.modules.name( module ) ) ) + print >> out, 'E: unknown property %s of module %s' % ( + name, + univention.admin.modules.name(module), + ) return required = { - 'create' : False, - 'modify' : False, - 'remove' : False, + 'create': False, + 'modify': False, + 'remove': False, 'editable': True, - } + } if property.required: - required [ 'create' ] = True + required['create'] = True if property.identifies: - required[ 'modify' ] = True - required[ 'remove' ] = True + required['modify'] = True + required['remove'] = True if not property.editable: - required[ 'modify' ] = False - required[ 'remove' ] = False - required[ 'editable' ] = False + required['modify'] = False + required['remove'] = False + required['editable'] = False - flags = '' - if action in required and required[ action ]: - flags='*' + flags = [] + if action in required and required[action]: + flags.append('*') elif not action in required: - if required[ 'create' ]: - flags += 'c' - if required[ 'modify' ]: - flags += 'm' - if required[ 'remove' ]: - flags += 'r' - if not required[ 'editable' ]: - flags += 'e' + if required['create']: + flags.append('c') + if required['modify']: + flags.append('m') + if required['remove']: + flags.append('r') + if not required['editable']: + flags.append('e') + if flags: + flags = [''.join(flags)] if property.options: - if flags: - flags += ',' - flags += ','.join(property.options) + flags.extend(property.options) if property.multivalue: - if flags: - flags += ',' - flags += '[]' + flags.append('[]') if flags: - flags = '(' + flags + ')' + name += ' (%s)' % (','.join(flags),) + + print >> out, ' %-40s %s' % ( + name, + property.short_description + ) - output.append( ' %-40s %s' % ( name + ' ' + flags, property.short_description ) ) -def module_usage(information, action=''): - out=[] +def module_usage(information, action='', out=sys.stdout): for module, l in information.items(): properties, options = l if options: - out.append('') - out.append('%s options:' % module.module) + print >> out, '' + print >> out, '%s options:' % module.module for name, option in options.items(): - out.append(' %-32s %s' % (name, option.short_description)) + print >> out, ' %-32s %s' % (name, option.short_description) - out.append('') - out.append('%s variables:' % module.module) + print >> out, '' + print >> out, '%s variables:' % module.module - if not hasattr(module,"layout"): + if not hasattr(module, "layout"): continue for moduletab in module.layout: - out.append(' %s:' % (moduletab.label)) + print >> out, ' %s:' % (moduletab.label) for row in moduletab.layout: - if isinstance( row, Group ): - out.append( ' %s' % row.label ) + if isinstance(row, Group): + print >> out, ' %s' % row.label for row in row.layout: - if isinstance( row, basestring ): - _print_property( module, action, row, out ) + if isinstance(row, basestring): + _print_property(module, action, row, out) continue for item in row: - _print_property( module, action, item, out ) + _print_property(module, action, item, out) else: - if isinstance( row, basestring ): - _print_property( module, action, row, out ) + if isinstance(row, basestring): + _print_property(module, action, row, out) continue for item in row: - _print_property( module, action, item, out ) + _print_property(module, action, item, out) - return out -def module_information(module, identifies_only=0): - information={module:[{},{}]} - if 'superordinate' in dir(module) and module.superordinate: - superordinate=univention.admin.modules.get(module.superordinate) - information.update(module_information(superordinate, identifies_only=1)) +def module_information(module, identifies_only=False): + information = { + module: [{}, {}], + } + if getattr(module, 'superordinate', None): + superordinate = univention.admin.modules.get(module.superordinate) + information.update(module_information(superordinate, identifies_only=True)) if not identifies_only: for name, property in module.property_descriptions.items(): - information[module][0][name]=property - if hasattr(module,'options'): + information[module][0][name] = property + if hasattr(module, 'options'): for name, option in module.options.items(): - information[module][1][name]=option + information[module][1][name] = option return information -def _2utf8( text ): + +def _2utf8(text): try: - return text.encode( 'utf-8' ) - except: - return text.decode( 'iso-8859-1' ) + return text.encode('utf-8') + except UnicodeError: + return text.decode('iso-8859-1') + -def object_input(module, object, input, append=None, remove=None): - out=[] +def object_input(module, object, input, append=None, remove=None, out=sys.stdout): if append: for key, value in append.items(): if module.property_descriptions[key].syntax.name == 'file': if os.path.exists(value): - fh = open(value, 'r') - content='' - for line in fh.readlines(): - content += line - object[key] = content - fh.close() + with open(value, 'r') as fh: + object[key] = fh.read() else: - out.append('WARNING: file not found: %s' % value) + print >> out, 'WARNING: file not found: %s' % value - elif univention.admin.syntax.is_syntax( module.property_descriptions[key].syntax, univention.admin.syntax.complex ): - for i in range(0,len(value)): - test_val=value[i].split('"') - if test_val[0] and test_val[0] == value[i]: - val=value[i].split(' ') + elif univention.admin.syntax.is_syntax(module.property_descriptions[key].syntax, univention.admin.syntax.complex): + for i in value: + test_val = i.split('"') + if test_val[0] and test_val[0] == i: + val = i.split(' ') else: - val=[] + val = [] for j in test_val: - if j and j.rstrip().lstrip(): - val.append(j.rstrip().lstrip()) - - if not object.has_key(key): - object[key]=[] - if val in object[key]: - out.append('WARNING: cannot append %s to %s, value exists'%(val,key)) - elif object[key] == [''] or object[key] == []: - object[key]=[val] + if j and j.strip(): + val.append(j.strip()) + + values = object.setdefault(key, []) + if val in values: + print >> out, 'WARNING: cannot append %s to %s, value exists' % (val, key) + elif values == [''] or values == []: + values[:] = [val] else: - object[key].append(val) + values.append(val) else: for val in value: - if val in object[key]: - out.append('WARNING: cannot append %s to %s, value exists'%(val,key)) - elif object[key] == [''] or object[key] == []: - object[key]=[val] + values = object[key] + if val in values: + print >> out, 'WARNING: cannot append %s to %s, value exists' % (val, key) + elif values == [''] or values == []: + values[:] = [val] else: try: - tmp = list(object[key]) + tmp = list(values) tmp.append(val) object[key] = list(tmp) - except univention.admin.uexceptions.valueInvalidSyntax, errmsg: - out.append('E: Invalid Syntax: %s' % str(errmsg)) + except uex.valueInvalidSyntax, errmsg: + print >> out, 'E: Invalid Syntax: %s' % (errmsg,) if remove: for key, value in remove.items(): - if univention.admin.syntax.is_syntax( module.property_descriptions[key].syntax, univention.admin.syntax.complex ): + if univention.admin.syntax.is_syntax(module.property_descriptions[key].syntax, univention.admin.syntax.complex): if value: - for i in range(0,len(value)): - test_val=value[i].split('"') - if test_val[0] and test_val[0] == value[i]: - val=value[i].split(' ') + for i in value: + test_val = i.split('"') + if test_val[0] and test_val[0] == i: + val = i.split(' ') else: - val=[] - out.append('test_val=%s' % test_val) + val = [] + print >> out, 'test_val=%s' % (test_val,) for j in test_val: - if j and j.rstrip().lstrip(): - val.append(j.rstrip().lstrip()) + j = j.strip() + if j: + val.append(j) - for j in range(0,len(val)): - val[j]='"%s"' % val[j] + val = ['"%s"' % _ for _ in val] if val and val in object[key]: object[key].remove(val) else: - out.append("WARNING: cannot remove %s from %s, value does not exist"%(val,key)) + print >> out, "WARNING: cannot remove %s from %s, value does not exist" % (val, key) else: - object[key]=[] + object[key] = [] else: - if type(object[key]) is str: - object[key] = [ object[key] ] + if isinstance(object[key], basestring): + object[key] = [object[key]] vallist = value - if type(value) is str: - vallist = [ value ] + if isinstance(value, basestring): + vallist = [value] for val in vallist: if val in object[key]: object[key].remove(val) else: - out.append("WARNING: cannot remove %s from %s, value does not exist"%(val,key)) + print >> out, "WARNING: cannot remove %s from %s, value does not exist" % (val, key) if input: for key, value in input.items(): if module.property_descriptions[key].syntax.name == 'binaryfile': if value == '': - object[key]=value + object[key] = value elif os.path.exists(value): fh = open(value, 'r') - content=fh.read() + content = fh.read() if "----BEGIN CERTIFICATE-----" in content: - content = content.replace('----BEGIN CERTIFICATE-----','') - content = content.replace('----END CERTIFICATE-----','') - object[key]=base64.decodestring(content) + content = content.replace('----BEGIN CERTIFICATE-----', '') + content = content.replace('----END CERTIFICATE-----', '') + object[key] = base64.decodestring(content) else: - object[key]= content + object[key] = content fh.close() else: - out.append('WARNING: file not found: %s' % value) + print >> out, 'WARNING: file not found: %s' % value - elif univention.admin.syntax.is_syntax( module.property_descriptions[key].syntax, univention.admin.syntax.complex ): - if type(value) == type([]): - for i in range(0,len(value)): - test_val=value[i].split('"') + elif univention.admin.syntax.is_syntax(module.property_descriptions[key].syntax, univention.admin.syntax.complex): + if isinstance(value, list): + for i in value: + test_val = i.split('"') if test_val[0] and test_val[0] == value[i]: - val=value[i].split(' ') + val = value[i].split(' ') else: - val=[] + val = [] for j in test_val: - if j and j.rstrip().lstrip(): - val.append(j.rstrip().lstrip()) + j = j.strip() + if j: + val.append(j) else: - val=value.split(' ') + val = value.split(' ') if module.property_descriptions[key].multivalue: - object[key]=[val] + object[key] = [val] else: - object[key]=val + object[key] = val else: try: - object[key]=value - except univention.admin.uexceptions.ipOverridesNetwork, e: - out.append('WARNING: %s' % e.message) - except univention.admin.uexceptions.valueMayNotChange, e: - raise univention.admin.uexceptions.valueMayNotChange, "%s: %s"%(e.message, key) - return out - -def list_available_modules(o=[]): - - o.append("Available Modules are:") - avail_modules = [] - for mod in univention.admin.modules.modules.keys(): - avail_modules.append(mod) + object[key] = value + except uex.ipOverridesNetwork, ex: + print >> out, 'WARNING: %s' % ex.message + except uex.valueMayNotChange, ex: + raise uex.valueMayNotChange, "%s: %s" % (ex.message, key) + + +def list_available_modules(out=sys.stdout): + print >> out, "Available Modules are:" + avail_modules = univention.admin.modules.modules.keys() avail_modules.sort() for mod in avail_modules: - o.append(" %s"%mod) - return o + print >> out, " %s" % mod + -def doit(arglist): - out=[] +def doit(arglist, out=sys.stdout): try: - out=_doit(arglist) - except univention.admin.uexceptions.base, e: - univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, traceback.format_exc()) + _doit(arglist, out) + except uex.base, ex: + ud.debug(ud.ADMIN, ud.WARN, traceback.format_exc()) # collect error information msg = [] - if getattr(e, 'message', None): - msg.append(e.message) - if getattr(e, 'args', None): + if getattr(ex, 'message', None): + msg.append(ex.message) + if getattr(ex, 'args', None): #avoid duplicate messages - if not len(msg) or len(e.args) > 1 or e.args[0] != msg[0]: - msg.extend(e.args) + if not len(msg) or len(ex.args) > 1 or ex.args[0] != msg[0]: + msg.extend(ex.args) # strip elements and make sure that a ':' is printed iff further information follows - msg = [i.strip() for i in msg] + msg = [_.strip() for _ in msg] if len(msg) == 1: msg[0] = '%s.' % msg[0].strip(':.') elif len(msg) > 1: msg[0] = '%s:' % msg[0].strip(':.') # append to the output - out.append(' '.join(msg)) - return out + ["OPERATION FAILED"] - return out + print >> out, ' '.join(msg) + print >> out, Failed() + except Failed as ex: + print >> out, ex + + +def get_policy(dn, out=sys.stdout, policyOptions=None, policies_with_DN=False): + cmd = ['univention_policy_result'] + if policyOptions: + cmd.extend(policyOptions) + cmd.append(dn) + + policy = attribute = '' + value = [] + client = {} + + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) + for line in proc.stdout: + line = line.strip() + if not line or line.startswith("DN: ") or line.startswith("POLICY "): + continue + + print >> out, " %s" % line + if policies_with_DN: + key, val = line.split(': ', 1) + if key == 'Policy': + if attribute and policy: + client[attribute] = [policy, value] + value = [] + policy = val + elif key == 'Attribute': + attribute = val + elif key == 'Value': + value.append(val) + else: + key, val = line.split('=', 1) + client.setdefault(key, []).append(val) + proc.wait() + if policies_with_DN and attribute and policy: + client[attribute] = [policy, value] + + return client -def _doit(arglist): - out=[] +def _doit(arglist, out=sys.stdout): # parse module and action - if len(arglist) < 2: - return usage() + ["OPERATION FAILED"] + if set(arglist) & set(('-h', '--help', '-?')): + return usage(out=out) - module_name=arglist[1] - if module_name in ['-h', '--help', '-?']: - return usage() + if '--version' in arglist: + return version(out=out) - if module_name == '--version': - return version() + if len(arglist) < 2: + usage(out=out) + raise Failed() + module_name = arglist[1] if module_name == 'modules': - return list_available_modules() + return list_available_modules(out=out) - remove_referring=0 - recursive=1 + remove_referring = False + recursive = True # BUG: if this is the default, there's no way to disable it # parse options - longopts=['position=', 'dn=', 'arg=', 'set=', 'append=', 'remove=', 'superordinate=', 'option=', 'append-option=', 'filter=', 'tls=', 'ignore_exists', 'logfile=', 'policies=', 'binddn=', 'bindpwd=', 'bindpwdfile=', 'customattribute=', 'customattribute-remove=','policy-reference=','policy-dereference=','remove_referring','recursive'] + longopts = [ + 'position=', + 'dn=', + 'set=', + 'append=', + 'remove=', + 'superordinate=', + 'option=', + 'append-option=', + 'filter=', + 'tls=', + 'ignore_exists', + 'logfile=', + 'policies=', + 'binddn=', + 'bindpwd=', + 'bindpwdfile=', + 'policy-reference=', + 'policy-dereference=', + 'remove_referring', + 'recursive', + ] try: - opts, args=getopt.getopt(arglist[3:], '', longopts) + opts, args = getopt.getopt(arglist[3:], '', longopts) except getopt.error, msg: - out.append(str(msg)) - return out + ["OPERATION FAILED"] - - if not args == [] and type(args) == type([]): - msg = "WARNING: the following arguments are ignored:" - for argument in args: - msg = '%s "%s"' % (msg, argument) - out.append(msg) - - position_dn='' - dn='' - arg=None - binddn=None - bindpwd=None - list_policies=False - policies_with_DN=False - policyOptions=[] - logfile='/var/log/univention/directory-manager-cmd.log' - tls=2 - ignore_exists=0 - superordinate_dn='' - parsed_append_options=[] - parsed_options=[] - filter='' - input={} - append={} - remove={} - customattribute={} - customattribute_remove=[] - policy_reference=[] - policy_dereference=[] + print >> out, msg + raise Failed() + + if isinstance(args, list) and args: + print >> out, "WARNING: the following arguments are ignored: %s" % ( + " ".join(('"%s"' % _ for _ in args)), + ) + + position_dn = '' + dn = '' + binddn = None + bindpwd = None + list_policies = False + policies_with_DN = False + policyOptions = [] + logfile = '/var/log/univention/directory-manager-cmd.log' + tls = 2 + ignore_exists = False + superordinate_dn = '' + parsed_append_options = [] + parsed_options = [] + filter = '' + input = {} + append = {} + remove = {} + policy_reference = [] + policy_dereference = [] for opt, val in opts: if opt == '--position': - position_dn = _2utf8( val ) + position_dn = _2utf8(val) elif opt == '--logfile': - logfile=val + logfile = val elif opt == '--policies': - policies = True - if val=="1": + list_policies = True + if val == "1": policies_with_DN = True else: policyOptions = ['-s'] elif opt == '--binddn': - binddn=val + binddn = val elif opt == '--bindpwd': - bindpwd=val + bindpwd = val elif opt == '--bindpwdfile': try: with open(val) as fp: - bindpwd=fp.read().strip() - except IOError as e: - out.append( 'E: could not read bindpwd from file (%s)' % str(e) ) - return out + ['OPERATION FAILED'] + bindpwd = fp.read().strip() + except IOError as ex: + print >> out, 'E: could not read bindpwd from file (%s)' % (ex,) + raise Failed() elif opt == '--dn': - dn = _2utf8( val ) - elif opt == '--arg': - arg=val + dn = _2utf8(val) elif opt == '--tls': - tls=val + tls = val elif opt == '--ignore_exists': - ignore_exists=1 + ignore_exists = True elif opt == '--superordinate': - superordinate_dn=val + superordinate_dn = val elif opt == '--option': parsed_options.append(val) elif opt == '--append-option': parsed_append_options.append(val) elif opt == '--filter': - filter=val - elif opt == '--customattribute': - pos=val.find('=') - name=val[:pos] - value= _2utf8( val[ pos + 1 : ] ) - if not customattribute.has_key(name): - customattribute[name]=[] - customattribute[name].append(value) - elif opt == '--customattribute-remove': - pos=val.find('=') - if pos == -1: - customattribute_remove.append((val,None)) - else: - name=val[:pos] - value = _2utf8( val[ pos + 1 : ] ) - customattribute_remove.append((name,value)) + filter = val elif opt == '--policy-reference': policy_reference.append(val) elif opt == '--policy-dereference': policy_dereference.append(val) if logfile: - univention.debug.init(logfile, 1, 0) + ud.init(logfile, ud.FLUSH, ud.NO_FUNCTION) else: - out.append("WARNING: no logfile specified") + print >> out, "WARNING: no logfile specified" - configRegistry=univention.config_registry.ConfigRegistry() + configRegistry = ConfigRegistry() configRegistry.load() - if configRegistry.has_key('ldap/master') and configRegistry['ldap/master']: - co=univention.admin.config.config(configRegistry['ldap/master']) + if configRegistry.get('ldap/master'): + co = univention.admin.config.config(configRegistry['ldap/master']) else: - co=univention.admin.config.config() + co = univention.admin.config.config() - baseDN=configRegistry['ldap/base'] - - if configRegistry.has_key('directory/manager/cmd/debug/level'): - debug_level=configRegistry['directory/manager/cmd/debug/level'] - else: - debug_level=0 + baseDN = configRegistry['ldap/base'] - univention.debug.set_level(univention.debug.LDAP, int(debug_level)) - univention.debug.set_level(univention.debug.ADMIN, int(debug_level)) + debug_level = int(configRegistry.get('directory/manager/cmd/debug/level', 0)) + ud.set_level(ud.LDAP, debug_level) + ud.set_level(ud.ADMIN, debug_level) if binddn and bindpwd: - univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, "using %s account" % binddn) + ud.debug(ud.ADMIN, ud.INFO, "using %s account" % binddn) try: - lo=univention.admin.uldap.access(host=configRegistry['ldap/master'], port=int(configRegistry.get('ldap/master/port', '7389')), base=baseDN, binddn=binddn, start_tls=tls, bindpw=bindpwd) - except Exception, e: - univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'authentication error: %s' % str(e)) - out.append('authentication error: %s' % str(e)) - return out + ["OPERATION FAILED"] - policyOptions.extend(['-D', binddn, '-w', bindpwd]) ## FIXME not so nice + lo = univention.admin.uldap.access( + host=configRegistry['ldap/master'], + port=int(configRegistry.get('ldap/master/port', 7389)), + base=baseDN, + binddn=binddn, + start_tls=tls, + bindpw=bindpwd + ) + except Exception, ex: + ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % (ex,)) + print >> out, 'authentication error: %s' % (ex,) + raise Failed() + policyOptions.extend(['-D', binddn, '-w', bindpwd]) # FIXME not so nice else: - if os.path.exists('/etc/ldap.secret'): - univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, "using cn=admin,%s account" % baseDN) - secretFileName='/etc/ldap.secret' - binddn='cn=admin,'+baseDN - policyOptions.extend(['-D', binddn, '-y', secretFileName]) - elif os.path.exists('/etc/machine.secret'): - univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, "using %s account" % configRegistry['ldap/hostdn']) - secretFileName='/etc/machine.secret' - binddn=configRegistry['ldap/hostdn'] - policyOptions.extend(['-D', binddn, '-y', secretFileName]) + for binddn, secretFileName in ( + ('cn=admin,' + baseDN, '/etc/ldap.secret'), + (configRegistry['ldap/hostdn'], '/etc/machine.secret'), + ): + if os.path.exists(secretFileName): + break + else: + return ["E: Missing LDAP credentials"] + FAILED + ud.debug(ud.ADMIN, ud.INFO, "using %s account" % binddn) + policyOptions.extend(['-D', binddn, '-y', secretFileName]) try: - secretFile=open(secretFileName,'r') + secretFile = open(secretFileName, 'r') except IOError: - out.append('E: Permission denied, try --binddn and --bindpwd') - return out + ["OPERATION FAILED"] - pwdLine=secretFile.readline() - pwd=re.sub('\n','',pwdLine) + print >> out, 'E: Permission denied, try --binddn and --bindpwd' + raise Failed() + pwdLine = secretFile.readline() + pwd = re.sub('\n', '', pwdLine) try: - lo=univention.admin.uldap.access(host=configRegistry['ldap/master'], port=int(configRegistry.get('ldap/master/port', '7389')), base=baseDN, binddn=binddn, bindpw=pwd, start_tls=tls) - except Exception, e: - univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'authentication error: %s' % str(e)) - out.append('authentication error: %s' % str(e)) - return out + ["OPERATION FAILED"] + lo = univention.admin.uldap.access( + host=configRegistry['ldap/master'], + port=int(configRegistry.get('ldap/master/port', '7389')), + base=baseDN, + binddn=binddn, + bindpw=pwd, + start_tls=tls + ) + except Exception, ex: + ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % (ex,)) + print >> out, 'authentication error: %s' % (ex,) + raise Failed() if not position_dn and superordinate_dn: - position_dn=superordinate_dn + position_dn = superordinate_dn elif not position_dn: - position_dn=baseDN + position_dn = baseDN try: - position=univention.admin.uldap.position(baseDN) + position = univention.admin.uldap.position(baseDN) position.setDn(position_dn) - except univention.admin.uexceptions.noObject: - out.append('E: Invalid position') - return out + ["OPERATION FAILED"] + except uex.noObject: + print >> out, 'E: Invalid position' + raise Failed() try: - module=univention.admin.modules.get(module_name) + module = univention.admin.modules.get(module_name) except: - out.append("failed to get module %s."%module_name) - out.append("") - return list_available_modules(out) + ["OPERATION FAILED"] + print >> out, "failed to get module %s." % module_name + print >> out, "" + list_available_modules(out) + raise Failed() if not module: - out.append("unknown module %s." % module_name) - out.append("") - return list_available_modules(out) + ["OPERATION FAILED"] + print >> out, "unknown module %s." % module_name + print >> out, "" + list_available_modules(out) + raise Failed() # initialise modules - univention.admin.modules.init(lo,position,module) + univention.admin.modules.init(lo, position, module) - information=module_information(module) + information = module_information(module) if superordinate_dn and univention.admin.modules.superordinate(module): try: - superordinate=univention.admin.objects.get(univention.admin.modules.superordinate(module), co, lo, '', dn=superordinate_dn) - except univention.admin.uexceptions.insufficientInformation, e: - out.append('Insufficient Information: %s' % str(e)) - return out + ["OPERATION FAILED"] + superordinate = univention.admin.objects.get(univention.admin.modules.superordinate(module), co, lo, '', dn=superordinate_dn) + except uex.insufficientInformation, ex: + print >> out, 'Insufficient Information: %s' % (ex,) + raise Failed() else: - superordinate=None - + superordinate = None if len(arglist) == 2: - out = usage() + module_usage(information) - return out + ["OPERATION FAILED"] + module_usage(information, out=out) + raise Failed() - action=arglist[2] + action = arglist[2] if len(arglist) == 3 and action != 'list': - out = usage() + module_usage(information, action) - return out + ["OPERATION FAILED"] - + module_usage(information, action, out=out) + raise Failed() for opt, val in opts: if opt == '--set': - pos=val.find('=') - name=val[:pos] - value = _2utf8( val[ pos + 1 : ] ) - - was_set=0 - for mod, (properties,options) in information.items(): - if properties.has_key(name): + name, value = val.split('=', 1) + value = _2utf8(value) + for mod, (properties, options) in information.items(): + if name in properties: if properties[name].multivalue: - if not input.has_key(name): - input[name]=[] - was_set=1 - if value: - input[name].append(value) - was_set=1 + input.setdefault(name, []).append(value) else: - input[name]=value - was_set=1 + input[name] = value + break + else: + print >> out, "WARNING: No attribute with name '%s' in this module, value not set." % name - if not was_set: - out.append("WARNING: No attribute with name '%s' in this module, value not set."%name) elif opt == '--append': - pos=val.find('=') - name=val[:pos] - value = _2utf8( val[ pos + 1 : ] ) - was_set=0 - for mod, (properties,options) in information.items(): - if properties.has_key(name): + name, value = val.split('=', 1) + value = _2utf8(value) + for mod, (properties, options) in information.items(): + if name in properties: if properties[name].multivalue: - if not append.has_key(name): - append[name]=[] + values = append.setdefault(name, []) if value: - append[name].append(value) - was_set=1 + values.append(value) else: - append[name]=value - was_set=1 - if not was_set: - out.append("WARNING: No attribute with name %s in this module, value not appended."%name) + append[name] = value + break + else: + print >> out, "WARNING: No attribute with name %s in this module, value not appended." % name elif opt == '--remove': - pos=val.find('=') - if pos == -1: - name=val - value=None - else: - name=val[:pos] - value = _2utf8( val[ pos + 1 : ] ) - was_set=0 - for mod, (properties,options) in information.items(): - if properties.has_key(name): + try: + name, value = val.split('=', 1) + value = _2utf8(value) + except ValueError: + name, value = val, None + for mod, (properties, options) in information.items(): + if name in properties: if properties[name].multivalue: - if not remove.has_key(name): - remove[name]=[] + values = remove.setdefault(name, []) if value: - remove[name].append(value) - was_set=1 + values.append(value) else: - remove[name]=value - was_set=1 - if not was_set: - out.append("WARNING: No attribute with name %s in this module, value not removed."%name) + remove[name] = value + break + else: + print >> out, "WARNING: No attribute with name %s in this module, value not removed." % name + elif opt == '--remove_referring': - remove_referring=1 + remove_referring = True + elif opt == '--recursive': - recursive=1 - - - extraOC=[] - extraAttributes=[] - customattributes_set =[] - if hasattr(module, 'ldap_extra_objectclasses') and action in ['modify','edit','create','new']: - for oc, pname, syntax, ldapMapping, deleteValues, deleteObjectClass in module.ldap_extra_objectclasses: - if customattribute.has_key(module.property_descriptions[pname].short_description): - customattributes_set.append(module.property_descriptions[pname].short_description) - extraOC.append(oc); - # check multivalue - if module.property_descriptions[pname].multivalue: - if action in ['create','new'] or not dn or dn == '': - values_found=[] - else: - values_found=lo.search(base=dn, attr=[ldapMapping]) - for i in customattribute[module.property_descriptions[pname].short_description]: - value_already_set=0 - for tmp,val in values_found: - if val.has_key(ldapMapping): - if i in val[ldapMapping]: - value_already_set=1 - if value_already_set: - out.append('WARNING: customattribute %s is already set to %s'%(module.property_descriptions[pname].short_description,i)) - else: - extraAttributes.append((ldapMapping,'',[i])) - else: - if len(customattribute[module.property_descriptions[pname].short_description])>1: - out.append('WARNING: cannot set singlevalue customattribute "%s" with more than one entry'%module.property_descriptions[pname].short_description) - else: - replaced=0 - if action in ['create','new'] or not dn or dn == '': - values_found=[] - else: - values_found=lo.search(base=dn, attr=[ldapMapping]) - for tmp,val in values_found: - if val.has_key(ldapMapping): - extraAttributes.append((ldapMapping,val[ldapMapping][0],[customattribute[module.property_descriptions[pname].short_description][0]])) - replaced = 1 - if len(val[ldapMapping]) > 1: - out.append("WARNING: singlevalue customattribute %s has more than one value set, replace first"%customattribute[module.property_descriptions[pname].short_description]) - if not replaced: - extraAttributes.append((ldapMapping,'',[customattribute[module.property_descriptions[pname].short_description][0]])) - - if action in ['modify','edit','create','new']: - for i in customattribute.keys(): - if not i in customattributes_set: - out.append("WARNING: customattribute %s not found, value not set"%i) + recursive = True + + if action in ('modify', 'edit', 'create', 'new'): + for el in policy_reference: + oc = lo.get(el, ['objectClass']) + if not oc: + print >> out, "Object to be referenced does not exist: %s" % (el,) + raise Failed() + if not 'univentionPolicy' in oc['objectClass']: + print >> out, "Object to be referenced is no valid Policy: %s" % (el,) + raise Failed() + + #+++# ACTION CREATE #+++# + if action in ('create', 'new'): + if getattr(module, 'operations', None): + if not 'add' in module.operations: + print >> out, 'Create %s not allowed' % module_name + raise Failed() + try: + object = module.object(co, lo, position=position, superordinate=superordinate) + except uex.insufficientInformation: + print >> out, 'E: Insufficient information' + print >> out, 'Superordinate object is missing' + raise Failed() - if policy_reference: - for el in policy_reference: - oc = lo.get(el,['objectClass']) - if not oc: - out.append("Object to be referenced does not exist:"+el) - return out + ["OPERATION FAILED"] - if not 'univentionPolicy' in oc['objectClass']: - out.append("Object to be referenced is no valid Policy:"+el) - return out + ["OPERATION FAILED"] - - -#+++# ACTION CREATE #+++# - if action == 'create' or action == 'new': - if hasattr(module,'operations') and module.operations: - if not 'add' in module.operations: - out.append('Create %s not allowed' % module_name) - return out + ["OPERATION FAILED"] - try: - object=module.object(co, lo, position=position, superordinate=superordinate) - except univention.admin.uexceptions.insufficientInformation: - out.append('E: Insufficient information') - out.append('Superordinate object is missing') - return out + ["OPERATION FAILED"] - - if parsed_options: - object.options=parsed_options - - object.open() - if hasattr(object,' open_warning') and object.open_warning: - out.append('WAR NING:%s'%object.open_warning) - exists=0 - try: - out.extend(object_input(module, object, input, append=append)) - except univention.admin.uexceptions.nextFreeIp: - if not ignore_exists: - out.append('E: No free IP address found') - return out + ['OPERATION FAILED'] - except univention.admin.uexceptions.valueInvalidSyntax, err: - out.append('E: Invalid Syntax: %s' % err) - return out + ["OPERATION FAILED"] - except Exception, err: - out.append('E: Option %s is not valid' %err) - return out + ['OPERATION FAILED'] - - exists=0 - exists_msg=None - try: - dn=object.create() - except univention.admin.uexceptions.objectExists, dn: - exists_msg = dn - if not ignore_exists: - out.append('E: Object exists: %s' % exists_msg) - return out + ["OPERATION FAILED"] - else: - exists=1 - except univention.admin.uexceptions.uidAlreadyUsed, user: - exists_msg = '(uid) %s' % user - if not ignore_exists: - out.append('E: Object exists: %s' % exists_msg) - return out + ["OPERATION FAILED"] - else: - exists=1 - except univention.admin.uexceptions.groupNameAlreadyUsed, group: - exists_msg = '(group) %s' % group - if not ignore_exists: - out.append('E: Object exists: %s' % exists_msg) - return out + ["OPERATION FAILED"] - else: - exists=1 - except univention.admin.uexceptions.dhcpServerAlreadyUsed, name: - exists_msg = '(dhcpserver) %s' % name - if not ignore_exists: - out.append('E: Object exists: %s' % exists_msg) - return out + ["OPERATION FAILED"] - else: - exists=1 - except univention.admin.uexceptions.macAlreadyUsed, mac: - exists_msg = '(mac) %s' % mac - if not ignore_exists: - out.append('E: Object exists: %s' % exists_msg) - return out + ["OPERATION FAILED"] - else: - exists=1 - except univention.admin.uexceptions.noLock, e: - exists_msg = '(nolock) %s' % str(e) - if not ignore_exists: - out.append('E: Object exists: %s' % exists_msg) - return out + ["OPERATION FAILED"] - else: - exists=1 - except univention.admin.uexceptions.invalidDhcpEntry: - out.append('E: The DHCP entry for this host should contain the zone dn, the ip address and the mac address.') - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.invalidOptions, e: - if not ignore_exists: - out.append('E: invalid Options: %s' % e) - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.insufficientInformation: - out.append('E: Insufficient information') - out.append('The following parameters are missing:') - for i in module.property_descriptions: - property=module.property_descriptions.get(i) - if property.required: - if not object.has_key(i) or (not object[i] or (type(object[i]) == list and object[i]==[''])): - out.append(i) - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.noObject, e: - out.append('E: object not found: %s' % e) - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.circularGroupDependency, e: - out.append('E: circular group dependency detected: %s' % e) - return out + ["OPERATION FAILED"] - - if extraOC or extraAttributes: - if extraOC: - oc=lo.search(base=dn, scope='base', attr=['objectClass']) - - noc=[] - for i in range(len(oc[0][1]['objectClass'])): - noc.append(oc[0][1]['objectClass'][i]) - - for i in range(len(extraOC)): - if extraOC[i] not in noc: - noc.append(extraOC[i]) - - if oc != noc: - extraAttributes.append(('objectClass',oc,noc)) - - if extraAttributes: - lo.modify(dn,extraAttributes) + if parsed_options: + object.options = parsed_options - if policy_reference: - lo.modify(dn,[('objectClass','','univentionPolicyReference')]) - modlist=[] - for el in policy_reference: - modlist.append(('univentionPolicyReference','',el)) - lo.modify(dn,modlist) + object.open() + if getattr(object, 'open_warning', None): + print >> out, 'WARNING:%s' % object.open_warning + try: + object_input(module, object, input, append=append, out=out) + except uex.nextFreeIp: + if not ignore_exists: + print >> out, 'E: No free IP address found' + raise Failed() + except uex.valueInvalidSyntax, ex: + print >> out, 'E: Invalid Syntax: %s' % ex + raise Failed() + except Exception, ex: + print >> out, 'E: Option %s is not valid' % ex + raise Failed() + + exists = False + exists_msg = None + try: + dn = object.create() + except uex.objectExists, dn: + exists_msg = dn + if not ignore_exists: + print >> out, 'E: Object exists: %s' % exists_msg + raise Failed() + else: + exists = True + except uex.uidAlreadyUsed, user: + exists_msg = '(uid) %s' % user + if not ignore_exists: + print >> out, 'E: Object exists: %s' % exists_msg + raise Failed() + else: + exists = True + except uex.groupNameAlreadyUsed, group: + exists_msg = '(group) %s' % group + if not ignore_exists: + print >> out, 'E: Object exists: %s' % exists_msg + raise Failed() + else: + exists = True + except uex.dhcpServerAlreadyUsed, name: + exists_msg = '(dhcpserver) %s' % name + if not ignore_exists: + print >> out, 'E: Object exists: %s' % exists_msg + raise Failed() + else: + exists = True + except uex.macAlreadyUsed, mac: + exists_msg = '(mac) %s' % mac + if not ignore_exists: + print >> out, 'E: Object exists: %s' % exists_msg + raise Failed() + else: + exists = True + except uex.noLock, ex: + exists_msg = '(nolock) %s' % (ex,) + if not ignore_exists: + print >> out, 'E: Object exists: %s' % exists_msg + raise Failed() + else: + exists = True + except uex.invalidDhcpEntry: + print >> out, 'E: The DHCP entry for this host should contain the zone dn, the ip address and the mac address.' + raise Failed() + except uex.invalidOptions, ex: + if not ignore_exists: + print >> out, 'E: invalid Options: %s' % ex + raise Failed() + except uex.insufficientInformation: + print >> out, 'E: Insufficient information' + print >> out, 'The following parameters are missing:' + for i in module.property_descriptions: + property = module.property_descriptions.get(i) + if property.required: + if i not in object or (not object[i] or (isinstance(object[i], list) and object[i] == [''])): + print >> out, i + raise Failed() + except uex.noObject, ex: + print >> out, 'E: object not found: %s' % ex + raise Failed() + except uex.circularGroupDependency, ex: + print >> out, 'E: circular group dependency detected: %s' % ex + raise Failed() - if exists == 1: - if exists_msg: - out.append('Object exists: %s' % exists_msg) - else: - out.append('Object exists') + if policy_reference: + lo.modify(dn, [('objectClass', '', 'univentionPolicyReference')]) + modlist = [('univentionPolicyReference', '', el) for el in policy_reference] + lo.modify(dn, modlist) + + if exists: + if exists_msg: + print >> out, 'Object exists: %s' % exists_msg else: - if not dn: - dn=object.dn - out.append('Object created: %s' % _2utf8( dn ) ) + print >> out, 'Object exists' + else: + if not dn: + dn = object.dn + print >> out, 'Object created: %s' % _2utf8(dn) -#+++# ACTION MODIFY #+++# + #+++# ACTION MODIFY #+++# elif action == 'modify' or action == 'edit' or action == 'move': if not dn: - out.append('E: DN is missing') - return out + ["OPERATION FAILED"] + print >> out, 'E: DN is missing' + raise Failed() object_modified = 0 - if hasattr(module,'operations') and module.operations: + if getattr(module, 'operations', None): if not 'edit' in module.operations: - out.append('Modify %s not allowed' % module_name) - return out + ["OPERATION FAILED"] + print >> out, 'Modify %s not allowed' % module_name + raise Failed() try: - object=univention.admin.objects.get(module, co, lo, position='', dn=dn) - except univention.admin.uexceptions.noObject: - out.append('E: object not found') - return out + ["OPERATION FAILED"] + object = univention.admin.objects.get(module, co, lo, position='', dn=dn) + except uex.noObject: + print >> out, 'E: object not found' + raise Failed() object.open() - if hasattr(object,'open_warning') and object.open_warning: - out.append('WARNING:%s'%object.open_warning) + if getattr(object, 'open_warning', None): + print >> out, 'WARNING:%s' % object.open_warning if action == 'move': - if hasattr(module,'operations') and module.operations: + if getattr(module, 'operations', None): if not 'move' in module.operations: - out.append('Move %s not allowed' % module_name) - return out + ["OPERATION FAILED"] + print >> out, 'Move %s not allowed' % module_name + raise Failed() if not position_dn: - out.append("need new position for moving object") + print >> out, "need new position for moving object" else: - res = '' - try: # check if goal-position exists + try: # check if global-position exists res = lo.get(position_dn) except: - pass + res = '' if not res: - out.append("position does not exsist: %s"%position_dn) - return out + ["OPERATION FAILED"] - rdn = dn[:string.find(dn,',')] - newdn="%s,%s" % (rdn,position_dn) + print >> out, "position does not exsist: %s" % position_dn + raise Failed() + rdn, _old_base = dn.split(',', 1) + newdn = "%s,%s" % (rdn, position_dn) try: object.move(newdn) - object_modified+=1 - except univention.admin.uexceptions.noObject: - out.append('E: object not found') - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.ldapError, msg: - out.append("ldap Error: %s"%msg) - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.nextFreeIp: - out.append('E: No free IP address found') - return out + ['OPERATION FAILED'] - except univention.admin.uexceptions.valueInvalidSyntax, err: - out.append('E: Invalid Syntax: %s' % err) - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.invalidOperation, msg: - out.append(str(msg)) - return out + ["OPERATION FAILED"] - - else: # modify - - if (len(input)+len(append)+len(remove)+len(parsed_append_options)+len(parsed_options))>0: + object_modified += 1 + except uex.noObject: + print >> out, 'E: object not found' + raise Failed() + except uex.ldapError, msg: + print >> out, "ldap Error: %s" % msg + raise Failed() + except uex.nextFreeIp: + print >> out, 'E: No free IP address found' + raise Failed() + except uex.valueInvalidSyntax, err: + print >> out, 'E: Invalid Syntax: %s' % err + raise Failed() + except uex.invalidOperation, msg: + print >> out, str(msg) + raise Failed() + + else: # modify + if any((input, append, remove, parsed_append_options, parsed_options)): if parsed_options: - object.options=parsed_options + object.options = parsed_options if parsed_append_options: for option in parsed_append_options: object.options.append(option) try: - out.extend(object_input(module, object, input, append, remove)) - except univention.admin.uexceptions.valueMayNotChange,e: - out.append(unicode(e[0])) - return out + ["OPERATION FAILED"] + object_input(module, object, input, append, remove, out=out) + except uex.valueMayNotChange, ex: + print >> out, unicode(ex[0]) + raise Failed() if object.hasChanged(input.keys()) or object.hasChanged(append.keys()) or object.hasChanged(remove.keys()) or parsed_append_options or parsed_options: try: - dn=object.modify() - object_modified+=1 - except univention.admin.uexceptions.noObject: - out.append('E: object not found') - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.invalidDhcpEntry: - out.append('E: The DHCP entry for this host should contain the zone dn, the ip address and the mac address.') - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.circularGroupDependency, e: - out.append('E: circular group dependency detected: %s' % e) - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.valueInvalidSyntax, e: - out.append('E: Invalid Syntax: %s' % e) - return out + ["OPERATION FAILED"] - - if extraOC or extraAttributes: - if extraOC: - oc=lo.search(base=dn, scope='base', attr=['objectClass']) - - noc=[] - for i in range(len(oc[0][1]['objectClass'])): - noc.append(oc[0][1]['objectClass'][i]) - - for i in range(len(extraOC)): - if not extraOC[i] in noc: - noc.append(extraOC[i]) - - if noc != oc[0][1]['objectClass']: - extraAttributes.append(('objectClass',oc[0][1]['objectClass'],noc)) - if extraAttributes: - try: - lo.modify(dn,extraAttributes) - object_modified+=1 - except univention.admin.uexceptions.ldapError, msg: - out.append("ldap Error: %s"%msg) - - if customattribute_remove: - extraAttributes=[] - removed_attributes=[] - if hasattr(module, 'ldap_extra_objectclasses'): - for oc, pname, syntax, ldapMapping, deleteValues, deleteObjectClass in module.ldap_extra_objectclasses: - for index in range(0,len(customattribute_remove)): - if customattribute_remove[index][0] == module.property_descriptions[pname].short_description: - for tmp,val in lo.search(base=dn, attr=[ldapMapping]): - if val.has_key(ldapMapping): - for i in range(0, len(val[ldapMapping])): - if (not customattribute_remove[index][1]) or customattribute_remove[index][1] == val[ldapMapping][i]: - extraAttributes.append((ldapMapping,val[ldapMapping][i],'')) - removed_attributes.append(module.property_descriptions[pname].short_description) - else: - out.append("customattribute %s not set"%module.property_descriptions[pname].short_description) - removed_attributes.append(module.property_descriptions[pname].short_description) - - if extraAttributes: - lo.modify(dn,extraAttributes) - object_modified+=1 - - for n,v in customattribute_remove: - if not n in removed_attributes: - out.append("WARNING: customattribute %s not found"%n) + dn = object.modify() + object_modified += 1 + except uex.noObject: + print >> out, 'E: object not found' + raise Failed() + except uex.invalidDhcpEntry: + print >> out, 'E: The DHCP entry for this host should contain the zone dn, the ip address and the mac address.' + raise Failed() + except uex.circularGroupDependency, ex: + print >> out, 'E: circular group dependency detected: %s' % ex + raise Failed() + except uex.valueInvalidSyntax, ex: + print >> out, 'E: Invalid Syntax: %s' % ex + raise Failed() if policy_reference: - if 'univentionPolicyReference' not in lo.get(dn,['objectClass'])['objectClass']: - lo.modify(dn,[('objectClass','','univentionPolicyReference')]) - object_modified+=1 - modlist=[] + if 'univentionPolicyReference' not in lo.get(dn, ['objectClass'])['objectClass']: + lo.modify(dn, [('objectClass', '', 'univentionPolicyReference')]) + object_modified += 1 + modlist = [] upr = lo.search(base=dn, scope='base', attr=['univentionPolicyReference'])[0][1] - if not upr.has_key('univentionPolicyReference'): + if 'univentionPolicyReference' not in upr: upr['univentionPolicyReference'] = [] for el in policy_reference: if val in upr['univentionPolicyReference']: - out.append('WARNING: cannot append %s to univentionPolicyReference, value exists' % val) + print >> out, 'WARNING: cannot append %s to univentionPolicyReference, value exists' % val else: - modlist.append(('univentionPolicyReference','',el)) + modlist.append(('univentionPolicyReference', '', el)) if modlist: - lo.modify(dn,modlist) - object_modified+=1 + lo.modify(dn, modlist) + object_modified += 1 if policy_dereference: - modlist=[] - for el in policy_dereference: - modlist.append(('univentionPolicyReference',el,'')) - lo.modify(dn,modlist) - object_modified+=1 + modlist = [('univentionPolicyReference', el, '') for el in policy_dereference] + lo.modify(dn, modlist) + object_modified += 1 if object_modified > 0: - out.append( 'Object modified: %s'% _2utf8( dn ) ) + print >> out, 'Object modified: %s' % _2utf8(dn) else: - out.append( 'No modification: %s'% _2utf8( dn ) ) + print >> out, 'No modification: %s' % _2utf8(dn) elif action == 'remove' or action == 'delete': - - if hasattr(module,'operations') and module.operations: + if getattr(module, 'operations', None): if not 'remove' in module.operations: - out.append('Remove %s not allowed' % module_name) - return out + ["OPERATION FAILED"] + print >> out, 'Remove %s not allowed' % module_name + raise Failed() try: if dn and filter: - object=univention.admin.modules.lookup(module, co, lo, scope='sub', superordinate=superordinate, base=dn, filter=filter, required=1, unique=1)[0] + object = univention.admin.modules.lookup(module, co, lo, scope='sub', superordinate=superordinate, base=dn, filter=filter, required=1, unique=1)[0] elif dn: - object=univention.admin.modules.lookup(module, co, lo, scope='base', superordinate=superordinate, base=dn, filter=filter, required=1, unique=1)[0] + object = univention.admin.modules.lookup(module, co, lo, scope='base', superordinate=superordinate, base=dn, filter=filter, required=1, unique=1)[0] elif filter: - object=univention.admin.modules.lookup(module, co, lo, scope='sub', superordinate=superordinate, base=position.getDn(), filter=filter, required=1, unique=1)[0] + object = univention.admin.modules.lookup(module, co, lo, scope='sub', superordinate=superordinate, base=position.getDn(), filter=filter, required=1, unique=1)[0] else: - out.append('E: dn or filter needed') - return out + ["OPERATION FAILED"] - except (univention.admin.uexceptions.noObject, IndexError): - out.append('E: object not found') - return out + ["OPERATION FAILED"] + print >> out, 'E: dn or filter needed' + raise Failed() + except (uex.noObject, IndexError): + print >> out, 'E: object not found' + raise Failed() object.open() - if hasattr(object,'open_warning') and object.open_warning: - out.append('WARNING:%s'%object.open_warning) + if getattr(object, 'open_warning', None): + print >> out, 'WARNING:%s' % object.open_warning if remove_referring and univention.admin.objects.wantsCleanup(object): univention.admin.objects.performCleanup(object) @@ -1098,159 +1150,103 @@ def _doit(arglist): if recursive: try: object.remove(recursive) - except univention.admin.uexceptions.ldapError,msg: - out.append(str(msg)) - return out + ["OPERATION FAILED"] + except uex.ldapError, msg: + print >> out, str(msg) + raise Failed() else: try: object.remove() - except univention.admin.uexceptions.primaryGroupUsed: - out.append('E: object in use') - return out + ["OPERATION FAILED"] - out.append( 'Object removed: %s'% _2utf8( dn ) ) + except uex.primaryGroupUsed: + print >> out, 'E: object in use' + raise Failed() + print >> out, 'Object removed: %s' % _2utf8(dn) elif action == 'list' or action == 'lookup': - - if hasattr(module,'operations') and module.operations: + if getattr(module, 'operations', None): if not 'search' in module.operations: - out.append('Search %s not allowed' % module_name) - return out + ["OPERATION FAILED"] + print >> out, 'Search %s not allowed' % module_name + raise Failed() - out.append( _2utf8( filter ) ) + print >> out, _2utf8(filter) try: for object in univention.admin.modules.lookup(module, co, lo, scope='sub', superordinate=superordinate, base=position.getDn(), filter=filter): - out.append( 'DN: %s' % _2utf8( univention.admin.objects.dn (object ) ) ) - out.append( 'ARG: %s' % univention.admin.objects.arg( object ) ) + print >> out, 'DN: %s' % _2utf8(univention.admin.objects.dn(object)) - if (hasattr(module,'virtual') and not module.virtual) or not hasattr(module,'virtual'): + if not getattr(module, 'virtual', None): object.open() - if hasattr(object,'open_warning') and object.open_warning: - out.append('WARNING: %s'%object.open_warning) + if getattr(object, 'open_warning', None): + print >> out, 'WARNING: %s' % object.open_warning for key, value in object.items(): - s=module.property_descriptions[key].syntax + s = module.property_descriptions[key].syntax if module.property_descriptions[key].multivalue: for v in value: if s.tostring(v): - out.append(' %s: %s' % ( _2utf8( key ), _2utf8( s.tostring( v ) ) ) ) + print >> out, ' %s: %s' % (_2utf8(key), _2utf8(s.tostring(v))) else: - out.append(' %s: %s' % ( _2utf8( key ), None ) ) + print >> out, ' %s: %s' % (_2utf8(key), None) else: if s.tostring(value): - out.append(' %s: %s' % ( _2utf8( key ), _2utf8( s.tostring( value ) ) ) ) + print >> out, ' %s: %s' % (_2utf8(key), _2utf8(s.tostring(value))) else: - out.append(' %s: %s' % ( _2utf8( key ), None ) ) + print >> out, ' %s: %s' % (_2utf8(key), None) - if 'univentionPolicyReference' in lo.get(univention.admin.objects.dn(object),['objectClass'])['objectClass']: - references = lo.get( _2utf8(univention.admin.objects.dn( object ) ), - [ 'univentionPolicyReference' ] ) + if 'univentionPolicyReference' in lo.get(univention.admin.objects.dn(object), ['objectClass'])['objectClass']: + references = lo.get( + _2utf8(univention.admin.objects.dn(object)), + ['univentionPolicyReference'] + ) if references: for el in references['univentionPolicyReference']: - out.append(' %s: %s' % ( 'univentionPolicyReference', - _2utf8( s.tostring( el ) ) ) ) + print >> out, ' %s: %s' % ( + 'univentionPolicyReference', + _2utf8(s.tostring(el)) + ) if list_policies: - utf8_objectdn = _2utf8( univention.admin.objects.dn( object ) ) - p1 = subprocess.Popen(['univention_policy_result'] + policyOptions + [utf8_objectdn], stdout=subprocess.PIPE) - policyResults = p1.communicate()[0].split('\n') - - out.append(" Policy-based Settings:") - policy='' - value=[] - client={} - for line in policyResults: - if not (line.strip() == "" or line.strip()[:4]=="DN: " or line.strip()[:7]=="POLICY "): - out.append(" %s"%line.strip()) - if policies_with_DN: - clsplit=string.split(line.strip(), ': ') - if clsplit[0] == 'Policy': - if policy: - client[attribute]=[policy, value] - value=[] - policy=clsplit[1] - elif clsplit[0] == 'Attribute': - attribute=clsplit[1] - elif clsplit[0] == 'Value': - value.append(clsplit[1]) - else: - clsplit=string.split(line.strip(), '=') - if not client.has_key(clsplit[0]): - client[clsplit[0]] = [] - client[clsplit[0]].append(clsplit[1]) - - if policies_with_DN: - client[attribute]=[policy, value] - value=[] - - out.append('') + utf8_objectdn = _2utf8(univention.admin.objects.dn(object)) + client = get_policy(utf8_objectdn, out, policyOptions, policies_with_DN) + print >> out, '' if module_name == 'dhcp/host': - subnet_module=univention.admin.modules.get('dhcp/subnet') - for subnet in univention.admin.modules.lookup(subnet_module, co, lo, scope='sub', superordinate=superordinate, base='', filter=''): - - if univention.admin.ipaddress.ip_is_in_network(subnet['subnet'], subnet['subnetmask'], object['fixedaddress'][0]): - utf8_subnet_dn = _2utf8( subnet.dn ) - p1 = subprocess.Popen(['univention_policy_result'] + policyOptions + [utf8_subnet_dn], stdout=subprocess.PIPE) - policyResults = p1.communicate()[0].split('\n') - out.append(" Subnet-based Settings:") - ddict={} - policy='' - value=[] - for line in policyResults: - if not (line.strip() == "" or line.strip()[:4]=="DN: " or line.strip()[:7]=="POLICY "): - out.append(" %s"%line.strip()) - if policies_with_DN: - subsplit=string.split(line.strip(), ': ') - if subsplit[0] == 'Policy': - if policy: - ddict[attribute]=[policy, value] - value=[] - policy=subsplit[1] - elif subsplit[0] == 'Attribute': - attribute=subsplit[1] - elif subsplit[0] == 'Value': - value.append(subsplit[1]) - else: - subsplit=string.split(line.strip(), '=') - if not ddict.has_key(subsplit[0]): - ddict[subsplit[0]] = [] - ddict[subsplit[0]].append(subsplit[1]) - - out.append('') - - if policies_with_DN: - ddict[attribute]=[policy, value] - value=[] - - out.append(" Merged Settings:") - - for key in ddict.keys(): - if not client.has_key(key): - client[key]=ddict[key] - - if policies_with_DN: - for key in client.keys(): - out.append(" Policy: "+client[key][0]) - out.append(" Attribute: "+key) - for i in range(0, len(client[key][1])): - out.append(" Value: "+client[key][1][i]) - else: - for key in client.keys(): - for i in range(0, len(client[key])): - out.append(" %s=%s" % (key, client[key][i])) - out.append('') - - out.append('') - except univention.admin.uexceptions.ldapError, errmsg: - out.append('%s' %str(errmsg)) - return out + ["OPERATION FAILED"] - except univention.admin.uexceptions.valueInvalidSyntax, errmsg: - out.append('%s' %str(errmsg.message)) - return out + ["OPERATION FAILED"] + subnet_module = univention.admin.modules.get('dhcp/subnet') + for subnet in univention.admin.modules.lookup(subnet_module, co, lo, scope='sub', superordinate=superordinate, base='', filter=''): + if univention.admin.ipaddress.ip_is_in_network(subnet['subnet'], subnet['subnetmask'], object['fixedaddress'][0]): + print >> out, " Subnet-based Settings:" + utf8_subnet_dn = _2utf8(subnet.dn) + ddict = get_policy(utf8_subnet_dn, out, policyOptions, policies_with_DN) + print >> out, '' + + print >> out, " Merged Settings:" + for key, values in ddict.items(): + if key not in client: + client[key] = values + + if policies_with_DN: + for key, (policy, values) in client.items(): + print >> out, " Policy: " + policy + print >> out, " Attribute: " + key + for value in values: + print >> out, " Value: " + value + else: + for key, values in client.items(): + for value in values: + print >> out, " %s=%s" % (key, value) + print >> out, '' + + print >> out, '' + except uex.ldapError, errmsg: + print >> out, '%s' % (errmsg,) + raise Failed() + except uex.valueInvalidSyntax, errmsg: + print >> out, '%s' % (errmsg.message,) + raise Failed() else: - out.append("Unknown or no action defined") - out.append('') - usage() - return out + ["OPERATION FAILED"] + print >> out, "Unknown or no action defined" + print >> out, '' + raise Failed() + - return out # nearly the only successfull return +if __name__ == '__main__': + import sys + doit(sys.argv, sys.stdout) diff --git a/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/univention-cli-server b/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/univention-cli-server index 908bd36..2de2caa 100755 --- a/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/univention-cli-server +++ b/branches/ucs-3.2/ucs-3.2-0/management/univention-directory-manager-modules/univention-cli-server @@ -48,23 +48,23 @@ try: licenseImportError = False except ImportError: licenseImportError = True +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO logfile = '' + class MyRequestHandler(SocketServer.BaseRequestHandler): """Handle request on listeneing socket to open new connection.""" def handle(self): ud.debug(ud.ADMIN, ud.INFO, 'daemon [%s] new connection [%s]' % (os.getppid(), os.getpid())) sarglist = '' - while True: + while not sarglist.endswith('\0'): buf = self.request.recv(1024) - if buf[-1] == '\0': - buf = buf[:-1] - sarglist += buf - break - else: - sarglist += buf - doit(sarglist, self.request) + sarglist += buf + doit(sarglist.rstrip('\0'), self.request) ud.debug(ud.ADMIN, ud.INFO, 'daemon [%s] connection closed [%s]' % (os.getppid(), os.getpid())) def finish(self): @@ -75,10 +75,11 @@ class ForkingTCPServer(SocketServer.ForkingTCPServer): """UDM server listening on UNIX socket.""" address_family = socket.AF_UNIX allow_reuse_address = 1 + def server_bind(self): SocketServer.TCPServer.server_bind(self) _host, port = self.socket.getsockname()[:2] - self.server_name = 'localhost' #socket.getfqdn(host) + self.server_name = 'localhost' # socket.getfqdn(host) self.server_port = port @@ -92,7 +93,7 @@ def server_main(): socket_dir = '/tmp/admincli_%s/' % os.getuid() socket_filename = 'sock' - socket_path = (socket_dir+socket_filename) + socket_path = os.path.join(socket_dir, socket_filename) ud.init(logfile, ud.FLUSH, ud.NO_FUNCTION) @@ -105,7 +106,7 @@ def server_main(): os.kill(pid, signal.SIGCONT) except (ValueError, OSError): pid = 0 - if not pid: # no pid found or no server running + if not pid: # no pid found or no server running os.unlink(socket_path) os.unlink(runfilename) os.rmdir(socket_dir) @@ -115,8 +116,8 @@ def server_main(): configRegistry = ConfigRegistry() configRegistry.load() - debug_level = configRegistry.get('directory/manager/cmd/debug/level', 1) - ud.set_level(ud.ADMIN, int(debug_level)) + debug_level = int(configRegistry.get('directory/manager/cmd/debug/level', 1)) + ud.set_level(ud.ADMIN, debug_level) ud.debug(ud.ADMIN, ud.INFO, 'daemon [%s] forked to background' % os.getpid()) try: @@ -129,9 +130,9 @@ def server_main(): else: print >> sys.stderr, 'E: socket directory exists (%s)' % socket_dir - timeout = configRegistry.get('directory/manager/cmd/timeout') + timeout = int(configRegistry.get('directory/manager/cmd/timeout')) if timeout: - if int(timeout) > 2147483647: + if timeout > 2147483647: timeout = 2147483647 else: timeout = 300 @@ -155,13 +156,12 @@ def server_main(): try: while True: - rlist, _wlist, _xlist = select([sock], [], [], float(timeout)) + rlist, _wlist, _xlist = select([sock], [], [], timeout) for handler in rlist: handler.handle_request() if not rlist: ud.debug(ud.ADMIN, ud.INFO, 'daemon [%s] stopped after %s seconds idle' % (os.getpid(), timeout)) sys.exit(0) - finally: os.unlink(socket_path) os.unlink(runfilename) @@ -219,7 +219,10 @@ def doit(sarglist, conn): if cmdfile in ('univention-admin', 'univention-directory-manager', 'udm'): ud.debug(ud.ADMIN, ud.PROCESS, 'daemon [%s] [%s] Calling univention-directory-manager' % (os.getppid(), os.getpid())) ud.debug(ud.ADMIN, ud.ALL, 'daemon [%s] [%s] arglist: %s' % (os.getppid(), os.getpid(), arglist)) - output = univention.admincli.admin.doit(arglist) + stream = StringIO() + univention.admincli.admin.doit(arglist, stream) + value = stream.getvalue() + output = value.splitlines() elif cmdfile == 'univention-passwd': ud.debug(ud.ADMIN, ud.PROCESS, 'daemon [%s] [%s] Calling univention-passwd' % (os.getppid(), os.getpid())) ud.debug(ud.ADMIN, ud.ALL, 'daemon [%s] [%s] arglist: %s' % (os.getppid(), os.getpid(), arglist)) @@ -257,5 +260,6 @@ def main(): else: # parent os.waitpid(pid, os.P_NOWAIT) + if __name__ == "__main__": main()