模拟shell实现su命令(切换用户)
来源:互联网 发布:db2 sql获取当前时间 编辑:程序博客网 时间:2024/06/06 02:51
在这里给大家推荐一本书《Linux程序设计 第4版》 里面有需要下面用到的几个函数
本篇博文和上篇博文实现mybash所用的到的函数一样
1、uid_t getuid(void)函数取得执行目前进程有效的用户识别码。有效的用户识别码用来决定进程执行的权限,改变此值,进程可以获得额外的权限。
2、struct passwd *getpwuid(uid_t uid)函数通过用户的uid查找用户的passwd数据。如果出错时,它们都返回一个空指针并设置errno的值,用户可以根据perror函数查看出错的信息。
3、struct passwd *getpwnam(const char *name)函数获取用户登录相关信息,其中name是当前登录的用户名。若成功,返回指针;若出错或者达到文件尾端,返回NULL。
4、int hostname(struct utsname *name)函数把主机信息写入name参数指向的结构体中。
5、char *getcwd(char *buf, size_t size)函数把当前目录的绝对地址保存到 buff中,buff 的大小为 size。如果 size太小无法保存该地址,返回 NULL 并设置 errno 为 ERANGE。可以采取令 buff 为 NULL并使 size 为负值来使 getcwd 调用 malloc 动态给 buff 分配,但是这种情况要特别注意使用后释放缓冲以防止内存泄漏。
需注意的是:
1、使用函数uname()得到的主机名“.”之后的部分是多余的,需要进行额外的处理。
2、getcwd()函数得到的是函数的绝对路径,在显示的信息中只需要当前目录的名字,需要进行处理。
代码实现:
#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <unistd.h>#include <pwd.h>#include <shadow.h>#include <termios.h>#include <string.h>int main(int argc,char *argv[]){char *s = "root";if(argc == 2){s = argv[1];}struct passwd *p = getpwnam(s);if( p == NULL){perror("su error:");exit(0);}struct spwd *sp = getspnam(s); //通过/etc/shadow获取密码if(sp == NULL){perror("su spnam error");}//printf("mima:%s\n",sp->sp_pwdp);char sl[256] = {0};//存储加密方法和密钥int i = 0;int num = 0;char *sps = sp->sp_pwdp;//$$$1加密方法 2密钥 3密码对应的密文while(sps != "\0"){if(*sps == '$'){num++;if(num == 3){break;}}sl[i++] = *sps;sps++;}//printf("\nsl=%s\n",sl);printf("passwd:");fflush(stdout);struct termios ts,newts;//终端属性tcgetattr(0,&ts);//获取终端属性newts = ts;newts.c_lflag &= ~(ECHO | ICANON); //本地属性回显 和 标准模式tcsetattr(0,TCSANOW,&newts);//设置新属性char buff[128] = {0};//fgets(buff,128,stdin);//buff[strlen(buff)-1] = 0;int ch = 0;i = 0;while((ch = getchar()) != '\n'){buff[i++] = ch;printf("*");fflush(stdout);}tcsetattr(0,TCSANOW,&ts);//还原终端属性char *newsp = crypt(buff,sl);//对输入的明文密码加钥if(strcmp(newsp,sp->sp_pwdp) != 0)//比较密码是否正确{printf("mima error\n");exit(0);}printf("\n");//printf("success\n");pid_t pid = fork();//产生子进程并替换长该用户的默认shellassert(pid != -1);if(pid == 0){setgid(p->pw_gid);setuid(p->pw_uid);setenv("HOME",p->pw_dir,1);execl(p->pw_shell,p->pw_shell,(char *)0);perror("execl error");exit(0);}wait(NULL);exit(0);}
- 模拟shell实现su命令(切换用户)
- Linux 切换用户命令: su 和 su -
- linux su命令 切换用户
- 切换用户命令 su sudo
- linux--> 切换用户命令su
- 使用 su 命令临时切换用户身份
- Rhyme/ Linux 用户切换命令su以及用户切换注意事项
- shell中用指定用户运行命令 su
- su与su-切换用户
- su与su-切换用户
- 禁止其它用户使用su命令切换用户身份
- linux 切换到 root 用户 [su命令,sudo命令]
- 切换用户身份su
- su切换用户
- linux 用户切换su 命令横杠的作用
- 解决FreeBSD中普通用户无法使用su命令切换用户
- Linux Ubuntu下使用su命令切换root用户
- 关于使用su切换用户之后,命令无法…
- CF contest 892 D题 Gluttony
- 秋招面经总结
- 1到10所有数的立方
- Leetcode 236. Lowest Common Ancestor of a Binary Tree
- 三大主流软件负载均衡器对比(LVS VS Nginx VS Haproxy)
- 模拟shell实现su命令(切换用户)
- Dom解析xml入门实例!!!!!!!!!!
- div,css
- c语言_猜数字游戏
- 计蒜客 奇异家庭
- 16进制转8进制的位运算 Java算法
- 用在线电路软件生成全加器与逻辑门
- 菜鸡的电路实践
- 数组的创建、数组的复制、Arrays中sort/binarySearch方法