Example #1
0
def lock_exclusive():
    store.aquire_lock(cmk.utils.paths.default_config_dir + "/multisite.mk")
Example #2
0
 def start(self) -> None:
     try:
         store.aquire_lock(self._job_initializiation_lock)
         self._start()
     finally:
         store.release_lock(self._job_initializiation_lock)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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
Example #6
0
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
Example #7
0
def test_aquire_lock_not_existing(tmp_path, path_type):
    store.aquire_lock(path_type(tmp_path / "asd"))
Example #8
0
def test_acquire_lock_not_existing(tmpdir):
    store.aquire_lock("%s/asd" % tmpdir)
Example #9
0
def test_acquire_lock_not_existing(tmp_path):
    store.aquire_lock(str(tmp_path / "asd"))