def main(cls):
     parser = argparse.ArgumentParser(
         prog='python -m univention.admin.rest.server')
     parser.add_argument('-d', '--debug', type=int, default=2)
     args = parser.parse_args()
     ud.init('stdout', ud.FLUSH, ud.NO_FUNCTION)
     ud.set_level(ud.MAIN, args.debug)
     tornado.httpclient.AsyncHTTPClient.configure(
         'tornado.curl_httpclient.CurlAsyncHTTPClient')
     tornado.locale.load_gettext_translations(
         '/usr/share/locale', 'univention-management-console-module-udm')
     cls.start_processes()
     cls.register_signal_handlers()
     app = tornado.web.Application(
         [
             (r'.*', cls),
         ],
         serve_traceback=ucr.is_true(
             'directory/manager/rest/show-tracebacks', True),
     )
     app.listen(
         int(ucr.get('directory/manager/rest/server/port', 9979)),
         ucr.get('directory/manager/rest/server/address', '127.0.0.1'))
     ioloop = tornado.ioloop.IOLoop.instance()
     ioloop.start()
def setup_logging(opt, ucr):
    # type: (Namespace, ConfigRegistry) -> IO[str]
    ud.init(LOGNAME, 0, 0)
    try:
        loglevel = int(ucr.get('update/debug/level', opt.verbose))
    except ValueError:
        loglevel = opt.verbose
    ud.set_level(ud.NETWORK, loglevel)

    if opt.silent:
        global nostdout
        nostdout = True

    return open(LOGNAME, 'a+')
def test_fifo(parse, tmpdir):
    """
	Using a non-seekable file should not crash Python.
	"""
    tmp = tmpdir.join('log')
    os.mkfifo(str(tmp))

    fd = os.open(str(tmp), os.O_RDONLY | os.O_NONBLOCK)
    try:
        ud.init(str(tmp), ud.NO_FLUSH, ud.FUNCTION)
        ud.exit()
        output = os.read(fd, 4096).decode('ascii')
    finally:
        os.close(fd)

    assert [typ for typ, groups in parse(output)] == ['init', 'exit']
def test_stdio(stream, idx, capfd, parse):
    fd = ud.init(stream, ud.NO_FLUSH, ud.FUNCTION)
    assert hasattr(fd, 'write')
    ud.exit()

    output = capfd.readouterr()
    assert [typ for typ, groups in parse(output[idx])] == ['init', 'exit']
def initialize_debug():
    # Use a little hack to determine if univention.debug has been initialized
    # get_level(..) returns always ud.ERROR if univention.debug is not initialized
    oldLevel = ud1.get_level(ud1.ADMIN)
    if oldLevel == ud1.PROCESS:
        ud1.set_level(ud1.ADMIN, ud1.DEBUG)
        is_ready = (ud1.get_level(ud1.ADMIN) == ud1.DEBUG)
    else:
        ud1.set_level(ud1.ADMIN, ud1.PROCESS)
        is_ready = (ud1.get_level(ud1.ADMIN) == ud1.PROCESS)
    if not is_ready:
        ud1.init('/var/log/univention/directory-manager-cmd.log', ud1.FLUSH, 0)
        ud1.set_level(ud1.LDAP, ud1.PROCESS)
        ud1.set_level(ud1.ADMIN, ud1.PROCESS)
    else:
        ud1.set_level(ud1.ADMIN, oldLevel)
def tmplog(tmpdir):
    """
	Setup temporary logging.
	"""
    tmp = tmpdir.ensure('log')
    fd = ud.init(str(tmp), ud.NO_FLUSH, ud.FUNCTION)
    assert hasattr(fd, 'write')

    yield tmp
def doit(arglist):
	ud.init('/var/log/univention/directory-manager-cmd.log', 1, 1)
	out = []
	configRegistry = univention.config_registry.ConfigRegistry()
	configRegistry.load()
	op = 'add'
	scope = 'user'
	cmd = os.path.basename(arglist[0])
	if cmd == 'univention-addgroup':
		scope = 'group'
		op = 'add'
	elif cmd == 'univention-deluser':
		scope = 'user'
		op = 'del'
	elif cmd == 'univention-delgroup':
		scope = 'group'
		op = 'del'
	elif cmd == 'univention-addmachine':
		scope = 'machine'
		op = 'add'
	elif cmd == 'univention-delmachine':
		scope = 'machine'
		op = 'del'
	elif cmd == 'univention-setprimarygroup':
		scope = 'user'
		op = 'primarygroup'

	opts, args = getopt.getopt(arglist[1:], '', ['status-fd=', 'status-fifo='])

	co = None
	try:
		lo, position = univention.admin.uldap.getAdminConnection()
	except Exception, e:
		ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % str(e))
		try:
			lo, position = univention.admin.uldap.getMachineConnection()
		except Exception, e2:
			ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % str(e2))
			out.append('authentication error: %s' % str(e))
			out.append('authentication error: %s' % str(e2))
			return out
def test_close(parse, tmpdir):
    """
	Closing the Python wrapped file should not close the underlying file descriptor.
	"""
    tmp = tmpdir.ensure('log')
    fd = ud.init(str(tmp), ud.NO_FLUSH, ud.FUNCTION)
    fd.close()
    ud.debug(ud.MAIN, ud.ERROR, 'open')
    ud.exit()

    output = tmp.read()
    assert [typ for typ, groups in parse(output)] == ['init', 'msg', 'exit']
Esempio n. 9
0
def doit(arglist):
	ud.init('/var/log/univention/directory-manager-cmd.log', 1, 1)
	out = []
	opts, args = getopt.getopt(arglist[1:], '', ['binddn=', 'pwdfile=', 'user='******'pwd='])

	binddn = None
	pwdfile = None
	user = None
	pwd = None

	for opt, val in opts:
		if opt == '--binddn':
			binddn = val
		elif opt == '--pwdfile':
			pwdfile = val
		elif opt == '--user':
			user = val
		elif opt == '--pwd':
			pwd = val

	ud.set_level(ud.LDAP, ud.ALL)
	ud.set_level(ud.ADMIN, ud.ALL)

	configRegistry = univention.config_registry.ConfigRegistry()
	configRegistry.load()

	baseDN = configRegistry['ldap/base']

	bindpw = open(pwdfile).read()
	if bindpw[-1] == '\n' or bindpw[-1] == '\r':
		bindpw = bindpw[0:-1]

	ud.debug(ud.ADMIN, ud.WARN, 'binddn: %s; bindpwd: *************' % (binddn))
	try:
		lo = univention.admin.uldap.access(host=configRegistry['ldap/master'], port=int(configRegistry.get('ldap/master/port', '7389')), base=baseDN, binddn=binddn, bindpw=bindpw, start_tls=2)
	except Exception, e:
		ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % str(e))
		out.append('authentication error: %s' % e)
		return out
Esempio n. 10
0
def log_init( filename, log_level = 2 ):
	"""Initializes Univention debug.

	:param str filename: The filename just needs to be a relative name. The directory /var/log/univention/ is prepended and the suffix '.log' is appended.
	:param int log_level: log level to use (1-4)
	"""

	if filename[ 0 ] != '/':
		filename = '/var/log/univention/%s.log' % filename
	fd = ud.init( filename, ud.FLUSH, ud.FUNCTION )
	adm = grp.getgrnam( 'adm' )
	os.chown( filename, 0, adm.gr_gid )
	os.chmod( filename, 0640 )
	log_set_level( log_level )

	return fd
Esempio n. 11
0
def log_init(filename, log_level=2):
    """Initializes Univention debug.

	:param str filename: The filename just needs to be a relative name. The directory /var/log/univention/ is prepended and the suffix '.log' is appended.
	:param int log_level: log level to use (1-4)
	"""

    if filename[0] != "/":
        filename = "/var/log/univention/%s.log" % filename
    fd = ud.init(filename, ud.FLUSH, ud.FUNCTION)
    adm = grp.getgrnam("adm")
    os.chown(filename, 0, adm.gr_gid)
    os.chmod(filename, 0640)
    log_set_level(log_level)

    return fd
def log_init(filename, log_level=2, log_pid=None):
    """Initializes Univention debug.

	:param str filename: The filename just needs to be a relative name. The directory /var/log/univention/ is prepended and the suffix '.log' is appended.
	:param int log_level: log level to use (1-4)
	:param bool log_pid: Prefix log message with process ID
	"""

    if filename[0] != '/':
        filename = '/var/log/univention/%s.log' % filename
    fd = ud.init(filename, ud.FLUSH, ud.NO_FUNCTION)
    adm = grp.getgrnam('adm')
    os.chown(filename, 0, adm.gr_gid)
    os.chmod(filename, 0o640)
    log_set_level(log_level)

    global _debug_ready, _log_pid
    _debug_ready = True
    if log_pid is not None:
        _log_pid = log_pid

    return fd
Esempio n. 13
0
        self.assertEqual((server, struct, 'preup', preup_path, 'preup_content'), gen.next())
        self.assertEqual((server, struct, 'postup', postup_path, 'postup_content'), gen.next())
        self.assertRaises(StopIteration, gen.next)

    def test_get_sh_files_bug27149(self):
        """Test preup.sh / postup.sh download for non-architecture component."""
        server = MockUCSHttpServer('server')
        struct = U.UCSRepoPoolNoArch(major=MAJOR, minor=MINOR, part='%s/component' % (PART,), patch='a')
        preup_path = struct.path('preup.sh')
        server.mock_add(preup_path, 'preup_content')
        postup_path = struct.path('postup.sh')
        server.mock_add(postup_path, 'postup_content')
        repo = ((server, struct),)

        gen = U.UniventionUpdater.get_sh_files(repo)

        self.assertEqual((server, struct, 'preup', preup_path, 'preup_content'), gen.next())
        self.assertEqual((server, struct, 'postup', postup_path, 'postup_content'), gen.next())
        self.assertRaises(StopIteration, gen.next)

if __name__ == '__main__':
    if False:
        import univention.debug as ud
        ud.init('stderr', ud.NO_FUNCTION, ud.NO_FLUSH)
        ud.set_level(ud.NETWORK, ud.ALL+1)
    if False:
        import logging
        logging.basicConfig(level=logging.DEBUG)
    unittest.main()
Esempio n. 14
0
        result = self.m.list_local_repositories(end=ver)
        self.assertEqual(len(result), 1)
        self.assertDeepEqual(result, [_ for _ in self.repos if _[1] <= ver and _[2]])

    def test_maintained(self):
        """Test maintained off."""
        result = self.m.list_local_repositories(maintained=False)
        self.assertEqual(len(result), 0)
        self.assertEqual(result, [])

    def test_unmaintained(self):
        """Test unmaintained on."""
        result = self.m.list_local_repositories(unmaintained=True)
        self.assertEqual(len(result), 6)
        # Check sorted by version
        self.assertDeepEqual([_[1] for _ in result], [_[1] for _ in self.repos])
        self.assertDeepEqual(sorted(result), sorted(self.repos))


if __name__ == "__main__":
    if False:
        import univention.debug as ud

        ud.init("stderr", ud.NO_FUNCTION, ud.NO_FLUSH)
        ud.set_level(ud.NETWORK, ud.ALL + 1)
    if False:
        import logging

        logging.basicConfig(level=logging.DEBUG)
    unittest.main()
def _doit(arglist):

	out = []
	# parse module and action
	if len(arglist) < 2:
		return usage() + ["OPERATION FAILED"]

	module_name = arglist[1]
	if module_name in ['-h', '--help', '-?']:
		return usage()

	if module_name == '--version':
		return version()

	if module_name == 'modules':
		return list_available_modules()

	remove_referring = 0
	recursive = 1
	# parse options
	longopts = ['position=', 'dn=', 'set=', 'append=', 'remove=', 'superordinate=', 'option=', 'append-option=', 'remove-option=', 'filter=', 'tls=', 'ignore_exists', 'ignore_not_exists', 'logfile=', 'policies=', 'binddn=', 'bindpwd=', 'bindpwdfile=', 'policy-reference=', 'policy-dereference=', 'remove_referring', 'recursive']
	try:
		opts, args = getopt.getopt(arglist[3:], '', longopts)
	except getopt.error as msg:
		out.append(str(msg))
		return out + ["OPERATION FAILED"]

	if not args == [] and isinstance(args, list):
		msg = "WARNING: the following arguments are ignored:"
		for argument in args:
			msg = '%s "%s"' % (msg, argument)
		out.append(msg)

	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 = 0
	ignore_not_exists = False
	superordinate_dn = ''
	parsed_append_options = []
	parsed_remove_options = []
	parsed_options = []
	filter = ''
	input = {}
	append = {}
	remove = {}
	policy_reference = []
	policy_dereference = []
	for opt, val in opts:
		if opt == '--position':
			position_dn = _2utf8(val)
		elif opt == '--logfile':
			logfile = val
		elif opt == '--policies':
			list_policies = True
			if val == "1":
				policies_with_DN = True
			else:
				policyOptions = ['-s']
		elif opt == '--binddn':
			binddn = val
		elif opt == '--bindpwd':
			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']
		elif opt == '--dn':
			dn = _2utf8(val)
		elif opt == '--tls':
			tls = val
		elif opt == '--ignore_exists':
			ignore_exists = 1
		elif opt == '--ignore_not_exists':
			ignore_not_exists = True
		elif opt == '--superordinate':
			superordinate_dn = val
		elif opt == '--option':
			parsed_options.append(val)
		elif opt == '--append-option':
			parsed_append_options.append(val)
		elif opt == '--remove-option':
			parsed_remove_options.append(val)
		elif opt == '--filter':
			ldapFilter.parse(val)
			filter = val
		elif opt == '--policy-reference':
			policy_reference.append(val)
		elif opt == '--policy-dereference':
			policy_dereference.append(val)

	if logfile:
		ud.init(logfile, 1, 0)
	else:
		out.append("WARNING: no logfile specified")

	configRegistry = univention.config_registry.ConfigRegistry()
	configRegistry.load()

	co = None
	baseDN = configRegistry['ldap/base']

	if configRegistry.get('directory/manager/cmd/debug/level'):
		debug_level = configRegistry['directory/manager/cmd/debug/level']
	else:
		debug_level = 0

	ud.set_level(ud.LDAP, int(debug_level))
	ud.set_level(ud.ADMIN, int(debug_level))

	if binddn and bindpwd:
		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 as e:
			ud.debug(ud.ADMIN, ud.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

	else:
		if os.path.exists('/etc/ldap.secret'):
			ud.debug(ud.ADMIN, ud.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'):
			ud.debug(ud.ADMIN, ud.INFO, "using %s account" % configRegistry['ldap/hostdn'])
			secretFileName = '/etc/machine.secret'
			binddn = configRegistry['ldap/hostdn']
			policyOptions.extend(['-D', binddn, '-y', secretFileName])

		try:
			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)

		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 as e:
			ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % str(e))
			out.append('authentication error: %s' % str(e))
			return out + ["OPERATION FAILED"]

	if not position_dn and superordinate_dn:
		position_dn = superordinate_dn
	elif not position_dn:
		position_dn = baseDN

	try:
		position = univention.admin.uldap.position(baseDN)
		position.setDn(position_dn)
	except univention.admin.uexceptions.noObject:
		out.append('E: Invalid position')
		return out + ["OPERATION FAILED"]

	try:
		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"]

	if not module:
		out.append("unknown module %s." % module_name)
		out.append("")
		return list_available_modules(out) + ["OPERATION FAILED"]

	# initialise modules
	if module_name == 'settings/usertemplate':
		univention.admin.modules.init(lo, position, univention.admin.modules.get('users/user'))
	univention.admin.modules.init(lo, position, module)

	information = module_information(module)

	superordinate = None
	if superordinate_dn and univention.admin.modules.superordinate(module):
		# the superordinate itself also has a superordinate, get it!
		superordinate = univention.admin.objects.get_superordinate(module, None, lo, superordinate_dn)
		if superordinate is None:
			out.append('E: %s is not a superordinate for %s.' % (superordinate_dn, univention.admin.modules.name(module)))
			return out + ["OPERATION FAILED"]

	if len(arglist) == 2:
		out = usage() + module_usage(information)
		return out + ["OPERATION FAILED"]

	action = arglist[2]

	if len(arglist) == 3 and action != 'list':
		out = usage() + module_usage(information, action)
		return out + ["OPERATION 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 name in properties:
					if properties[name].multivalue:
						if name not in input:
							input[name] = []
							was_set = 1
						if value:
							input[name].append(value)
							was_set = 1
					else:
						input[name] = value
						was_set = 1

			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 name in properties:
					if properties[name].multivalue:
						if name not in append:
							append[name] = []
						if value:
							append[name].append(value)
							was_set = 1
					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)

		elif opt == '--remove':
			pos = val.find('=')
			if pos == -1:
				name = val
				value = None
			else:
				name = val[:pos]
				value = _2utf8(val[pos + 1:])
			was_set = False
			for mod, (properties, options) in information.items():
				if name in properties:
					was_set = True
					if properties[name].multivalue:
						if value is None:
							remove[name] = value
						elif value:
							remove.setdefault(name, [])
							if remove[name] is not None:
								remove[name].append(value)
					else:
						remove[name] = value
			if not was_set:
				out.append("WARNING: No attribute with name %s in this module, value not removed." % name)
		elif opt == '--remove_referring':
			remove_referring = 1
		elif opt == '--recursive':
			recursive = 1

	#+++# ACTION CREATE #+++#
	if action == 'create' or action == 'new':
			if hasattr(module, 'operations') and module.operations:
				if 'add' not 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 as exc:
				out.append('E: Insufficient information: %s' % (exc,))
				return out + ["OPERATION FAILED"]

			if parsed_options:
				object.options = parsed_options
			for option in parsed_append_options:
				object.options.append(option)
			for option in parsed_remove_options:
				try:
					object.option.remove(option)
				except ValueError:
					pass

			object.open()
			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 as err:
				out.append('E: Invalid Syntax: %s' % err)
				return out + ["OPERATION FAILED"]

			default_containers = object.get_default_containers(lo)
			if default_containers and position.isBase() and not any(lo.compare_dn(default_container, position.getDn()) for default_container in default_containers):
				out.append('WARNING: The object is not going to be created underneath of its default containers.')

			object.policy_reference(*policy_reference)

			exists = 0
			exists_msg = None
			created = False
			try:
				dn = object.create()
				created = True
			except univention.admin.uexceptions.objectExists as exc:
				exists_msg = '%s' % (exc,)
				dn = exc.args[0]
				if not ignore_exists:
					out.append('E: Object exists: %s' % exists_msg)
					return out + ["OPERATION FAILED"]
				else:
					exists = 1
			except univention.admin.uexceptions.uidAlreadyUsed as 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 as 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 as 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 as 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 as e:
				exists_msg = '(nolock) %s' % (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 as e:
				out.append('E: invalid Options: %s' % e)
				if not ignore_exists:
					return out + ["OPERATION FAILED"]
			except univention.admin.uexceptions.insufficientInformation as exc:
				out.append('E: Insufficient information: %s' % (exc,))
				return out + ["OPERATION FAILED"]
			except univention.admin.uexceptions.noObject as e:
				out.append('E: object not found: %s' % e)
				return out + ["OPERATION FAILED"]
			except univention.admin.uexceptions.circularGroupDependency as e:
				out.append('E: circular group dependency detected: %s' % e)
				return out + ["OPERATION FAILED"]
			except univention.admin.uexceptions.invalidChild as e:
				out.append('E: %s' % e)
				return out + ["OPERATION FAILED"]

			if exists == 1:
				if exists_msg:
					out.append('Object exists: %s' % exists_msg)
				else:
					out.append('Object exists')
			elif created:
				out.append('Object created: %s' % _2utf8(dn))

	#+++# ACTION MODIFY #+++#
	elif action == 'modify' or action == 'edit' or action == 'move':
		if not dn:
			out.append('E: DN is missing')
			return out + ["OPERATION FAILED"]

		object_modified = 0

		if hasattr(module, 'operations') and module.operations:
			if 'edit' not in module.operations:
				out.append('Modify %s not allowed' % module_name)
				return out + ["OPERATION 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.open()

		if action == 'move':
			if hasattr(module, 'operations') and module.operations:
				if 'move' not in module.operations:
					out.append('Move %s not allowed' % module_name)
					return out + ["OPERATION FAILED"]
			if not position_dn:
				out.append("need new position for moving object")
			else:
				try:  # check if destination exists
					lo.get(position_dn, required=True)
				except (univention.admin.uexceptions.noObject, ldap.INVALID_DN_SYNTAX):
					out.append("position does not exists: %s" % position_dn)
					return out + ["OPERATION FAILED"]
				rdn = ldap.dn.dn2str([ldap.dn.str2dn(dn)[0]])
				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 as 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 as err:
					out.append('E: Invalid Syntax: %s' % err)
					return out + ["OPERATION FAILED"]
				except univention.admin.uexceptions.invalidOperation as msg:
					out.append(str(msg))
					return out + ["OPERATION FAILED"]

		else:  # modify

			if (len(input) + len(append) + len(remove) + len(parsed_append_options) + len(parsed_remove_options) + len(parsed_options) + len(policy_reference) + len(policy_dereference)) > 0:
				if parsed_options:
					object.options = parsed_options
				for option in parsed_append_options:
					object.options.append(option)
				for option in parsed_remove_options[:]:
					try:
						object.options.remove(option)
					except ValueError:
						parsed_remove_options.remove(option)
						out.append('WARNING: option %r is not set. Ignoring.' % (option,))

				try:
					out.extend(object_input(module, object, input, append, remove))
				except univention.admin.uexceptions.valueMayNotChange as e:
					out.append(unicode(e[0]))
					return out + ["OPERATION FAILED"]

				object.policy_reference(*policy_reference)
				object.policy_dereference(*policy_dereference)

				if object.hasChanged(input.keys()) or object.hasChanged(append.keys()) or object.hasChanged(remove.keys()) or parsed_append_options or parsed_remove_options or parsed_options or object.policiesChanged():
					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 as e:
						out.append('E: circular group dependency detected: %s' % e)
						return out + ["OPERATION FAILED"]
					except univention.admin.uexceptions.valueInvalidSyntax as e:
						out.append('E: Invalid Syntax: %s' % e)
						return out + ["OPERATION FAILED"]

		if object_modified > 0:
			out.append('Object modified: %s' % _2utf8(dn))
		else:
			out.append('No modification: %s' % _2utf8(dn))

	elif action == 'remove' or action == 'delete':

		if hasattr(module, 'operations') and module.operations:
			if 'remove' not in module.operations:
				out.append('Remove %s not allowed' % module_name)
				return out + ["OPERATION FAILED"]

		try:
			if dn and filter:
				object = univention.admin.modules.lookup(module, co, lo, scope='sub', superordinate=superordinate, base=dn, filter=filter, required=True, unique=True)[0]
			elif dn:
				object = univention.admin.modules.lookup(module, co, lo, scope='base', superordinate=superordinate, base=dn, filter=filter, required=True, unique=True)[0]
			elif filter:
				object = univention.admin.modules.lookup(module, co, lo, scope='sub', superordinate=superordinate, base=position.getDn(), filter=filter, required=True, unique=True)[0]
			else:
				out.append('E: dn or filter needed')
				return out + ["OPERATION FAILED"]
		except (univention.admin.uexceptions.noObject, IndexError):
			if ignore_not_exists:
				out.append('Object not found: %s' % _2utf8(dn or filter))
				return out
			out.append('E: object not found')
			return out + ["OPERATION FAILED"]

		object.open()

		if remove_referring and univention.admin.objects.wantsCleanup(object):
			univention.admin.objects.performCleanup(object)

		if recursive:
			try:
				object.remove(recursive)
			except univention.admin.uexceptions.ldapError as msg:
				out.append(str(msg))
				return out + ["OPERATION 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 or object.dn))

	elif action == 'list' or action == 'lookup':

		if hasattr(module, 'operations') and module.operations:
			if 'search' not in module.operations:
				out.append('Search %s not allowed' % module_name)
				return out + ["OPERATION FAILED"]

		out.append(_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)))

				if (hasattr(module, 'virtual') and not module.virtual) or not hasattr(module, 'virtual'):
					object.open()
					for key, value in sorted(object.items()):
						if key == 'sambaLogonHours':
							# returns a list, which breaks things here
							# better show the bit string. See Bug #33703
							value = module.mapping.mapValue(key, value)
						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))))
								else:
									out.append('  %s: %s' % (_2utf8(key), None))
						else:
							if s.tostring(value):
								if module.module == 'settings/portal' and key == 'content':
									out.append('  %s:\n  %s' % (_2utf8(key), _2utf8(s.tostring(value).replace('\n', '\n  '))))
								else:
									out.append('  %s: %s' % (_2utf8(key), _2utf8(s.tostring(value))))
							else:
								out.append('  %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 references:
							for el in references['univentionPolicyReference']:
								out.append('  %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 = ''
					attribute = ''
					value = []
					client = {}
					for line in policyResults:
						line = line.strip()
						if not line or line.startswith("DN: ") or line.startswith("POLICY "):
							continue
						out.append("    %s" % line)

						if not policies_with_DN:
							ckey, cval = line.split('=', 1)
							client.setdefault(ckey, []).append(cval)
							continue

						ckey, cval = line.split(': ', 1)
						if ckey == 'Policy':
							if policy:
								client[attribute] = [policy, value]
								value = []
							policy = cval
						elif ckey == 'Attribute':
							attribute = cval
						elif ckey == 'Value':
							value.append(cval)

					if policies_with_DN:
						client[attribute] = [policy, value]
						value = []

					out.append('')

					if module_name == 'dhcp/host':
						subnet_module = univention.admin.modules.get('dhcp/subnet')
						# TODO: sharedsubnet_module = univention.admin.modules.get('dhcp/sharedsubnet')
						ips = object['fixedaddress']
						for ip in ips:
							for subnet in univention.admin.modules.lookup(subnet_module, co, lo, scope='sub', superordinate=superordinate, base=superordinate_dn, filter=''):
								if univention.admin.ipaddress.ip_is_in_network(subnet['subnet'], subnet['subnetmask'], ip):
									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 subsplit[0] not in ddict:
													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 key not in client:
											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 as errmsg:
			out.append('%s' % str(errmsg))
			return out + ["OPERATION FAILED"]
		except univention.admin.uexceptions.valueInvalidSyntax as errmsg:
			out.append('%s' % str(errmsg.message))
			return out + ["OPERATION FAILED"]
	else:
		out.append("Unknown or no action defined")
		out.append('')
		usage()
		return out + ["OPERATION FAILED"]

	return out  # nearly the only successful return
Esempio n. 16
0
#!/usr/share/ucs-test/runner /usr/bin/py.test -s -lvvx
# -*- coding: utf-8 -*-
## desc: Test 'remove' operation in UDM API
## exposure: dangerous
## roles: [domaincontroller_master]
## tags: [udm_api, skip_admember]
## packages: [python-univention-directory-manager]
## bugs: [53620]

import pytest

import univention.debug as ud
from univention.testing.strings import random_username
from univention.udm.exceptions import DeleteError, NoObject

ud.init('/var/log/univention/directory-manager-cmd.log', ud.FLUSH,
        ud.NO_FUNCTION)
ud.set_level(ud.ADMIN, ud.ALL)


def test_remove_children(ldap_base, schedule_delete_udm_obj, simple_udm):
    cn_mod = simple_udm.get("container/cn")
    cn_obj = cn_mod.new(ldap_base)
    cn_obj.props.name = random_username()
    cn_obj.save()
    schedule_delete_udm_obj(cn_obj.dn, "container/cn")
    cn_obj_dn = cn_obj.dn
    assert cn_mod.get(cn_obj_dn)

    users_mod = simple_udm.get("users/ldap")
    user_obj = users_mod.new()
    user_obj.position = cn_obj.dn
Esempio n. 17
0
def doit(arglist):
	ud.init('/var/log/univention/directory-manager-cmd.log', ud.FLUSH, ud.FUNCTION)
	out = []
	opts, args = getopt.getopt(arglist[1:], '', ['binddn=', 'pwdfile=', 'user='******'pwd='])

	binddn = None
	pwdfile = None
	user = None
	pwd = None

	for opt, val in opts:
		if opt == '--binddn':
			binddn = val
		elif opt == '--pwdfile':
			pwdfile = val
		elif opt == '--user':
			user = val
		elif opt == '--pwd':
			pwd = val

	ud.set_level(ud.LDAP, ud.ALL)
	ud.set_level(ud.ADMIN, ud.ALL)

	configRegistry = univention.config_registry.ConfigRegistry()
	configRegistry.load()

	baseDN = configRegistry['ldap/base']

	with open(pwdfile) as fd:
		bindpw = fd.read().rstrip()

	ud.debug(ud.ADMIN, ud.WARN, 'binddn: %s; bindpwd: *************' % (binddn,))
	try:
		lo = univention.admin.uldap.access(host=configRegistry['ldap/master'], port=int(configRegistry.get('ldap/master/port', '7389')), base=baseDN, binddn=binddn, bindpw=bindpw, start_tls=2)
	except Exception as exc:
		ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % (exc,))
		out.append('authentication error: %s' % (exc,))
		return out

	if isinstance(user, bytes):  # python 2
		user = user.decode('utf-8')

	if configRegistry.get('samba/charset/unix', 'utf8') in ['utf8', 'latin']:
		ud.debug(ud.ADMIN, ud.INFO, 'univention-passwd: known charset given: %s' % configRegistry.get('samba/charset/unix'))
		if not isinstance(pwd, bytes):  # python 3
			pwd = pwd.encode('UTF-8')
		pwd = pwd.decode(configRegistry.get('samba/charset/unix', 'utf8'))
	else:
		ud.debug(ud.ADMIN, ud.INFO, 'univention-passwd: unknown charset given, try fallback')
		if isinstance(pwd, bytes):  # python 2
			pwd = pwd.decode('utf-8')

	try:
		dn = lo.searchDn(filter=filter_format(u'(&(uid=%s)(|(objectClass=posixAccount)(objectClass=sambaSamAccount)(objectClass=person)))', [user]), base=baseDN, unique=True)
		position = univention.admin.uldap.position(baseDN)

		module = univention.admin.modules.get('users/user')
		univention.admin.modules.init(lo, position, module)

		object = univention.admin.objects.get(module, None, lo, position=position, dn=dn[0])
		object.open()

		# hack, to prevent that attributes belonging to the samba option are changed; Bug #41530
		if 'samba' in object.options:
			object.options.remove('samba')
			object.old_options.remove('samba')
			object._ldap_object_classes = lambda ml: ml

		object['password'] = pwd

		ud.debug(ud.ADMIN, ud.INFO, 'univention-passwd: passwd set, modify object')
		dn = object.modify()

		out.append('password changed')
		ud.debug(ud.ADMIN, ud.INFO, 'univention-passwd: password changed')

	except univention.admin.uexceptions.pwalreadyused:
		out.append('passwd error: password already used')
		return out

	except Exception as exc:
		ud.debug(ud.ADMIN, ud.WARN, 'passwd error: %s' % (exc,))
		out.append('passwd error: %s' % (exc,))
		return out

	try:
		# check for local ldap server connection
		if configRegistry.is_true('ldap/replication/preferredpassword'):
			if configRegistry.get('ldap/server/type') == 'slave':
				if os.path.exists('/etc/ldap/rootpw.conf'):
					lo = univention.admin.uldap.access(lo=univention.uldap.getRootDnConnection())
					dn = lo.searchDn(filter=filter_format(u'(&(uid=%s)(|(objectClass=posixAccount)(objectClass=sambaSamAccount)(objectClass=person)))', [user]), base=baseDN, unique=True)
					position = univention.admin.uldap.position(baseDN)
					module = univention.admin.modules.get('users/user')
					univention.admin.modules.init(lo, position, module)

					object = univention.admin.objects.get(module, None, lo, position=position, dn=dn[0])
					object.open()
					object['password'] = pwd

					ud.debug(ud.ADMIN, ud.INFO, 'univention-passwd: passwd set, modify object')
					object['overridePWHistory'] = '1'
					object['overridePWLength'] = '1'
					dn = object.modify()

					ud.debug(ud.ADMIN, ud.INFO, 'univention-passwd: password changed')
	except Exception as exc:
		ud.debug(ud.ADMIN, ud.WARN, 'passwd error: %s' % (exc,))

	return out
Esempio n. 18
0
        for item in self:
            if item.pid == service.pid:
                item.update(service)
                break
        else:
            self.append(service)


def usage():
    print('Usage: {} [file]'.format(sys.argv[0]))
    print('If no file is given, runs smbstatus and parses its output.')
    print('(Test data: /usr/share/ucs-school-lib/smbstatus_testdata.txt)')


if __name__ == '__main__':
    ud.init('/var/log/univention/smbstatus.log', 0, 0)
    ud.set_level(ud.PARSER, 4)
    if len(sys.argv) == 1:
        status = SMB_Status()
    elif len(sys.argv) == 2:
        try:
            testdata = open(sys.argv[1], 'rb').read()
        except IOError:
            print('Error: Cannot read {!r}\n'.format(sys.argv[1]))
            usage()
            sys.exit(1)
        status = SMB_Status(testdata=testdata.split('\n'))
    else:
        usage()
        sys.exit(1)
    for process in map(str, status):
def doit(arglist):
    ud.init('/var/log/univention/directory-manager-cmd.log', 1, 1)
    out = []
    configRegistry = univention.config_registry.ConfigRegistry()
    configRegistry.load()
    op = 'add'
    scope = 'user'
    cmd = os.path.basename(arglist[0])
    if cmd == 'univention-addgroup':
        scope = 'group'
        op = 'add'
    elif cmd == 'univention-deluser':
        scope = 'user'
        op = 'del'
    elif cmd == 'univention-delgroup':
        scope = 'group'
        op = 'del'
    elif cmd == 'univention-addmachine':
        scope = 'machine'
        op = 'add'
    elif cmd == 'univention-delmachine':
        scope = 'machine'
        op = 'del'
    elif cmd == 'univention-setprimarygroup':
        scope = 'user'
        op = 'primarygroup'

    opts, args = getopt.getopt(arglist[1:], '', ['status-fd=', 'status-fifo='])

    co = None
    try:
        lo, position = univention.admin.uldap.getAdminConnection()
    except Exception as e:
        ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % str(e))
        try:
            lo, position = univention.admin.uldap.getMachineConnection()
        except Exception as e2:
            ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % str(e2))
            out.append('authentication error: %s' % str(e))
            out.append('authentication error: %s' % str(e2))
            return out

    for i in range(0, len(args)):
        try:
            args[i] = codecs.utf_8_decode(args[i])[0]
        except:
            args[i] = codecs.latin_1_decode(args[i])[0]

    univention.admin.modules.update()

    if len(args) == 1:
        if scope == 'machine':
            machine = args[0]
            if machine[-1] == '$':
                machine = machine[0:-1]
            if configRegistry.get('samba/defaultcontainer/computer'):
                position.setDn(
                    configRegistry['samba/defaultcontainer/computer'])
            else:
                position.setDn(
                    univention.admin.config.getDefaultContainer(
                        lo, 'computers/windows'))
        elif scope == 'group':
            group = args[0]
            if configRegistry.get('samba/defaultcontainer/group'):
                position.setDn(configRegistry['samba/defaultcontainer/group'])
            else:
                position.setDn(
                    univention.admin.config.getDefaultContainer(
                        lo, 'groups/group'))
        else:
            user = args[0]
            if configRegistry.get('samba/defaultcontainer/user'):
                position.setDn(configRegistry['samba/defaultcontainer/user'])
            else:
                position.setDn(
                    univention.admin.config.getDefaultContainer(
                        lo, 'users/user'))
        action = op + scope

    elif len(args) == 2:
        user, group = args
        if op == 'del':
            action = 'deluserfromgroup'
        elif op == 'primarygroup':
            action = 'setprimarygroup'
        else:
            action = 'addusertogroup'
    else:
        return out

    if action == 'adduser':
        out.append(status('Adding user %s' % codecs.utf_8_encode(user)[0]))
        object = univention.admin.handlers.users.user.object(co,
                                                             lo,
                                                             position=position)
        object.open()
        object['username'] = user
        try:
            object['lastname'] = codecs.ascii_decode(user)[0]
        except UnicodeEncodeError:
            object['lastname'] = 'unknown'
        a, b = os.popen2('/usr/bin/makepasswd --minchars=8')
        line = b.readline()
        if line[-1] == '\n':
            line = line[0:-1]
        object['password'] = line
        object['primaryGroup'] = univention.admin.config.getDefaultValue(
            lo, 'group')
        object.create()
        nscd_invalidate('passwd')

    elif action == 'deluser':
        out.append(status('Removing user %s' % codecs.utf_8_encode(user)[0]))
        object = univention.admin.modules.lookup(
            univention.admin.handlers.users.user,
            co,
            lo,
            scope='domain',
            base=position.getDomain(),
            filter='(username=%s)' % user,
            required=True,
            unique=True)[0]
        object.remove()
        nscd_invalidate('passwd')

    elif action == 'addgroup':
        out.append(status('Adding group %s' % codecs.utf_8_encode(group)[0]))
        object = univention.admin.handlers.groups.group.object(
            co, lo, position=position)
        object.options = ['posix']
        object['name'] = group
        object.create()
        nscd_invalidate('group')

    elif action == 'delgroup':
        out.append(status('Removing group %s' % codecs.utf_8_encode(group)[0]))
        object = univention.admin.modules.lookup(
            univention.admin.handlers.groups.group,
            co,
            lo,
            scope='domain',
            base=position.getDomain(),
            filter='(name=%s)' % group,
            required=True,
            unique=True)[0]
        object.remove()
        nscd_invalidate('group')

    elif action == 'addusertogroup':
        ucr_key_samba_bdc_udm_cli_addusertogroup_filter_group = 'samba/addusertogroup/filter/group'
        if configRegistry.get(
                ucr_key_samba_bdc_udm_cli_addusertogroup_filter_group):
            if group in configRegistry[
                    ucr_key_samba_bdc_udm_cli_addusertogroup_filter_group].split(
                        ','):
                out.append(
                    status('addusertogroup: filter protects group "%s"' %
                           (codecs.utf_8_encode(group)[0])))
                return out
        out.append(
            status(
                'Adding user %s to group %s' %
                (codecs.utf_8_encode(user)[0], codecs.utf_8_encode(group)[0])))
        groupobject = univention.admin.modules.lookup(
            univention.admin.handlers.groups.group,
            co,
            lo,
            scope='domain',
            base=position.getDn(),
            filter='(name=%s)' % group,
            required=True,
            unique=True)[0]
        userobject = get_user_object(user, position, lo, co)
        if isinstance(userobject, types.StringType):
            out.append(userobject)
            return out

        if userobject.dn not in groupobject['users']:
            if groupobject['users'] == [''] or groupobject['users'] == []:
                groupobject['users'] = [userobject.dn]
            else:
                groupobject['users'].append(userobject.dn)
            groupobject.modify()
            nscd_invalidate('group')

    elif action == 'deluserfromgroup':
        out.append(
            status(
                'Removing user %s from group %s' %
                (codecs.utf_8_encode(user)[0], codecs.utf_8_encode(group)[0])))
        groupobject = univention.admin.modules.lookup(
            univention.admin.handlers.groups.group,
            co,
            lo,
            scope='domain',
            base=position.getDn(),
            filter='(name=%s)' % group,
            required=True,
            unique=True)[0]

        userobject = get_user_object(user, position, lo, co)
        if isinstance(userobject, types.StringType):
            out.append(userobject)
            return out

        userobject.open()
        if userobject.dn in groupobject[
                'users'] and not userobject['primaryGroup'] == groupobject.dn:
            groupobject['users'].remove(userobject.dn)
            groupobject.modify()
            nscd_invalidate('group')

    elif action == 'addmachine':
        out.append(
            status('Adding machine %s' % codecs.utf_8_encode(machine)[0]))
        object = univention.admin.handlers.computers.windows.object(
            co, lo, position=position)
        univention.admin.objects.open(object)
        object.options = ['posix']
        object['name'] = machine
        object['primaryGroup'] = univention.admin.config.getDefaultValue(
            lo, 'computerGroup')
        object.create()
        nscd_invalidate('hosts')
        nscd_invalidate('passwd')

    elif action == 'delmachine':
        out.append(
            status('Removing machine %s' % codecs.utf_8_encode(machine)[0]))
        object = univention.admin.modules.lookup(
            univention.admin.handlers.computers.windows,
            co,
            lo,
            scope='domain',
            base=position.getDomain(),
            filter='(name=%s)' % machine,
            required=True,
            unique=True)[0]
        object.remove()
        nscd_invalidate('hosts')

    elif action == 'setprimarygroup':
        out.append(
            status(
                'Set primary group %s for user %s' %
                (codecs.utf_8_encode(group)[0], codecs.utf_8_encode(user)[0])))
        try:
            groupobject = univention.admin.modules.lookup(
                univention.admin.handlers.groups.group,
                co,
                lo,
                scope='domain',
                base=position.getDn(),
                filter='(name=%s)' % group,
                required=True,
                unique=True)[0]
        except:
            out.append('ERROR: group not found, nothing modified')
            return out

        userobject = get_user_object(user, position, lo, co)
        if isinstance(userobject, types.StringType):
            out.append(userobject)
            return out

        if hasattr(userobject, 'options'):
            if 'samba' in userobject.options:
                userobject.options.remove('samba')
        userobject.open()

        if userobject.has_property('primaryGroup'):
            userobject['primaryGroup'] = groupobject.dn
        elif userobject.has_property('machineAccountGroup'):
            userobject['machineAccountGroup'] = groupobject.dn
        else:
            out.append('ERROR: unknown group attribute, nothing modified')
            return out

        userobject.modify()

        if userobject.dn not in groupobject['users']:
            groupobject['users'].append(userobject.dn)
            groupobject.modify()

        nscd_invalidate('group')
        nscd_invalidate('passwd')
    return out
Esempio n. 20
0
def doit(arglist):
	ud.init('/var/log/univention/directory-manager-cmd.log', ud.FLUSH, ud.FUNCTION)
	out = []
	configRegistry = univention.config_registry.ConfigRegistry()
	configRegistry.load()
	op = 'add'
	scope = 'user'
	cmd = os.path.basename(arglist[0])
	if cmd == 'univention-addgroup':
		scope = 'group'
		op = 'add'
	elif cmd == 'univention-deluser':
		scope = 'user'
		op = 'del'
	elif cmd == 'univention-delgroup':
		scope = 'group'
		op = 'del'
	elif cmd == 'univention-addmachine':
		scope = 'machine'
		op = 'add'
	elif cmd == 'univention-delmachine':
		scope = 'machine'
		op = 'del'
	elif cmd == 'univention-setprimarygroup':
		scope = 'user'
		op = 'primarygroup'

	opts, args = getopt.getopt(arglist[1:], '', ['status-fd=', 'status-fifo='])

	try:
		lo, position = univention.admin.uldap.getAdminConnection()
	except Exception as exc:
		ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % (exc,))
		try:
			lo, position = univention.admin.uldap.getMachineConnection()
		except Exception as exc2:
			ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % (exc2,))
			out.append('authentication error: %s' % (exc,))
			out.append('authentication error: %s' % (exc2,))
			return out

	if six.PY2:
		args = list(_decode(args))

	univention.admin.modules.update()

	if len(args) == 1:
		if scope == 'machine':
			machine = args[0]
			if machine.endswith('$'):
				machine = machine[:-1]
			if configRegistry.get('samba/defaultcontainer/computer'):
				position.setDn(configRegistry['samba/defaultcontainer/computer'])
			else:
				position.setDn(univention.admin.config.getDefaultContainer(lo, 'computers/windows'))
		elif scope == 'group':
			group = args[0]
			if configRegistry.get('samba/defaultcontainer/group'):
				position.setDn(configRegistry['samba/defaultcontainer/group'])
			else:
				position.setDn(univention.admin.config.getDefaultContainer(lo, 'groups/group'))
		else:
			user = args[0]
			if configRegistry.get('samba/defaultcontainer/user'):
				position.setDn(configRegistry['samba/defaultcontainer/user'])
			else:
				position.setDn(univention.admin.config.getDefaultContainer(lo, 'users/user'))
		action = op + scope

	elif len(args) == 2:
		user, group = args
		if op == 'del':
			action = 'deluserfromgroup'
		elif op == 'primarygroup':
			action = 'setprimarygroup'
		else:
			action = 'addusertogroup'
	else:
		return out

	if action == 'adduser':
		out.append(status(u'Adding user %s' % (user,)))
		object = univention.admin.handlers.users.user.object(None, lo, position=position)
		object.open()
		object['username'] = user
		object['lastname'] = user.encode('utf-8').decode('ASCII')
		object['password'] = subprocess.check_output(['/usr/bin/makepasswd', '--minchars=8'], close_fds=True).strip().decode('ASCII', 'ignore')
		object['primaryGroup'] = univention.admin.config.getDefaultValue(lo, 'group')
		object.create()
		nscd_invalidate('passwd')

	elif action == 'deluser':
		out.append(status(u'Removing user %s' % (user,)))
		object = univention.admin.modules.lookup(univention.admin.handlers.users.user, None, lo, scope='domain', base=position.getDomain(), filter=filter_format(u'(username=%s)', [user]), required=True, unique=True)[0]
		object.open()
		object.remove()
		nscd_invalidate('passwd')

	elif action == 'addgroup':
		out.append(status(u'Adding group %s' % (group,)))
		object = univention.admin.handlers.groups.group.object(None, lo, position=position)
		object.open()
		object.options = ['posix']
		object['name'] = group
		object.create()
		nscd_invalidate('group')

	elif action == 'delgroup':
		out.append(status(u'Removing group %s' % (group,)))
		object = univention.admin.modules.lookup(univention.admin.handlers.groups.group, None, lo, scope='domain', base=position.getDomain(), filter=filter_format(u'(name=%s)', [group]), required=True, unique=True)[0]
		object.open()
		object.remove()
		nscd_invalidate('group')

	elif action == 'addusertogroup':
		if group in configRegistry.get('samba/addusertogroup/filter/group', '').split(','):
			out.append(status(u'addusertogroup: filter protects group "%s"' % (group,)))
			return out
		out.append(status(u'Adding user %s to group %s' % (user, group)))
		groupobject = univention.admin.modules.lookup(univention.admin.handlers.groups.group, None, lo, scope='domain', base=position.getDn(), filter=filter_format(u'(name=%s)', [group]), required=True, unique=True)[0]
		groupobject.open()
		userobject = get_user_object(user, position, lo)
		if isinstance(userobject, six.string_types):
			out.append(userobject)
			return out

		if userobject.dn not in groupobject['users']:
			if groupobject['users'] == [''] or groupobject['users'] == []:
				groupobject['users'] = [userobject.dn]
			else:
				groupobject['users'].append(userobject.dn)
			groupobject.modify()
			nscd_invalidate('group')

	elif action == 'deluserfromgroup':
		out.append(status(u'Removing user %s from group %s' % (user, group)))
		groupobject = univention.admin.modules.lookup(univention.admin.handlers.groups.group, None, lo, scope='domain', base=position.getDn(), filter=filter_format(u'(name=%s)', [group]), required=True, unique=True)[0]
		groupobject.open()

		userobject = get_user_object(user, position, lo)
		if isinstance(userobject, six.string_types):
			out.append(userobject)
			return out

		userobject.open()
		if userobject.dn in groupobject['users'] and userobject['primaryGroup'] != groupobject.dn:
			groupobject['users'].remove(userobject.dn)
			groupobject.modify()
			nscd_invalidate('group')

	elif action == 'addmachine':
		out.append(status(u'Adding machine %s' % (machine,)))
		object = univention.admin.handlers.computers.windows.object(None, lo, position=position)
		object.open()
		object.options = ['posix']
		object['name'] = machine
		object['primaryGroup'] = univention.admin.config.getDefaultValue(lo, 'computerGroup')
		object.create()
		nscd_invalidate('hosts')
		nscd_invalidate('passwd')

	elif action == 'delmachine':
		out.append(status(u'Removing machine %s' % (machine,)))
		object = univention.admin.modules.lookup(univention.admin.handlers.computers.windows, None, lo, scope='domain', base=position.getDomain(), filter=filter_format(u'(name=%s)', [machine]), required=True, unique=True)[0]
		object.open()
		object.remove()
		nscd_invalidate('hosts')

	elif action == 'setprimarygroup':
		out.append(status(u'Set primary group %s for user %s' % (group, user)))
		try:
			groupobject = univention.admin.modules.lookup(univention.admin.handlers.groups.group, None, lo, scope='domain', base=position.getDn(), filter=filter_format(u'(name=%s)', [group]), required=True, unique=True)[0]
		except Exception:
			out.append('ERROR: group not found, nothing modified')
			return out
		groupobject.open()

		userobject = get_user_object(user, position, lo)
		if isinstance(userobject, six.string_types):
			out.append(userobject)
			return out

		if 'samba' in userobject.options:
			userobject.options.remove('samba')
		userobject.open()

		if userobject.has_property('primaryGroup'):
			userobject['primaryGroup'] = groupobject.dn
		elif userobject.has_property('machineAccountGroup'):
			userobject['machineAccountGroup'] = groupobject.dn
		else:
			out.append('ERROR: unknown group attribute, nothing modified')
			return out

		userobject.modify()

		if userobject.dn not in groupobject['users']:
			groupobject['users'].append(userobject.dn)
			groupobject.modify()

		nscd_invalidate('group')
		nscd_invalidate('passwd')
	return out
def doit(arglist):
    ud.init('/var/log/univention/directory-manager-cmd.log', 1, 1)
    out = []
    opts, args = getopt.getopt(arglist[1:], '',
                               ['binddn=', 'pwdfile=', 'user='******'pwd='])

    binddn = None
    pwdfile = None
    user = None
    pwd = None

    for opt, val in opts:
        if opt == '--binddn':
            binddn = val
        elif opt == '--pwdfile':
            pwdfile = val
        elif opt == '--user':
            user = val
        elif opt == '--pwd':
            pwd = val

    ud.set_level(ud.LDAP, ud.ALL)
    ud.set_level(ud.ADMIN, ud.ALL)

    configRegistry = univention.config_registry.ConfigRegistry()
    configRegistry.load()

    baseDN = configRegistry['ldap/base']

    bindpw = open(pwdfile).read()
    if bindpw[-1] == '\n' or bindpw[-1] == '\r':
        bindpw = bindpw[0:-1]

    ud.debug(ud.ADMIN, ud.WARN,
             'binddn: %s; bindpwd: *************' % (binddn))
    try:
        lo = univention.admin.uldap.access(
            host=configRegistry['ldap/master'],
            port=int(configRegistry.get('ldap/master/port', '7389')),
            base=baseDN,
            binddn=binddn,
            bindpw=bindpw,
            start_tls=2)
    except Exception as e:
        ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % str(e))
        out.append('authentication error: %s' % e)
        return out

    try:
        dn = lo.searchDn(filter=unicode(
            '(&(uid=%s)(|(objectClass=posixAccount)(objectClass=sambaSamAccount)(objectClass=person)))'
            % user, 'utf8'),
                         base=baseDN,
                         unique=True)
        position = univention.admin.uldap.position(baseDN)

        module = univention.admin.modules.get('users/user')
        univention.admin.modules.init(lo, position, module)

        object = univention.admin.objects.get(module,
                                              None,
                                              lo,
                                              position=position,
                                              dn=dn[0])
        object.open()

        # hack, to prevent that attributes belonging to the samba option are changed; Bug #41530
        if 'samba' in object.options:
            object.options.remove('samba')
            object.old_options.remove('samba')
            object._ldap_object_classes = lambda ml: ml

        if 'samba/charset/unix' not in configRegistry:
            ud.debug(ud.ADMIN, ud.INFO,
                     'univention-passwd: no unix-charset given')
            object['password'] = unicode(pwd, 'utf8')
        elif configRegistry['samba/charset/unix'] in ['utf8', 'latin']:
            ud.debug(
                ud.ADMIN, ud.INFO,
                'univention-passwd: known charset given: %s' %
                configRegistry['samba/charset/unix'])
            object['password'] = unicode(pwd,
                                         configRegistry['samba/charset/unix'])
        else:
            ud.debug(ud.ADMIN, ud.INFO,
                     'univention-passwd: unknown charset given, try fallback')
            object['password'] = unicode(pwd)

        ud.debug(ud.ADMIN, ud.INFO,
                 'univention-passwd: passwd set, modify object')
        dn = object.modify()

        out.append('password changed')
        ud.debug(ud.ADMIN, ud.INFO, 'univention-passwd: password changed')

    except univention.admin.uexceptions.pwalreadyused:
        out.append('passwd error: password already used')
        return out

    except Exception as e:
        ud.debug(ud.ADMIN, ud.WARN, 'passwd error: %s' % e)
        out.append('passwd error: %s' % e)
        return out

    try:
        # check for local ldap server connection
        if configRegistry.is_true('ldap/replication/preferredpassword'):
            if configRegistry.get('ldap/server/type') == 'slave':
                if os.path.exists('/etc/ldap/rootpw.conf'):
                    bindpw = open('/etc/ldap/rootpw.conf').read()
                    bindpw = bindpw.split(' ')[1].strip('\n\r"')
                    lo = univention.admin.uldap.access(
                        host='%s.%s' % (configRegistry['hostname'],
                                        configRegistry['domainname']),
                        base=baseDN,
                        binddn='cn=update,%s' % (baseDN),
                        bindpw=bindpw,
                        start_tls=2)
                    dn = lo.searchDn(filter=unicode(
                        '(&(uid=%s)(|(objectClass=posixAccount)(objectClass=sambaSamAccount)(objectClass=person)))'
                        % user, 'utf8'),
                                     base=baseDN,
                                     unique=True)
                    position = univention.admin.uldap.position(baseDN)
                    module = univention.admin.modules.get('users/user')
                    univention.admin.modules.init(lo, position, module)

                    object = univention.admin.objects.get(module,
                                                          None,
                                                          lo,
                                                          position=position,
                                                          dn=dn[0])
                    object.open()

                    if 'samba/charset/unix' not in configRegistry:
                        ud.debug(ud.ADMIN, ud.INFO,
                                 'univention-passwd: no unix-charset given')
                        object['password'] = unicode(pwd, 'utf8')
                    elif configRegistry['samba/charset/unix'] in [
                            'utf8', 'latin'
                    ]:
                        ud.debug(
                            ud.ADMIN, ud.INFO,
                            'univention-passwd: known charset given: %s' %
                            configRegistry['samba/charset/unix'])
                        object['password'] = unicode(
                            pwd, configRegistry['samba/charset/unix'])
                    else:
                        ud.debug(
                            ud.ADMIN, ud.INFO,
                            'univention-passwd: unknown charset given, try fallback'
                        )
                        object['password'] = unicode(pwd)

                    ud.debug(ud.ADMIN, ud.INFO,
                             'univention-passwd: passwd set, modify object')
                    object['overridePWHistory'] = '1'
                    object['overridePWLength'] = '1'
                    dn = object.modify()

                    ud.debug(ud.ADMIN, ud.INFO,
                             'univention-passwd: password changed')
    except Exception as e:
        ud.debug(ud.ADMIN, ud.WARN, 'passwd error: %s' % e)

    return out
        result = self.m.list_local_repositories(end=ver)
        self.assertEqual(len(result), 1)
        self.assertDeepEqual(result,
                             [_ for _ in self.repos if _[1] <= ver and _[2]])

    def test_maintained(self):
        """Test maintained off."""
        result = self.m.list_local_repositories(maintained=False)
        self.assertEqual(len(result), 0)
        self.assertEqual(result, [])

    def test_unmaintained(self):
        """Test unmaintained on."""
        result = self.m.list_local_repositories(unmaintained=True)
        self.assertEqual(len(result), 6)
        # Check sorted by version
        self.assertDeepEqual([_[1] for _ in result],
                             [_[1] for _ in self.repos])
        self.assertDeepEqual(sorted(result), sorted(self.repos))


if __name__ == '__main__':
    if False:
        import univention.debug as ud
        ud.init('stderr', ud.NO_FUNCTION, ud.NO_FLUSH)
        ud.set_level(ud.NETWORK, ud.ALL + 1)
    if False:
        import logging
        logging.basicConfig(level=logging.DEBUG)
    unittest.main()
    parser = ArgumentParser()
    parser.add_argument(
        "--direct-resync",
        action="store_true",
        dest="direct_resync",
        default=False,
        help="Filter the output of univention-ldapsearch through this module")
    options = parser.parse_args()

    if not options.direct_resync:
        parser.error(
            "The option --direct-resync is required to run this module directly"
        )
        sys.exit(1)

    ud.init("stderr", ud.NO_FLUSH, ud.NO_FUNCTION)
    ucr = ConfigRegistry()
    ucr.load()
    ud.set_level(ud.LISTENER, int(ucr.get('listener/debug/level', 2)))

    cmd = ['/usr/bin/univention-ldapsearch', '-LLL', filter, 'objectClass']
    cmd.extend(attributes)
    p1 = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    (stdout, stderr) = p1.communicate()

    class ListenerHandler(LDIFParser):
        def __init__(self, input):
            LDIFParser.__init__(self, input)

        def handle(self, dn, entry):
            handler(dn, entry, {}, 'a')
Esempio n. 24
0
## desc: Test UDM API for users/user module
## exposure: dangerous
## roles: [domaincontroller_master]
## tags: [udm_api, skip_admember]
## packages: [python-univention-directory-manager]
## bugs: [51184]

from __future__ import print_function

from unittest import main, TestCase
import univention.debug as ud
from univention.testing.strings import random_username
from univention.udm import UDM
from univention.udm.exceptions import DeleteError

ud.init('/var/log/univention/directory-manager-cmd.log', ud.FLUSH, 0)
ud.set_level(ud.ADMIN, ud.ALL)


class TestEncoders(TestCase):
    user_objects = []

    @classmethod
    def setUpClass(cls):
        cls.udm = UDM.admin().version(2)

    @classmethod
    def tearDownClass(cls):
        for obj in cls.user_objects:
            try:
                obj.delete()
def _doit(arglist):
	out = []
	# parse module and action
	if len(arglist) < 2:
		raise OperationFailed(usage())

	module_name = arglist[1]
	if module_name in ['-h', '--help', '-?']:
		return usage()

	if module_name == '--version':
		return version()

	if module_name == 'modules':
		return list_available_modules()

	remove_referring = 0
	recursive = 1
	# parse options
	longopts = ['position=', 'dn=', 'set=', 'append=', 'remove=', 'superordinate=', 'option=', 'append-option=', 'remove-option=', 'filter=', 'tls=', 'ignore_exists', 'ignore_not_exists', 'logfile=', 'policies=', 'binddn=', 'bindpwd=', 'bindpwdfile=', 'policy-reference=', 'policy-dereference=', 'remove_referring', 'recursive']
	try:
		opts, args = getopt.getopt(arglist[3:], '', longopts)
	except getopt.error as msg:
		raise OperationFailed(out, str(msg))

	if args and isinstance(args, list):
		msg = "WARNING: the following arguments are ignored:"
		for argument in args:
			msg = '%s "%s"' % (msg, argument)
		out.append(msg)

	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 = 0
	ignore_not_exists = False
	superordinate_dn = ''
	parsed_append_options = []
	parsed_remove_options = []
	parsed_options = []
	filter = ''
	input = {}
	append = {}
	remove = {}
	policy_reference = []
	policy_dereference = []
	for opt, val in opts:
		if opt == '--position':
			position_dn = val
		elif opt == '--logfile':
			logfile = val
		elif opt == '--policies':
			list_policies = True
			if val == "1":
				policies_with_DN = True
			else:
				policyOptions = ['-s']
		elif opt == '--binddn':
			binddn = val
		elif opt == '--bindpwd':
			bindpwd = val
		elif opt == '--bindpwdfile':
			try:
				with open(val) as fp:
					bindpwd = fp.read().strip()
			except IOError as exc:
				raise OperationFailed(out, 'E: could not read bindpwd from file (%s)' % (exc,))
		elif opt == '--dn':
			dn = val
		elif opt == '--tls':
			tls = val
		elif opt == '--ignore_exists':
			ignore_exists = 1
		elif opt == '--ignore_not_exists':
			ignore_not_exists = True
		elif opt == '--superordinate':
			superordinate_dn = val
		elif opt == '--option':
			parsed_options.append(val)
		elif opt == '--append-option':
			parsed_append_options.append(val)
		elif opt == '--remove-option':
			parsed_remove_options.append(val)
		elif opt == '--filter':
			ldapFilter.parse(val)
			filter = val
		elif opt == '--policy-reference':
			policy_reference.append(val)
		elif opt == '--policy-dereference':
			policy_dereference.append(val)

	if logfile:
		ud.init(logfile, ud.FLUSH, ud.NO_FUNCTION)
	else:
		out.append("WARNING: no logfile specified")

	configRegistry = univention.config_registry.ConfigRegistry()
	configRegistry.load()

	baseDN = configRegistry['ldap/base']

	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:
		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 as exc:
			ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % (exc,))
			raise OperationFailed(out, 'authentication error: %s' % (exc,))
		policyOptions.extend(['-D', binddn, '-w', bindpwd])  # FIXME not so nice
	else:
		if os.path.exists('/etc/ldap.secret'):
			ud.debug(ud.ADMIN, ud.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'):
			ud.debug(ud.ADMIN, ud.INFO, "using %s account" % configRegistry['ldap/hostdn'])
			secretFileName = '/etc/machine.secret'
			binddn = configRegistry['ldap/hostdn']
			policyOptions.extend(['-D', binddn, '-y', secretFileName])

		try:
			with open(secretFileName, 'r') as secretFile:
				pwd = secretFile.read().strip('\n')
		except IOError:
			raise OperationFailed(out, 'E: Permission denied, try --binddn and --bindpwd')

		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 as exc:
			ud.debug(ud.ADMIN, ud.WARN, 'authentication error: %s' % (exc,))
			raise OperationFailed(out, 'authentication error: %s' % (exc,))

	if not position_dn and superordinate_dn:
		position_dn = superordinate_dn
	elif not position_dn:
		position_dn = baseDN

	try:
		position = univention.admin.uldap.position(baseDN)
		position.setDn(position_dn)
	except univention.admin.uexceptions.noObject:
		raise OperationFailed(out, 'E: Invalid position')

	module = univention.admin.modules.get(module_name)
	if not module:
		out.append("unknown module %s." % module_name)
		out.append("")
		raise OperationFailed(list_available_modules(out))

	# initialise modules
	if module_name == 'settings/usertemplate':
		univention.admin.modules.init(lo, position, univention.admin.modules.get('users/user'))
	univention.admin.modules.init(lo, position, module)

	information = module_information(module)

	superordinate = None
	if superordinate_dn and univention.admin.modules.superordinate(module):
		# the superordinate itself also has a superordinate, get it!
		superordinate = univention.admin.objects.get_superordinate(module, None, lo, superordinate_dn)
		if superordinate is None:
			raise OperationFailed(out, 'E: %s is not a superordinate for %s.' % (superordinate_dn, univention.admin.modules.name(module)))

	if len(arglist) == 2:
		out = usage() + module_usage(information)
		raise OperationFailed(out)

	action = arglist[2]

	if len(arglist) == 3 and action != 'list':
		out = usage() + module_usage(information, action)
		raise OperationFailed(out)

	for opt, val in opts:
		if opt == '--set':
			name, delim, value = val.partition('=')

			for mod, (properties, options) in information.items():
				if name in properties:
					if properties[name].multivalue:
						input.setdefault(name, [])
						if value:
							input[name].append(value)
					else:
						input[name] = value

			if name not in input:
				out.append("WARNING: No attribute with name '%s' in this module, value not set." % name)
		elif opt == '--append':
			name, delim, value = val.partition('=')
			for mod, (properties, options) in information.items():
				if name in properties:
					if properties[name].multivalue:
						append.setdefault(name, [])
						if value:
							append[name].append(value)
					else:
						append[name] = value
			if name not in append:
				out.append("WARNING: No attribute with name %s in this module, value not appended." % name)

		elif opt == '--remove':
			name, delim, value = val.partition('=')
			value = value or None
			for mod, (properties, options) in information.items():
				if name in properties:
					if properties[name].multivalue:
						if value is None:
							remove[name] = value
						elif value:
							remove.setdefault(name, [])
							if remove[name] is not None:
								remove[name].append(value)
					else:
						remove[name] = value
			if name not in remove:
				out.append("WARNING: No attribute with name %s in this module, value not removed." % name)
		elif opt == '--remove_referring':
			remove_referring = True
		elif opt == '--recursive':
			recursive = True

	cli = CLI(module_name, module, dn, lo, position, superordinate)
	if action == 'create' or action == 'new':
		out.extend(cli.create(input, append, ignore_exists, parsed_options, parsed_append_options, parsed_remove_options, policy_reference))
	elif action == 'modify' or action == 'edit':
		out.extend(cli.modify(input, append, remove, parsed_append_options, parsed_remove_options, parsed_options, policy_reference, policy_dereference, ignore_not_exists=ignore_not_exists))
	elif action == 'move':
		out.extend(cli.move(position_dn))
	elif action == 'remove' or action == 'delete':
		out.extend(cli.remove(remove_referring=remove_referring, recursive=recursive, ignore_not_exists=ignore_not_exists, filter=filter))
	elif action == 'list' or action == 'lookup':
		out.extend(cli.list(list_policies, filter, superordinate_dn, policyOptions, policies_with_DN))
	else:
		out.append("Unknown or no action defined")
		out.append('')
		raise OperationFailed(out)

	return out  # nearly the only successful return