Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(user): user management tool #825

Merged
merged 6 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions user/apps/user-manage/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/target
/Cargo.lock
/install
36 changes: 36 additions & 0 deletions user/apps/user-manage/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[package]
name = "user_manage_tool"
version = "0.1.0"
edition = "2021"

[[bin]]
name = "useradd"
path = "src/main.rs"

[[bin]]
name = "userdel"
path = "src/main.rs"

[[bin]]
name = "usermod"
path = "src/main.rs"

[[bin]]
name = "passwd"
path = "src/main.rs"

[[bin]]
name = "groupadd"
path = "src/main.rs"

[[bin]]
name = "groupdel"
path = "src/main.rs"

[[bin]]
name = "groupmod"
path = "src/main.rs"

[dependencies]
libc = "0.2.153"
lazy_static = "1.4.0"
47 changes: 47 additions & 0 deletions user/apps/user-manage/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# The toolchain we use.
# You can get it by running DragonOS' `tools/bootstrap.sh`
TOOLCHAIN="+nightly-2023-08-15-x86_64-unknown-linux-gnu"
RUSTFLAGS+=""

ifdef DADK_CURRENT_BUILD_DIR
# 如果是在dadk中编译,那么安装到dadk的安装目录中
INSTALL_DIR = $(DADK_CURRENT_BUILD_DIR)
else
# 如果是在本地编译,那么安装到当前目录下的install目录中
INSTALL_DIR = ./install
endif


ifeq ($(ARCH), x86_64)
export RUST_TARGET=x86_64-unknown-linux-musl
else ifeq ($(ARCH), riscv64)
export RUST_TARGET=riscv64gc-unknown-linux-gnu
else
# 默认为x86_86,用于本地编译
export RUST_TARGET=x86_64-unknown-linux-musl
endif

build:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET)

run-dragonreach:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET) --bin DragonReach

clean:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean

build-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET) --release

clean-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET) --release

fmt:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt

fmt-check:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt --check

.PHONY: install
install:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) install --target $(RUST_TARGET) --path . --no-track --root $(INSTALL_DIR) --force
142 changes: 142 additions & 0 deletions user/apps/user-manage/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
## useradd

- usage:添加用户

> useradd [options] username

useradd -c \<comment\> -d \<home\> -G \<group\> -g \<gid\> -s \<shell\> -u \<uid\> username

- 参数说明:

- 选项:
-c comment 指定一段注释性描述
-d 目录 指定用户主目录,如果不存在,则创建该目录
-G 用户组 指定用户所属的用户组
-g 组id
-s Shell 文件 指定用户的登录 Shell
-u 用户号 指定用户的用户号

- 用户名:
指定新账号的登录名。

- 更新文件:
> /etc/passwd
> /etc/shadow
> /etc/group
> /etc/gshadow

## userdel

- usage:删除用户

> userdel [options] username

userdel -r username

- 选项:
-r 连同用户主目录一起删除。

- 更新文件:
> /etc/passwd
> /etc/shadow
> /etc/group

## usermod

- usage:修改用户

> usermod [options] username

usermod -a -G<组 1,组 2,...> -c<备注> -d<登入目录> -G<组名> -l<名称> -s<登入终端> -u<用户 id> username

- 选项:
-a -G<组 1,组 2,...> 将用户添加到其它组中
-c<备注>  修改用户帐号的备注文字。
-d 登入目录>  修改用户登入时的目录。
-G<组名>  修改用户所属的群组。
-l<名称>  修改用户名称。
-s\<shell\>  修改用户登入后所使用的 shell。
-u\<uid\>  修改用户 ID。

- 更新文件:
> /etc/passwd
> /etc/shadow
> /etc/group
> /etc/gshadow

## passwd

- usage:设置密码

> 普通用户: passwd
> root 用户: passwd username

普通用户只能修改自己的密码,因此不需要指定用户名。

- 更新文件
> /etc/shadow
> /etc/passwd

## groupadd

- usage:添加用户组

> groupadd [options] groupname

groupadd -g\<gid\> -p\<passwd\> groupname

- 选项:
-g\<gid\> 指定组 id
-p 设置密码

- 更新文件
> /etc/group
> /etc/gshadow

## groupdel

- usage:删除用户组

> groupdel groupname

groupdel \<groupname\>

- 注意事项:
只有当用户组的组成员为空时才可以删除该组

- 更新文件
> /etc/group
> /etc/gshadow

## groupmod

- usage:修改用户组信息

> groupmod [options] groupname

groupadd -g\<new gid\> -n\<new groupname\> groupname

- 选项:
-g 设置新 gid
-n 设置新组名

- 更新文件
> /etc/group
> /etc/gshadow
> /etc/passwd

_/etc/passwd 文件格式:_

> 用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录 Shell

_/etc/shadow 文件格式:_

> 登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志

_/etc/group 文件格式:_

> 组名:口令:组标识号:组内用户列表

_/etc/gshadow 文件格式:_

> 组名:组密码:组管理员名称:组成员
95 changes: 95 additions & 0 deletions user/apps/user-manage/src/check/info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#[derive(Debug, Default, Clone)]
/// useradd的信息
pub struct UAddInfo {
/// 用户名
pub username: String,
pub uid: String,
pub gid: String,
/// 所在组的组名
pub group: String,
/// 用户描述信息
pub comment: String,
/// 主目录
pub home_dir: String,
/// 终端程序名
pub shell: String,
}

impl From<UAddInfo> for String {
fn from(info: UAddInfo) -> Self {
format!(
"{}::{}:{}:{}:{}:{}\n",
info.username, info.uid, info.gid, info.comment, info.home_dir, info.shell
)
}
}

#[derive(Debug, Default, Clone)]
/// userdel的信息
pub struct UDelInfo {
pub username: String,
pub home: Option<String>,
}

#[derive(Debug, Default, Clone)]
/// usermod的信息
pub struct UModInfo {
pub username: String,
pub groups: Option<Vec<String>>,
pub new_comment: Option<String>,
pub new_home: Option<String>,
pub new_gid: Option<String>,
pub new_group: Option<String>,
pub new_name: Option<String>,
pub new_shell: Option<String>,
pub new_uid: Option<String>,
}

#[derive(Debug, Default, Clone)]
/// passwd的信息
pub struct PasswdInfo {
pub username: String,
pub new_password: String,
}

#[derive(Debug, Default, Clone)]
/// groupadd的信息
pub struct GAddInfo {
pub groupname: String,
pub gid: String,
pub passwd: Option<String>,
}

impl GAddInfo {
pub fn to_string_group(&self) -> String {
let mut passwd = String::from("");
if self.passwd.is_some() {
passwd = "x".to_string();
}
format!("{}:{}:{}:\n", self.groupname, passwd, self.gid)
}

pub fn to_string_gshadow(&self) -> String {
let mut passwd = String::from("!");
if let Some(gpasswd) = &self.passwd {
passwd = gpasswd.clone();
}

format!("{}:{}::\n", self.groupname, passwd)
}
}

#[derive(Debug, Default, Clone)]
/// groupdel的信息
pub struct GDelInfo {
pub groupname: String,
}

#[derive(Debug, Default, Clone)]
/// groupmod的信息
pub struct GModInfo {
pub groupname: String,
pub gid: String,
pub new_groupname: Option<String>,
pub new_gid: Option<String>,
}
Loading
Loading