def lock_exclusive(): store.aquire_lock(cmk.utils.paths.default_config_dir + "/multisite.mk")
def start(self) -> None: try: store.aquire_lock(self._job_initializiation_lock) self._start() finally: store.release_lock(self._job_initializiation_lock)
def _create_php_file(callee, users, role_permissions, groups): # Do not change WATO internal objects nagvis_users = copy.deepcopy(users) # Set a language for all users for user in nagvis_users.values(): user.setdefault('language', config.default_language) # need an extra lock file, since we move the auth.php.tmp file later # to auth.php. This move is needed for not having loaded incomplete # files into php. tempfile = _auth_base_dir + '/auth.php.tmp' lockfile = _auth_base_dir + '/auth.php.state' open(lockfile, "a") store.aquire_lock(lockfile) # First write a temp file and then do a move to prevent syntax errors # when reading half written files during creating that new file open(tempfile, 'w').write('''<?php // Created by Multisite UserDB Hook (%s) global $mk_users, $mk_roles, $mk_groups; $mk_users = %s; $mk_roles = %s; $mk_groups = %s; function all_users() { global $mk_users; return $mk_users; } function user_roles($username) { global $mk_users; if(!isset($mk_users[$username])) return array(); else return $mk_users[$username]['roles']; } function user_groups($username) { global $mk_users; if(!isset($mk_users[$username]) || !isset($mk_users[$username]['contactgroups'])) return array(); else return $mk_users[$username]['contactgroups']; } function user_permissions($username) { global $mk_roles; $permissions = array(); foreach(user_roles($username) AS $role) $permissions = array_merge($permissions, $mk_roles[$role]); // Make the array uniq array_flip($permissions); array_flip($permissions); return $permissions; } function users_with_role($want_role) { global $mk_users, $mk_roles; $result = array(); foreach($mk_users AS $username => $user) { foreach($user['roles'] AS $role) { if($want_role == $role) { $result[] = $username; } } } return $result; } function roles_with_permission($want_permission) { global $mk_roles; $result = array(); foreach($mk_roles AS $rolename => $role) { foreach($role AS $permission) { if($permission == $want_permission) { $result[] = $rolename; break; } } } return $result; } function users_with_permission($need_permission) { global $mk_users; $result = array(); foreach(roles_with_permission($need_permission) AS $rolename) { $result = array_merge($result, users_with_role($rolename)); } return $result; } function may($username, $need_permission) { global $mk_roles; foreach(user_roles($username) AS $role) { foreach($mk_roles[$role] AS $permission) { if($need_permission == $permission) { return true; } } } return false; } function permitted_maps($username) { global $mk_groups; $maps = array(); foreach (user_groups($username) AS $groupname) { if (isset($mk_groups[$groupname])) { foreach ($mk_groups[$groupname] AS $mapname) { $maps[$mapname] = null; } } } return array_keys($maps); } ?> ''' % (callee, _format_php(nagvis_users), _format_php(role_permissions), _format_php(groups))) # Now really replace the file os.rename(tempfile, _auth_base_dir + '/auth.php') store.release_lock(lockfile)
def _export_hosttags_to_php(cfg): php_api_dir = cmk.utils.paths.var_dir + "/wato/php-api/" path = php_api_dir + '/hosttags.php' store.mkdir(php_api_dir) tag_config = cmk.utils.tags.TagConfig() tag_config.parse_config(cfg) tag_config += cmk.utils.tags.BuiltinTagConfig() # need an extra lock file, since we move the auth.php.tmp file later # to auth.php. This move is needed for not having loaded incomplete # files into php. tempfile = path + '.tmp' lockfile = path + '.state' file(lockfile, 'a') store.aquire_lock(lockfile) # Transform WATO internal data structures into easier usable ones hosttags_dict = {} for tag_group in tag_config.tag_groups: tags = {} for grouped_tag in tag_group.tags: tags[grouped_tag.id] = (grouped_tag.title, grouped_tag.aux_tag_ids) hosttags_dict[tag_group.id] = (tag_group.topic, tag_group.title, tags) auxtags_dict = dict(tag_config.aux_tag_list.get_choices()) # First write a temp file and then do a move to prevent syntax errors # when reading half written files during creating that new file file(tempfile, 'w').write('''<?php // Created by WATO global $mk_hosttags, $mk_auxtags; $mk_hosttags = %s; $mk_auxtags = %s; function taggroup_title($group_id) { global $mk_hosttags; if (isset($mk_hosttags[$group_id])) return $mk_hosttags[$group_id][0]; else return $taggroup; } function taggroup_choice($group_id, $object_tags) { global $mk_hosttags; if (!isset($mk_hosttags[$group_id])) return false; foreach ($object_tags AS $tag) { if (isset($mk_hosttags[$group_id][2][$tag])) { // Found a match of the objects tags with the taggroup // now return an array of the matched tag and its alias return array($tag, $mk_hosttags[$group_id][2][$tag][0]); } } // no match found. Test whether or not a "None" choice is allowed if (isset($mk_hosttags[$group_id][2][null])) return array(null, $mk_hosttags[$group_id][2][null][0]); else return null; // no match found } function all_taggroup_choices($object_tags) { global $mk_hosttags; $choices = array(); foreach ($mk_hosttags AS $group_id => $group) { $choices[$group_id] = array( 'topic' => $group[0], 'title' => $group[1], 'value' => taggroup_choice($group_id, $object_tags), ); } return $choices; } ?> ''' % (_format_php(hosttags_dict), _format_php(auxtags_dict))) # Now really replace the destination file os.rename(tempfile, path) store.release_lock(lockfile) os.unlink(lockfile)
def load_users(lock: bool = False) -> Users: filename = _root_dir() + "contacts.mk" if lock: # Note: the lock will be released on next save_users() call or at # end of page request automatically. store.aquire_lock(filename) if 'users' in g: return g.users # First load monitoring contacts from Check_MK's world. If this is # the first time, then the file will be empty, which is no problem. # Execfile will the simply leave contacts = {} unchanged. contacts = store.load_from_mk_file(filename, "contacts", {}) # Now load information about users from the GUI config world filename = _multisite_dir() + "users.mk" users = store.load_from_mk_file(_multisite_dir() + "users.mk", "multisite_users", {}) # Merge them together. Monitoring users not known to Multisite # will be added later as normal users. result = {} for uid, user in users.items(): # Transform user IDs which were stored with a wrong type uid = ensure_str(uid) profile = contacts.get(uid, {}) profile.update(user) result[uid] = profile # Convert non unicode mail addresses if "email" in profile: profile["email"] = ensure_str(profile["email"]) # This loop is only neccessary if someone has edited # contacts.mk manually. But we want to support that as # far as possible. for uid, contact in contacts.items(): # Transform user IDs which were stored with a wrong type uid = ensure_str(uid) if uid not in result: result[uid] = contact result[uid]["roles"] = ["user"] result[uid]["locked"] = True result[uid]["password"] = "" # Passwords are read directly from the apache htpasswd-file. # That way heroes of the command line will still be able to # change passwords with htpasswd. Users *only* appearing # in htpasswd will also be loaded and assigned to the role # they are getting according to the multisite old-style # configuration variables. def readlines(f): try: return Path(f).open(encoding="utf-8") except IOError: return [] # FIXME TODO: Consolidate with htpasswd user connector filename = cmk.utils.paths.htpasswd_file for line in readlines(filename): line = line.strip() if ':' in line: uid, password = line.strip().split(":")[:2] uid = ensure_str(uid) if password.startswith("!"): locked = True password = password[1:] else: locked = False if uid in result: result[uid]["password"] = password result[uid]["locked"] = locked else: # Create entry if this is an admin user new_user = { "roles": config.roles_of_user(uid), "password": password, "locked": False, } result[uid] = new_user # Make sure that the user has an alias result[uid].setdefault("alias", uid) # Other unknown entries will silently be dropped. Sorry... # Now read the serials, only process for existing users serials_file = '%s/auth.serials' % os.path.dirname( cmk.utils.paths.htpasswd_file) for line in readlines(serials_file): line = line.strip() if ':' in line: user_id, serial = line.split(':')[:2] user_id = ensure_str(user_id) if user_id in result: result[user_id]['serial'] = utils.saveint(serial) # Now read the user specific files directory = cmk.utils.paths.var_dir + "/web/" for d in os.listdir(directory): if d[0] != '.': uid = ensure_str(d) # read special values from own files if uid in result: for attr, conv_func in [ ('num_failed_logins', utils.saveint), ('last_pw_change', utils.saveint), ('last_seen', utils.savefloat), ('enforce_pw_change', lambda x: bool(utils.saveint(x))), ('idle_timeout', _convert_idle_timeout), ('session_id', _convert_session_info), ]: val = load_custom_attr(uid, attr, conv_func) if val is not None: result[uid][attr] = val # read automation secrets and add them to existing # users or create new users automatically try: user_secret_path = Path(directory) / d / "automation.secret" with user_secret_path.open(encoding="utf-8") as f: secret: Optional[str] = ensure_str(f.read().strip()) except IOError: secret = None if secret: if uid in result: result[uid]["automation_secret"] = secret else: result[uid] = { "roles": ["guest"], "automation_secret": secret, } # populate the users cache g.users = result return result
def test_aquire_lock(locked_file, path_type): path = path_type(locked_file) assert store.have_lock(path) is False store.aquire_lock(path) assert store.have_lock(path) is True
def test_aquire_lock_not_existing(tmp_path, path_type): store.aquire_lock(path_type(tmp_path / "asd"))
def test_acquire_lock_not_existing(tmpdir): store.aquire_lock("%s/asd" % tmpdir)
def test_acquire_lock_not_existing(tmp_path): store.aquire_lock(str(tmp_path / "asd"))