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
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)
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 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)
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)
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)