def __init__( self, host=None, tls=True, krb5=False, user='******', password='', timeout=60, logger=None, counter=None, ): '''expects ready to use "partial" for counter (CounterWrapper)''' self.logger = logger or logging.getLogger() self._counter = counter('') self.use_tls = tls self.use_krb5 = krb5 self.user_base_dn = ','.join(explode_dn(user)[1:]) self.user_filter = '(' + explode_dn(user)[0] + ')' self.user_attrib = ['dn'] # password auth self.bind_dn = user self.__password = password self.session = None self.host = host if self.host and len(self.host.split('.')) <= 1: # FIXME self.host += '.zalando' if not password and not krb5 and tls: raise ConfigurationError('LDAP password is not set properly!')
def __init__( self, host=None, tls=True, krb5=False, user='******', password='', timeout=60, logger=None, counter=None, ): '''expects ready to use "partial" for counter (CounterWrapper)''' self.logger = logger or logging.getLogger() self._counter = counter('') self.use_tls = tls self.use_krb5 = krb5 self.user_base_dn = ','.join(explode_dn(user)[1:]) self.user_filter = '(' + explode_dn(user)[0] + ')' self.user_attrib = ['dn'] # password auth self.bind_dn = user self.__password = password self.session = None self.host = host if self.host and len(self.host.split('.')) <= 1: # FIXME self.host += '.zalando'
def __init__( self, host=None, tls=True, krb5=False, user="******", password="", timeout=60, logger=None, counter=None, ): """expects ready to use "partial" for counter (CounterWrapper)""" self.logger = logger or logging.getLogger() self._counter = counter("") self.use_tls = tls self.use_krb5 = krb5 self.user_base_dn = ",".join(explode_dn(user)[1:]) self.user_filter = "(" + explode_dn(user)[0] + ")" self.user_attrib = ["dn"] # password auth self.bind_dn = user self.__password = password self.session = None self.host = host if self.host and len(self.host.split(".")) <= 1: # FIXME self.host += ".zalando"
def ldap_dn2path(ldap_dn, include_rdn=True): """Returns a path representation of an LDAP DN. If include_rdn is false just the container of the given object is returned in a path representation""" ldap_base = ucr.get('ldap/base') if not ldap_base or not ldap_dn.lower().endswith(ldap_base.lower()): return ldap_dn rel_path = ldap_dn[:-(1 + len(ldap_base))] rel_path = explode_dn(rel_path, True)[int(not include_rdn):] return '%s:/%s' % ('.'.join(reversed(explode_dn(ldap_base, True))), '/'.join(reversed(rel_path)))
def create_recursive_container(dn, lo, pos): if dn_exists(dn, lo): return position_parts = explode_dn(dn) previous_position = ','.join(position_parts[1:]) create_recursive_container(previous_position, lo, pos) pos.setDn(previous_position) name = explode_dn(position_parts[0], 1)[0] if dn.startswith('ou'): module = 'container/ou' else: module = 'container/cn' create_object_if_not_exists(module, lo, pos, name=name)
def __getitem__(self, key): key = ensure_text(key) try: return self.storage[key] except KeyError: criteria = {self._key_attr: key} attrlist = ['rdn', self._key_attr] res = self.context.search(criteria=criteria, attrlist=attrlist) if not res: raise KeyError(key) if len(res) > 1: # pragma: no cover msg = u'More than one principal with id "{0}" found.' logger.warning(msg.format(key)) prdn = res[0][1]['rdn'] if prdn in self.context._deleted_children: raise KeyError(key) dn = res[0][0] path = explode_dn(dn)[:len(self.context.DN.split(',')) * -1] context = self.context for rdn in reversed(path): context = context[rdn] principal = self.principal_factory( context, attraliaser=self.principal_attraliaser) principal.__name__ = key principal.__parent__ = self self.storage[key] = principal return principal
def delete_s(self, dn): elems = explode_dn(dn) elems.reverse() rdn = elems[-1] base = elems[:-1] tree_pos = TREE for elem in base: if tree_pos.has_key(elem): tree_pos = tree_pos[elem] else: raise ldap.NO_SUCH_OBJECT(elem) if not tree_pos.has_key(rdn): raise ldap.NO_SUCH_OBJECT(rdn) # Maintain memberOf if self.maintain_memberof: rec = tree_pos[rdn] if self.member_attr in rec: for v in rec[self.member_attr]: self.modify_s(v, [(ldap.MOD_DELETE, self.memberof_attr, [dn])]) if self.memberof_attr in rec: for v in rec[self.memberof_attr]: self.modify_s(v, [(ldap.MOD_DELETE, self.member_attr, [dn])]) del tree_pos[rdn]
def add_s(self, dn, attr_list): elems = explode_dn(dn) elems.reverse() rdn = elems[-1] base = elems[:-1] tree_pos = TREE for elem in base: if tree_pos.has_key(elem): tree_pos = tree_pos[elem] else: raise ldap.NO_SUCH_OBJECT(elem) if tree_pos.has_key(rdn): raise ldap.ALREADY_EXISTS(rdn) # Add rdn to attributes as well. k, v = rdn.split('=') tree_pos[rdn] = {k:[v]} rec = tree_pos[rdn] for key, val in attr_list: rec[key] = val # Maintain memberOf if self.maintain_memberof: if key == self.member_attr: for v in val: self.modify_s(v, [(ldap.MOD_ADD, self.memberof_attr, [dn])])
def from_student_dn(cls, lo, school, dn): examUserPrefix = ucr.get('ucsschool/ldap/default/userprefix/exam', 'exam-') dn = 'uid=%s%s,%s' % (escape_dn_chars(examUserPrefix), explode_dn(dn, True)[0], cls.get_container(school)) return cls.from_dn(dn, school, lo)
def unique_id(dn): dn_parts = explode_dn(dn) reg = re.compile('uniqueIdentifier=(.*)', re.IGNORECASE) for part in dn_parts: matcher = reg.match(part) if matcher: return matcher.groups()[0] raise INVALID_PERSON_DN(dn)
def _read_user(self, userstr, ldap_user_read=None): match = self.USER_REGEX.match(userstr) if not match or not userstr: raise AttributeError('invalid key "%s"' % userstr) username = match.groupdict()['username'] if not username: raise AttributeError('username missing: %s' % userstr) lo = ldap_user_read try: userobj = User.get_only_udm_obj( lo, filter_format('uid=%s', (username, ))) if userobj is None: raise noObject(username) user = User.from_udm_obj(userobj, None, lo) except (noObject, MultipleObjectsError): MODULE.info('Unknown user "%s"' % username) dict.__setitem__(self, userstr, UserInfo('', '')) return blacklisted_groups = set([ x.strip().lower() for x in ucr.get( 'ucsschool/umc/computerroom/hide_screenshots/groups', 'Domain Admins').split(',') ]) users_groupmemberships = set( [explode_dn(x, True)[0].lower() for x in userobj['groups']]) MODULE.info('UserMap: %s: hide screenshots for following groups: %s' % ( username, blacklisted_groups, )) MODULE.info('UserMap: %s: user is member of following groups: %s' % ( username, users_groupmemberships, )) hide_screenshot = bool(blacklisted_groups & users_groupmemberships) if ucr.is_true('ucsschool/umc/computerroom/hide_screenshots/teachers', True) and user.is_teacher(lo): MODULE.info('UserMap: %s: is teacher hiding screenshot' % (username, )) hide_screenshot = True MODULE.info('UserMap: %s: hide_screenshot=%r' % (username, hide_screenshot)) dict.__setitem__( self, userstr, UserInfo(user.dn, username, isTeacher=user.is_teacher(lo), hide_screenshot=hide_screenshot))
def apply_filter(tree_pos, base, fltr): res = [] q_key, q_val = fltr.attr, fltr.value wildcard = False if q_val.startswith('*') or q_val.endswith('*'): if q_val != '*': # Wildcard search if q_val.startswith('*') and q_val.endswith('*'): wildcard = 'both' q_val = q_val[1:-1] elif q_val.startswith('*'): wildcard = 'start' q_val = q_val[1:] elif q_val.endswith('*'): wildcard = 'end' q_val = q_val[:-1] # Need to find out if tree_pos is a leaf record, it needs different handling # Leaf records will appear when doing BASE-scoped searches. if tree_pos.has_key('dn'): key = explode_dn(tree_pos['dn'])[0] to_search = [(key, tree_pos)] else: to_search = tree_pos.items() for key, val in to_search: found = True if val.has_key(q_key): if q_val == '*': # Always include if there's a value for it. pass elif wildcard: found = False for x in val[q_key]: if wildcard == 'start': if x.endswith(q_val): found = True break elif wildcard == 'end': if x.startswith(q_val): found = True break else: if q_val in x: found = True break elif not q_val in val[q_key]: found = False if found: res.append(('%s,%s' % (key, base), val)) return res
def modify_s(self, dn, mod_list): elems = explode_dn(dn) elems.reverse() rdn = elems[-1] base = elems[:-1] tree_pos = TREE for elem in base: if tree_pos.has_key(elem): tree_pos = tree_pos[elem] else: raise ldap.NO_SUCH_OBJECT(elem) if not tree_pos.has_key(rdn): raise ldap.NO_SUCH_OBJECT(rdn) rec = deepcopy(tree_pos.get(rdn)) for mod in mod_list: if mod[0] == ldap.MOD_REPLACE: rec[mod[1]] = mod[2] elif mod[0] == ldap.MOD_ADD: cur_val = rec.get(mod[1], []) cur_val.extend(mod[2]) rec[mod[1]] = cur_val else: if rec.has_key(mod[1]): if mod[2] is None: del rec[mod[1]] else: cur_vals = rec[mod[1]] for removed in mod[2]: if removed in cur_vals: cur_vals.remove(removed) rec[mod[1]] = cur_vals tree_pos[rdn] = rec # Maintain memberOf if self.maintain_memberof: for mod in mod_list: if mod[1] == self.member_attr: if mod[0] == ldap.MOD_ADD: for v in mod[2]: self.modify_s(v, [(ldap.MOD_ADD, self.memberof_attr, [dn])]) elif mod[0] == ldap.MOD_DELETE: for v in mod[2]: self.modify_s(v, [(ldap.MOD_DELETE, self.memberof_attr, [dn])])
def setTreeItem(dn, attrs=None): elems = explode_dn(dn) elems.reverse() tree_pos = TREE last_i = len(elems) - 1 for i, elem in enumerate(elems): key = ','.join(elems[:i + 1][::-1]) if not tree_pos.has_key(key): if i == last_i and attrs is not None: tree_pos[key] = attrs else: tree_pos[key] = {} tree_pos = tree_pos[key] return tree_pos
def setTreeItem(dn, attrs=None): elems = explode_dn(dn) elems.reverse() tree_pos = TREE last_i = len(elems) - 1 for i, elem in enumerate(elems): key = ','.join(elems[:i+1][::-1]) if not tree_pos.has_key(key): if i == last_i and attrs is not None: tree_pos[key] = attrs else: tree_pos[key] = {} tree_pos = tree_pos[key] return tree_pos
def modrdn_s(self, dn, new_rdn, *ign): elems = explode_dn(dn) rdn = elems[0] tree_pos = TREE.getElementByDN(elems[1:]) if not tree_pos.has_key(rdn): raise ldap.NO_SUCH_OBJECT(rdn) if tree_pos.has_key(new_rdn): raise ldap.ALREADY_EXISTS(new_rdn) rec = tree_pos.get(rdn) del tree_pos[rdn] tree_pos[new_rdn] = rec
def addTreeItems(self, dn): """ Add structure directly to the tree given a DN returns the last added tree position for convenience """ elems = explode_dn(dn) elems.reverse() tree_pos = self for elem in elems: if not tree_pos.has_key(elem): tree_pos[elem] = {} tree_pos = tree_pos[elem] return tree_pos
def create(self, dn, new): groups = self._load() groups[dn] = { 'usernames': [ username.lower() for username in new.get('memberUid', []) if not username.endswith('$') ], 'groups': [ member.lower() for member in new.get('uniqueMember', []) if member.startswith('cn=') and not ( '%s$' % explode_dn(member, True)[0]) in new.get('memberUid', []) ], } self._save(groups) self._refresh_cache()
def getSubtree(dn): elems = explode_dn(dn) elems.reverse() tree_pos = TREE tree_pos_dn = '' for elem in elems: if not tree_pos_dn: tree_pos_dn = elem else: tree_pos_dn = '%s,%s' % (elem, tree_pos_dn) if tree_pos.has_key(tree_pos_dn): tree_pos = tree_pos[tree_pos_dn] else: raise ldap.NO_SUCH_OBJECT(tree_pos_dn) assert tree_pos_dn == dn return tree_pos
def getElementByDN(self, dn): """ Get a tree element by DN Returns None if the path cannot be found """ if isinstance(dn, str): elems = explode_dn(dn) else: elems = dn elems.reverse() tree_pos = self for elem in elems: if not tree_pos.has_key(elem): raise ldap.NO_SUCH_OBJECT(elem) else: tree_pos = tree_pos[elem] return tree_pos
def modrdn_s(self, dn, new_rdn, *ign): elems = explode_dn(dn) elems.reverse() rdn = elems[-1] base = elems[:-1] tree_pos = TREE for elem in base: if tree_pos.has_key(elem): tree_pos = tree_pos[elem] else: raise ldap.NO_SUCH_OBJECT(elem) if not tree_pos.has_key(rdn): raise ldap.NO_SUCH_OBJECT(rdn) if tree_pos.has_key(new_rdn): raise ldap.ALREADY_EXISTS(new_rdn) rec = tree_pos.get(rdn) del tree_pos[rdn] tree_pos[new_rdn] = rec
def delete_s(self, dn): elems = explode_dn(dn) rdn = elems[0] tree_pos = TREE.getElementByDN(elems[1:]) if not tree_pos.has_key(rdn): raise ldap.NO_SUCH_OBJECT(rdn) # Maintain memberOf if self.maintain_memberof: record = tree_pos[rdn] if self.member_attr in record: for value in record[self.member_attr]: self.modify_s( value , [(ldap.MOD_DELETE, self.memberof_attr, [dn])] ) if self.memberof_attr in record: for value in record[self.memberof_attr]: self.modify_s( value , [(ldap.MOD_DELETE, self.member_attr, [dn])] ) del tree_pos[rdn]
def add_s(self, dn, attr_list): elems = explode_dn(dn) rdn = elems[0] tree_pos = TREE.getElementByDN(elems[1:]) if tree_pos.has_key(rdn): raise ldap.ALREADY_EXISTS(rdn) # Add rdn to attributes as well. rdn_key, rdn_value = rdn.split('=') tree_pos[rdn] = {rdn_key: [rdn_value]} record = tree_pos[rdn] for key, value in attr_list: record[key] = value # Maintain memberOf if self.maintain_memberof: if key == self.member_attr: for v in value: self.modify_s( v , [(ldap.MOD_ADD, self.memberof_attr, [dn])] )
def _start_docker_image(self, app, hostdn, password, args): docker = self._get_docker(app) if not docker: return self.log('Verifying Docker registry manifest for app image %s' % docker.image) docker.verify() if args.pull_image: docker.pull() self.log('Initializing app image') hostname = explode_dn(hostdn, 1)[0] set_vars = (args.set_vars or {}).copy() after_image_configuration = {} for setting in app.get_settings(): if setting.should_go_into_image_configuration(app): if setting.name not in set_vars: set_vars[setting.name] = setting.get_initial_value(app) else: try: after_image_configuration[setting.name] = set_vars.pop( setting.name) except KeyError: after_image_configuration[ setting.name] = setting.get_initial_value(app) set_vars['docker/host/name'] = '%s.%s' % (ucr_get('hostname'), ucr_get('domainname')) set_vars['ldap/hostdn'] = hostdn if app.docker_env_ldap_user: set_vars[app.docker_env_ldap_user] = hostdn set_vars['server/role'] = app.docker_server_role set_vars['update/warning/releasenotes'] = 'no' ucr_keys_list = list(ucr_keys()) for var in [ 'nameserver.*', 'repository/online/server', 'repository/app_center/server', 'update/secure_apt', 'appcenter/index/verify', 'ldap/base', 'ldap/server.*', 'ldap/master.*', 'locale.*', 'domainname' ]: for key in ucr_keys_list: if re.match(var, key): set_vars[key] = ucr_get(key) if ucr_is_true('appcenter/docker/container/proxy/settings', default=True): if ucr_get('proxy/http'): set_vars['proxy/http'] = ucr_get('proxy/http') set_vars['http_proxy'] = ucr_get('proxy/http') if ucr_get('proxy/https'): set_vars['proxy/https'] = ucr_get('proxy/https') set_vars['https_proxy'] = ucr_get('proxy/https') if ucr_get('proxy/no_proxy'): set_vars['proxy/no_proxy'] = ucr_get('proxy/no_proxy') set_vars['no_proxy'] = ucr_get('proxy/no_proxy') set_vars['updater/identify'] = 'Docker App' database_connector = DatabaseConnector.get_connector(app) database_password_file = None if database_connector: try: database_password = database_connector.get_db_password() database_password_file = database_connector.get_db_password_file( ) if database_password: set_vars[ app. docker_env_database_host] = database_connector.get_db_host( ) db_port = database_connector.get_db_port() if db_port: set_vars[app.docker_env_database_port] = db_port set_vars[ app. docker_env_database_name] = database_connector.get_db_name( ) set_vars[ app. docker_env_database_user] = database_connector.get_db_user( ) if app.docker_env_database_password_file: set_vars[ app. docker_env_database_password_file] = database_password_file else: set_vars[ app. docker_env_database_password] = database_password autostart_variable = database_connector.get_autostart_variable( ) if autostart_variable: set_vars[autostart_variable] = 'no' except DatabaseError as exc: raise DatabaseConnectorError(str(exc)) container = docker.create(hostname, set_vars) self.log('Preconfiguring container %s' % container) autostart = 'yes' if not Start.call(app=app): raise DockerCouldNotStartContainer(str(Status.get_status(app))) time.sleep(3) if not docker.is_running(): dlogs = docker.dockerd_logs() clogs = docker.logs() inspect = docker.inspect_container() msg = """ The container for {app} could not be started! docker logs {container}: {clogs} dockerd logs: {dlogs} docker inspect: {state} {graphdriver}""".format(app=app, container=docker.container, clogs=clogs, dlogs=dlogs, state=inspect.get('State'), graphdriver=inspect.get('GraphDriver')) raise AppCenterErrorContainerStart(msg) # copy password files if os.path.isfile(app.secret_on_host): # we can not use docker-cp here, as we support read-only containers too :-( f_name = docker.path('/etc/machine.secret') f_dir = os.path.dirname(f_name) # if the container start takes a little longer the f_dir may not exist yet # so wait max 60s for i in xrange(0, 12): if os.path.isdir(f_dir): break time.sleep(5) try: with open(f_name, 'w+b') as f: os.chmod(f_name, 0o600) f.write(password) except Exception as exc: raise DockerCouldNotStartContainer( 'Could not copy machine.secret to container: %s (%s)' % (str(exc), docker.logs())) if database_password_file: docker.cp_to_container(database_password_file, database_password_file) # update timezone in container logfile_logger = get_logfile_logger('docker.base') docker.execute('rm', '-f', '/etc/timezone', '/etc/localtime', _logger=logfile_logger) docker.cp_to_container('/etc/timezone', '/etc/timezone', _logger=logfile_logger) docker.cp_to_container('/etc/localtime', '/etc/localtime', _logger=logfile_logger) # configure app after_image_configuration.update(set_vars) configure = get_action('configure') configure.call(app=app, autostart=autostart, run_script='no', set_vars=after_image_configuration)
def from_udm_obj(cls, udm_obj, lo, pos): app_id = explode_dn(udm_obj.dn, 1)[1] app = FakeApp(id=app_id, version=udm_obj.info.get('version')) return cls(app, lo, pos)
def search_s(self, base, scope=ldap.SCOPE_SUBTREE, query='(objectClass=*)', attrs=()): elems = explode_dn(base) elems.reverse() tree_pos = TREE tree_pos_dn = '' for elem in elems: if not tree_pos_dn: tree_pos_dn = elem else: tree_pos_dn = '%s,%s' % (elem, tree_pos_dn) if tree_pos.has_key(elem): tree_pos = tree_pos[elem] else: raise ldap.NO_SUCH_OBJECT(elem) q = parse_query(query) if cmp_query(q, ANY, strict=True): # Return all objects, no matter what class if scope == ldap.SCOPE_BASE and tree_pos_dn == base: # Only if dn matches 'base' return [(base, deepcopy(filter_attrs(tree_pos, attrs)))] else: return [(k, deepcopy(filter_attrs(v, attrs))) for k, v in tree_pos.items()] by_level = {} for idx, (operation, filters) in enumerate(explode_query(q)): lvl = by_level[idx] = [] by_filter = {} for fltr in filters: sub = apply_filter(tree_pos, base, fltr) by_filter[fltr] = sub # Optimization: If it's an AND query bail out on # the first empty value, but still set the empty # value on by_filter so it gets caught in the # operations below. if not sub and operation.op in ('&',): break if filters: values = by_filter.values() else: # If there are no filters, it's an operation on # all the previous levels. values = by_level.values() if operation.op in ('|',): # Do an union lvl_vals = dict(lvl) lvl_keys = set(lvl_vals.keys()) for sub in values: sub_vals = dict(sub) sub_keys = set(sub_vals.keys()) for k in sub_keys - lvl_keys: lvl.append((k, sub_vals[k])) lvl_keys = sub_keys | lvl_keys elif operation.op in ('&',): # Do an intersection for sub in values: # Optimization: If it's an AND query bail out on # the first empty value. if not sub: lvl[:] = [] break if not lvl: lvl[:] = sub else: new_lvl = [] lvl_vals = dict(lvl) sub_vals = dict(sub) lvl_keys = set(lvl_vals.keys()) sub_keys = set(sub_vals.keys()) for k in sub_keys & lvl_keys: new_lvl.append((k, lvl_vals[k])) lvl[:] = new_lvl if by_level: # Return the last one. return [(k, deepcopy(filter_attrs(v, attrs))) for k, v in by_level[idx]] return []
inumApllience_inum = 'inum='+ ldif_parser.inumApllience processed_fp = open('gluu_noinum.ldif','w') ldif_writer = LDIFWriter(processed_fp) def checkIfAsimbaEntry(new_entry): for objCls in ('oxAsimbaConfiguration', 'oxAsimbaIDP', 'oxAsimbaRequestorPool', 'oxAsimbaSPRequestor', 'oxAsimbaSelector'): if objCls in new_entry['objectClass']: return True for dn in ldif_parser.DNs: dne = explode_dn(dn) new_entry = ldif_parser.entries[dn] #we won't have asimba, pass asimba related entries if checkIfAsimbaEntry(new_entry): continue if inumOrg_ou in dne: dne.remove(inumOrg_ou) if inumApllience_inum in dne: dne.remove(inumApllience_inum) dne.remove('ou=appliances')
def search_s(self, base, scope=ldap.SCOPE_SUBTREE, query='(objectClass=*)', attrs=()): parsed_query = self.parser.parse_query(query) tree_pos = TREE.getElementByDN(base) if self.parser.cmp_query(parsed_query, ANY, strict=True): # Return all objects, no matter what class if scope == ldap.SCOPE_BASE: # Only if dn matches 'base' return [(base, deepcopy(self._filter_attrs(tree_pos, attrs)))] else: return [(k, deepcopy(self._filter_attrs(v, attrs))) for k, v in tree_pos.items()] if scope == ldap.SCOPE_BASE: # At this stage tree_pos will be a leaf record. We need to # "re-wrap" it. rdn = explode_dn(base)[0] tree_pos = {rdn: tree_pos} by_level = {} enumerated = enumerate(self.parser.explode_query(parsed_query)) for idx, (operation, filters) in enumerated: lvl = by_level[idx] = [] by_filter = {} for fltr in filters: sub = fltr(tree_pos, base) by_filter[fltr] = sub # Optimization: If it's an AND query bail out on # the first empty value, but still set the empty # value on by_filter so it gets caught in the # operations below. if not sub and operation.op in ('&',): break if filters: values = by_filter.values() else: # If there are no filters, it's an operation on # all the previous levels. values = by_level.values() if operation.op in ('|',): # Do an union lvl_vals = dict(lvl) lvl_keys = set(lvl_vals.keys()) for sub in values: sub_vals = dict(sub) sub_keys = set(sub_vals.keys()) for k in sub_keys - lvl_keys: lvl.append((k, sub_vals[k])) lvl_keys = sub_keys | lvl_keys elif operation.op in ('&',): # Do an intersection for sub in values: # Optimization: If it's an AND query bail out on # the first empty value. if not sub: lvl[:] = [] break if not lvl: lvl[:] = sub else: new_lvl = [] lvl_vals = dict(lvl) sub_vals = dict(sub) lvl_keys = set(lvl_vals.keys()) sub_keys = set(sub_vals.keys()) for k in sub_keys & lvl_keys: new_lvl.append((k, lvl_vals[k])) lvl[:] = new_lvl if by_level: # Return the last one. return [(k, deepcopy(self._filter_attrs(v, attrs))) for k, v in by_level[idx]] return []
def _start_docker_image(self, app, hostdn, password, args): docker = self._get_docker(app) if not docker: return self.log('Verifying Docker registry manifest for app image %s' % docker.image) docker.verify() if args.pull_image: self.log('Downloading app image %s' % docker.image) if not docker.pull(): raise DockerImagePullFailed(docker.image) self.log('Initializing app image') hostname = explode_dn(hostdn, 1)[0] set_vars = (args.set_vars or {}).copy() after_image_configuration = {} for setting in app.get_settings(): if setting.should_go_into_image_configuration(app): if setting.name not in set_vars: set_vars[setting.name] = setting.get_initial_value() else: try: after_image_configuration[setting.name] = set_vars.pop( setting.name) except KeyError: pass set_vars['docker/host/name'] = '%s.%s' % (ucr_get('hostname'), ucr_get('domainname')) set_vars['ldap/hostdn'] = hostdn if app.docker_env_ldap_user: set_vars[app.docker_env_ldap_user] = hostdn set_vars['server/role'] = app.docker_server_role set_vars['update/warning/releasenotes'] = 'no' ucr_keys_list = list(ucr_keys()) for var in [ 'nameserver.*', 'repository/online/server', 'repository/app_center/server', 'update/secure_apt', 'appcenter/index/verify', 'ldap/master.*', 'locale.*', 'domainname' ]: for key in ucr_keys_list: if re.match(var, key): set_vars[key] = ucr_get(key) if ucr_is_true('appcenter/docker/container/proxy/settings', default=True): if ucr_get('proxy/http'): set_vars['proxy/http'] = ucr_get('proxy/http') set_vars['http_proxy'] = ucr_get('proxy/http') if ucr_get('proxy/https'): set_vars['proxy/https'] = ucr_get('proxy/https') set_vars['https_proxy'] = ucr_get('proxy/https') if ucr_get('proxy/no_proxy'): set_vars['proxy/no_proxy'] = ucr_get('proxy/no_proxy') set_vars['no_proxy'] = ucr_get('proxy/no_proxy') set_vars['updater/identify'] = 'Docker App' database_connector = DatabaseConnector.get_connector(app) database_password_file = None if database_connector: try: database_password = database_connector.get_db_password() database_password_file = database_connector.get_db_password_file( ) if database_password: set_vars[ app. docker_env_database_host] = database_connector.get_db_host( ) db_port = database_connector.get_db_port() if db_port: set_vars[app.docker_env_database_port] = db_port set_vars[ app. docker_env_database_name] = database_connector.get_db_name( ) set_vars[ app. docker_env_database_user] = database_connector.get_db_user( ) if app.docker_env_database_password_file: set_vars[ app. docker_env_database_password_file] = database_password_file else: set_vars[ app. docker_env_database_password] = database_password autostart_variable = database_connector.get_autostart_variable( ) if autostart_variable: set_vars[autostart_variable] = 'no' except DatabaseError as exc: raise DatabaseConnectorError(str(exc)) container = docker.create(hostname, set_vars) self.log('Preconfiguring container %s' % container) autostart = 'yes' if not Start.call(app=app): raise DockerCouldNotStartContainer() time.sleep(3) if not docker.is_running(): dlogs = docker.dockerd_logs() clogs = docker.logs() inspect = docker.inspect_container() msg = """ The container for {app} could not be started! docker logs {container}: {clogs} dockerd logs: {dlogs} docker inspect: {state} {graphdriver}""".format(app=app, container=docker.container, clogs='\n'.join(clogs), dlogs='\n'.join(dlogs), state=inspect.get('State'), graphdriver=inspect.get('GraphDriver')) raise AppCenterErrorContainerStart(msg) if password: with open(docker.path('/etc/machine.secret'), 'w+b') as f: f.write(password) docker.cp_to_container('/etc/timezone', '/etc/timezone') docker.cp_to_container('/etc/localtime', '/etc/localtime') if database_password_file: docker.cp_to_container(database_password_file, database_password_file) after_image_configuration.update(set_vars) configure = get_action('configure') configure.call(app=app, autostart=autostart, run_script='no', set_vars=after_image_configuration)
def handler(dn, new, old): change_affects_this_host = False need_to_reload_samba = False need_to_reload_cups = False printer_is_group = False quota_support = False samba_force_printername = listener.baseConfig.is_true( 'samba/force_printername', True) global reload_samba_in_postrun reload_samba_in_postrun = True changes = [] if old: if filter_match(old): if old.get('univentionPrinterSambaName'): old_sharename = old['univentionPrinterSambaName'][0] else: old_sharename = old['cn'][0] old_filename = '/etc/samba/printers.conf.d/%s' % old_sharename samba_force_printername = testparm_is_true(old_filename, old_sharename, 'force printername') if 'univentionPrinterGroup' in old.get('objectClass', ()): printer_is_group = True if old.get('univentionPrinterQuotaSupport', EMPTY)[0] == "1": quota_support = True if new: if 'univentionPrinterGroup' in new.get('objectClass', ()): printer_is_group = True if new.get('univentionPrinterQuotaSupport', EMPTY)[0] == "1": quota_support = True else: quota_support = False modified_uri = '' for n in new.keys(): if new.get(n, []) != old.get(n, []): changes.append(n) if n == 'univentionPrinterURI': if quota_support: modified_uri = "cupspykota:%s" % new['univentionPrinterURI'][0] else: modified_uri = new['univentionPrinterURI'][0] for o in old.keys(): if o not in changes and new.get(o, []) != old.get(o, []): changes.append(o) if o == 'univentionPrinterURI' and not modified_uri: if quota_support: modified_uri = "cupspykota:%s" % old['univentionPrinterURI'][0] else: modified_uri = old['univentionPrinterURI'][0] options = { 'univentionPrinterURI': '-v', 'univentionPrinterLocation': '-L', 'description': '-D', 'univentionPrinterModel': '-m' } if (filter_match(new) or filter_match(old)): change_affects_this_host = True reload_samba_in_postrun = True # default, if it isn't done earlier if filter_match(old): if 'cn' in changes or not filter_match(new): # Deletions done via UCR-Variables printer_name = old['cn'][0] listener.baseConfig.load() printer_list = listener.baseConfig.get('cups/restrictedprinters', '').split() printer_is_restricted = printer_name in printer_list if printer_is_restricted and not listener.baseConfig.is_false( 'cups/automaticrestrict', False): printer_list.remove(printer_name) keyval = 'cups/restrictedprinters=%s' % ' '.join(printer_list) listener.setuid(0) try: univention.config_registry.handler_set([keyval.encode()]) finally: listener.unsetuid() # Deletions done via lpadmin lpadmin(['-x', old['cn'][0]]) if old.get('univentionPrinterQuotaSupport', EMPTY)[0] == "1": if printer_is_group: for member in old['univentionPrinterGroupMember']: pkprinters( ['--groups', old['cn'][0], '--remove', member]) pkprinters(['--delete', old['cn'][0]]) need_to_reload_samba = True # Deletions done via editing the Samba config if old.get('univentionPrinterSambaName'): filename = '/etc/samba/printers.conf.d/%s' % old[ 'univentionPrinterSambaName'][0] listener.setuid(0) try: if os.path.exists(filename): os.unlink(filename) finally: listener.unsetuid() filename = '/etc/samba/printers.conf.d/%s' % old['cn'][0] listener.setuid(0) try: if os.path.exists(filename): os.unlink(filename) finally: listener.unsetuid() if filter_match(new): # Modifications done via UCR-Variables printer_name = new['cn'][0] listener.baseConfig.load() printer_list = listener.baseConfig.get('cups/restrictedprinters', '').split() printer_is_restricted = printer_name in printer_list restrict_printer = (new.get('univentionPrinterACLUsers', []) or new.get('univentionPrinterACLGroups', []) ) and not (new['univentionPrinterACLtype'][0] == 'allow all') update_restricted_printers = False if printer_is_restricted and not restrict_printer: printer_list.remove(printer_name) update_restricted_printers = True elif not printer_is_restricted and restrict_printer: printer_list.append(printer_name) update_restricted_printers = True if update_restricted_printers and not listener.baseConfig.is_false( 'cups/automaticrestrict', False): keyval = 'cups/restrictedprinters=%s' % ' '.join(printer_list) listener.setuid(0) try: univention.config_registry.handler_set([keyval.encode()]) finally: listener.unsetuid() need_to_reload_cups = True # Modifications done via lpadmin description = "" page_price = 0 job_price = 0 aclUsers = [] aclGroups = [] args = [] # lpadmin args if new.get('univentionPrinterSambaName'): description = new['univentionPrinterSambaName'][0] if new.get('univentionPrinterPricePerPage'): page_price = new['univentionPrinterPricePerPage'][0] if new.get('univentionPrinterPricePerJob'): job_price = new['univentionPrinterPricePerJob'][0] if new.get('univentionPrinterACLtype'): if new['univentionPrinterACLtype'][0] == 'allow all': args += ['-u', 'allow:all', '-o', 'auth-info-required=none'] elif new.get('univentionPrinterACLUsers') or new.get( 'univentionPrinterACLGroups'): args.append('-u') argument = "%s:" % new['univentionPrinterACLtype'][0] for userDn in new.get('univentionPrinterACLUsers', ()): argument += '%s,' % (explode_dn(userDn, True)[0], ) for groupDn in new.get('univentionPrinterACLGroups', ()): argument += '@%s,' % (explode_dn(groupDn, True)[0], ) args.append(argument[:-1]) else: args += ['-o', 'auth-info-required=none'] # Add/Modify Printergroup if printer_is_group: add = [] if old: # Diff old <==> new rem = old['univentionPrinterGroupMember'] for el in new['univentionPrinterGroupMember']: if el not in old['univentionPrinterGroupMember']: add.append(el) else: rem.remove(el) else: # Create new group add = new['univentionPrinterGroupMember'] if new.get('univentionPrinterQuotaSupport', EMPTY)[0] == "1": pkprinters([ "--add", "-D", '"%s"' % description, "--charge", "%s,%s" % (page_price, job_price), new['cn'][0] ]) for member in new['univentionPrinterGroupMember']: pkprinters(["--groups", new['cn'][0], member]) elif new.get('univentionPrinterQuotaSupport', EMPTY)[0] == "0" and old: for member in old['univentionPrinterGroupMember']: pkprinters(['--groups', old['cn'][0], '--remove', member]) for add_member in add: # Add Members args += ['-p', add_member, '-c', new['cn'][0]] if new.get('univentionPrinterQuotaSupport', EMPTY)[0] == "1": pkprinters(["--groups", new['cn'][0], add_member]) if old: # Remove Members for rem_member in rem: args += ['-p', rem_member, '-r', new['cn'][0]] pkprinters( ["--groups", new['cn'][0], "--remove", rem_member]) lpadmin(args) # Add/Modify Printer else: args.append('-p') args.append(new['cn'][0]) for a in changes: if a == 'univentionPrinterQuotaSupport': if new.get('univentionPrinterQuotaSupport'): if new['univentionPrinterQuotaSupport'][0] == '1': pkprinters([ "--add", "-D", '"%s"' % description, "--charge", "%s,%s" % (page_price, job_price), new['cn'][0] ]) else: pkprinters(['--delete', new['cn'][0]]) if a == 'univentionPrinterURI': continue if a == 'univentionPrinterSpoolHost' and 'univentionPrinterModel' not in changes: model = new.get('univentionPrinterModel', EMPTY)[0] if model in ['None', 'smb']: model = 'raw' args += [options['univentionPrinterModel'], model] if a not in options: continue if a == 'univentionPrinterModel': model = new.get(a, EMPTY)[0] if model in ['None', 'smb']: model = 'raw' args += [options[a], model] else: args += [options[a], '%s' % new.get(a, EMPTY)[0]] args += [options['univentionPrinterURI'], modified_uri] args += ['-E'] # insert printer lpadmin(args) need_to_reload_samba = True # Modifications done via editing Samba config printername = new['cn'][0] if new.get('univentionPrinterSambaName'): printername = new['univentionPrinterSambaName'][0] filename = '/etc/samba/printers.conf.d/%s' % printername listener.setuid(0) # samba permissions perm = "" # users for dn in new.get('univentionPrinterACLUsers', ()): user = explode_dn(dn, True)[0] if " " in user: user = "******"" + user + "\"" perm = perm + " " + user # groups for dn in new.get('univentionPrinterACLGroups', ()): group = "@" + explode_dn(dn, True)[0] if " " in group: group = "\"" + group + "\"" perm = perm + " " + group try: fp = open(filename, 'w') print >> fp, '[%s]' % printername print >> fp, 'printer name = %s' % new['cn'][0] print >> fp, 'path = /tmp' print >> fp, 'guest ok = yes' print >> fp, 'printable = yes' if samba_force_printername: print >> fp, 'force printername = yes' if perm: if new['univentionPrinterACLtype'][0] == 'allow': print >> fp, 'valid users = %s' % perm if new['univentionPrinterACLtype'][0] == 'deny': print >> fp, 'invalid users = %s' % perm if new.get('univentionPrinterUseClientDriver', [''])[0] == '1': print >> fp, 'use client driver = yes' uid = 0 gid = 0 mode = '0755' os.chmod(filename, int(mode, 0)) os.chown(filename, uid, gid) finally: listener.unsetuid() if change_affects_this_host: listener.setuid(0) try: fp = open('/etc/samba/printers.conf.temp', 'w') for f in os.listdir('/etc/samba/printers.conf.d'): print >> fp, 'include = %s' % os.path.join( '/etc/samba/printers.conf.d', f) fp.close() os.rename('/etc/samba/printers.conf.temp', '/etc/samba/printers.conf') finally: listener.unsetuid() reload_printer_restrictions() if need_to_reload_cups: reload_cups_daemon() if need_to_reload_samba: reload_smbd() time.sleep(3) reload_smbd()
def get_users_list(self, REQUEST): """ List accounts with the reporter and client roles for current folder and subfolders """ from ldap.dn import explode_dn role_param = REQUEST.get('role', '') members = {} global_members = {} catalog = getattr(self, constants.DEFAULT_CATALOG) ldap_groups = self.getLDAPGroups() # retrieve the global accounts ldap_user_folder = self.acl_users['ldapmultiplugin']['acl_users'] for user_dn, roles in ldap_user_folder.getLocalUsers(): member = explode_dn(user_dn,notypes=1)[0] for role in roles: if role_param and role_param in ['Reporter', 'Client']: if role == role_param: global_members[member] = { 'type': 'user', 'roles': [role] } else: if role in ['Reporter', 'Client']: if member in global_members: global_members[member]['roles'].append(role) else: global_members[member] = { 'type': 'user', 'roles': [role] } # retrieve the local accounts folders = catalog(meta_type=['Report Collection'], path=self.absolute_url(1)) for folder in folders: context = catalog.getobject(folder.data_record_id_) for member, roles in context.get_local_roles(): for role in list(roles): if role_param and role_param in ['Reporter', 'Client']: if role == role_param: if member in members: members[member]['roles'].append([context, [role]]) else: u_type = 'user' if member in ldap_groups: u_type = 'group' members[member] = { 'type': u_type, 'roles': [[context, [role]]] } else: if role in ['Reporter', 'Client']: if member in members: members[member]['roles'].append([context, list(roles)]) else: u_type = 'user' if member in ldap_groups: u_type = 'group' members[member] = { 'type': u_type, 'roles': [[context, list(roles)]] } return self._get_users_list(REQUEST, members=members, global_members=global_members, groups=bool(ldap_groups))