Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2108491
  • 博文数量: 413
  • 博客积分: 10926
  • 博客等级: 上将
  • 技术积分: 3862
  • 用 户 组: 普通用户
  • 注册时间: 2006-01-09 18:14
文章分类

全部博文(413)

文章存档

2015年(5)

2014年(1)

2013年(5)

2012年(6)

2011年(138)

2010年(85)

2009年(42)

2008年(46)

2007年(26)

2006年(59)

分类: LINUX

2006-12-25 12:49:46

级别: 初级

郑彦兴国防科大计算机学院

2002 年 9 月 15 日

开 机自动登录linux,并自动运行X window应用程序,有其特殊的应用背景,如基于linux平台的监控系统,linux启动后不需要身份验证,而直接运行监控程序等等。本文以 Redhat7.2为平台,结合linux启动过程,介绍了如何避免身份验证自动登录,并直接进入X window自动运行应用程序。

linux 在启动过程的最后阶段(具体启动步骤略),init 会根据 /etc/inittab文件的最后一行x:5:respawn:/etc/X11/prefdm -nodaemon运行/etc/X11/prefdm脚本,(Red hat 7.2缺省时是这样的)。prefdm脚本的主要任务是完成X window的启动,可以有几种启动X window的方法,都包含在prefdm脚本中,几种主要方法有:

  • 运行xdm启动X window;
  • 运行gdm,进入gnome桌面环境;
  • 运行kdm进入kde桌面环境;
  • 自动登录进入linux;

prefdm脚本框架大致如下:



#!/bin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
. /etc/profile.d/lang.sh
# 第一步:查看是否为自动登录
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
if /usr/sbin/autologin; then
exit 0
fi
fi

# 第二步:如果不是自动登录方式,就会在/etc/sysconfig/desktop中搜寻用户偏爱的登录方式
......
# 可以是kdm、gdm以及xdm,并运行相应的kdm、gdm以及xdm。
......





回页首


在/etc/X11/prefdm脚本中,是否实现自动登录有一个条件测试开关,事实上,可以在这里注释掉测试开关,直接执行启动X window的操作。

自动登录实质上就是绕过身份验证,直接启动X window。X window的启动可以由xinit来完成。

  1. Xinit 用来启动X window系统服务器以及系统上的第一个客户程序,可以通过为xinit传递命令行参数的形式指定要启动的服务器及客户程序。如果不传递参数给 xinit,它将在用户的根目录下寻找并运行 .xinitrc脚本来启动客户程序;在用户的根目录下寻找并运行 .xserverrc脚本来启动服务器。如果xinit在用户的根目录下找不到.xinitrc、.xserverrc,xinit将使用缺省的X :0。
  2. 实际上,用startx来启动X更为方便。对于运行单一会话的X window 系统,startx提供了更为良好的用户接口。同样,startx首先在用户的根目录下寻找 .xinitrc及.xserverrc脚本,如果找不到这两个脚本,startx将使用/etc/X11/xinit/xinitrc以及 /etc/X11/xinit/xserverrc脚本。

startx脚本的最基本框架是:

  • a、 寻找.xinitrc,如果没有则使用xinitrc;
  • b、 寻找.xserverrc,如果没有则使用xserverrc;
  • c、 根据找到的脚本确定xinit的参数;

由此可看出,startx在不需要传递任何参数的情况下,可以完成启动X的任务,因此,可以如下修改/etc/X11/prefdm脚本来实现自动登录:



#!/bin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
. /etc/profile.d/lang.sh
# 第一步:查看是否为自动登录
#if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
#注释掉上边的条件测试,直接运行startx
if /usr/X11R6/bin/startx; then
exit 0
fi
#fi

当然,应确保/etc/inittab中的启动级别为5。

重 新启动系统,会发现系统不验证用户身份,直接进入X window,此时的用户身份为root。但是,如果原来root有自己的桌面、默认shell时,上述方法启动X不一定保证还能拥有原来的设置。为了在 启动X后,在避免验证身份的同时,又不改变用户原来的设置,那么在运行startx之前,还有工作要做。





回页首


观察原来/etc/X11/prefdm脚本的自动登录部分:



......
# 第一步:查看是否为自动登录
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
if /usr/sbin/autologin; then
exit 0
fi
fi
......

不难看出,脚本中保留了自动登录的接口:一个可执行文件/usr/sbin/autologin以及一个配置文件/etc/sysconfig/autologin。

1、/etc/sysconfig/autologin配置文件的实现:



#config for autologin
USER=root
EXEC=/usr/X11R6/bin/startx
说明,USER指定自动登录时的用户名;EXEC指定启动X要运行的程序。

2、/usr/sbin/autologin可执行文件的实现:



/*********************
**** autologin.c ****
*********************/
#include
#include
#include
#include
#include
#include
#include

int main(int argc, char **argv)
{
struct stat st;
FILE *f;
char *cfg;
struct passwd *pw;
uid_t uid;
gid_t gid;
char *dir, *shell;
char *user=NULL;
char *cmd=NULL;

user="root";
/*为了能说明问题又保持程序简洁,这里默认登录用户为root,实际上,
登陆用户名应该从/etc/sysconfig/autologin中得到,
程序实现时要注意过滤掉/etc/sysconfig/autologin中的无效用户名*/
cmd="/usr/X11R6/bin/startx";
/*同样,这里直接指定启动X window的程序,实际上,该程序应该从/etc/sysconfig/autologin中得到*/

pw = getpwnam(user);
//getpwnam返回包含用户信息的passwd结构(该结构在pwd.h中定义)。
if(pw) {
uid=pw->pw_uid;
gid=pw->pw_gid; dir=strdup(pw->pw_dir);
shell=strdup(pw->pw_shell);
}
//获得用户相关信息
else {
printf("ERROR: No such user %s!\n", user);
return 1;
}

chown("/dev/console", uid, gid);
chown("/dev/tty", uid, gid);
//为控制台和终端设置用户ID及组ID

//下面是设置用户相关ID
setregid(gid, gid);
setegid(gid);
setgid(gid);
setreuid(uid, uid);
seteuid(uid);
setuid(uid);

setenv("HOME", dir, 1);
setenv("SHELL", shell, 1);
setenv("USER", user, 1);
setenv("LOGNAME", user, 1);
//设置用户相关环境变量

chdir(dir);
//切换到用户根目录
user=NULL;

execvp(cmd, argv);
/*在配置完用户的相关信息后,执行启动X window操作。注意这里默认执行/usr/X11R6/bin/startx */
printf("ERROR: Couldn't exec %s: %s\n", cmd, strerror(errno));
return 2;
}

运行gcc -o autologin autologin.c,拷贝autologin可执行文件到/usr/sbin/autologin,拷贝autologin配置文件到/etc/sysconfig/autologin。 重新启动系统,会直接进入X window并保留用户原来所有的风格。

如 果不需要自动登录的配置文件/etc/sysconfig/autologin,所有的操作都在/usr/sbin/autologin以默认的方式实现 (比如,默认登录身份为root,默认执行操作为/usr/X11R6/bin/startx等),那么,/etc/X11/prefdm脚本的自动登录 部分可简化如下:



......
# 第一步:查看是否为自动登录
if /usr/sbin/autologin; then
exit 0
fi
//第二步 ......
......

即在脚本中去掉条件测试开关,直接执行/usr/sbin/autologin,这时,只需要拷贝autologin可执行文件到/usr/sbin/autologin,不再需要拷贝autologin配置文件到/etc/sysconfig/autologin。





回页首


  1. 如果重新启动后系统进入了kde,而用户需要进入gnome,只需运行switchdesk gnome在重新启动系统即可,以后每次启动时会自动进入gnome;反之亦然。
  2. 一 般系统自动登录的目的是启动X window 后自动运行某个X window程序。如果系统默认的启动级别为3,那么如果要在系统启动后自动运行某些应用程序,只需要在某些脚本中加入相应命令即可,不再详述。在X window启动后自动运行应用程序要复杂一些,幸好,kde和gnome都为此留下了自动启动接口。如果在kde桌面环境下自动启动应用程序,只需要把 应用程序名字加入/root/.kde/Autostart/目录下即可(这里注意不同用户的根目录可能不同,如用户zyx的根目录可能为 /home/zyx)。如果在gnome桌面环境下自动启动应用程序,只需把应用程序的名字加入/主菜单/程序/设置/会话/会话特性及启动程序的 startup programs属性页中即可。




回页首






回页首



郑彦兴,男,现攻读国防科大计算机学院网络方向博士学位。您可以通过电子邮件 和他联系。


from: http://www-128.ibm.com/developerworks/cn/linux/l-tip-prompt/tip20/index.html




如何自动登录linux(续)

developerWorks
文档选项
将此页作为电子邮件发送

将此页作为电子邮件发送

未显示需要 JavaScript 的文档选项


拓展 Tomcat 应用

下载 IBM 开源 J2EE 应用服务器 WAS CE 新版本 V1.1


级别: 初级

郑彦兴, 现攻读国防科大计算机学院博士学位

2003 年 6 月 01 日

在” 如何自动登录linux”中,以redhat 7.2操作系统平台为背景,阐述了如何实现自动登录X window(系统启动级别为5),并自动运行指定的应用程序。本文以redhat 8.0操作系统平台为背景,阐述如何实现启动级别为3时的自动登录,及自动运行相应程序,并简要介绍了如何在redhat 8.0下自动登录X window(系统启动级别为5),并自动运行指定的应用程序。

启动级别为3时自动登录的实现涉及两个软件包:mingetty-1.00-3.src.rpm软件包及util-linux-2.11r-10.src.rpm软件包。

对于启动级别为3的自动登录的实现,仍然需要考察/etc/inittab脚本,


3:123:respawn:/sbin/mingetty tty3


因此,如果想在启动 级别3的情况下实现自动登录,必须要了解mingetty的功能,甚至要修改mingetty的代码。用命令rpm -qf /sbin/mingetty 可知redhat 8.0版本的mingetty包含在mingetty-1.00-3.src.rpm软件包中,下载该软件包,安装源代码,缺省情况下,代码会安装在 /usr/src/redhat/下,我们关心的只是mingetty.c源文件。mingetty.c约有五百行代码,主要实现如下功能:

  • 打开指定的tty(由参数指定);
  • 提示用户登录(login:);
  • 获得登录用户名;
  • 把用户登录名作为参数,调用/bin/login。

我们所关心的部分实质上只有以下三行:


... ...
438 while ((logname = get_logname ()) == 0); //mingetty.c文件438行
439 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
440 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
... ...

第一行的功能是输出login提示,并获得用户输入的登录用户名,登录用户名由logname返回。因此,可作如下修改


... ...
438 // while ((logname = get_logname ()) == 0); //注释掉本行,不再提示login:
439 logname = "root"; //添加本行代码
440 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
441 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
... ...

注意,这里假定用户以超级用户身份登录。

第二行以用户登录名为参数,调用/bin/login程序,进一步实现登录。因此,要想实现自动登录,还应该了解/bin/login的功能,必要时还应修改其源代码。

第三行为出错处理。

采 用同样的方法,查看/bin/login所属软件包(redhad8.0版本的login包含在util-linux-2.11r-10.src.rpm 软件包中),下载并安装util-linux-2.11r-10.src.rpm,login可执行文件有几个源文件编译而成,我们最关心的是 login.c源文件(大约1500行的代码)。下面简要分析一下login要实现的功能,并对相应部分作必要的修改。

Login程序主要可以分为以下几个主要部分:

  1. Login首先检查登录者是否为超级用户,如果不是超级用户,并且存在/etc/nologin文件,则输出该文件内容,并中止登录过程;主要由checknologin()实现;
  2. 如果登录用户是超级用户,那么login必须在/etc/securetty/中指定的tty列表中实现登录,否则将导致登录失败。同样可以不指定/etc/securetty文件,此时,超级用户可以在任何tty上登录。
  3. 经过前两步测试后,login接下来将提示输入登录密码(由getpass()调用完成,有兴趣的读者可参考其手册页面),并进行验证,如果密码不对,则提示重新登录。
  4. 顺利经过密码验证后,login还将检查是否存在.hushlogin文件,如果该文件存在,则执行一次"quiet"登录(所谓的quiet登录指的是,登录时不再提示邮件mail,不再显示最后一次登录时间,不输出任何消息。启动级别为3时,正常情况下输出这些信息)
  5. login 接下来设置登录tty的用户ID和组ID,并设置相应的环境变量,包括HOME、PATH、SHELL、TERM、LOGNAME等。对于普通用户来说, PATH缺省被设置成/usr/local/bin: /bin/usr/bin:;对于超级用户来说,PATH被设置成/sbin: /bin: /usr/sbin: /usr/bin:
  6. login的最后一步是为用户启动shell。如果在/etc/passwd中没有为用户指定shell,那么将使用/bin/sh,如果在/etc/passwd中没有给出当前工作目录,则使用"/"。

至此,一个完整的登录过程就结束了。

从 以上对login源程序分析过程中可发现,如果要实现自动登录,应该在第三步做文章,设法绕过提示输入密码以及对密码进行验证这一过程。实际上很简单, login源程序对是否要求输入密码设置了一个开关控制passwd_req,缺省情况下,其值为1(passwd_req = 1),即要求输入密码进行身份验证。把该行代码改为(passwd_req = 0)后,问题就解决了。即对源文件作如下修改即可:


... ...
402 fflag = hflag = pflag = 0; //login.c文件402行
403 //passwd_req = 1 //缺省时,要求进行密码验证,注释掉本行
404 passwd_req = 0 //添加本行
... ...

修改后,可以直接使用util-linux-2.11r-10.src.rpm提供的Makefile进行重新编译,也可以自己对其编译:


gcc -o login login.c setproctitle.c checktty.c xstrncpy.c -Wall -lcrypt注意包含后面的编译选项-lcrypt,否则会出问题。


有了新版的mingetty及login后,拷贝mingetty到/sbin/目录,拷贝login到/bin目录,并将/etc/inittab中的启动级别设置为3,再重新引导系统即可(读者可以自己写一个脚本实现上述过程)。

如果读者对mingetty或login代码的其他部分感兴趣,可以反复修改login.c或mingetty.c的源代码,测试一下代码的功能,这里要注意的是,在拷贝新版mingetty和login之前, 一定要把原来的mingetty和login备份,同时还要准备系统引导盘(有系统安装盘亦可,这样读者有机会键入linux rescue),在测试新版程序前更应如此,如果对代码修改稍有不当,系统将不能正常启动。

如果不想再作进一步的代码测试,只是按本文给出的方法进行代码修改,在系统启动上不会出现什么问题。





回页首


在实现了启动级别3时的自动登录后,自动运行应用程序非常简单,把应用程序添加在/etc/rc.d/rc.local脚本中既可。(读者可以尝试一下把startx加入脚本中,看一看效果如何。在某种意义上,又增加了一种自动登录X window的方法)





回页首


在"如何实现自动登录linux"中,主要以redhat 7.2平台为背景进行阐述的,其中的自动登录部分可以直接用于redhat 8.0中,不需要任何修改。

但 是,登录后自动运行应用程序的接口在redhat 8.0中有所不同,主要是登录gnome后,自动运行应用程序的接口有所改变:首先点击面板上的GNOME帮助(那个红色的小帽子),然后选择/其它/首 选项/Sessions,在Session对话框的启动程序属性页中添加要启动的程序即可。

对于登录kde后,自动运行程序的接口没有改变。





回页首


本文同"如何实现自动登录linux"一文,基本上解决了如何实现自动登录Linux,并自动运行相应应用程序的问题。对于两个最常见的启动级别(3、5),都给出了各自的方法。

在 系统初始化到mingetty及login这一阶段,内核实际上已经完成了引导过程,已经到了系统初始化的最高阶段,与内核没什么关系了。此时,主要是 /sbin/init根据/etc/inittab的内容而相机行事。读者可通过(man 8 init)或者(man 5 inittab)了解更多东西。

在对文中提到的软件包修改时,请遵守GNU General Public License(GPL)相关标准,另外,替换login通常被视为黑客行为,应当谨慎行事。





回页首


  1. login手册页面
  2. mingetty-1.00-3.src.rpm,在redhat 8.0的发行版本的源代码中,包含该软件包;
  3. util-linux-2.11r-10.src.rpm,

可在 处下载,注意下载源代码包(..src.rpm)





回页首






回页首



郑彦兴,男,现攻读国防科大计算机学院博士学位。您可以通过电子邮件 和他联系




from: http://www-128.ibm.com/developerworks/cn/linux/l-tip-prompt/tip20/index2.html
阅读(3693) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~