MyMiniBash之su命令
su 命令用来切换用户
su—》表示默认切换到root用户
su uer --》表示切换到user用户
主体框架
通过mybash–fork–》su–fork–》bash
1/切换到那个用户
2、输入密码
3、密码匹配
4、fork子进程调用bash,父进程等待子进程结束
实现代码:
int main(int argc, char *argv[]) { char *user="root"; if(argc>1) { user=argv[1]; } printf("Password:"); fflush(stdout); char passwd[128]={0}; struct termios old, new; tcgetattr(0,&old); new=old; new.c_lflag&=~ECHO;//设置不回显 new.c_lflag&=ICANON; tcsetattr(0,TCSANOW,&new); fgets(passwd,128,stdin); tcsetattr(0,TCSANOW,&old); passwd[strlen(passwd)-1]=0; printf("\n"); //获取密文 struct spwd *sp=getspnam(user); assert(sp!=NULL); //sp->sp_pwdp $id$salt$.....第3个$结束 char *p=sp->sp_pwdp; char salt[128]={0}; int i=0,count=0; while(*p!=0)//获取密文 { salt[i++]=*p; if(*p=='$') { count++; } if(count==3) { break; } p++; } char *pwd=crypt(passwd, salt);//加密 assert(pwd!=NULL); if(strcmp(pwd,sp->sp_pwdp)!=0) { printf("passwd error"); exit(0); } pid_t pid=fork(); assert(pid!=-1); if(pid==0) { struct passwd *UserInfo=getpwnam(user); setuid(UserInfo->pw_uid);//切换用户 setenv("HOME",UserInfo->pw_dir,1); execl(UserInfo->pw_shell,UserInfo->pw_shell,(char *)0); printf("su exec fail\n"); exit(0); } else { wait(NULL); } }
知识点总结:
1、密码的回显控制
struct termios
{
tcflag_t c_iflag //输入标志,通过终端设备驱动程序控制字符的输入
tcflag_t c_oflag //输出标志,控制驱动程序输出
tcflag_t c_cflag //控制标志,影响RS-232串行线
tcflag_t c_lflag //本地标志,影响驱动程序和用户之间的接口(回显的开关ECHO)
cc_t c_cc[NCCS]
}
我们使用的本地标志,来控制密码的回显,通过new.c_lflag &=~ECHO来控制不回显
设置两个termios变量 old 和new 通过old获得当前的终端控制,在赋值给new,在让new设置为不回显,在通过new来设置终端,输入完密码后再,在将终端设置为old,还原终端。
2、获取密文
struct spwd {
char sp_namp; / user login name */
char sp_pwdp; / encrypted password /
long int sp_lstchg; / last password change /
long int sp_min; / days until change allowed. /
long int sp_max; / days before change required /
long int sp_warn; / days warning for expiration /
long int sp_inact; / days before account inactive /
long int sp_expire; / date when account expires /
unsigned long int sp_flag; / reserved for future use */
}
用来描述用户的密码的结构体
每个字段的含义是:
· sp_namp - 指向以 null 结束的用户名的指针 · sp_pwdp - 指向 null 结束的密码的指针 · sp_lstchg - 最近更改密码的日期(日期计算方法是从1970年1月1日开始的天数) · sp_min - days before which password may not be changed · sp_max - days after which password must be changed · sp_warn - days before password is to expire that user is warned of pending password expiration · sp_inact - days after password expires that account is considered inactive and disabled · sp_expire - days since Jan 1, 1970 when account will be disabled · sp_flag - reserved for future use
通过该结构体的getspnam(const char * username);来获取该结构体变量指针。从而得到该用户的密文,密文由$id$salt$encode组成,在得到crypt函参数中的salt变量$id$salt$,对密码进行加密。
3、判断获得的密文是否正确
strcmp(pwd,sp->sp_pwdp);
4、切换用户
通过struct passwd
{
char *pw_name 用户登录名
uid_t pw_uid UID号
gid_t pw_gid GID 号
char *pw_dir 用户家目录
char *pw_gecos 用户全名
char *pw_shell 用户默认shell
};
来获取用户信息,setuid是用来切换用户的,而setenv是来改变当前的环境变量,参数1,是设置是立即改变的。
5、开辟进程
execl来进入用户的环境。
- MyMiniBash之sleep命令
- su root后还是不能使用usermod,useradd等命令,错误描述:bash:usermod:command not found(转自http://myjieli.blog.51cto.com/135162/286462)
- bash脚本里su命令执行
- -bash: ls: command not found 或ifconfig ,su 等命令不能使用
- Linux基础:Linux(BASH)命令执行和搜索机制
- Linux(centos)不能使用FTP 命令 -bash: ftp: command not found
- Linux 下几个文件操作命令的代码实现+myfind find 查找命令 实现
- PC上运行平板的命令(有su限制的)
- su命令改写
- 为你在 Bash 历史中执行过的每一项命令设置时间和日期
- Linux命令之for - Bash中的For循环
- Linux 切换用户命令: su 和 su -
- SU命令的功能及基本用法--psmerge
- mac上的终端bash命令
- Linux:-bash: ***: command not found,系统很多命令都用不了,均提
- bash: rebar:未找到命令...
- 禁止其它用户使用su命令切换用户身份
- 利用BASH提权的技巧,使用SU创建用户
- Bash脚本中的set命令
- 单行bash命令