Beispiel #1
0
    def parent_dir_test(self):
        """Test the parent_dir function"""
        dirs = [("", ""), ("/", ""), ("/home/", ""), ("/home/bcl", "/home"), ("home/bcl", "home"),
                ("/home/bcl/", "/home"), ("/home/extra/bcl", "/home/extra"),
                ("/home/extra/bcl/", "/home/extra"), ("/home/extra/../bcl/", "/home")]

        for d, r in dirs:
            self.assertEqual(util.parent_dir(d), r)
Beispiel #2
0
    def parent_dir_test(self):
        """Test the parent_dir function"""
        dirs = [("", ""), ("/", ""), ("/home/", ""), ("/home/bcl", "/home"), ("home/bcl", "home"),
                ("/home/bcl/", "/home"), ("/home/extra/bcl", "/home/extra"),
                ("/home/extra/bcl/", "/home/extra"), ("/home/extra/../bcl/", "/home")]

        for d, r in dirs:
            self.assertEqual(util.parent_dir(d), r)
Beispiel #3
0
    def test_parent_dir(self):
        """Test the parent_dir function"""
        dirs = [("", ""), ("/", ""), ("/home/", ""), ("/home/bcl", "/home"),
                ("home/bcl", "home"), ("/home/bcl/", "/home"),
                ("/home/extra/bcl", "/home/extra"),
                ("/home/extra/bcl/", "/home/extra"),
                ("/home/extra/../bcl/", "/home")]

        for d, r in dirs:
            assert util.parent_dir(d) == r
Beispiel #4
0
def create_user(username,
                password=False,
                is_crypted=False,
                lock=False,
                homedir=None,
                uid=None,
                gid=None,
                groups=None,
                shell=None,
                gecos="",
                root=None):
    """Create a new user on the system with the given name.

    :param str username: The username for the new user to be created.
    :param str password: The password. See is_crypted for how this is interpreted.
                         If the password is "" then the account is created
                         with a blank password. If None or False the account will
                         be left in its initial state (locked)
    :param bool is_crypted: Is the password already encrypted? Defaults to False.
    :param bool lock: Is the new account locked by default?
                      Defaults to False.
    :param str homedir: The home directory for the new user.
                        Defaults to /home/<name>.
    :param int uid: The UID for the new user.
                    If none is given, the next available one is used.
    :param int gid: The GID for the new user.
                    If none is given, the next available one is used.
    :param groups: A list of group names the user should be added to.
                   Each group name can contain an optional GID in parenthesis,
                   such as "groupName(5000)".
                   Defaults to [].
    :type groups: list of str
    :param str shell: The shell for the new user.
                      If none is given, the login.defs default is used.
    :param str gecos: The GECOS information (full name, office, phone, etc.).
                      Defaults to "".
    :param str root: The directory of the system to create the new user in.
                     The homedir option will be interpreted relative to this.
                     Defaults to util.getSysroot().
    """

    # resolve the optional arguments that need a default that can't be
    # reasonably set in the function signature
    if homedir:
        homedir = homedir
    else:
        homedir = "/home/" + username

    if groups is None:
        groups = []

    if root is None:
        root = util.getSysroot()

    if check_user_exists(username, root):
        raise ValueError("User %s already exists" % username)

    args = ["-R", root]

    # Split the groups argument into a list of (username, gid or None) tuples
    # the gid, if any, is a string since that makes things simpler
    group_gids = [
        GROUPLIST_FANCY_PARSE.match(group).groups() for group in groups
    ]

    # If a specific gid is requested:
    #   - check if a group already exists with that GID. i.e., the user's
    #     GID should refer to a system group, such as users. If so, just set
    #     the GID.
    #   - check if a new group is requested with that GID. If so, set the GID
    #     and let the block below create the actual group.
    #   - if neither of those are true, create a new user group with the requested
    #     GID
    # otherwise use -U to create a new user group with the next available GID.
    if gid:
        if not _getgrgid(gid, root) and not any(one_gid[1] == str(gid)
                                                for one_gid in group_gids):
            create_group(username, gid=gid, root=root)

        args.extend(['-g', str(gid)])
    else:
        args.append('-U')

    # If any requested groups do not exist, create them.
    group_list = []
    for group_name, gid in group_gids:
        existing_group = _getgrnam(group_name, root)

        # Check for a bad GID request
        if gid and existing_group and gid != existing_group[2]:
            raise ValueError("Group %s already exists with GID %s" %
                             (group_name, gid))

        # Otherwise, create the group if it does not already exist
        if not existing_group:
            create_group(group_name, gid=gid, root=root)
        group_list.append(group_name)

    if group_list:
        args.extend(['-G', ",".join(group_list)])

    # useradd expects the parent directory tree to exist.
    parent_dir = util.parent_dir(root + homedir)

    # If root + homedir came out to "/", such as if we're creating the sshpw user,
    # parent_dir will be empty. Don't create that.
    if parent_dir:
        util.mkdirChain(parent_dir)

    args.extend(["-d", homedir])

    # Check whether the directory exists or if useradd should create it
    mk_homedir = not os.path.exists(root + homedir)
    if mk_homedir:
        args.append("-m")
    else:
        args.append("-M")

    if shell:
        args.extend(["-s", shell])

    if uid:
        args.extend(["-u", str(uid)])

    if gecos:
        args.extend(["-c", gecos])

    args.append(username)
    with _ensure_login_defs(root):
        status = util.execWithRedirect("useradd", args)

    if status == 4:
        raise ValueError("UID %s already exists" % uid)
    elif status == 6:
        raise ValueError("Invalid groups %s" % groups)
    elif status == 9:
        raise ValueError("User %s already exists" % username)
    elif status != 0:
        raise OSError("Unable to create user %s: status=%s" %
                      (username, status))

    if not mk_homedir:
        try:
            stats = os.stat(root + homedir)
            orig_uid = stats.st_uid
            orig_gid = stats.st_gid

            # Get the UID and GID of the created user
            pwent = _getpwnam(username, root)

            log.info(
                "Home directory for the user %s already existed, "
                "fixing the owner and SELinux context.", username)
            # home directory already existed, change owner of it properly
            util.chown_dir_tree(root + homedir, int(pwent[2]), int(pwent[3]),
                                orig_uid, orig_gid)
            util.execWithRedirect("restorecon", ["-r", root + homedir])
        except OSError as e:
            log.critical(
                "Unable to change owner of existing home directory: %s",
                e.strerror)
            raise

    set_user_password(username, password, is_crypted, lock, root)
Beispiel #5
0
    def createUser(self, user_name, *args, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           :keyword str algo: The password algorithm to use in case isCrypted=True.
                              If none is given, the cryptPassword default is used.
           :keyword str gecos: The GECOS information (full name, office, phone, etc.).
                               Defaults to "".
           :keyword groups: A list of group names the user should be added to.
                            Each group name can contain an optional GID in parenthesis,
                            such as "groupName(5000)". Defaults to [].
           :type groups: list of str
           :keyword str homedir: The home directory for the new user.  Defaults to
                                 /home/<name>.
           :keyword bool isCrypted: Is the password kwargs already encrypted?  Defaults
                                    to False.
           :keyword bool lock: Is the new account locked by default?  Defaults to
                               False.
           :keyword str password: The password.  See isCrypted for how this is interpreted.
                                  If the password is "" then the account is created
                                  with a blank password. If None or False the account will
                                  be left in its initial state (locked)
           :keyword str root: The directory of the system to create the new user
                              in.  homedir will be interpreted relative to this.
                              Defaults to util.getSysroot().
           :keyword str shell: The shell for the new user.  If none is given, the
                               login.defs default is used.
           :keyword int uid: The UID for the new user.  If none is given, the next
                             available one is used.
           :keyword int gid: The GID for the new user.  If none is given, the next
                             available one is used.
        """

        root = kwargs.get("root", util.getSysroot())

        if self.checkUserExists(user_name, root):
            raise ValueError("User %s already exists" % user_name)

        args = ["-R", root]

        # Split the groups argument into a list of (username, gid or None) tuples
        # the gid, if any, is a string since that makes things simpler
        group_gids = [GROUPLIST_FANCY_PARSE.match(group).groups()
                      for group in kwargs.get("groups", [])]

        # If a specific gid is requested:
        #   - check if a group already exists with that GID. i.e., the user's
        #     GID should refer to a system group, such as users. If so, just set
        #     the GID.
        #   - check if a new group is requested with that GID. If so, set the GID
        #     and let the block below create the actual group.
        #   - if neither of those are true, create a new user group with the requested
        #     GID
        # otherwise use -U to create a new user group with the next available GID.
        if kwargs.get("gid", None):
            if not self._getgrgid(kwargs['gid'], root) and \
                    not any(gid[1] == str(kwargs['gid']) for gid in group_gids):
                self.createGroup(user_name, gid=kwargs['gid'], root=root)

            args.extend(['-g', str(kwargs['gid'])])
        else:
            args.append('-U')

        # If any requested groups do not exist, create them.
        group_list = []
        for group_name, gid in group_gids:
            existing_group = self._getgrnam(group_name, root)

            # Check for a bad GID request
            if gid and existing_group and gid != existing_group[2]:
                raise ValueError("Group %s already exists with GID %s" % (group_name, gid))

            # Otherwise, create the group if it does not already exist
            if not existing_group:
                self.createGroup(group_name, gid=gid, root=root)
            group_list.append(group_name)

        if group_list:
            args.extend(['-G', ",".join(group_list)])

        if kwargs.get("homedir"):
            homedir = kwargs["homedir"]
        else:
            homedir = "/home/" + user_name

        # useradd expects the parent directory tree to exist.
        parent_dir = util.parent_dir(root + homedir)

        # If root + homedir came out to "/", such as if we're creating the sshpw user,
        # parent_dir will be empty. Don't create that.
        if parent_dir:
            util.mkdirChain(parent_dir)

        args.extend(["-d", homedir])

        # Check whether the directory exists or if useradd should create it
        mk_homedir = not os.path.exists(root + homedir)
        if mk_homedir:
            args.append("-m")
        else:
            args.append("-M")

        if kwargs.get("shell"):
            args.extend(["-s", kwargs["shell"]])

        if kwargs.get("uid"):
            args.extend(["-u", str(kwargs["uid"])])

        if kwargs.get("gecos"):
            args.extend(["-c", kwargs["gecos"]])

        args.append(user_name)
        with self._ensureLoginDefs(root):
            status = util.execWithRedirect("useradd", args)

        if status == 4:
            raise ValueError("UID %s already exists" % kwargs.get("uid"))
        elif status == 6:
            raise ValueError("Invalid groups %s" % kwargs.get("groups", []))
        elif status == 9:
            raise ValueError("User %s already exists" % user_name)
        elif status != 0:
            raise OSError("Unable to create user %s: status=%s" % (user_name, status))

        if not mk_homedir:
            try:
                stats = os.stat(root + homedir)
                orig_uid = stats.st_uid
                orig_gid = stats.st_gid

                # Gett the UID and GID of the created user
                pwent = self._getpwnam(user_name, root)

                log.info("Home directory for the user %s already existed, "
                         "fixing the owner and SELinux context.", user_name)
                # home directory already existed, change owner of it properly
                util.chown_dir_tree(root + homedir,
                                    int(pwent[2]), int(pwent[3]),
                                    orig_uid, orig_gid)
                util.execWithRedirect("restorecon", ["-r", root + homedir])
            except OSError as e:
                log.critical("Unable to change owner of existing home directory: %s", e.strerror)
                raise

        pw = kwargs.get("password", False)
        crypted = kwargs.get("isCrypted", False)
        algo = kwargs.get("algo", None)
        lock = kwargs.get("lock", False)

        self.setUserPassword(user_name, pw, crypted, lock, algo, root)
Beispiel #6
0
    def createUser(self, user_name, *args, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           :keyword str algo: The password algorithm to use in case isCrypted=True.
                              If none is given, the cryptPassword default is used.
           :keyword str gecos: The GECOS information (full name, office, phone, etc.).
                               Defaults to "".
           :keyword groups: A list of group names the user should be added to.
                            Each group name can contain an optional GID in parenthesis,
                            such as "groupName(5000)". Defaults to [].
           :type groups: list of str
           :keyword str homedir: The home directory for the new user.  Defaults to
                                 /home/<name>.
           :keyword bool isCrypted: Is the password kwargs already encrypted?  Defaults
                                    to False.
           :keyword bool lock: Is the new account locked by default?  Defaults to
                               False.
           :keyword str password: The password.  See isCrypted for how this is interpreted.
                                  If the password is "" then the account is created
                                  with a blank password. If None or False the account will
                                  be left in its initial state (locked)
           :keyword str root: The directory of the system to create the new user
                              in.  homedir will be interpreted relative to this.
                              Defaults to util.getSysroot().
           :keyword str shell: The shell for the new user.  If none is given, the
                               login.defs default is used.
           :keyword int uid: The UID for the new user.  If none is given, the next
                             available one is used.
           :keyword int gid: The GID for the new user.  If none is given, the next
                             available one is used.
        """

        root = kwargs.get("root", util.getSysroot())

        if self.checkUserExists(user_name, root):
            raise ValueError("User %s already exists" % user_name)

        args = ["-R", root]

        # Split the groups argument into a list of (username, gid or None) tuples
        # the gid, if any, is a string since that makes things simpler
        group_gids = [
            GROUPLIST_FANCY_PARSE.match(group).groups()
            for group in kwargs.get("groups", [])
        ]

        # If a specific gid is requested:
        #   - check if a group already exists with that GID. i.e., the user's
        #     GID should refer to a system group, such as users. If so, just set
        #     the GID.
        #   - check if a new group is requested with that GID. If so, set the GID
        #     and let the block below create the actual group.
        #   - if neither of those are true, create a new user group with the requested
        #     GID
        # otherwise use -U to create a new user group with the next available GID.
        if kwargs.get("gid", None):
            if not self._getgrgid(kwargs['gid'], root) and \
                    not any(gid[1] == str(kwargs['gid']) for gid in group_gids):
                self.createGroup(user_name, gid=kwargs['gid'], root=root)

            args.extend(['-g', str(kwargs['gid'])])
        else:
            args.append('-U')

        # If any requested groups do not exist, create them.
        group_list = []
        for group_name, gid in group_gids:
            existing_group = self._getgrnam(group_name, root)

            # Check for a bad GID request
            if gid and existing_group and gid != existing_group[2]:
                raise ValueError("Group %s already exists with GID %s" %
                                 (group_name, gid))

            # Otherwise, create the group if it does not already exist
            if not existing_group:
                self.createGroup(group_name, gid=gid, root=root)
            group_list.append(group_name)

        if group_list:
            args.extend(['-G', ",".join(group_list)])

        if kwargs.get("homedir"):
            homedir = kwargs["homedir"]
        else:
            homedir = "/home/" + user_name

        # useradd expects the parent directory tree to exist.
        parent_dir = util.parent_dir(root + homedir)

        # If root + homedir came out to "/", such as if we're creating the sshpw user,
        # parent_dir will be empty. Don't create that.
        if parent_dir:
            util.mkdirChain(parent_dir)

        args.extend(["-d", homedir])

        # Check whether the directory exists or if useradd should create it
        mk_homedir = not os.path.exists(root + homedir)
        if mk_homedir:
            args.append("-m")
        else:
            args.append("-M")

        if kwargs.get("shell"):
            args.extend(["-s", kwargs["shell"]])

        if kwargs.get("uid"):
            args.extend(["-u", str(kwargs["uid"])])

        if kwargs.get("gecos"):
            args.extend(["-c", kwargs["gecos"]])

        args.append(user_name)
        with self._ensureLoginDefs(root):
            status = util.execWithRedirect("useradd", args)

        if status == 4:
            raise ValueError("UID %s already exists" % kwargs.get("uid"))
        elif status == 6:
            raise ValueError("Invalid groups %s" % kwargs.get("groups", []))
        elif status == 9:
            raise ValueError("User %s already exists" % user_name)
        elif status != 0:
            raise OSError("Unable to create user %s: status=%s" %
                          (user_name, status))

        if not mk_homedir:
            try:
                stats = os.stat(root + homedir)
                orig_uid = stats.st_uid
                orig_gid = stats.st_gid

                # Gett the UID and GID of the created user
                pwent = self._getpwnam(user_name, root)

                log.info(
                    "Home directory for the user %s already existed, "
                    "fixing the owner and SELinux context.", user_name)
                # home directory already existed, change owner of it properly
                util.chown_dir_tree(root + homedir, int(pwent[2]),
                                    int(pwent[3]), orig_uid, orig_gid)
                util.execWithRedirect("restorecon", ["-r", root + homedir])
            except OSError as e:
                log.critical(
                    "Unable to change owner of existing home directory: %s",
                    e.strerror)
                raise

        pw = kwargs.get("password", False)
        crypted = kwargs.get("isCrypted", False)
        algo = kwargs.get("algo", None)
        lock = kwargs.get("lock", False)

        self.setUserPassword(user_name, pw, crypted, lock, algo, root)