Blame cloudinit/distros/netbsd.py

Packit Service 751c4a
# Copyright (C) 2019-2020 Gonéri Le Bouder
Packit Service 751c4a
#
Packit Service 751c4a
# This file is part of cloud-init. See LICENSE file for license information.
Packit Service 751c4a
Packit Service 751c4a
import crypt
Packit Service 751c4a
import os
Packit Service 751c4a
import platform
Packit Service 751c4a
Packit Service 751c4a
import cloudinit.distros.bsd
Packit Service 751c4a
from cloudinit import log as logging
Packit Service 751c4a
from cloudinit import subp
Packit Service 751c4a
from cloudinit import util
Packit Service 751c4a
Packit Service 751c4a
LOG = logging.getLogger(__name__)
Packit Service 751c4a
Packit Service 751c4a
Packit Service 751c4a
class NetBSD(cloudinit.distros.bsd.BSD):
Packit Service 751c4a
    """
Packit Service 751c4a
    Distro subclass for NetBSD.
Packit Service 751c4a
Packit Service 751c4a
    (N.B. OpenBSD inherits from this class.)
Packit Service 751c4a
    """
Packit Service 751c4a
Packit Service 751c4a
    ci_sudoers_fn = '/usr/pkg/etc/sudoers.d/90-cloud-init-users'
Packit Service 751c4a
    group_add_cmd_prefix = ["groupadd"]
Packit Service 751c4a
Packit Service 751c4a
    def __init__(self, name, cfg, paths):
Packit Service 751c4a
        super().__init__(name, cfg, paths)
Packit Service 751c4a
        if os.path.exists("/usr/pkg/bin/pkgin"):
Packit Service 751c4a
            self.pkg_cmd_install_prefix = ['pkgin', '-y', 'install']
Packit Service 751c4a
            self.pkg_cmd_remove_prefix = ['pkgin', '-y', 'remove']
Packit Service 751c4a
            self.pkg_cmd_update_prefix = ['pkgin', '-y', 'update']
Packit Service 751c4a
            self.pkg_cmd_upgrade_prefix = ['pkgin', '-y', 'full-upgrade']
Packit Service 751c4a
        else:
Packit Service 751c4a
            self.pkg_cmd_install_prefix = ['pkg_add', '-U']
Packit Service 751c4a
            self.pkg_cmd_remove_prefix = ['pkg_delete']
Packit Service 751c4a
Packit Service 751c4a
    def _get_add_member_to_group_cmd(self, member_name, group_name):
Packit Service 751c4a
        return ['usermod', '-G', group_name, member_name]
Packit Service 751c4a
Packit Service 751c4a
    def add_user(self, name, **kwargs):
Packit Service 751c4a
        if util.is_user(name):
Packit Service 751c4a
            LOG.info("User %s already exists, skipping.", name)
Packit Service 751c4a
            return False
Packit Service 751c4a
Packit Service 751c4a
        adduser_cmd = ['useradd']
Packit Service 751c4a
        log_adduser_cmd = ['useradd']
Packit Service 751c4a
Packit Service 751c4a
        adduser_opts = {
Packit Service 751c4a
            "homedir": '-d',
Packit Service 751c4a
            "gecos": '-c',
Packit Service 751c4a
            "primary_group": '-g',
Packit Service 751c4a
            "groups": '-G',
Packit Service 751c4a
            "shell": '-s',
Packit Service 751c4a
        }
Packit Service 751c4a
        adduser_flags = {
Packit Service 751c4a
            "no_user_group": '--no-user-group',
Packit Service 751c4a
            "system": '--system',
Packit Service 751c4a
            "no_log_init": '--no-log-init',
Packit Service 751c4a
        }
Packit Service 751c4a
Packit Service 751c4a
        for key, val in kwargs.items():
Packit Service 751c4a
            if key in adduser_opts and val and isinstance(val, str):
Packit Service 751c4a
                adduser_cmd.extend([adduser_opts[key], val])
Packit Service 751c4a
Packit Service 751c4a
            elif key in adduser_flags and val:
Packit Service 751c4a
                adduser_cmd.append(adduser_flags[key])
Packit Service 751c4a
                log_adduser_cmd.append(adduser_flags[key])
Packit Service 751c4a
Packit Service 751c4a
        if 'no_create_home' not in kwargs or 'system' not in kwargs:
Packit Service 751c4a
            adduser_cmd += ['-m']
Packit Service 751c4a
            log_adduser_cmd += ['-m']
Packit Service 751c4a
Packit Service 751c4a
        adduser_cmd += [name]
Packit Service 751c4a
        log_adduser_cmd += [name]
Packit Service 751c4a
Packit Service 751c4a
        # Run the command
Packit Service 751c4a
        LOG.info("Adding user %s", name)
Packit Service 751c4a
        try:
Packit Service 751c4a
            subp.subp(adduser_cmd, logstring=log_adduser_cmd)
Packit Service 751c4a
        except Exception:
Packit Service 751c4a
            util.logexc(LOG, "Failed to create user %s", name)
Packit Service 751c4a
            raise
Packit Service 751c4a
        # Set the password if it is provided
Packit Service 751c4a
        # For security consideration, only hashed passwd is assumed
Packit Service 751c4a
        passwd_val = kwargs.get('passwd', None)
Packit Service 751c4a
        if passwd_val is not None:
Packit Service 751c4a
            self.set_passwd(name, passwd_val, hashed=True)
Packit Service 751c4a
Packit Service 751c4a
    def set_passwd(self, user, passwd, hashed=False):
Packit Service 751c4a
        if hashed:
Packit Service 751c4a
            hashed_pw = passwd
Packit Service 751c4a
        elif not hasattr(crypt, 'METHOD_BLOWFISH'):
Packit Service 751c4a
            # crypt.METHOD_BLOWFISH comes with Python 3.7 which is available
Packit Service 751c4a
            # on NetBSD 7 and 8.
Packit Service 751c4a
            LOG.error((
Packit Service 751c4a
                'Cannot set non-encrypted password for user %s. '
Packit Service 751c4a
                'Python >= 3.7 is required.'), user)
Packit Service 751c4a
            return
Packit Service 751c4a
        else:
Packit Service 751c4a
            method = crypt.METHOD_BLOWFISH  # pylint: disable=E1101
Packit Service 751c4a
            hashed_pw = crypt.crypt(
Packit Service 751c4a
                passwd,
Packit Service 751c4a
                crypt.mksalt(method)
Packit Service 751c4a
            )
Packit Service 751c4a
Packit Service 751c4a
        try:
Packit Service 751c4a
            subp.subp(['usermod', '-p', hashed_pw, user])
Packit Service 751c4a
        except Exception:
Packit Service 751c4a
            util.logexc(LOG, "Failed to set password for %s", user)
Packit Service 751c4a
            raise
Packit Service 751c4a
        self.unlock_passwd(user)
Packit Service 751c4a
Packit Service 751c4a
    def force_passwd_change(self, user):
Packit Service 751c4a
        try:
Packit Service 751c4a
            subp.subp(['usermod', '-F', user])
Packit Service 751c4a
        except Exception:
Packit Service 751c4a
            util.logexc(LOG, "Failed to set pw expiration for %s", user)
Packit Service 751c4a
            raise
Packit Service 751c4a
Packit Service 751c4a
    def lock_passwd(self, name):
Packit Service 751c4a
        try:
Packit Service 751c4a
            subp.subp(['usermod', '-C', 'yes', name])
Packit Service 751c4a
        except Exception:
Packit Service 751c4a
            util.logexc(LOG, "Failed to lock user %s", name)
Packit Service 751c4a
            raise
Packit Service 751c4a
Packit Service 751c4a
    def unlock_passwd(self, name):
Packit Service 751c4a
        try:
Packit Service 751c4a
            subp.subp(['usermod', '-C', 'no', name])
Packit Service 751c4a
        except Exception:
Packit Service 751c4a
            util.logexc(LOG, "Failed to unlock user %s", name)
Packit Service 751c4a
            raise
Packit Service 751c4a
Packit Service 751c4a
    def apply_locale(self, locale, out_fn=None):
Packit Service 751c4a
        LOG.debug('Cannot set the locale.')
Packit Service 751c4a
Packit Service 751c4a
    def apply_network_config_names(self, netconfig):
Packit Service 751c4a
        LOG.debug('NetBSD cannot rename network interface.')
Packit Service 751c4a
Packit Service 751c4a
    def _get_pkg_cmd_environ(self):
Packit Service 751c4a
        """Return env vars used in NetBSD package_command operations"""
Packit Service 751c4a
        os_release = platform.release()
Packit Service 751c4a
        os_arch = platform.machine()
Packit Service 751c4a
        e = os.environ.copy()
Packit Service 751c4a
        e['PKG_PATH'] = (
Packit Service 751c4a
            'http://cdn.netbsd.org/pub/pkgsrc/'
Packit Service 751c4a
            'packages/NetBSD/%s/%s/All'
Packit Service 751c4a
        ) % (os_arch, os_release)
Packit Service 751c4a
        return e
Packit Service 751c4a
Packit Service 751c4a
    def update_package_sources(self):
Packit Service 751c4a
        pass
Packit Service 751c4a
Packit Service 751c4a
Packit Service 751c4a
class Distro(NetBSD):
Packit Service 751c4a
    pass
Packit Service 751c4a
Packit Service 751c4a
# vi: ts=4 expandtab