数学建模社区-数学中国

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

作者: huashi3483    时间: 2004-9-27 14:26
标题: 如何自动登录linux[转载]
<>如何自动登录linux[转载]</P>" t7 K) y1 [- k
<>本文以redhat 8.0操作系统平台为背景,阐述如何实现启动级别为3时的自动登录,及自动运行相应程序,并简要介绍了如何在redhat 8.0下自动登录X window(系统启动级别为5),并自动运行指定的应用程序。 ( F+ O& Z( h$ @: d
[b:804aea7097]一、启动级别为3时自动登录的实现[/b:804aea7097] 8 g0 A6 `% s# k" f/ O/ ]- A2 o# Q
, b4 ~1 {( x! @$ n6 b4 T, b- C, U
启动级别为3时自动登录的实现涉及两个软件包:mingetty-1.00-3.src.rpm软件包及util-linux-2.11r-10.src.rpm软件包。 & I; J( X0 h# G' F9 l

3 Y# T/ E. i4 L. M4 K(1)mingetty-1.00-3.src.rpm软件包  
# Z2 n* a5 F& l+ }  [7 |" h对于启动级别为3的自动登录的实现,仍然需要考察/etc/inittab脚本,  
2 y6 G/ z4 W: P, S) j) h# H) c' A; J3:123:respawn:/sbin/mingetty tty3
, z6 R/ `/ U8 c
& h1 ~% x; l  ?% ?: L; t" J8 T/ g4 @
  J7 ~1 q. U3 A) z/ z1 m  " Q" J1 Z0 K8 k* f9 ]
& P$ Z& m0 u, ?* W9 T  o, f; ~+ o

9 _. O% m+ v& H" B因此,如果想在启动级别3的情况下实现自动登录,必须要了解mingetty的功能,甚至要修改mingetty的代码。用命令rpm -qf /sbin/mingetty 可知redhat 8.0版本的mingetty包含在mingetty-1.00-3.src.rpm软件包中,下载该软件包,安装源代码,缺省情况下,代码会安装在/usr/src/redhat/下,我们关心的只是mingetty.c源文件。mingetty.c约有五百行代码,主要实现如下功能:
2 b. v7 d1 Y, o' K0 e' \# [* p3 L0 J. g/ m! q! ~- _" [/ A
+ e* {. I2 o; X5 P  \; v  S; n: i2 P2 @
打开指定的tty(由参数指定);  
6 V& A+ @: B- a提示用户登录(login:);  * m2 C2 \3 f& c+ |  [
获得登录用户名;  0 J; E+ F+ }& E* ~; Y; q3 [2 E
把用户登录名作为参数,调用/bin/login。  : U( c6 f! Z  @0 Q. m5 M4 {# V, }# n

; n8 d- N# n# ]& X  D4 h0 m我们所关心的部分实质上只有以下三行: ) j7 t. j. p# M! D

2 _$ ~# {/ @4 D% r& R) `; s: u3 T# G. X
... ...
1 p. O- p: U" i3 n+ e438 while ((logname = get_logname ()) == 0); //mingetty.c文件438行 . R, x& m; f2 `, T( G$ V) b. ~4 @0 N
439 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL); , m% I& p( i8 D0 _# \
440 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
" w& X7 X; ]$ z9 E% R8 h... ... 1 v4 M: e- Q! y3 I+ @' z

! K# ?  v. p" B% f0 F    S+ Q9 h% ]: B* \  F, |
3 m1 [8 k9 ~1 o4 Q$ E8 g& r
第一行的功能是输出login提示,并获得用户输入的登录用户名,登录用户名由logname返回。因此,可作如下修改
, [* ^! l% W' D: s: |% }2 f8 t1 C+ s# H% O0 W& K. `- M; G
1 X2 D3 z% `9 W' ~
... ...
- |, U# ~( V. p. m9 Q9 A8 _/ w3 a438 // while ((logname = get_logname ()) == 0); //注释掉本行,不再提示login: 5 |% ]6 U" G- E
439 logname = "root"; //添加本行代码 # w  K5 D) h5 [0 U+ A
440 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
( D$ K( a8 f7 U! I1 ]441 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
; O2 n: P9 Y3 L$ ~9 ]; G... ...
; B' d0 Y* ]3 r' a( J7 R  f
9 |1 X0 E5 n: Y4 {4 V3 L  2 ~0 {# N( o3 J" ]+ e. x8 m# A# j* R- C

8 J0 Y! o" c+ b5 t3 J0 v注意,这里假定用户以超级用户身份登录。 . ^+ n0 [  @! Z7 v2 j$ b

' v; K8 Y3 v7 W, Y- j第二行以用户登录名为参数,调用/bin/login程序,进一步实现登录。因此,要想实现自动登录,还应该了解/bin/login的功能,必要时还应修改其源代码。 $ X0 _8 j& j: i; G5 N% Y

+ {2 P& R2 M0 g" R第三行为出错处理。
( v( p! |- d$ M) \  F* E' h4 y% T- }+ w( F
(2)util-linux-2.11r-10.src.rpm软件包  
1 F4 x7 Y, x/ r4 F. n# S; R采用同样的方法,查看/bin/login所属软件包(redhad8.0版本的login包含在util-linux-2.11r-10.src.rpm软件包中),下载并安装util-linux-2.11r-10.src.rpm,login可执行文件有几个源文件编译而成,我们最关心的是login.c源文件(大约1500行的代码)。下面简要分析一下login要实现的功能,并对相应部分作必要的修改。
' A# b: [) c, Q1 a  l; m- C% c8 p: P2 _0 J: S
Login程序主要可以分为以下几个主要部分:
; O) r) r# R- ^6 O! G( R. a2 \  _( g) S- d+ t: c$ `/ n
1.Login首先检查登录者是否为超级用户,如果不是超级用户,并且存在/etc/nologin文件,则输出该文件内容,并中止登录过程;主要由checknologin()实现;  
7 N# Z* R: e; V% \2 l) N; P+ k2.如果登录用户是超级用户,那么login必须在/etc/securetty/中指定的tty列表中实现登录,否则将导致登录失败。同样可以不指定/etc/securetty文件,此时,超级用户可以在任何tty上登录。  8 q  s5 L) n6 l# x. p5 t' S
3.经过前两步测试后,login接下来将提示输入登录密码(由getpass()调用完成,有兴趣的读者可参考其手册页面),并进行验证,如果密码不对,则提示重新登录。  
2 ^- N2 V7 D+ `; `; u( v! h4.顺利经过密码验证后,login还将检查是否存在.hushlogin文件,如果该文件存在,则执行一次"quiet"登录(所谓的quiet登录指的是,登录时不再提示邮件mail,不再显示最后一次登录时间,不输出任何消息。启动级别为3时,正常情况下输出这些信息)  5 y- O3 M: W& f1 r6 u/ O
5.login接下来设置登录tty的用户ID和组ID,并设置相应的环境变量,包括HOME、PATH、SHELL、TERM、LOGNAME等。对于普通用户来说,PATH缺省被设置成/usr/local/bin: /bin/usr/bin:;对于超级用户来说,PATH被设置成/sbin: /bin: /usr/sbin: /usr/bin:  0 f$ y! o* O( _; `) r
6.login的最后一步是为用户启动shell。如果在/etc/passwd中没有为用户指定shell,那么将使用/bin/sh,如果在/etc/passwd中没有给出当前工作目录,则使用"/"。  " I& H9 ]1 x; a
至此,一个完整的登录过程就结束了。
, l, n9 B( Z- Y9 c
0 S$ j0 @/ `3 Z从以上对login源程序分析过程中可发现,如果要实现自动登录,应该在第三步做文章,设法绕过提示输入密码以及对密码进行验证这一过程。实际上很简单,login源程序对是否要求输入密码设置了一个开关控制passwd_req,缺省情况下,其值为1(passwd_req = 1),即要求输入密码进行身份验证。把该行代码改为(passwd_req = 0)后,问题就解决了。即对源文件作如下修改即可:
% h; [: O1 m6 t) Y& L8 n
. }& @% d. Z0 b; s9 w0 f1 t1 n
6 A  j8 ]* o7 G5 Q. V9 b... ...
8 g9 b8 n. X! J* J402 fflag = hflag = pflag = 0; //login.c文件402行
# G. ^! D; S( Y  c403 //passwd_req = 1   //缺省时,要求进行密码验证,注释掉本行
. u, b' s6 h9 }7 c6 l" x' P7 l404 passwd_req = 0 //添加本行 * B- @7 z5 T. I! B4 T
... ...
: h. P- o$ h$ Q  ~$ j! [# d- @8 a; V6 S+ V+ e
  5 ?  Q& x% S: K- F8 o
" ]1 M3 L$ c: Z! C9 r, ^& o, f
修改后,可以直接使用util-linux-2.11r-10.src.rpm提供的Makefile进行重新编译,也可以自己对其编译:
& A: @3 ]4 @. @! t/ z' @
* ^" k- G# Z+ D: j
) _( T/ G  C/ agcc -o login login.c setproctitle.c checktty.c xstrncpy.c -Wall -lcrypt注意包含后面的编译选项-lcrypt,否则会出问题。 , c- ?" @# z% ?
) p! R( ~2 ]+ k7 _0 p0 ~
& `' o( B; Y" k7 U
有了新版的mingetty及login后,拷贝mingetty到/sbin/目录,拷贝login到/bin目录,并将/etc/inittab中的启动级别设置为3,再重新引导系统即可(读者可以自己写一个脚本实现上述过程)。
5 D0 k! t2 N% i7 R' V( k  K1 \8 A
9 {1 f2 G3 Y% r0 M" ?8 E" y如果读者对mingetty或login代码的其他部分感兴趣,可以反复修改login.c或mingetty.c的源代码,测试一下代码的功能,这里要注意的是,在拷贝新版mingetty和login之前,一定要把原来的mingetty和login备份,同时还要准备系统引导盘(有系统安装盘亦可,这样读者有机会键入linux rescue),在测试新版程序前更应如此,如果对代码修改稍有不当,系统将不能正常启动。 / E4 [1 A& M9 c' f! ^  @1 I" E
' L! f* o- l4 q8 o# |: T
如果不想再作进一步的代码测试,只是按本文给出的方法进行代码修改,在系统启动上不会出现什么问题。 $ K+ ?" P+ r- L; |2 I

8 T1 [* J3 Y: \6 r[b:804aea7097]二、自动登录后,自动运行特定的应用程序[/b:804aea7097]
7 ^5 [: }$ E7 v! N% D4 b! d$ l5 S4 T; M" @
在实现了启动级别3时的自动登录后,自动运行应用程序非常简单,把应用程序添加在/etc/rc.d/rc.local脚本中既可。(读者可以尝试一下把startx加入脚本中,看一看效果如何。在某种意义上,又增加了一种自动登录X window的方法) 6 n. {3 I1 ~" S0 K( K

! H: X1 [3 o4 C3 E0 ?[b:804aea7097]三、对自动登录X window(系统启动级别为5),并自动运行指定的应用程序的补充[/b:804aea7097]
) ?" z9 Y( x/ @% ?" R' X" o4 ?5 ^$ f
, c2 u" F, b9 f在"如何实现自动登录linux"中,主要以redhat 7.2平台为背景进行阐述的,其中的自动登录部分可以直接用于redhat 8.0中,不需要任何修改。 9 I( F% U" v$ K: H8 T0 C6 k. L# _

& \+ `0 V( U" o: @4 n  p但是,登录后自动运行应用程序的接口在redhat 8.0中有所不同,主要是登录gnome后,自动运行应用程序的接口有所改变:首先点击面板上的GNOME帮助(那个红色的小帽子),然后选择/其它/首选项/Sessions,在Session对话框的启动程序属性页中添加要启动的程序即可。 / K  F7 R; `3 w6 }4 S4 \' Q

% G6 S' u) ]& v% q& m. g/ [, a4 z对于登录kde后,自动运行程序的接口没有改变。
. ]5 H- A" S- u/ h
9 b- y) ^0 b& @1 B* L2 c- P4 Y$ a[b:804aea7097]四、结论[/b:804aea7097]
/ r4 s  I8 h( d) x) {! F$ h$ X, p/ k% i. c2 c- D
本文同"如何实现自动登录linux"一文,基本上解决了如何实现自动登录Linux,并自动运行相应应用程序的问题。对于两个最常见的启动级别(3、5),都给出了各自的方法。
' h5 S; b$ Z" y
( Q4 D! W8 f3 o# g/ h在系统初始化到mingetty及login这一阶段,内核实际上已经完成了引导过程,已经到了系统初始化的最高阶段,与内核没什么关系了。此时,主要是/sbin/init根据/etc/inittab的内容而相机行事。读者可通过(man 8 init)或者(man 5 inittab)了解更多东西。
7 @6 A$ e. Z, n3 N; B& ?! y" `0 |7 z* P+ h, t& l0 n" p6 E/ i
在对文中提到的软件包修改时,请遵守GNU General Public License(GPL)相关标准,另外,替换login通常被视为黑客行为,应当谨慎行事。
! p" s$ [( m1 a  s6 F1 V6 Z
' M/ n  O; B  F2 t, O( |& _' s# H, v4 B

( J3 F: B; ]) w6 o5 Y5 W[b:804aea7097]参考文献[/b:804aea7097] 5 }, n5 b7 r0 \- z

8 H0 W3 C6 D# d$ g2 x2 F) v
6 `2 G! p7 l" i1 S; c6 ]! k1.login手册页面  
/ r( h) @8 G  ]$ S4 \0 O1 s2.mingetty-1.00-3.src.rpm,在redhat 8.0的发行版本的源代码中,包含该软件包;  6 }; R) U1 w/ P7 q
3.util-linux-2.11r-10.src.rpm,  . K$ A; I5 F; D3 ^
) h8 l/ j6 F& [# e
可在http://rpmfind.net/linux/RPM/redhat/8.0/i386/util-linux-2.11r-10.i386.html处下载,注意下载源代码包(..src.rpm)
; ]; t9 ?' n) X
$ v& `0 W, |; M2 |+ N: D2 X[b:804aea7097]关于作者[/b:804aea7097]  
. K9 c! e, b0 t" Y/ Z6 u2 y  J. f+ O" t( `2 B. h2 V
郑彦兴,男,现攻读国防科大计算机学院博士学位。您可以通过电子邮件 mlinux@163.com和他联系: f! T' ^9 R" D( Z

( T/ c; ]' m) Q* u$ [5 n; ^' `! Z</P>
作者: huashi3483    时间: 2004-9-27 14:27
如何实现自动登录Linux (Runlevel 5)
0 p7 N& O3 ]0 F0 w- u% y  Z/ [; g
/ Y: S  L4 }! b) m' \+ ^4 ?机自动登录linux,并自动运行X window应用程序,有其特殊的应用背景,如基于linux平台的监控系统,linux启动后不需要身份验证,而直接运行监控程序等等。本文以Redhat7.2为平台,结合linux启动过程,介绍了如何避免身份验证自动登录,并直接进入X window自动运行应用程序。
, K9 @/ K- T, V6 |: j8 G  T8 p一、linux启动的最后阶段的工作 # l& c; j$ z6 _% p6 O& z

+ E8 V" s8 c' F( r. v9 klinux 在启动过程的最后阶段(具体启动步骤略),init 会根据 /etc/inittab文件的最后一行x:5:respawn:/etc/X11/prefdm -nodaemon运行/etc/X11/prefdm脚本,(Red hat 7.2缺省时是这样的)。prefdm脚本的主要任务是完成X window的启动,可以有几种启动X window的方法,都包含在prefdm脚本中,几种主要方法有:
3 @9 K: q) x; A! B- x
8 y8 s0 z% ?, x% @运行xdm启动X window;  
+ R) }% q5 s% I% a+ ~, F运行gdm,进入gnome桌面环境;  
, ^+ o+ I! g/ n1 d& ~运行kdm进入kde桌面环境;  
# Y6 S7 j' r9 [' M' x  w1 P& P自动登录进入linux;  ) V& w, b% [4 Z6 `
prefdm脚本框架大致如下:
3 N( l7 d2 r- ^) a+ i2 e! f. R  \1 W# L& ^- M) _8 s' D
#!/bin/sh
; i8 }# y" n* q% m0 Y, P, hPATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin ' o- @* H" Y& h: n8 y
. /etc/profile.d/lang.sh
4 h. W$ t, F' ^& w. r# 第一步:查看是否为自动登录 / A$ b/ q9 C" ~. D8 X% P1 Z6 ^" w+ e
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
- [: J- r9 q+ _+ v- H, u0 jif /usr/sbin/autologin; then
9 d% D: q' f" r! x7 [exit 0 ( O+ w% \& ^5 V% I. f! E6 ~
fi 7 W! |5 H% K7 q+ Q* L
fi
2 P9 G" J# X! s' d3 J& s9 a' \* L0 `; B! S+ d9 u  @
# 第二步:如果不是自动登录方式,就会在/etc/sysconfig/desktop中搜寻用户偏爱的登录方式 ) f! q1 P- ~$ i5 B
...... * n/ P8 F3 f, i. F6 A! Q
# 可以是kdm、gdm以及xdm,并运行相应的kdm、gdm以及xdm。 5 o% G+ b* w3 Y2 \, O" b- l: ^
......
9 E! _& x' F! s' d4 Z# I! }
# `) |- B5 C! p/ b: x0 S- V  
$ S# U4 p/ w7 ~) y' ?/ q1 T. f
2 P" ?! i1 P0 R" G. F( T& V2 n- V! s7 O
二、自动登录的实现(autologin的实现) ) J" h- }' d" t& q4 g

4 V# C8 M3 {9 r9 t, G% c% d2 ]4 o在/etc/X11/prefdm脚本中,是否实现自动登录有一个条件测试开关,事实上,可以在这里注释掉测试开关,直接执行启动X window的操作。 % L9 d6 i) S" j. b* {1 B
4 I; O6 y% o' a& H# v4 b
自动登录实质上就是绕过身份验证,直接启动X window。X window的启动可以由xinit来完成。 / _' j/ D$ a% ]
$ R7 W. p$ O: \: |1 \  ^
Xinit用来启动X window系统服务器以及系统上的第一个客户程序,可以通过为xinit传递命令行参数的形式指定要启动的服务器及客户程序。如果不传递参数给xinit,它将在用户的根目录下寻找并运行 .xinitrc脚本来启动客户程序;在用户的根目录下寻找并运行 .xserverrc脚本来启动服务器。如果xinit在用户的根目录下找不到.xinitrc、.xserverrc,xinit将使用缺省的X :0。  8 f) o# K9 w9 A7 x, i
实际上,用startx来启动X更为方便。对于运行单一会话的X window 系统,startx提供了更为良好的用户接口。同样,startx首先在用户的根目录下寻找 .xinitrc及.xserverrc脚本,如果找不到这两个脚本,startx将使用/etc/X11/xinit/xinitrc以及/etc/X11/xinit/xserverrc脚本。  + _1 H" D- O3 B9 D1 U# A7 _
startx脚本的最基本框架是:
) s$ A; N; Z7 T1 o9 Y' i$ q/ f
# t* e0 ?  Y4 m! f( m% da、 寻找.xinitrc,如果没有则使用xinitrc; $ C& E- J3 _7 Y8 ]
b、 寻找.xserverrc,如果没有则使用xserverrc; / ]( ?$ ~) C: ?, f, {' ?  c
c、 根据找到的脚本确定xinit的参数;
- v1 E* I! |2 I5 ?' q* F% d( J- A7 @5 G6 @7 F! Z* E1 k
由此可看出,startx在不需要传递任何参数的情况下,可以完成启动X的任务,因此,可以如下修改/etc/X11/prefdm脚本来实现自动登录:
4 g+ w4 A3 b1 F
" S7 O$ a, b/ B* z4 @
( \+ Z  N3 X5 G#!/bin/sh
3 {- w2 I8 G  q/ \* u  V2 _% S3 ]PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
7 G. M& ?2 H$ X! e8 y. /etc/profile.d/lang.sh + i2 r/ L* |7 E6 E; ^/ m
# 第一步:查看是否为自动登录 9 N' n# W7 p  r/ O5 [1 i& }
#if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then 4 U+ ]. G) I+ ?. m( t1 i
#注释掉上边的条件测试,直接运行startx ( ~8 S: r  ?7 h( c8 [4 n
if /usr/X11R6/bin/startx; then
6 R5 p- D7 v+ Mexit 0
, W6 \$ `" ?- ]' |  a- @: Yfi 6 p- L. n8 c5 e( c1 ]) E
#fi / \& \% n7 _9 Q( z( C
6 F$ s9 \  X1 E4 ]; E+ j  r
  
) t( B+ w- R; j: ^& v* k; ]; o6 m9 ?/ f+ i' n, \2 f. t

( ?. z* q- M. u2 P8 n' D+ `! P当然,应确保/etc/inittab中的启动级别为5。 5 S$ i- x. N! E3 \" u

  d3 T: r% [& L- R% U: R重新启动系统,会发现系统不验证用户身份,直接进入X window,此时的用户身份为root。但是,如果原来root有自己的桌面、默认shell时,上述方法启动X不一定保证还能拥有原来的设置。为了在启动X后,在避免验证身份的同时,又不改变用户原来的设置,那么在运行startx之前,还有工作要做。 ) k; `& d+ I/ \

" U# O; I3 k' A" ?三、自动登录后,保持用户原来的配置(桌面、shell以及其它的一些环境变量)。 - N( U5 g+ b; |
0 W  H9 x9 d- _1 x
观察原来/etc/X11/prefdm脚本的自动登录部分: 7 h/ C* q! z7 [6 o) a

& E) f4 B) {5 @: d$ H( @% x7 }
% T+ M- u5 C2 H" Q......
5 c: m1 f, u* H6 R6 f4 C# 第一步:查看是否为自动登录 6 G4 V. u$ Q+ U  d* X7 p% G* R
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then 4 V6 V3 N. }3 }0 A6 O4 m
if /usr/sbin/autologin; then
8 a+ @/ h' p7 i) L$ m" k% J0 wexit 0 4 Y. U3 G" R# j1 F, V
fi 6 V$ p( p5 i" Y8 r! t
fi : |4 J3 _, E/ X/ _9 H
......
0 b7 p* e8 z( R: A' _/ l+ j/ B5 }$ D8 X. l9 }0 p) ]
  : u1 P3 M7 G7 w$ f- x
  K0 q) t# T+ o. |) L  l- E3 U
9 ~& i( [3 K) U: D
不难看出,脚本中保留了自动登录的接口:一个可执行文件/usr/sbin/autologin以及一个配置文件/etc/sysconfig/autologin。 9 X3 o6 z/ w7 L; F
8 X0 U  P: |* F" H! i0 |  p
1、/etc/sysconfig/autologin配置文件的实现:
7 g5 z3 b6 Y# s4 @! x1 f8 ~! v) A) r# o0 u+ l

+ Z. H. D: J! c$ f#config for autologin
7 d0 x/ k4 S1 K% ~USER=root
# P0 k6 f& [3 K  K2 V( D# \$ [EXEC=/usr/X11R6/bin/startx
4 s& U; v5 y) i! X9 r说明,USER指定自动登录时的用户名;EXEC指定启动X要运行的程序。
3 p) N3 y) l: U' `$ }
" s- D4 ]: |! K7 }, u  8 z- r2 _' B- q1 o" p: G

* L8 m! k' T, `0 `0 i
/ r6 k3 V, R3 w* ?, ?7 W. g7 L2、/usr/sbin/autologin可执行文件的实现:
! }5 i4 L7 v* D! X8 p( E+ N
! k3 v0 j$ I9 Q5 B5 b! r0 `
  P. X4 L, A& B' m: C0 D& P, ?* ?/********************* ' a! \; T) r# m
****  autologin.c  ****
4 W5 s3 T; q: c*********************/ . K  I! P! Y1 |. O/ n) B! t
#include &lt;stdio.h&gt;
4 g4 c( R- D' J- z9 O#include &lt;unistd.h&gt;
2 W  ~4 K! n( C#include &lt;string.h&gt; 4 ]5 D; H: ?& v! `0 S
#include &lt;errno.h&gt; ( U4 T7 C/ ^, w# w& \& r
#include &lt;sys/types.h&gt; 6 Y1 H) d# k% k- S
#include &lt;sys/stat.h&gt; : J5 F3 N( v6 h' _0 J  c; A$ D: X
#include &lt;pwd.h&gt;
  j4 h1 ?3 i( R* w9 m$ i) z
, i" Q2 z( W8 d) H% g% Uint main(int argc, char **argv) 5 N7 ?  f3 {0 R. I' ]
{ 5 O) F. C1 S5 q% @$ p, t
struct stat st;
) f+ G: {2 ~) M# T# |, PFILE *f;
: A0 \9 n) g2 \& Uchar *cfg; 0 ?! w& A" e$ g" Z  R$ w
struct passwd *pw; / A  [5 ?# _; P* R# w# m
uid_t uid;
$ K) g! V) @( tgid_t gid;
' H) A% q) `" zchar *dir, *shell; . {( o1 h9 W5 n( F
char *user=NULL;
- m, S3 _) f" _$ L0 `char *cmd=NULL; ! ?8 i' \9 o4 U$ ^. c% r8 Z
" k/ Z* \4 G& H+ n) S" D9 P1 ?
user="root";
& X7 C% D# \. \/*为了能说明问题又保持程序简洁,这里默认登录用户为root,实际上, + u% Q/ I' g' J* R$ p+ g
登陆用户名应该从/etc/sysconfig/autologin中得到,
9 O5 X8 L- g3 I: f  b程序实现时要注意过滤掉/etc/sysconfig/autologin中的无效用户名*/ ' w% b1 G! J1 P
cmd="/usr/X11R6/bin/startx"; % ?& Y' ^- n0 X! A& V8 z) S# s
/*同样,这里直接指定启动X window的程序,实际上,该程序应该从/etc/sysconfig/autologin中得到*/
! w+ O( e5 `, w  x7 ?/ a9 A, c! i6 j8 d
pw = getpwnam(user);
2 v" v" E$ p$ p1 S7 n. [//getpwnam返回包含用户信息的passwd结构(该结构在pwd.h中定义)。
4 G6 Q" \; s1 e2 ^0 Aif(pw) {
; E9 @7 u1 V7 }; ^$ y: v* Puid=pw-&gt;pw_uid;
( \& w: D" I" f+ f  P5 pgid=pw-&gt;pw_gid; dir=strdup(pw-&gt;pw_dir); ; ]& H2 D6 G! t8 p
shell=strdup(pw-&gt;pw_shell); : J& g8 V3 [  S. {
} 7 x* s! c" e9 j, T: o3 h
//获得用户相关信息
# v9 u3 V/ o4 D5 ] else {
5 z2 k9 D6 r9 {# N; j; L4 T" b3 ]printf("ERROR: No such user %s!\n", user); $ z" h9 Q0 j0 {7 u. h" M; ]( }
return 1;
$ B2 O. }$ l9 K% |7 e4 k} 3 f+ H7 d' w9 A1 w& A4 X" z

! i! b( I2 b$ Gchown("/dev/console", uid, gid); 3 c$ r* y  j+ s7 m
chown("/dev/tty", uid, gid); ! ]6 j3 U! j9 m' ?0 U; }; Z3 I
//为控制台和终端设置用户ID及组ID 4 L; a: j, x$ ^( z  N2 G/ s1 Z
& H8 ~- d2 D/ A, R
//下面是设置用户相关ID " Z1 N" h- P  r- X' C
setregid(gid, gid); , ~, D2 _6 j. K  w& \% `
setegid(gid);
! v2 E1 a* o! V& M# U* U! M  psetgid(gid); / B/ Q8 J3 |$ \' |0 d
setreuid(uid, uid); 0 e0 k7 V' z0 P, F* k- e& p; A* ?
seteuid(uid);
$ U* N" }+ e; L$ W4 isetuid(uid); ) n* ]3 a! U6 ^  P
& P! U4 s  L4 k
setenv("HOME", dir, 1);
9 X# L# F: }$ X8 ^setenv("SHELL", shell, 1); " k, C1 K' ^% F' d
setenv("USER", user, 1);
, A6 i) Z! f4 w' ~8 Tsetenv("LOGNAME", user, 1); 8 n( a, O$ f& U) T1 N/ L+ t% {
//设置用户相关环境变量
  `& J2 b6 p$ e8 C: b1 p1 U, ]$ B7 c5 |
chdir(dir); + X/ h2 l! o. O( |- d4 @
//切换到用户根目录
) a% X, C( u, H! e2 Y5 q- S6 xuser=NULL;
; @; w/ _+ Z- l. u" z
2 _( ?$ X  o: u1 U! E8 Pexecvp(cmd, argv);
: t; n- X! {+ f% @1 E, }/*在配置完用户的相关信息后,执行启动X window操作。注意这里默认执行/usr/X11R6/bin/startx */ 8 I; k1 C# N% B+ x# J- b3 N; a& b
printf("ERROR: Couldn't exec %s: %s\n", cmd, strerror(errno));
0 M9 Z/ R( G4 N2 E+ p/ {, ?return 2; ! Z8 R' x" Q# [, w  q" ?& a4 R
} $ C, G4 B: d+ x6 g0 |8 B6 Q
% i/ w4 X$ O/ z/ _1 i3 T
  9 ^# ]% e# d( i" G$ Y
, i0 Z, O3 |4 Q) C; m9 B

% z5 u& m  z8 |! t. S* ]. p  X1 K运行gcc -o autologin autologin.c,拷贝autologin可执行文件到/usr/sbin/autologin,拷贝autologin配置文件到/etc/sysconfig/autologin。 重新启动系统,会直接进入X window并保留用户原来所有的风格。
( @: M# e, x* W5 y
+ M- g  X0 K" y4 U0 H如果不需要自动登录的配置文件/etc/sysconfig/autologin,所有的操作都在/usr/sbin/autologin以默认的方式实现(比如,默认登录身份为root,默认执行操作为/usr/X11R6/bin/startx等),那么,/etc/X11/prefdm脚本的自动登录部分可简化如下:
/ h$ D% d, w% U; R( L# q+ {) Q$ O% s- t. y7 v
( K/ _  q' ^/ u
...... / H8 ~) b1 O  w! N
# 第一步:查看是否为自动登录 1 S# l* ^4 Z( H- a
if /usr/sbin/autologin; then
- H8 j* O2 b  {1 p. q3 W) v  K  vexit 0
. T; D/ k4 h% v/ P( n: u5 ffi
. P7 E" p6 O: }3 b//第二步 ......
$ F4 o3 f# n% C6 S...... ! e6 ?2 m$ {& T/ E. }

! {0 z& h  b, V& J6 H  E, R& X  2 ~1 r1 i1 {, e1 n- U6 F4 L  i

+ e8 i3 U4 a8 A  V& E, }8 c
2 S4 {+ l" }; Y/ t+ p% s即在脚本中去掉条件测试开关,直接执行/usr/sbin/autologin,这时,只需要拷贝autologin可执行文件到/usr/sbin/autologin,不再需要拷贝autologin配置文件到/etc/sysconfig/autologin。
, _' r* n) i/ ?! _* ?1 P4 p, T. u. A2 D5 I( _' Z
四、选择进入kde或者gnome,并自动启动X window应用程序
: S% x: q1 C' X. j5 {5 s) |
. u, D8 Q. D/ T4 i* ~, o  x' W如果重新启动后系统进入了kde,而用户需要进入gnome,只需运行switchdesk gnome在重新启动系统即可,以后每次启动时会自动进入gnome;反之亦然。  6 |1 b; G, }0 K3 B
一般系统自动登录的目的是启动X window 后自动运行某个X window程序。如果系统默认的启动级别为3,那么如果要在系统启动后自动运行某些应用程序,只需要在某些脚本中加入相应命令即可,不再详述。在X window启动后自动运行应用程序要复杂一些,幸好,kde和gnome都为此留下了自动启动接口。如果在kde桌面环境下自动启动应用程序,只需要把应用程序名字加入/root/.kde/Autostart/目录下即可(这里注意不同用户的根目录可能不同,如用户zyx的根目录可能为/home/zyx)。如果在gnome桌面环境下自动启动应用程序,只需把应用程序的名字加入/主菜单/程序/设置/会话/会话特性及启动程序的startup programs属性页中即可。  
5 q5 Z; r$ L2 @; B+ N0 p8 o7 h& b7 @) ?0 a4 [# i

% T+ p2 ^/ N5 \; Chttp://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip20/index.shtml




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