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']
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
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): """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
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()
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
#!/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
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
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
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')
## 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