进程关系之终端登录

1. 终端登录

终端登录要么是本地的要么是远程的。在这两种情况下,登录都要经由内核中的终端设备驱动程序。终端登录至UNIX系统。该过程是类似的,而与所使用的终端无关,终端可以是基于字符的终端、仿真简单的基于字符终端的图形终端,或者是运行窗口系统的图形界面。

 

1.1. BSD终端登录

系统管理员创建名为/etc/ttys的文件,其中每个终端设备都有一行,每一行说明了设备名和传递给getty程序的参数。当系统自举时,内核创建进程ID为1的进程,也就是init进程。init进程使系统进入多用户状态。init进程读配置文件/etc/ttys,对于每一个允许登录的终端设备,init调用一次fork,它所生成的子进程则执行(exec)getty程序。

getty为终端设备调用open函数,以读、写方式将终端打开。一旦设备被打开,文件描述符0、1、2就被设置到该设备。然后,getty就输出"login:"之类的信息。当用户键入了用户名,getty的工作就完成了,类似的调用方式如下:

execle("/bin/login", "login","-p", username, (char *)0, envp); 

因为init具有超级用户特权,所以它fork的所有子进程都有超级用户特权。login得到了用户名,就能调用getpwnam取得相应用户的口令文件登录项。然后调用getpass以显示提示"Password:",接着读用户键入的口令。它调用crypt将用户键入的口令加密,并与该用户在阴影文件中的登录项的pw_passwd自导比较。如果用户几次键入的口令都无效,则login以参数1调用exit表示登录失败。父进程(1)了解到子进程的登录终止情况后,将再次调用fork,其后接着执行getty,对此重复上述过程。

这是UNIX系统传统的用户身份验证过程。不过,现在很多UNIX系统支持PAM(Pluggable Authentication Module, 可插入式身份验证模块)。PAM的优点是,管理员可以基于本地策略,针对不同任务配置不同的验证用户身份的方法。

如果用户正确登录,login就将执行如下的工作:

1). 将当前工作目录更改为该用户的起始努力(chidr)

2). 调用chown改变终端的所有权,是登录用户成为它的所有者

3). 将针对该终端设备的访问权限改变成用户读和写

4). 调用setgid和initgroups设置进程的组ID

5). 用login所得到的所有信息初始化环境:起始目录(HOME)、shell(SHELL)、用户名(USER和LOGNAME),以及系统默认路径(PATH)

6). login进程改变为登录用户的用户ID(setuid)并调用该用户的登录shell,如下

     execl("/bin/sh","-sh",(char *)0);

登录shell会读取启动文件(Bourne shell和Korn shell是.profile;GNU Bourne-again shell是.bash_profile、bash_login或.profile;C shell是.cshrc和.login)。当登录shell终止时,init会得到通知(SIGCHLD信号),它会重复上述过程。

 

1.2. 网络登录

通过串行终端登录至系统和经由网络登录至系统的主要(物理上)区别是:通过网络登录时,终端和计算机之间的连接不是点对点的连接。

为使同一个软件既能处理终端login,又能处理网络login,系统使用了一种称为伪终端(pseudo terminal)的软件驱动程序。

在BSD中,有一个称为inetd的进程,它等待大多数网络连接。作为系统启动的一部分,init调用一个shell,使其执行shell脚本/etc/rc。由此shell脚本启动一个守护进程inetd。一旦此shell脚本终止,inetd的父进程就变成init。inetd等待TCP/IP连接请求到达主机,而当一个连接请求到达时,他执行一次fork,然后生成的子进程执行适当的程序。

当通过终端或网络登录时,我们得到一个登录shell,其标准输入、标准输出和标准出错连接到一个终端设备或伪终端设备上。而此终端或伪终端则是会话的控制终端。

 

 

你可能感兴趣的:(网络,unix,shell,Authentication,login,终端)