用户概述
Unix/Linux中的用户,一般分为两种:超级用户root和一般用户。一般用户登录后shell的提示符为$,而root用户的提示符为#。
root用户具有至高无上的权利,而一般用户几乎没有什么特权。
从安全性的角度来看,我们强烈建议:除了非用root不可这种情况,平时要以一般用户身份进行使用。这么做的好处是:(1)失误的操作一般不会引起过大损失;(2)在一般用户的状态下,及时运行恶意的软件、感染病毒,它的破坏性也是非常局限。
当你一定要使用root权限进行操作时,我们有两种选择:(1)切换到root用户,用完后赶紧退出root用户;(2)使用sudo。我们这里只介绍第一种方法。
使用su -
切换成超级用户。
su
命令可以用来切换至其他用户,后面的小横线一般要跟着,这表示我们会切换至目标用户的环境变量。
如何在系统中表示一个用户?
/etc/passwd
是一个文本文件,用于存储Unix/Linux系统中的用户记录,每一行表示一个用户记录。
每一行的含义为:用户名:密码:用户ID:组ID:姓名:主目录:使用哪个shell。当密码显示为x时,说明其密码存储于/etc/shadow
里。打开文件/etc/passwd
,我们可以看到,每一个用户会对应一行条目。
注意:用户名并不重要,而用户ID才重要。你可以试图(当然这么做有一定风险)以root身份用vi 编辑/etc/passwd
,将一般用户的用户ID改为0,再用该用户登录后,你将会看见#提示符。此时该用户为超级用户root。
passwd文件中每个条目项目的具体含义,可以通过man 5 passwd查看。
如何在系统中添加/删除一个用户?
添加/删除用户从本质上就是对/etc/passwd
和/etc/shadow
这两个文件进行修改,建立/删除用户的主目录(如用户polaris的主目录通常为/home/polaris
),以及设置合适的shell命令(通常为/bin/bash
)。但是,很显然,这种原始的操作困难且易错,因此Unix/Linux会提供相应的命令,简化对配置文件的修改。注意,系统管理操作通常必须是root用户才有权限。
添加用户使用:
useradd 用户名
给新用户初始密码并激活该用户:
passwd 用户名
另外,每个用户都可以通过passwd修改自己的密码。
删除一个用户并删除其主目录:
userdel -r 用户名
如果不写-r选项,该用户的主目录不会被删除。
总之,Unix/Linux的配置文件通常都会存储于/etc
目录下,并且通常会提供相应的命令来修改这些配置文件。
如何在系统中表示一个“登录”了的用户?
who命令可以用来查看当前登录到系统中有哪些用户。

编写who命令
who的版本很多,传统的who命令可以这样编写:
#include <fcntl.h>
#include <utmp.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
void main(){
int fd;
struct utmp buf;
char *cp;
time_t timeval;
if((fd=open(UTMP_FILE, O_RDONLY))==-1){
perror(UTMP_FILE);
exit(1);
}
while(read(fd, &buf, sizeof(struct utmp))==sizeof(struct utmp)){
if(buf.ut_type == USER_PROCESS){
timeval=buf.ut_time;
printf("%s\t%s\t%.12s (%s)\n", buf.ut_user, buf.ut_line, 4+ctime(&timeval), buf.ut_host);
}
}
close(fd);
}
注意:64bit的系统上,sizeof(time_t)=8字节,而struct utmp的ut_time是4字节,因此必须将ut_time复制给一个long(64bit系统上为8字节),之后再取地址,才可以获得正确的结果。
下面这个版本的who与我的演示用系统中的who运行结果几乎一致了。
#include <stdio.h>
#include <fcntl.h>
#include <utmp.h>
#include <time.h>
void show_info(struct utmp utbuf) {
struct tm *login_time;
time_t timeval;
printf("%-8s", utbuf.ut_name);
printf(" ");
printf("%-8s", utbuf.ut_line);
printf(" ");
timeval=utbuf.ut_time;
login_time = localtime((const time_t *)&timeval);
printf("%04d", login_time->tm_year+1900);
printf("-");
printf("%02d", login_time->tm_mon+1);
printf("-");
printf("%02d", login_time->tm_mday);
printf(" ");
printf("%02d", login_time->tm_hour);
printf(":");
printf("%02d", login_time->tm_min);
printf(" ");
printf("(%s)", utbuf.ut_host);
printf("\n");
}
void main(){
int fd;
struct utmp buf;
fd=open("/var/run/utmp", O_RDONLY);
while(read(fd, &buf, sizeof(struct utmp))>0){
if(buf.ut_type == USER_PROCESS){
show_info(buf);
}
}
close(fd);
}
运行的结果如下:
