<commit_before>#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#

import os
import re
import shutil
import socket
import array
import struct
import time
import pwd
import fcntl
import azurelinuxagent.logger as logger
from azurelinuxagent.future import text
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil

__RULES_FILES__ = [ "/lib/udev/rules.d/75-persistent-net-generator.rules",
                    "/etc/udev/rules.d/70-persistent-net.rules" ]

"""
Define distro specific behavior. OSUtil class defines default behavior
for all distros. Each concrete distro classes could overwrite default behavior
if needed.
"""

class OSUtilError(Exception):
    pass

class DefaultOSUtil(object):

    def __init__(self):
        self.lib_dir = "/var/lib/waagent"
        self.ext_log_dir = "/var/log/azure"
        self.dvd_mount_point = "/mnt/cdrom/secure"
        self.ovf_env_file_path = "/mnt/cdrom/secure/ovf-env.xml"
        self.agent_pid_file_path = "/var/run/waagent.pid"
        self.passwd_file_path = "/etc/shadow"
        self.home = '/home'
        self.sshd_conf_file_path = '/etc/ssh/sshd_config'
        self.openssl_cmd = '/usr/bin/openssl'
        self.conf_file_path = '/etc/waagent.conf'
        self.selinux=None

    def get_lib_dir(self):
        return self.lib_dir

    def get_ext_log_dir(self):
        return self.ext_log_dir

    def get_dvd_mount_point(self):
        return self.dvd_mount_point

    def get_conf_file_path(self):
        return self.conf_file_path

    def get_ovf_env_file_path_on_dvd(self):
        return self.ovf_env_file_path

    def get_agent_pid_file_path(self):
        return self.agent_pid_file_path

    def get_openssl_cmd(self):
        return self.openssl_cmd

    def get_userentry(self, username):
        try:
            return pwd.getpwnam(username)
        except KeyError:
            return None

    def is_sys_user(self, username):
        userentry = self.get_userentry(username)
        uidmin = None
        try:
            uidmin_def = fileutil.get_line_startingwith("UID_MIN", 
                                                        "/etc/login.defs")
            if uidmin_def is not None:
                uidmin = int(uidmin_def.split()[1])
        except IOError as e:
            pass
        if uidmin == None:
            uidmin = 100
        if userentry != None and userentry[2] < uidmin:
            return True
        else:
            return False

    def useradd(self, username, expiration=None):
        """
        Update password and ssh key for user account.
        New account will be created if not exists.
        """
        if expiration is not None:
            cmd = "useradd -m {0} -e {1}".format(username, expiration)
        else:
            cmd = "useradd -m {0}".format(username)
        retcode, out = shellutil.run_get_output(cmd)
        if retcode != 0:
            raise OSUtilError(("Failed to create user account:{0}, "
                               "retcode:{1}, "
                               "output:{2}").format(username, retcode, out))

    def chpasswd(self, username, password, crypt_id=6, salt_len=10):
        if self.is_sys_user(username):
            raise OSUtilError(("User {0} is a system user. "
                               "Will not set passwd.").format(username))
        passwd_hash = textutil.gen_password_hash(password, crypt_id, salt_len)
        try:
            passwd_content = fileutil.read_file(self.passwd_file_path)
            passwd = passwd_content.split("\n")
            new_passwd = [x for x in passwd if not x.startswith(username)]
            new_passwd.append("{0}:{1}:14600::::::".format(username, passwd_hash))
            fileutil.write_file(self.passwd_file_path, "\n".join(new_passwd))
        except IOError as e:
            raise OSUtilError(("Failed to set password for {0}: {1}"
                               "").format(username, e))

    def conf_sudoer(self, username, nopasswd):
        # for older distros create sudoers.d
        if not os.path.isdir('/etc/sudoers.d/'):
            # create the /etc/sudoers.d/ directory
            os.mkdir('/etc/sudoers.d/')
            # add the include of sudoers.d to the /etc/sudoers
            sudoers = '\n' + '#includedir /etc/sudoers.d/\n'
            fileutil.append_file('/etc/sudoers', sudoers)
        sudoer = None
        if nopasswd:
            sudoer = "{0} ALL = (ALL) NOPASSWD\n".format(username)
        else:
            sudoer = "{0} ALL = (ALL) ALL\n".format(username)
        fileutil.append_file('/etc/sudoers.d/waagent', sudoer)
        fileutil.chmod('/etc/sudoers.d/waagent', 0o440)<commit_msg>Using usermod -p to update user password hash<commit_after>#
# Copyright 2014 Microsoft Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Requires Python 2.4+ and Openssl 1.0+
#

import os
import re
import shutil
import socket
import array
import struct
import time
import pwd
import fcntl
import azurelinuxagent.logger as logger
from azurelinuxagent.future import text
import azurelinuxagent.utils.fileutil as fileutil
import azurelinuxagent.utils.shellutil as shellutil
import azurelinuxagent.utils.textutil as textutil

__RULES_FILES__ = [ "/lib/udev/rules.d/75-persistent-net-generator.rules",
                    "/etc/udev/rules.d/70-persistent-net.rules" ]

"""
Define distro specific behavior. OSUtil class defines default behavior
for all distros. Each concrete distro classes could overwrite default behavior
if needed.
"""

class OSUtilError(Exception):
    pass

class DefaultOSUtil(object):

    def __init__(self):
        self.lib_dir = "/var/lib/waagent"
        self.ext_log_dir = "/var/log/azure"
        self.dvd_mount_point = "/mnt/cdrom/secure"
        self.ovf_env_file_path = "/mnt/cdrom/secure/ovf-env.xml"
        self.agent_pid_file_path = "/var/run/waagent.pid"
        self.passwd_file_path = "/etc/shadow"
        self.home = '/home'
        self.sshd_conf_file_path = '/etc/ssh/sshd_config'
        self.openssl_cmd = '/usr/bin/openssl'
        self.conf_file_path = '/etc/waagent.conf'
        self.selinux=None

    def get_lib_dir(self):
        return self.lib_dir

    def get_ext_log_dir(self):
        return self.ext_log_dir

    def get_dvd_mount_point(self):
        return self.dvd_mount_point

    def get_conf_file_path(self):
        return self.conf_file_path

    def get_ovf_env_file_path_on_dvd(self):
        return self.ovf_env_file_path

    def get_agent_pid_file_path(self):
        return self.agent_pid_file_path

    def get_openssl_cmd(self):
        return self.openssl_cmd

    def get_userentry(self, username):
        try:
            return pwd.getpwnam(username)
        except KeyError:
            return None

    def is_sys_user(self, username):
        userentry = self.get_userentry(username)
        uidmin = None
        try:
            uidmin_def = fileutil.get_line_startingwith("UID_MIN", 
                                                        "/etc/login.defs")
            if uidmin_def is not None:
                uidmin = int(uidmin_def.split()[1])
        except IOError as e:
            pass
        if uidmin == None:
            uidmin = 100
        if userentry != None and userentry[2] < uidmin:
            return True
        else:
            return False

    def useradd(self, username, expiration=None):
        """
        Update password and ssh key for user account.
        New account will be created if not exists.
        """
        if expiration is not None:
            cmd = "useradd -m {0} -e {1}".format(username, expiration)
        else:
            cmd = "useradd -m {0}".format(username)
        retcode, out = shellutil.run_get_output(cmd)
        if retcode != 0:
            raise OSUtilError(("Failed to create user account:{0}, "
                               "retcode:{1}, "
                               "output:{2}").format(username, retcode, out))

    def chpasswd(self, username, password, crypt_id=6, salt_len=10):
        if self.is_sys_user(username):
            raise OSUtilError(("User {0} is a system user. "
                               "Will not set passwd.").format(username))
        passwd_hash = textutil.gen_password_hash(password, crypt_id, salt_len)
        cmd = "usermod {0} -p '{1}'".format(username, passwd_hash)
        ret, output = shellutil.run_get_output(cmd)
        if ret != 0:
            raise OSUtilError(("Failed to set password for {0}: {1}"
                               "").format(username, output))

    def conf_sudoer(self, username, nopasswd):
        # for older distros create sudoers.d
        if not os.path.isdir('/etc/sudoers.d/'):
            # create the /etc/sudoers.d/ directory
            os.mkdir('/etc/sudoers.d/')
            # add the include of sudoers.d to the /etc/sudoers
            sudoers = '\n' + '#includedir /etc/sudoers.d/\n'
            fileutil.append_file('/etc/sudoers', sudoers)
        sudoer = None
        if nopasswd:
            sudoer = "{0} ALL = (ALL) NOPASSWD\n".format(username)
        else:
            sudoer = "{0} ALL = (ALL) ALL\n".format(username)
        fileutil.append_file('/etc/sudoers.d/waagent', sudoer)
        fileutil.chmod('/etc/sudoers.d/waagent', 0o440)
{'fraction_non_alphanumeric': 0.09923150816522575, 'fraction_numerical': 0.008645533141210375, 'mean_word_length': 2.30612892981899, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6527093', 'n_tokens_mistral': 3259, 'n_tokens_neox': 3135, 'n_words': 826}