数学建模社区-数学中国

标题: 如何自动登录linux[转载] [打印本页]

作者: huashi3483    时间: 2004-9-27 14:26
标题: 如何自动登录linux[转载]
<>如何自动登录linux[转载]</P>
: e0 o4 Q' ?4 H/ _<>本文以redhat 8.0操作系统平台为背景,阐述如何实现启动级别为3时的自动登录,及自动运行相应程序,并简要介绍了如何在redhat 8.0下自动登录X window(系统启动级别为5),并自动运行指定的应用程序。   }2 ?% T. N7 ]; q# e0 d
[b:804aea7097]一、启动级别为3时自动登录的实现[/b:804aea7097] % _& {! G6 Z- k* E1 K- c
  Q) }) ?3 B7 [2 Z5 e! m# }; h: B
启动级别为3时自动登录的实现涉及两个软件包:mingetty-1.00-3.src.rpm软件包及util-linux-2.11r-10.src.rpm软件包。
7 [  S0 z1 S( G* t) ^0 ~7 ?$ L9 x- k" i1 a" e
(1)mingetty-1.00-3.src.rpm软件包  
+ g0 f' w1 A% M对于启动级别为3的自动登录的实现,仍然需要考察/etc/inittab脚本,  
# `8 D0 n, e+ H! t0 k3:123:respawn:/sbin/mingetty tty3 6 \; E# m% |  J3 I* x" c
$ r% c$ d  f3 R
: p  x4 ^. k' f5 [" d" m" e) u
  ! i9 L& b' h" ]% E; U! j
; h8 \9 S1 l1 `) P5 o
: }& A9 A: Q- k# }
因此,如果想在启动级别3的情况下实现自动登录,必须要了解mingetty的功能,甚至要修改mingetty的代码。用命令rpm -qf /sbin/mingetty 可知redhat 8.0版本的mingetty包含在mingetty-1.00-3.src.rpm软件包中,下载该软件包,安装源代码,缺省情况下,代码会安装在/usr/src/redhat/下,我们关心的只是mingetty.c源文件。mingetty.c约有五百行代码,主要实现如下功能: 6 V6 _0 K- A: [% E# {  S( R
( |; k. q/ v- d. [8 w
- \$ l6 h( ]8 j: \2 S$ P8 I+ N; P
打开指定的tty(由参数指定);  
1 X/ E5 x% |7 W, i, V提示用户登录(login:);  
6 [* c4 Z7 T/ m" |1 g. C( {获得登录用户名;  
+ J( r9 w. r. B$ ]% J把用户登录名作为参数,调用/bin/login。  
& \: r- _  c) S; M* g" d. k' Z- W4 x2 c8 j& ]3 K8 u
我们所关心的部分实质上只有以下三行:
. A( p- o6 D% O$ T' T6 I7 u/ [! Q
: y9 K. U- g, ^
  ^1 p9 I4 ^" _% Q% W5 T. H6 [0 K( y. z... ... : n) R2 a5 L1 X% I, [
438 while ((logname = get_logname ()) == 0); //mingetty.c文件438行 2 |2 m% \) L& L  c; D4 D
439 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
8 Q7 d2 L' d2 [, z5 N& F& q, i440 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
* }4 c+ _* r) e& l9 C7 L; X... ...
4 q0 z& ]" \" i7 J4 ]1 `  u3 f: A) e% W- ^) T* R( ]. N
  0 }( }8 @. H% O  i4 H  b* Y6 a

1 R# Q2 `* {$ J: A( R5 |7 f第一行的功能是输出login提示,并获得用户输入的登录用户名,登录用户名由logname返回。因此,可作如下修改
- I9 C' ?# ~! L+ d* ~+ w6 `" c# G! }+ E, X

8 {( |. j- L' f7 r' g' u' F... ... 7 J0 [, @9 q6 a4 A. v# Q$ P
438 // while ((logname = get_logname ()) == 0); //注释掉本行,不再提示login:   d; Z' h4 l) y) I* a
439 logname = "root"; //添加本行代码
0 X/ v5 q' y( y7 `( f- K7 R440 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
' ?- g) L* Y# M) c9 g9 i4 N1 q9 i0 h441 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
9 H( w. e. t6 {" B% V- R) e... ...
$ d4 j3 v5 i' A  {' x5 M/ g" F$ |
1 A- R' ?5 m2 p8 T, ~2 y  7 t0 b4 b1 I# p

: E4 S9 ?+ O9 X注意,这里假定用户以超级用户身份登录。
) s2 j% G& k, Q+ a' B7 U2 ]% b& N6 b4 u3 Y; u5 n1 E) G
第二行以用户登录名为参数,调用/bin/login程序,进一步实现登录。因此,要想实现自动登录,还应该了解/bin/login的功能,必要时还应修改其源代码。
% O* }3 D. n  u: f! S8 }! ^; i& N3 F3 [8 S
第三行为出错处理。 9 @# M& x" e7 i, ]

/ E. C) i# X+ u( {4 K(2)util-linux-2.11r-10.src.rpm软件包  * W8 s" m* e8 K4 ~* a3 ?0 V
采用同样的方法,查看/bin/login所属软件包(redhad8.0版本的login包含在util-linux-2.11r-10.src.rpm软件包中),下载并安装util-linux-2.11r-10.src.rpm,login可执行文件有几个源文件编译而成,我们最关心的是login.c源文件(大约1500行的代码)。下面简要分析一下login要实现的功能,并对相应部分作必要的修改。
0 n' X/ I, G. |8 d
4 c* T4 I# U! F0 G, ^Login程序主要可以分为以下几个主要部分: 7 R) @4 i; p2 x) }4 p6 F- c
- M8 f- p7 o% c% J, \1 D3 T! b
1.Login首先检查登录者是否为超级用户,如果不是超级用户,并且存在/etc/nologin文件,则输出该文件内容,并中止登录过程;主要由checknologin()实现;  " w* J. V5 W- x" R9 X
2.如果登录用户是超级用户,那么login必须在/etc/securetty/中指定的tty列表中实现登录,否则将导致登录失败。同样可以不指定/etc/securetty文件,此时,超级用户可以在任何tty上登录。  8 h% d* e* c. R2 Q' r7 {; b/ f
3.经过前两步测试后,login接下来将提示输入登录密码(由getpass()调用完成,有兴趣的读者可参考其手册页面),并进行验证,如果密码不对,则提示重新登录。  
+ u/ B. ?" Z6 ?" L& y4.顺利经过密码验证后,login还将检查是否存在.hushlogin文件,如果该文件存在,则执行一次"quiet"登录(所谓的quiet登录指的是,登录时不再提示邮件mail,不再显示最后一次登录时间,不输出任何消息。启动级别为3时,正常情况下输出这些信息)  # `+ Y$ w! T/ s% b  \' s5 V8 h
5.login接下来设置登录tty的用户ID和组ID,并设置相应的环境变量,包括HOME、PATH、SHELL、TERM、LOGNAME等。对于普通用户来说,PATH缺省被设置成/usr/local/bin: /bin/usr/bin:;对于超级用户来说,PATH被设置成/sbin: /bin: /usr/sbin: /usr/bin:  
9 h: e# k& ?0 c! N# W( V6.login的最后一步是为用户启动shell。如果在/etc/passwd中没有为用户指定shell,那么将使用/bin/sh,如果在/etc/passwd中没有给出当前工作目录,则使用"/"。  , g0 p7 m0 w2 r" I6 S5 n
至此,一个完整的登录过程就结束了。
# a3 }  E, u; ~" Y
, i$ @; O, B$ v) Z6 B+ t从以上对login源程序分析过程中可发现,如果要实现自动登录,应该在第三步做文章,设法绕过提示输入密码以及对密码进行验证这一过程。实际上很简单,login源程序对是否要求输入密码设置了一个开关控制passwd_req,缺省情况下,其值为1(passwd_req = 1),即要求输入密码进行身份验证。把该行代码改为(passwd_req = 0)后,问题就解决了。即对源文件作如下修改即可:
- O: [4 K7 r- [! d0 `4 c% t( T2 C; k7 r8 K
: m' H3 N& L  D0 U, K3 A  j5 }
... ...
# b" r( Q$ Q" m* `; B6 ?402 fflag = hflag = pflag = 0; //login.c文件402行
2 c! _" ?" ?2 N- |403 //passwd_req = 1   //缺省时,要求进行密码验证,注释掉本行 1 ]4 i' Z4 j: R" R5 c3 a9 X/ F# [
404 passwd_req = 0 //添加本行 ! O9 A* R- c5 g" G% w+ e1 b& d8 P' \
... ... / g' g$ f7 p  J4 y) c- \5 P9 d
2 K  W3 h1 ^) k6 ^8 A+ F: `2 H2 j4 e
  * R. ]: r5 E" D0 f4 C9 ~
/ i3 L3 [( T3 c) k
修改后,可以直接使用util-linux-2.11r-10.src.rpm提供的Makefile进行重新编译,也可以自己对其编译: / s% G; F9 C! O1 j  ^$ s- E2 [. j

. F5 c. H! ]) }+ R( j4 G3 A. d" |+ f
gcc -o login login.c setproctitle.c checktty.c xstrncpy.c -Wall -lcrypt注意包含后面的编译选项-lcrypt,否则会出问题。 9 m' k6 K  B! b; i! M. b5 f

' ]8 c- N. [9 I9 c6 ]7 u* f
: A5 b4 P! L( K! Q4 h/ s有了新版的mingetty及login后,拷贝mingetty到/sbin/目录,拷贝login到/bin目录,并将/etc/inittab中的启动级别设置为3,再重新引导系统即可(读者可以自己写一个脚本实现上述过程)。
# A0 h1 q) Z6 ?! \8 _2 q1 V0 F" Q" e  q# q# {9 W
如果读者对mingetty或login代码的其他部分感兴趣,可以反复修改login.c或mingetty.c的源代码,测试一下代码的功能,这里要注意的是,在拷贝新版mingetty和login之前,一定要把原来的mingetty和login备份,同时还要准备系统引导盘(有系统安装盘亦可,这样读者有机会键入linux rescue),在测试新版程序前更应如此,如果对代码修改稍有不当,系统将不能正常启动。 8 N& b6 E) Z, e

) n3 x. q' V8 D, O4 E如果不想再作进一步的代码测试,只是按本文给出的方法进行代码修改,在系统启动上不会出现什么问题。
  q! p' E/ f8 A5 C7 ?: M, E/ V0 ~
! q) i" u0 w; _4 z[b:804aea7097]二、自动登录后,自动运行特定的应用程序[/b:804aea7097] 6 }- ^% |+ E( N1 g
+ w# s' x) b5 P3 }; R4 v$ i7 ~# ^
在实现了启动级别3时的自动登录后,自动运行应用程序非常简单,把应用程序添加在/etc/rc.d/rc.local脚本中既可。(读者可以尝试一下把startx加入脚本中,看一看效果如何。在某种意义上,又增加了一种自动登录X window的方法) + {1 C9 J  x9 Y( u! ?  j

5 Z1 f. e! \; j4 y% g% }5 L[b:804aea7097]三、对自动登录X window(系统启动级别为5),并自动运行指定的应用程序的补充[/b:804aea7097]
* S% r1 N. k4 z
* O  J5 r. u$ N7 A- U' W- B1 M4 x在"如何实现自动登录linux"中,主要以redhat 7.2平台为背景进行阐述的,其中的自动登录部分可以直接用于redhat 8.0中,不需要任何修改。
: {8 a; U! v8 B# v% E9 a' s" b! K+ U, A
但是,登录后自动运行应用程序的接口在redhat 8.0中有所不同,主要是登录gnome后,自动运行应用程序的接口有所改变:首先点击面板上的GNOME帮助(那个红色的小帽子),然后选择/其它/首选项/Sessions,在Session对话框的启动程序属性页中添加要启动的程序即可。 $ \4 O5 T- i. W, i7 q: j6 T
+ v& ?  `9 Y$ o* r
对于登录kde后,自动运行程序的接口没有改变。 0 H% k+ ~, y! M8 Q
1 V2 m; ]* w- ~, D
[b:804aea7097]四、结论[/b:804aea7097] : R9 c+ H6 c8 d. `: s
8 R* n7 T# y1 J
本文同"如何实现自动登录linux"一文,基本上解决了如何实现自动登录Linux,并自动运行相应应用程序的问题。对于两个最常见的启动级别(3、5),都给出了各自的方法。 : c( j/ ~$ H# y7 H

" G2 S/ ~; D" N: W" Q) M在系统初始化到mingetty及login这一阶段,内核实际上已经完成了引导过程,已经到了系统初始化的最高阶段,与内核没什么关系了。此时,主要是/sbin/init根据/etc/inittab的内容而相机行事。读者可通过(man 8 init)或者(man 5 inittab)了解更多东西。
; `. A+ X/ q' k/ I, i; ?" I* K1 X+ H
在对文中提到的软件包修改时,请遵守GNU General Public License(GPL)相关标准,另外,替换login通常被视为黑客行为,应当谨慎行事。 0 j; R7 ~$ W9 k0 {& a8 p5 g
9 V; o6 ~% R) B/ i

2 W! J" l6 g6 b$ R6 Q' ]9 d* g0 E# `7 g3 M( s! W
[b:804aea7097]参考文献[/b:804aea7097]
' z! H. R2 F5 V2 Q
/ z+ {0 h5 W+ {; w- J0 a7 ~
( t, k. r4 z- C" Y7 `9 g# ^6 L/ o1.login手册页面  
. E% n4 k- T9 q2.mingetty-1.00-3.src.rpm,在redhat 8.0的发行版本的源代码中,包含该软件包;  
# D; X+ [: M& R0 u; t3 o3.util-linux-2.11r-10.src.rpm,  
' U0 o$ t6 v6 A* S1 ]; ?
9 G- m: w) ]4 U# a+ b" w5 c可在http://rpmfind.net/linux/RPM/redhat/8.0/i386/util-linux-2.11r-10.i386.html处下载,注意下载源代码包(..src.rpm) 8 p" s; y- g' }2 j( L

, Z' e3 E3 p% O. }0 m# c; W[b:804aea7097]关于作者[/b:804aea7097]  0 ^  E0 X5 q9 \: Y5 g0 f8 g
( O) d  s  I. W
郑彦兴,男,现攻读国防科大计算机学院博士学位。您可以通过电子邮件 mlinux@163.com和他联系
6 p7 t. L. c0 v' X6 S- d6 f5 C8 e  K9 m; w1 q  z* G  ]4 v
</P>
作者: huashi3483    时间: 2004-9-27 14:27
如何实现自动登录Linux (Runlevel 5)
/ i- \: J! I3 Q( p" _% t4 v3 O2 x* L* P8 x1 t# O
机自动登录linux,并自动运行X window应用程序,有其特殊的应用背景,如基于linux平台的监控系统,linux启动后不需要身份验证,而直接运行监控程序等等。本文以Redhat7.2为平台,结合linux启动过程,介绍了如何避免身份验证自动登录,并直接进入X window自动运行应用程序。
- n  |8 R2 c( q' E( _  j: H一、linux启动的最后阶段的工作
- @4 z9 \1 n: d' W; X, D/ h) ?5 A/ f: U5 K1 z) H
linux 在启动过程的最后阶段(具体启动步骤略),init 会根据 /etc/inittab文件的最后一行x:5:respawn:/etc/X11/prefdm -nodaemon运行/etc/X11/prefdm脚本,(Red hat 7.2缺省时是这样的)。prefdm脚本的主要任务是完成X window的启动,可以有几种启动X window的方法,都包含在prefdm脚本中,几种主要方法有: 8 @# o& ~8 l4 e
; G* Y1 B" K7 p3 u
运行xdm启动X window;  8 f& p5 M/ V+ |/ W$ |& j; z/ I
运行gdm,进入gnome桌面环境;  
: Z- }. w  r) [% W- D运行kdm进入kde桌面环境;  
1 [4 S/ [5 B4 U% }, h. Q' ^自动登录进入linux;  $ R8 F9 E! ~2 R; e
prefdm脚本框架大致如下: 8 C3 d* ?# a7 a! u& e- Z" L( D, h( h
/ R* H# |) p5 E: P5 @" ~6 M6 s
#!/bin/sh : e1 f9 A# b5 [+ U5 t: @
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
0 D% P  F3 z' h5 U1 h. /etc/profile.d/lang.sh
* n0 P* p" n4 Z+ Y* l3 A# 第一步:查看是否为自动登录
) |0 W( w5 G. b% O3 v4 \  f: |* c& bif [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then % X# h: d& Q- Q% w+ g
if /usr/sbin/autologin; then
4 d+ ?: j0 ^* R. z* Z2 f5 Jexit 0
. {4 ]' \: Q/ y( kfi & L6 V2 G0 F# g7 V+ n2 S$ d; I+ j
fi
% b) u0 R, f- O  \0 i% n. Q" @
7 d  k6 E% Z3 ~- |+ }4 ~# 第二步:如果不是自动登录方式,就会在/etc/sysconfig/desktop中搜寻用户偏爱的登录方式
+ G; d# x; z+ a# `4 R......
% Y: x2 m( Q9 Q; y5 \5 C+ o2 `' {+ h# 可以是kdm、gdm以及xdm,并运行相应的kdm、gdm以及xdm。 7 T% }" w% g) _; w3 A5 p, Y
......   I/ r* B: D& p7 Y- H! f3 z6 B
# x3 Y- b& y* i; K
    A5 |2 N  d: F$ l8 y2 T
* P* y3 \+ d- V  P4 f* j, \8 m
- Y" V* U7 y0 S. m8 N) j8 T1 K
二、自动登录的实现(autologin的实现) & H9 v! S. c6 V2 X
# d$ G2 V9 w/ l6 e% G7 L2 f! P0 T
在/etc/X11/prefdm脚本中,是否实现自动登录有一个条件测试开关,事实上,可以在这里注释掉测试开关,直接执行启动X window的操作。 2 c: @) O( J7 M$ ?

2 s* Q2 l* v7 ?自动登录实质上就是绕过身份验证,直接启动X window。X window的启动可以由xinit来完成。 ! F3 k5 r/ S! j  n- h; \
- }8 j# u& z/ K- F; u
Xinit用来启动X window系统服务器以及系统上的第一个客户程序,可以通过为xinit传递命令行参数的形式指定要启动的服务器及客户程序。如果不传递参数给xinit,它将在用户的根目录下寻找并运行 .xinitrc脚本来启动客户程序;在用户的根目录下寻找并运行 .xserverrc脚本来启动服务器。如果xinit在用户的根目录下找不到.xinitrc、.xserverrc,xinit将使用缺省的X :0。  / I& g  o; a! F' W- e2 d
实际上,用startx来启动X更为方便。对于运行单一会话的X window 系统,startx提供了更为良好的用户接口。同样,startx首先在用户的根目录下寻找 .xinitrc及.xserverrc脚本,如果找不到这两个脚本,startx将使用/etc/X11/xinit/xinitrc以及/etc/X11/xinit/xserverrc脚本。  
- r" _, {7 M+ q$ F" M6 Fstartx脚本的最基本框架是: % n  r0 a4 n- ^* y2 N5 }9 O% k1 B
- x# k% W9 v; [, H
a、 寻找.xinitrc,如果没有则使用xinitrc; & \- Z- d! i8 I0 V  k
b、 寻找.xserverrc,如果没有则使用xserverrc; 5 f$ D! v' O5 \% p7 ]
c、 根据找到的脚本确定xinit的参数;
. z! K2 c/ |' I9 m3 y( \' d% ?/ r2 Z
由此可看出,startx在不需要传递任何参数的情况下,可以完成启动X的任务,因此,可以如下修改/etc/X11/prefdm脚本来实现自动登录: ' p, y4 p3 z) N! c- \) [3 e

5 l9 D" r7 `6 x) h/ X4 \' t1 V" D8 Q9 Q- v7 ?& M; }, H/ e
#!/bin/sh ! f5 G6 Y- d' k
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
6 E8 H6 b, ^* a1 B. /etc/profile.d/lang.sh
$ r  H8 j6 N$ a$ ]0 K# 第一步:查看是否为自动登录
% b' ?; `& T2 c9 [0 Z1 @5 w#if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
* K( P, x& o8 n" }#注释掉上边的条件测试,直接运行startx 0 _+ r  p0 l* J/ C7 B# Q
if /usr/X11R6/bin/startx; then & O0 Y8 `- e0 S# b
exit 0 * }* i; y, s; }" d! z' O. i
fi 1 O" {3 `" J& Y3 g
#fi ) w2 M, ]  i3 x, i' ?

' i0 C, P1 I  D. ?9 z  
0 a" g# q/ B& _$ t" [4 i2 \- T6 ]4 {2 u6 g

$ D" D1 f% X8 [: v当然,应确保/etc/inittab中的启动级别为5。
3 x$ S$ F& M5 a3 u& b$ R
: ^6 R" M- Q  X7 Z  f" W  Z6 G& l重新启动系统,会发现系统不验证用户身份,直接进入X window,此时的用户身份为root。但是,如果原来root有自己的桌面、默认shell时,上述方法启动X不一定保证还能拥有原来的设置。为了在启动X后,在避免验证身份的同时,又不改变用户原来的设置,那么在运行startx之前,还有工作要做。 " h' S& R& X9 B

6 ?9 i4 h' q: K3 z; T6 D- c8 |1 `三、自动登录后,保持用户原来的配置(桌面、shell以及其它的一些环境变量)。
0 g: o, T9 x7 J/ C+ M3 r* M, e" ?- W' s% n& T2 [
观察原来/etc/X11/prefdm脚本的自动登录部分:
# O- s) j# A$ z# g7 q& p; q$ C8 {7 e! o  F* _, r
9 f0 B3 {, f  `
......
* E2 m% J- T& n  _! J# 第一步:查看是否为自动登录 ' Z9 [3 |; B3 n" B; _1 t
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then 4 e  c1 I2 l: s) q) t5 ~
if /usr/sbin/autologin; then ; t" F( l1 V* i5 I+ d; L9 Y$ R$ g
exit 0
4 i: v. }. e5 E: dfi
& u3 n- R5 o# C0 bfi
3 l, Q+ G0 S) J/ x% e& ~...... ; b+ A. a" h! N: E2 O
9 @' n3 v4 b* t5 P  v
  
" T% T' j& ]$ K( u5 c- J' u5 R
- _2 J+ t1 \6 J( X& _+ V+ _  o
1 q5 C( D3 v  ~1 l不难看出,脚本中保留了自动登录的接口:一个可执行文件/usr/sbin/autologin以及一个配置文件/etc/sysconfig/autologin。 - `' W6 D4 E5 J# ?" l5 M" P

% |, E7 p1 n! B" S- \# U/ t1、/etc/sysconfig/autologin配置文件的实现:
5 |* T* y( T/ ?0 Q- l
& W- `$ ~7 @1 {1 ^9 u
! o7 Q5 t) w: G' W5 l#config for autologin
1 E7 G) S1 T5 e$ R% [' B4 V- \* BUSER=root 2 l! j) i6 X* k* B& s9 w) s
EXEC=/usr/X11R6/bin/startx
& A# ]( U+ N) o说明,USER指定自动登录时的用户名;EXEC指定启动X要运行的程序。 2 q, a, A+ i  @2 s' ~, O. B

: x3 g4 ^" S: K9 h  
8 Y, a0 \& m5 P, B* ~3 X8 C7 w$ h2 i, d; M& U: n

. O+ W5 R- C  m8 C1 A8 B9 {5 M2、/usr/sbin/autologin可执行文件的实现: ( R5 d; }/ O4 o" U

  o1 L7 J* Y1 B/ L* `8 I! Q4 w* f9 a) K; z8 `$ N) I& z( a
/*********************
( r' g% z8 o2 j****  autologin.c  ****
+ h" ~2 R! l* n*********************/
& w1 g+ e4 I0 |* B+ P3 }#include &lt;stdio.h&gt;
7 U; \: l& \+ y1 W#include &lt;unistd.h&gt; : D, |+ y) S9 i, K; s0 V
#include &lt;string.h&gt; 2 |7 ?. \3 m/ t/ O
#include &lt;errno.h&gt;
$ `' w) S. d9 ~% }4 K: A% M# {3 i* J' H#include &lt;sys/types.h&gt;
, w$ L6 m  c/ P% F1 D7 Z/ [#include &lt;sys/stat.h&gt; ! d8 S7 M9 d% G- f) p
#include &lt;pwd.h&gt; 0 }* G. [/ g$ k# @

) t6 ]7 i) h+ T( q% pint main(int argc, char **argv) , ^' r6 N! v# s1 F6 k/ A7 y- l
{
9 Z: L5 _  l* j) ^" J. R* \" vstruct stat st;
" ~5 N! ]* `+ B. S3 XFILE *f; , U- x8 a2 \; Z/ w. c
char *cfg; 6 j5 A) t9 R9 L5 O: p$ _
struct passwd *pw; 8 j/ Q+ W& e3 o% M- U$ y0 H6 t1 E
uid_t uid; ) ]" e* A# P5 K: a% S! U  _/ ^* G
gid_t gid; 2 [4 A) P6 W0 ~( h& D
char *dir, *shell; ' ]3 L8 @2 ?) a: o' O
char *user=NULL;
+ g( \4 O# C6 W4 k8 ]* {char *cmd=NULL;
8 }6 D4 k8 ?+ Y1 u
. v; q: _& }' _2 q7 h/ d+ p9 {- Juser="root";
( S  J) N) T2 I6 ^3 ^$ k/*为了能说明问题又保持程序简洁,这里默认登录用户为root,实际上,
% j- R3 t7 c$ L# ?! V登陆用户名应该从/etc/sysconfig/autologin中得到, ! L. M3 U+ j' I* {0 C
程序实现时要注意过滤掉/etc/sysconfig/autologin中的无效用户名*/
# N: x+ l# d9 qcmd="/usr/X11R6/bin/startx"; ) j1 J: ^% b6 a  e1 D! D, {! t
/*同样,这里直接指定启动X window的程序,实际上,该程序应该从/etc/sysconfig/autologin中得到*/ . z8 \0 @" w; d  U4 M

8 K( f6 z" F* \$ Epw = getpwnam(user); 2 q5 G( {0 |0 ~3 n0 f; ]
//getpwnam返回包含用户信息的passwd结构(该结构在pwd.h中定义)。 % U- E: W& n" U* v8 Z
if(pw) {
  G6 }9 ~; t- Z* Ouid=pw-&gt;pw_uid;
  ^& p0 N% Y, v2 i5 w2 bgid=pw-&gt;pw_gid; dir=strdup(pw-&gt;pw_dir); ; B9 ?7 Y% z" W  o
shell=strdup(pw-&gt;pw_shell);
2 V; B5 Y1 c) J% T' c! ^} ( o/ J% h2 Q* Q
//获得用户相关信息
2 p" E3 I1 L. p5 l. r- F else {
. F" N" \1 Y0 N, Dprintf("ERROR: No such user %s!\n", user);
  v9 g7 ~& l6 O! j& B! Dreturn 1; 7 n$ D; p5 p& O9 `; E) N
}
  _6 C) e5 V* `) Y7 k: p
& Z! s0 U8 g% ^: h0 U8 A! Bchown("/dev/console", uid, gid); : K3 T3 N5 g# r9 l
chown("/dev/tty", uid, gid); 8 R  H- |7 C% s0 u) ^/ N- l
//为控制台和终端设置用户ID及组ID
. p; r! A0 ?* i  W# v: L# J; f+ h/ k5 E7 R0 o4 `
//下面是设置用户相关ID / a  s# X+ A. W* b  E
setregid(gid, gid);
+ T2 F" w3 [9 m: h1 B. Y) x0 T$ Usetegid(gid); , i3 ^* |$ N5 u% j/ w0 j, `8 S
setgid(gid); * C! h) R- j% E% S0 t
setreuid(uid, uid);
$ r/ d1 j/ ?1 s; ~8 E; I) ~% p: X1 Fseteuid(uid);
0 h8 K2 z* s  B( y8 qsetuid(uid);
: O5 ?8 n% c+ ^  l; i
9 }9 f5 ^) \( U8 Csetenv("HOME", dir, 1);
: }& Q. y! o0 }, k$ Gsetenv("SHELL", shell, 1);
* O3 a! a+ P. p5 dsetenv("USER", user, 1); 8 F! W! `) h2 Q/ `
setenv("LOGNAME", user, 1); ( Z" l% s3 E: w+ H( }5 W
//设置用户相关环境变量 1 _, H9 P4 B2 X. p  d) V

8 e) S% Q3 L' i" q0 Pchdir(dir);
+ Z' N; S! ^0 U: K$ ~0 }# P//切换到用户根目录 7 C: J  m$ C( r3 B, P( o
user=NULL; 0 p' W3 ]* R) m5 X3 y5 ]

5 L# H6 J- J  Y" k1 Pexecvp(cmd, argv); 5 i. B, t& U* ]! q$ s
/*在配置完用户的相关信息后,执行启动X window操作。注意这里默认执行/usr/X11R6/bin/startx */
6 `% Y+ k9 L- ^, g) T; P" xprintf("ERROR: Couldn't exec %s: %s\n", cmd, strerror(errno));
/ r/ s5 j, }: Z/ F& q) O* Wreturn 2;
+ Y/ j- {- b% a- o# j6 {}
; ~# J$ G& `/ q8 K+ t+ o/ q/ a" ^6 M# v* [% P
  
2 F0 _- s! h) L) U, Y8 j
" M" \6 j# q1 X" t/ m7 P3 y' v$ o0 r( ~" T! R! N5 u: ^) g2 q
运行gcc -o autologin autologin.c,拷贝autologin可执行文件到/usr/sbin/autologin,拷贝autologin配置文件到/etc/sysconfig/autologin。 重新启动系统,会直接进入X window并保留用户原来所有的风格。
6 u# R# ^- I" @9 x( ^
* }5 e! X5 d9 H6 q: i% k如果不需要自动登录的配置文件/etc/sysconfig/autologin,所有的操作都在/usr/sbin/autologin以默认的方式实现(比如,默认登录身份为root,默认执行操作为/usr/X11R6/bin/startx等),那么,/etc/X11/prefdm脚本的自动登录部分可简化如下:
( A9 A+ R! v& t" |* h/ x0 {% u5 o$ m' d

" K& y" A3 c, w. e+ b6 I...... ' j9 ?7 h( _2 {2 S/ ~$ t' H; \
# 第一步:查看是否为自动登录 9 @. @/ I8 t! s4 C
if /usr/sbin/autologin; then
. s9 ?- ]3 W* ^) Q8 ~) cexit 0 / `" H* L# }9 r5 q0 `
fi ; C, u4 u5 D" e% |/ P; ^2 s, Z) z
//第二步 ...... 7 R3 ^9 i  Z) f* {+ A5 q# s
......
  [" P3 i5 b! C2 k' b+ h- L/ U2 K. X: ~& \/ s( f$ m
  
4 `9 ?- U3 h5 t' o' j
3 x9 ?- \! d7 U: J" }' D5 u
' F8 S' \' ~% q  k$ A& |7 a# |即在脚本中去掉条件测试开关,直接执行/usr/sbin/autologin,这时,只需要拷贝autologin可执行文件到/usr/sbin/autologin,不再需要拷贝autologin配置文件到/etc/sysconfig/autologin。
0 U% d. Q0 T" Y6 S2 s' t8 ]/ j
, V6 q& C' ^2 T, R8 s3 f1 q四、选择进入kde或者gnome,并自动启动X window应用程序 % v# \) J% H, ^  k" n4 Q
. G, G9 R% a$ i, b$ k
如果重新启动后系统进入了kde,而用户需要进入gnome,只需运行switchdesk gnome在重新启动系统即可,以后每次启动时会自动进入gnome;反之亦然。  : u1 m, k" ~7 L; t% A
一般系统自动登录的目的是启动X window 后自动运行某个X window程序。如果系统默认的启动级别为3,那么如果要在系统启动后自动运行某些应用程序,只需要在某些脚本中加入相应命令即可,不再详述。在X window启动后自动运行应用程序要复杂一些,幸好,kde和gnome都为此留下了自动启动接口。如果在kde桌面环境下自动启动应用程序,只需要把应用程序名字加入/root/.kde/Autostart/目录下即可(这里注意不同用户的根目录可能不同,如用户zyx的根目录可能为/home/zyx)。如果在gnome桌面环境下自动启动应用程序,只需把应用程序的名字加入/主菜单/程序/设置/会话/会话特性及启动程序的startup programs属性页中即可。  
( z7 D, a4 `1 D8 |
( b: C; w; @- S4 A7 Z
% H' d  e) r) |' K: N8 shttp://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip20/index.shtml




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5