Example #1
0
    def createUser (self, user_name, *args, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           algo      -- The password algorithm to use in case isCrypted=True.
                        If none is given, the cryptPassword default is used.
           gecos     -- The GECOS information (full name, office, phone, etc.).
                        Defaults to "".
           groups    -- A list of existing group names the user should be
                        added to.  Defaults to [].
           homedir   -- The home directory for the new user.  Defaults to
                        /home/<name>.
           isCrypted -- Is the password kwargs already encrypted?  Defaults
                        to False.
           lock      -- Is the new account locked by default?  Defaults to
                        False.
           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)
           root      -- The directory of the system to create the new user
                        in.  homedir will be interpreted relative to this.
                        Defaults to /mnt/sysimage.
           shell     -- The shell for the new user.  If none is given, the
                        libuser default is used.
           uid       -- The UID for the new user.  If none is given, the next
                        available one is used.
           gid       -- The GID for the new user.  If none is given, the next
                        available one is used.
        """
        childpid = os.fork()
        root = kwargs.get("root", "/mnt/sysimage")

        if not childpid:
            if not root in ["","/"]:
                os.chroot(root)
                os.chdir("/")
                del(os.environ["LIBUSER_CONF"])

            self.admin = libuser.admin()

            if self.admin.lookupUserByName(user_name):
                log.error("User %s already exists, not creating.", user_name)
                os._exit(1)

            userEnt = self.admin.initUser(user_name)
            groupEnt = self.admin.initGroup(user_name)

            if kwargs.get("gid", -1) >= 0:
                groupEnt.set(libuser.GIDNUMBER, kwargs["gid"])

            grpLst = filter(lambda grp: grp,
                            map(self.admin.lookupGroupByName, kwargs.get("groups", [])))
            userEnt.set(libuser.GIDNUMBER, [groupEnt.get(libuser.GIDNUMBER)[0]] +
                        map(lambda grp: grp.get(libuser.GIDNUMBER)[0], grpLst))

            if kwargs.get("homedir", False):
                userEnt.set(libuser.HOMEDIRECTORY, kwargs["homedir"])
            else:
                iutil.mkdirChain('/home')
                userEnt.set(libuser.HOMEDIRECTORY, "/home/" + user_name)

            if kwargs.get("shell", False):
                userEnt.set(libuser.LOGINSHELL, kwargs["shell"])

            if kwargs.get("uid", -1) >= 0:
                userEnt.set(libuser.UIDNUMBER, kwargs["uid"])

            if kwargs.get("gecos", False):
                userEnt.set(libuser.GECOS, kwargs["gecos"])

            # need to create home directory for the user or does it already exist?
            # userEnt.get returns lists (usually with a single item)
            mk_homedir = not os.path.exists(userEnt.get(libuser.HOMEDIRECTORY)[0])

            try:
                self.admin.addUser(userEnt, mkmailspool=kwargs.get("mkmailspool", True),
                                   mkhomedir=mk_homedir)
            except RuntimeError as e:
                log.critical("Error when creating new user: %s", e)
                os._exit(1)

            try:
                self.admin.addGroup(groupEnt)
            except RuntimeError as e:
                log.critical("Error when creating new group: %s", e)
                os._exit(1)

            if not mk_homedir:
                try:
                    stats = os.stat(userEnt.get(libuser.HOMEDIRECTORY)[0])
                    orig_uid = stats.st_uid
                    orig_gid = stats.st_gid

                    log.info("Home directory for the user %s already existed, "
                             "fixing the owner.", user_name)
                    # home directory already existed, change owner of it properly
                    iutil.chown_dir_tree(userEnt.get(libuser.HOMEDIRECTORY)[0],
                                         userEnt.get(libuser.UIDNUMBER)[0],
                                         groupEnt.get(libuser.GIDNUMBER)[0],
                                         orig_uid, orig_gid)
                except OSError as e:
                    log.critical("Unable to change owner of existing home directory: %s",
                            os.strerror)
                    os._exit(1)

            pw = kwargs.get("password", False)
            try:
                if pw:
                    if kwargs.get("isCrypted", False):
                        password = kwargs["password"]
                    else:
                        password = cryptPassword(kwargs["password"], algo=kwargs.get("algo", None))
                    self.admin.setpassUser(userEnt, password, True)
                    userEnt.set(libuser.SHADOWLASTCHANGE, "")
                    self.admin.modifyUser(userEnt)
                elif pw == "":
                    # Setup the account with *NO* password
                    self.admin.unlockUser(userEnt)
                    log.info("user account %s setup with no password", user_name)

                if kwargs.get("lock", False):
                    self.admin.lockUser(userEnt)
                    log.info("user account %s locked", user_name)
            # setpassUser raises SystemError on failure, while unlockUser and lockUser
            # raise RuntimeError
            except (RuntimeError, SystemError) as e:
                log.critical("Unable to set password for new user: %s", e)
                os._exit(1)

            # Add the user to all the groups they should be part of.
            grpLst.append(self.admin.lookupGroupByName(user_name))
            try:
                for grp in grpLst:
                    grp.add(libuser.MEMBERNAME, user_name)
                    self.admin.modifyGroup(grp)
            except RuntimeError as e:
                log.critical("Unable to add user to groups: %s", e)
                os._exit(1)

            os._exit(0)

        try:
            status = os.waitpid(childpid, 0)[1]
        except OSError as e:
            log.critical("exception from waitpid while creating a user: %s %s", e.errno, e.strerror)
            return False

        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
            return True
        else:
            return False
Example #2
0
    def createUser (self, user_name, *args, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           algo      -- The password algorithm to use in case isCrypted=True.
                        If none is given, the cryptPassword default is used.
           gecos     -- The GECOS information (full name, office, phone, etc.).
                        Defaults to "".
           groups    -- A list of existing group names the user should be
                        added to.  Defaults to [].
           homedir   -- The home directory for the new user.  Defaults to
                        /home/<name>.
           isCrypted -- Is the password kwargs already encrypted?  Defaults
                        to False.
           lock      -- Is the new account locked by default?  Defaults to
                        False.
           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)
           root      -- The directory of the system to create the new user
                        in.  homedir will be interpreted relative to this.
                        Defaults to /mnt/sysimage.
           shell     -- The shell for the new user.  If none is given, the
                        libuser default is used.
           uid       -- The UID for the new user.  If none is given, the next
                        available one is used.
           gid       -- The GID for the new user.  If none is given, the next
                        available one is used.
        """
        childpid = os.fork()
        root = kwargs.get("root", "/mnt/sysimage")

        if not childpid:
            if not root in ["","/"]:
                os.chroot(root)
                os.chdir("/")
                del(os.environ["LIBUSER_CONF"])

            self.admin = libuser.admin()

            if self.admin.lookupUserByName(user_name):
                log.error("User %s already exists, not creating.", user_name)
                os._exit(1)

            userEnt = self.admin.initUser(user_name)
            groupEnt = self.admin.initGroup(user_name)

            if kwargs.get("gid", -1) >= 0:
                groupEnt.set(libuser.GIDNUMBER, kwargs["gid"])

            grpLst = filter(lambda grp: grp,
                            map(self.admin.lookupGroupByName, kwargs.get("groups", [])))
            userEnt.set(libuser.GIDNUMBER, [groupEnt.get(libuser.GIDNUMBER)[0]] +
                        map(lambda grp: grp.get(libuser.GIDNUMBER)[0], grpLst))

            if kwargs.get("homedir", False):
                userEnt.set(libuser.HOMEDIRECTORY, kwargs["homedir"])
            else:
                iutil.mkdirChain('/home')
                userEnt.set(libuser.HOMEDIRECTORY, "/home/" + user_name)

            if kwargs.get("shell", False):
                userEnt.set(libuser.LOGINSHELL, kwargs["shell"])

            if kwargs.get("uid", -1) >= 0:
                userEnt.set(libuser.UIDNUMBER, kwargs["uid"])

            if kwargs.get("gecos", False):
                userEnt.set(libuser.GECOS, kwargs["gecos"])

            # need to create home directory for the user or does it already exist?
            # userEnt.get returns lists (usually with a single item)
            mk_homedir = not os.path.exists(userEnt.get(libuser.HOMEDIRECTORY)[0])

            try:
                self.admin.addUser(userEnt, mkmailspool=kwargs.get("mkmailspool", True),
                                   mkhomedir=mk_homedir)
            except RuntimeError as e:
                log.critical("Error when creating new user: %s", e)
                os._exit(1)

            try:
                self.admin.addGroup(groupEnt)
            except RuntimeError as e:
                log.critical("Error when creating new group: %s", e)
                os._exit(1)

            if not mk_homedir:
                try:
                    stats = os.stat(userEnt.get(libuser.HOMEDIRECTORY)[0])
                    orig_uid = stats.st_uid
                    orig_gid = stats.st_gid

                    log.info("Home directory for the user %s already existed, "
                             "fixing the owner.", user_name)
                    # home directory already existed, change owner of it properly
                    iutil.chown_dir_tree(userEnt.get(libuser.HOMEDIRECTORY)[0],
                                         userEnt.get(libuser.UIDNUMBER)[0],
                                         groupEnt.get(libuser.GIDNUMBER)[0],
                                         orig_uid, orig_gid)
                except OSError as e:
                    log.critical("Unable to change owner of existing home directory: %s",
                            os.strerror)
                    os._exit(1)

            pw = kwargs.get("password", False)
            try:
                if pw:
                    if kwargs.get("isCrypted", False):
                        password = kwargs["password"]
                    else:
                        password = cryptPassword(kwargs["password"], algo=kwargs.get("algo", None))
                    self.admin.setpassUser(userEnt, password, True)
                    userEnt.set(libuser.SHADOWLASTCHANGE, "")
                    self.admin.modifyUser(userEnt)
                elif pw == "":
                    # Setup the account with *NO* password
                    self.admin.unlockUser(userEnt)
                    log.info("user account %s setup with no password", user_name)

                if kwargs.get("lock", False):
                    self.admin.lockUser(userEnt)
                    log.info("user account %s locked", user_name)
            # setpassUser raises SystemError on failure, while unlockUser and lockUser
            # raise RuntimeError
            except (RuntimeError, SystemError) as e:
                log.critical("Unable to set password for new user: %s", e)
                os._exit(1)

            # Add the user to all the groups they should be part of.
            grpLst.append(self.admin.lookupGroupByName(user_name))
            try:
                for grp in grpLst:
                    grp.add(libuser.MEMBERNAME, user_name)
                    self.admin.modifyGroup(grp)
            except RuntimeError as e:
                log.critical("Unable to add user to groups: %s", e)
                os._exit(1)

            os._exit(0)

        try:
            status = os.waitpid(childpid, 0)[1]
        except OSError as e:
            log.critical("exception from waitpid while creating a user: %s %s", e.errno, e.strerror)
            return False

        if os.WIFEXITED(status) and (os.WEXITSTATUS(status) == 0):
            return True
        else:
            return False
Example #3
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 iutil.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", iutil.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 = iutil.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:
            iutil.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 = iutil.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
                iutil.chown_dir_tree(root + homedir, int(pwent[2]),
                                     int(pwent[3]), orig_uid, orig_gid)
                iutil.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)
Example #4
0
    def createUser(self, user_name, *args, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           algo      -- The password algorithm to use in case isCrypted=True.
                        If none is given, the cryptPassword default is used.
           gecos     -- The GECOS information (full name, office, phone, etc.).
                        Defaults to "".
           groups    -- A list of existing group names the user should be
                        added to.  Defaults to [].
           homedir   -- The home directory for the new user.  Defaults to
                        /home/<name>.
           isCrypted -- Is the password kwargs already encrypted?  Defaults
                        to False.
           lock      -- Is the new account locked by default?  Defaults to
                        False.
           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)
           root      -- The directory of the system to create the new user
                        in.  homedir will be interpreted relative to this.
                        Defaults to /mnt/sysimage.
           shell     -- The shell for the new user.  If none is given, the
                        libuser default is used.
           uid       -- The UID for the new user.  If none is given, the next
                        available one is used.
           gid       -- The GID for the new user.  If none is given, the next
                        available one is used.
        """
        childpid = self._prepareChroot(kwargs.get("root", iutil.getSysroot()))
        if childpid == 0:
            if self.admin.lookupUserByName(user_name):
                log.error("User %s already exists, not creating.", user_name)
                os._exit(1)

            userEnt = self.admin.initUser(user_name)
            groupEnt = self.admin.initGroup(user_name)

            gid = kwargs.get("gid") or -1
            if gid >= 0:
                groupEnt.set(libuser.GIDNUMBER, kwargs["gid"])

            grpLst = [grp for grp in map(self.admin.lookupGroupByName, kwargs.get("groups", [])) if grp]
            userEnt.set(libuser.GIDNUMBER, [groupEnt.get(libuser.GIDNUMBER)[0]] +
                        [grp.get(libuser.GIDNUMBER)[0] for grp in grpLst])

            homedir = kwargs.get("homedir", None)
            if not homedir:
                homedir = "/home/" + user_name
            # libuser expects the parent directory tree to exist.
            parent_dir = iutil.parent_dir(homedir)
            if parent_dir:
                iutil.mkdirChain(parent_dir)
            userEnt.set(libuser.HOMEDIRECTORY, homedir)

            if kwargs.get("shell", False):
                userEnt.set(libuser.LOGINSHELL, kwargs["shell"])

            uid = kwargs.get("uid") or -1
            if uid >= 0:
                userEnt.set(libuser.UIDNUMBER, kwargs["uid"])

            if kwargs.get("gecos", False):
                userEnt.set(libuser.GECOS, kwargs["gecos"])

            # need to create home directory for the user or does it already exist?
            # userEnt.get returns lists (usually with a single item)
            mk_homedir = not os.path.exists(userEnt.get(libuser.HOMEDIRECTORY)[0])

            try:
                self.admin.addUser(userEnt, mkmailspool=kwargs.get("mkmailspool", True),
                                   mkhomedir=mk_homedir)
            except RuntimeError as e:
                log.critical("Error when creating new user: %s", e)
                os._exit(1)

            try:
                self.admin.addGroup(groupEnt)
            except RuntimeError as e:
                log.critical("Error when creating new group: %s", e)
                os._exit(1)

            if not mk_homedir:
                try:
                    stats = os.stat(userEnt.get(libuser.HOMEDIRECTORY)[0])
                    orig_uid = stats.st_uid
                    orig_gid = stats.st_gid

                    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
                    iutil.chown_dir_tree(userEnt.get(libuser.HOMEDIRECTORY)[0],
                                         userEnt.get(libuser.UIDNUMBER)[0],
                                         groupEnt.get(libuser.GIDNUMBER)[0],
                                         orig_uid, orig_gid)
                    iutil.execWithRedirect("restorecon",
                                           ["-r", userEnt.get(libuser.HOMEDIRECTORY)[0]])
                except OSError as e:
                    log.critical("Unable to change owner of existing home directory: %s",
                            os.strerror)
                    os._exit(1)

            pw = kwargs.get("password", False)
            try:
                if pw:
                    if kwargs.get("isCrypted", False):
                        password = kwargs["password"]
                    else:
                        password = cryptPassword(kwargs["password"], algo=kwargs.get("algo", None))
                    self.admin.setpassUser(userEnt, password, True)
                    userEnt.set(libuser.SHADOWLASTCHANGE, "")
                    self.admin.modifyUser(userEnt)
                elif pw == "":
                    # Setup the account with *NO* password
                    self.admin.unlockUser(userEnt)
                    log.info("user account %s setup with no password", user_name)

                if kwargs.get("lock", False):
                    self.admin.lockUser(userEnt)
                    log.info("user account %s locked", user_name)
            # setpassUser raises SystemError on failure, while unlockUser and lockUser
            # raise RuntimeError
            except (RuntimeError, SystemError) as e:
                log.critical("Unable to set password for new user: %s", e)
                os._exit(1)

            # Add the user to all the groups they should be part of.
            grpLst.append(self.admin.lookupGroupByName(user_name))
            try:
                for grp in grpLst:
                    grp.add(libuser.MEMBERNAME, user_name)
                    self.admin.modifyGroup(grp)
            except RuntimeError as e:
                log.critical("Unable to add user to groups: %s", e)
                os._exit(1)

            os._exit(0)
        else:
            return self._finishChroot(childpid)
Example #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 iutil.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", iutil.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 = iutil.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:
            iutil.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 = iutil.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
                iutil.chown_dir_tree(root + homedir,
                                     int(pwent[2]), int(pwent[3]),
                                     orig_uid, orig_gid)
                iutil.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)
Example #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 existing group names the user should be
                            added to.  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 iutil.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", iutil.getSysroot())

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

        args = ["-R", root]

        # If a specific gid is requested, create the user group with that GID.
        # Otherwise let useradd do it automatically.
        if kwargs.get("gid", None):
            self.createGroup(user_name, gid=kwargs['gid'], root=root)
            args.extend(['-g', str(kwargs['gid'])])
        else:
            args.append('-U')

        if kwargs.get("groups"):
            args.extend(['-G', ",".join(kwargs["groups"])])

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

        # useradd expects the parent directory tree to exist.
        parent_dir = iutil.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:
            iutil.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 = iutil.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
                iutil.chown_dir_tree(root + homedir, int(pwent[2]),
                                     int(pwent[3]), orig_uid, orig_gid)
                iutil.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)
Example #7
0
    def createUser(self, user_name, *args, **kwargs):
        """Create a new user on the system with the given name.  Optional kwargs:

           algo      -- The password algorithm to use in case isCrypted=True.
                        If none is given, the cryptPassword default is used.
           gecos     -- The GECOS information (full name, office, phone, etc.).
                        Defaults to "".
           groups    -- A list of existing group names the user should be
                        added to.  Defaults to [].
           homedir   -- The home directory for the new user.  Defaults to
                        /home/<name>.
           isCrypted -- Is the password kwargs already encrypted?  Defaults
                        to False.
           lock      -- Is the new account locked by default?  Defaults to
                        False.
           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)
           root      -- The directory of the system to create the new user
                        in.  homedir will be interpreted relative to this.
                        Defaults to /mnt/sysimage.
           shell     -- The shell for the new user.  If none is given, the
                        libuser default is used.
           uid       -- The UID for the new user.  If none is given, the next
                        available one is used.
           gid       -- The GID for the new user.  If none is given, the next
                        available one is used.
        """
        childpid = self._prepareChroot(kwargs.get("root", iutil.getSysroot()))
        if childpid == 0:
            if self.admin.lookupUserByName(user_name):
                log.error("User %s already exists, not creating.", user_name)
                os._exit(1)

            userEnt = self.admin.initUser(user_name)
            groupEnt = self.admin.initGroup(user_name)

            gid = kwargs.get("gid") or -1
            if gid >= 0:
                groupEnt.set(libuser.GIDNUMBER, kwargs["gid"])

            grpLst = [
                grp for grp in map(self.admin.lookupGroupByName,
                                   kwargs.get("groups", [])) if grp
            ]
            userEnt.set(libuser.GIDNUMBER,
                        [groupEnt.get(libuser.GIDNUMBER)[0]] +
                        [grp.get(libuser.GIDNUMBER)[0] for grp in grpLst])

            homedir = kwargs.get("homedir", None)
            if not homedir:
                homedir = "/home/" + user_name
            # libuser expects the parent directory tree to exist.
            parent_dir = iutil.parent_dir(homedir)
            if parent_dir:
                iutil.mkdirChain(parent_dir)
            userEnt.set(libuser.HOMEDIRECTORY, homedir)

            if kwargs.get("shell", False):
                userEnt.set(libuser.LOGINSHELL, kwargs["shell"])

            uid = kwargs.get("uid") or -1
            if uid >= 0:
                userEnt.set(libuser.UIDNUMBER, kwargs["uid"])

            if kwargs.get("gecos", False):
                userEnt.set(libuser.GECOS, kwargs["gecos"])

            # need to create home directory for the user or does it already exist?
            # userEnt.get returns lists (usually with a single item)
            mk_homedir = not os.path.exists(
                userEnt.get(libuser.HOMEDIRECTORY)[0])

            try:
                self.admin.addUser(userEnt,
                                   mkmailspool=kwargs.get("mkmailspool", True),
                                   mkhomedir=mk_homedir)
            except RuntimeError as e:
                log.critical("Error when creating new user: %s", e)
                os._exit(1)

            try:
                self.admin.addGroup(groupEnt)
            except RuntimeError as e:
                log.critical("Error when creating new group: %s", e)
                os._exit(1)

            if not mk_homedir:
                try:
                    stats = os.stat(userEnt.get(libuser.HOMEDIRECTORY)[0])
                    orig_uid = stats.st_uid
                    orig_gid = stats.st_gid

                    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
                    iutil.chown_dir_tree(
                        userEnt.get(libuser.HOMEDIRECTORY)[0],
                        userEnt.get(libuser.UIDNUMBER)[0],
                        groupEnt.get(libuser.GIDNUMBER)[0], orig_uid, orig_gid)
                    iutil.execWithRedirect(
                        "restorecon",
                        ["-r", userEnt.get(libuser.HOMEDIRECTORY)[0]])
                except OSError as e:
                    log.critical(
                        "Unable to change owner of existing home directory: %s",
                        os.strerror)
                    os._exit(1)

            pw = kwargs.get("password", False)
            try:
                if pw:
                    if kwargs.get("isCrypted", False):
                        password = kwargs["password"]
                    else:
                        password = cryptPassword(kwargs["password"],
                                                 algo=kwargs.get("algo", None))
                    self.admin.setpassUser(userEnt, password, True)
                    userEnt.set(libuser.SHADOWLASTCHANGE, "")
                    self.admin.modifyUser(userEnt)
                elif pw == "":
                    # Setup the account with *NO* password
                    self.admin.unlockUser(userEnt)
                    log.info("user account %s setup with no password",
                             user_name)

                if kwargs.get("lock", False):
                    self.admin.lockUser(userEnt)
                    log.info("user account %s locked", user_name)
            # setpassUser raises SystemError on failure, while unlockUser and lockUser
            # raise RuntimeError
            except (RuntimeError, SystemError) as e:
                log.critical("Unable to set password for new user: %s", e)
                os._exit(1)

            # Add the user to all the groups they should be part of.
            grpLst.append(self.admin.lookupGroupByName(user_name))
            try:
                for grp in grpLst:
                    grp.add(libuser.MEMBERNAME, user_name)
                    self.admin.modifyGroup(grp)
            except RuntimeError as e:
                log.critical("Unable to add user to groups: %s", e)
                os._exit(1)

            os._exit(0)
        else:
            return self._finishChroot(childpid)
    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 existing group names the user should be
                            added to.  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 iutil.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", iutil.getSysroot())

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

        args = ["-R", root]

        # If a specific gid is requested, create the user group with that GID.
        # Otherwise let useradd do it automatically.
        if kwargs.get("gid", None):
            self.createGroup(user_name, gid=kwargs['gid'], root=root)
            args.extend(['-g', str(kwargs['gid'])])
        else:
            args.append('-U')

        if kwargs.get("groups"):
            args.extend(['-G', ",".join(kwargs["groups"])])

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

        # useradd expects the parent directory tree to exist.
        parent_dir = iutil.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:
            iutil.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 = iutil.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
                iutil.chown_dir_tree(root + homedir,
                                     int(pwent[2]), int(pwent[3]),
                                     orig_uid, orig_gid)
                iutil.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)