数学建模社区-数学中国
标题:
如何自动登录linux[转载]
[打印本页]
作者:
huashi3483
时间:
2004-9-27 14:26
标题:
如何自动登录linux[转载]
<
>如何自动登录linux[转载]</P>
, ^3 P$ c1 H0 a# r9 J5 v1 r
<
>本文以redhat 8.0操作系统平台为背景,阐述如何实现启动级别为3时的自动登录,及自动运行相应程序,并简要介绍了如何在redhat 8.0下自动登录X window(系统启动级别为5),并自动运行指定的应用程序。
3 d/ i+ P" [ ?4 v! u! O5 ?. S5 L
[b:804aea7097]一、启动级别为3时自动登录的实现[/b:804aea7097]
8 O) ]. \1 B6 s% g1 Q9 c& V" K
- H1 F( R7 L7 q& B; F _; _5 d2 n
启动级别为3时自动登录的实现涉及两个软件包:mingetty-1.00-3.src.rpm软件包及util-linux-2.11r-10.src.rpm软件包。
" ]. T! X2 z: A; a U* v, z
7 k$ ` A) M+ m" f/ F. @
(1)mingetty-1.00-3.src.rpm软件包
0 e: S9 Z$ i" s/ j* G2 ^- a3 T
对于启动级别为3的自动登录的实现,仍然需要考察/etc/inittab脚本,
# c( \7 b8 k- G- G
3:123:respawn:/sbin/mingetty tty3
" ~' ?1 k U( E- q l, @ L8 V
, ]$ s* r" N/ O( \
|, D6 J3 f! r5 q
$ n& N" d$ W& S
* N: J% g4 H1 V- o5 }
* Y# \" u- h# @; h, h8 ^0 m( ?( E
因此,如果想在启动级别3的情况下实现自动登录,必须要了解mingetty的功能,甚至要修改mingetty的代码。用命令rpm -qf /sbin/mingetty 可知redhat 8.0版本的mingetty包含在mingetty-1.00-3.src.rpm软件包中,下载该软件包,安装源代码,缺省情况下,代码会安装在/usr/src/redhat/下,我们关心的只是mingetty.c源文件。mingetty.c约有五百行代码,主要实现如下功能:
0 t8 E) C4 a) V. q$ S
" f. L: @; `4 m# [3 _, y- O3 T3 D
( ~7 E$ P6 C2 B* g
打开指定的tty(由参数指定);
! C4 q0 w* }! I; \& Q8 m7 N
提示用户登录(login:);
/ Z+ E6 x, [. v+ q: v
获得登录用户名;
+ c9 e0 T N. k+ t0 y1 G, T3 M! O* X
把用户登录名作为参数,调用/bin/login。
1 Z5 D8 A+ k2 ?. K+ G
; C% Y/ N) k9 L/ u
我们所关心的部分实质上只有以下三行:
$ S. Z1 E+ }( n
/ y$ ^$ b3 K9 U* H
& v! U* g8 [( c
... ...
) O- X' \1 K3 T8 J* m5 \; F: q
438 while ((logname = get_logname ()) == 0); //mingetty.c文件438行
" F" k3 ]# r$ ~+ @9 l# b
439 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
" l( k( l9 B+ {" K7 Q/ l
440 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
/ j+ i; m, \5 ?
... ...
2 d8 ^6 c, c+ i+ Y: g* E6 d
8 K0 }( B$ M. E$ z. c0 q
4 P2 ]5 `5 \- v, y. `) S
( K; @) d0 h, o8 t3 t% `
第一行的功能是输出login提示,并获得用户输入的登录用户名,登录用户名由logname返回。因此,可作如下修改
7 X9 ?) Z+ t/ V' F8 @2 O
# c: G/ e1 O/ k# c$ k* r7 [
|; A+ U. g% j8 \
... ...
2 K0 t0 K+ K7 X) |3 \
438 // while ((logname = get_logname ()) == 0); //注释掉本行,不再提示login:
. t' @( L/ M1 c5 f' L1 P) u
439 logname = "root"; //添加本行代码
9 _; G( D; _2 x' o, v4 m7 Y2 S+ o) i
440 execl (_PATH_LOGIN, _PATH_LOGIN, "--", logname, NULL);
4 t) P7 U1 a) m( _. L
441 error ("%s: can't exec " _PATH_LOGIN ": %s", tty, sys_errlist[errno]);
! a R$ n$ b* T% J1 p5 ]
... ...
* X: f e: B; t o) t
" m& X7 P6 N7 c& g( }, ?
" W! t4 ?. B& y0 e/ S: K! w
& S; K6 c* R4 ~7 W1 v- I) V
注意,这里假定用户以超级用户身份登录。
8 @( `$ P9 x5 n( H' D* Y8 d
0 d0 t* a& g' P3 |7 ?, i) I
第二行以用户登录名为参数,调用/bin/login程序,进一步实现登录。因此,要想实现自动登录,还应该了解/bin/login的功能,必要时还应修改其源代码。
2 G/ |3 n1 z% N$ X1 z" t% Z2 u
5 [% G# l. ?! r3 y) r
第三行为出错处理。
8 O3 p! E/ L I9 `, [# x$ m% Y
! d$ V* X% F2 D Q& x; Z4 B' v
(2)util-linux-2.11r-10.src.rpm软件包
9 F, Z7 {8 w' W* }. w$ H
采用同样的方法,查看/bin/login所属软件包(redhad8.0版本的login包含在util-linux-2.11r-10.src.rpm软件包中),下载并安装util-linux-2.11r-10.src.rpm,login可执行文件有几个源文件编译而成,我们最关心的是login.c源文件(大约1500行的代码)。下面简要分析一下login要实现的功能,并对相应部分作必要的修改。
3 a. ~& n& C! {- S" N
: y0 @1 l0 ^9 y8 V& {
Login程序主要可以分为以下几个主要部分:
7 l6 i [6 m# c1 B& b5 V1 O
' ?- ?/ M5 f* I4 E) _
1.Login首先检查登录者是否为超级用户,如果不是超级用户,并且存在/etc/nologin文件,则输出该文件内容,并中止登录过程;主要由checknologin()实现;
0 V9 m" g5 F/ d
2.如果登录用户是超级用户,那么login必须在/etc/securetty/中指定的tty列表中实现登录,否则将导致登录失败。同样可以不指定/etc/securetty文件,此时,超级用户可以在任何tty上登录。
7 j* R" ?# y% p
3.经过前两步测试后,login接下来将提示输入登录密码(由getpass()调用完成,有兴趣的读者可参考其手册页面),并进行验证,如果密码不对,则提示重新登录。
& u+ `3 V$ E" k
4.顺利经过密码验证后,login还将检查是否存在.hushlogin文件,如果该文件存在,则执行一次"quiet"登录(所谓的quiet登录指的是,登录时不再提示邮件mail,不再显示最后一次登录时间,不输出任何消息。启动级别为3时,正常情况下输出这些信息)
: `5 f: z( w5 P$ S& B9 P$ K
5.login接下来设置登录tty的用户ID和组ID,并设置相应的环境变量,包括HOME、PATH、SHELL、TERM、LOGNAME等。对于普通用户来说,PATH缺省被设置成/usr/local/bin: /bin/usr/bin:;对于超级用户来说,PATH被设置成/sbin: /bin: /usr/sbin: /usr/bin:
# y. Y( N2 K6 ]: I' z. r$ \( b2 \
6.login的最后一步是为用户启动shell。如果在/etc/passwd中没有为用户指定shell,那么将使用/bin/sh,如果在/etc/passwd中没有给出当前工作目录,则使用"/"。
5 {: A6 |6 a4 p6 o2 {
至此,一个完整的登录过程就结束了。
7 ~& U" O4 B, E3 W
; Q6 p1 Q0 Y( \3 [# x% R" }
从以上对login源程序分析过程中可发现,如果要实现自动登录,应该在第三步做文章,设法绕过提示输入密码以及对密码进行验证这一过程。实际上很简单,login源程序对是否要求输入密码设置了一个开关控制passwd_req,缺省情况下,其值为1(passwd_req = 1),即要求输入密码进行身份验证。把该行代码改为(passwd_req = 0)后,问题就解决了。即对源文件作如下修改即可:
1 Q; N4 @. |2 _6 h5 Z
* j0 u- R9 J9 e1 h# }8 h/ U
" p- n' X, G" N' F. m
... ...
3 C" N8 M z- U" |) D$ l" ?
402 fflag = hflag = pflag = 0; //login.c文件402行
( u) R& S+ J% l( C0 l! j
403 //passwd_req = 1 //缺省时,要求进行密码验证,注释掉本行
0 z0 a& _% J5 C5 ]
404 passwd_req = 0 //添加本行
' F# D' ~ q3 K Y4 Z, ~
... ...
4 F1 t9 M, O ]; c* z, t
8 k9 `! ^/ O* k! l: Q8 W
2 N: }& q$ {7 v2 l: h* r
5 z2 I/ d: n: {7 c( g+ o& q [- b5 K
修改后,可以直接使用util-linux-2.11r-10.src.rpm提供的Makefile进行重新编译,也可以自己对其编译:
. m0 f, p Q% U* H1 f, B# D# O
$ U m1 T' K/ }6 l
l+ J1 w# I8 @5 h! e! [
gcc -o login login.c setproctitle.c checktty.c xstrncpy.c -Wall -lcrypt注意包含后面的编译选项-lcrypt,否则会出问题。
+ i9 a$ Q1 I$ F$ n% a; N
, G5 l4 f$ }6 j( u( A
( d1 O. G3 B) r9 _6 l
有了新版的mingetty及login后,拷贝mingetty到/sbin/目录,拷贝login到/bin目录,并将/etc/inittab中的启动级别设置为3,再重新引导系统即可(读者可以自己写一个脚本实现上述过程)。
+ _& {) ~4 f; l9 C) T9 \( @ d
/ q2 ^7 ~, p* l0 V8 ?& q( I4 ~8 S! b
如果读者对mingetty或login代码的其他部分感兴趣,可以反复修改login.c或mingetty.c的源代码,测试一下代码的功能,这里要注意的是,在拷贝新版mingetty和login之前,一定要把原来的mingetty和login备份,同时还要准备系统引导盘(有系统安装盘亦可,这样读者有机会键入linux rescue),在测试新版程序前更应如此,如果对代码修改稍有不当,系统将不能正常启动。
b4 N. Z- Q3 W! r6 D! Z# p5 b* e
; g2 h) i! X/ ~( [
如果不想再作进一步的代码测试,只是按本文给出的方法进行代码修改,在系统启动上不会出现什么问题。
$ k$ J& E) e- N1 \6 ]5 a* r" H- c
4 l( b) c0 {: r9 ?/ y
[b:804aea7097]二、自动登录后,自动运行特定的应用程序[/b:804aea7097]
0 y4 w2 K: l5 W, d: h
) `/ E; x* M8 R
在实现了启动级别3时的自动登录后,自动运行应用程序非常简单,把应用程序添加在/etc/rc.d/rc.local脚本中既可。(读者可以尝试一下把startx加入脚本中,看一看效果如何。在某种意义上,又增加了一种自动登录X window的方法)
( }* ~ P }8 j. P6 [) } `$ {
9 G! A% e4 `. Z. Y% ]% w
[b:804aea7097]三、对自动登录X window(系统启动级别为5),并自动运行指定的应用程序的补充[/b:804aea7097]
5 p- X% ?4 p0 g+ @9 c
5 f* L3 F* L; y( @: ^) s! E
在"如何实现自动登录linux"中,主要以redhat 7.2平台为背景进行阐述的,其中的自动登录部分可以直接用于redhat 8.0中,不需要任何修改。
6 ]8 n4 A( g, `/ Q7 q! I& J
6 U7 q$ } w( ~6 f
但是,登录后自动运行应用程序的接口在redhat 8.0中有所不同,主要是登录gnome后,自动运行应用程序的接口有所改变:首先点击面板上的GNOME帮助(那个红色的小帽子),然后选择/其它/首选项/Sessions,在Session对话框的启动程序属性页中添加要启动的程序即可。
' A% e9 j# I$ V: M- F
: z$ p. J T" V) U) g4 N% N3 s
对于登录kde后,自动运行程序的接口没有改变。
0 w" n% c+ S- q" b9 U6 Z6 ^) i# g4 @3 c
4 N- `& P9 Z2 F% p2 J/ N
[b:804aea7097]四、结论[/b:804aea7097]
8 R7 f' D ?; f9 k( y2 U
4 A& |' u) Y! d( ?$ d. s
本文同"如何实现自动登录linux"一文,基本上解决了如何实现自动登录Linux,并自动运行相应应用程序的问题。对于两个最常见的启动级别(3、5),都给出了各自的方法。
- [+ c- R2 j# q2 b a5 N) i" J
9 c$ H4 B, ~0 U7 X% X7 S
在系统初始化到mingetty及login这一阶段,内核实际上已经完成了引导过程,已经到了系统初始化的最高阶段,与内核没什么关系了。此时,主要是/sbin/init根据/etc/inittab的内容而相机行事。读者可通过(man 8 init)或者(man 5 inittab)了解更多东西。
% ^9 M* ^- W( g6 K2 [, b) P
, `. o$ M& z3 [( }
在对文中提到的软件包修改时,请遵守GNU General Public License(GPL)相关标准,另外,替换login通常被视为黑客行为,应当谨慎行事。
5 h: m& u! W0 n. \5 R9 Z0 c
1 S A2 w5 M/ ^5 A
9 ?( b2 ]# `8 k6 c6 E* [
) P2 n- f- g. m- _+ s; B
[b:804aea7097]参考文献[/b:804aea7097]
9 C# k; d- c/ D! l
5 \( [ [+ Q _. j; C; D
8 ^5 @: K$ W3 d# _
1.login手册页面
5 L% p3 X! B7 \4 W
2.mingetty-1.00-3.src.rpm,在redhat 8.0的发行版本的源代码中,包含该软件包;
' l" z( D! R# b+ F ~9 {
3.util-linux-2.11r-10.src.rpm,
0 [* Y, S: E0 Z1 D# N+ R
( L6 u: h1 B/ t7 X& B
可在http://rpmfind.net/linux/RPM/redhat/8.0/i386/util-linux-2.11r-10.i386.html处下载,注意下载源代码包(..src.rpm)
3 c; ~5 P$ F7 x1 d. ]5 Q; D3 W
$ |$ h! E2 C. Q4 d2 l
[b:804aea7097]关于作者[/b:804aea7097]
4 D$ _+ j! N2 [; ] {! u
" M% K5 ]4 r# F* Y7 Q! Y, ]2 `
郑彦兴,男,现攻读国防科大计算机学院博士学位。您可以通过电子邮件 mlinux@163.com和他联系
: X! ]6 ?) ?, F8 h# m3 U3 n# ?/ l
/ A/ J( u- O8 q- b( A
</P>
作者:
huashi3483
时间:
2004-9-27 14:27
如何实现自动登录Linux (Runlevel 5)
a. `! `0 G5 a
8 m7 s. }% @/ p3 [, j
机自动登录linux,并自动运行X window应用程序,有其特殊的应用背景,如基于linux平台的监控系统,linux启动后不需要身份验证,而直接运行监控程序等等。本文以Redhat7.2为平台,结合linux启动过程,介绍了如何避免身份验证自动登录,并直接进入X window自动运行应用程序。
) H; a6 Q# [- j: \" o
一、linux启动的最后阶段的工作
3 B" V% W7 `% R
- s1 m/ X9 k" T6 A& B0 w2 ?
linux 在启动过程的最后阶段(具体启动步骤略),init 会根据 /etc/inittab文件的最后一行x:5:respawn:/etc/X11/prefdm -nodaemon运行/etc/X11/prefdm脚本,(Red hat 7.2缺省时是这样的)。prefdm脚本的主要任务是完成X window的启动,可以有几种启动X window的方法,都包含在prefdm脚本中,几种主要方法有:
: ?6 q9 ~8 \4 ?6 _
. `9 u5 \9 K/ h# z
运行xdm启动X window;
( C- I* S2 } ~! B9 H
运行gdm,进入gnome桌面环境;
' q4 U4 A8 M5 q( M2 i7 r3 s2 l
运行kdm进入kde桌面环境;
" }: b4 f. @& T* E0 ]( ?" H3 n
自动登录进入linux;
. _" @6 }) [! i* C% d4 [1 c
prefdm脚本框架大致如下:
& T! z# b% ~; x0 t2 r5 x9 ~3 O
- g$ i! \0 \- M' z5 A, p
#!/bin/sh
* R6 \; s, ]9 }/ y ^8 T
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
. }& t# n! D: C" p+ v7 J! l
. /etc/profile.d/lang.sh
3 V C2 a% T5 r" ]% s
# 第一步:查看是否为自动登录
0 E0 ~- O8 j% W, [# ?' h2 V' G2 j
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
k. l) F5 r3 t* p' M! J) L
if /usr/sbin/autologin; then
0 I2 x- X9 ~' ]0 q- ?; e2 G' m; f
exit 0
* k7 V/ l, M/ a3 r& y) m
fi
9 L5 Q3 i) S$ Q+ F) U$ r
fi
3 z" |- m4 ^$ U# E: Q p
' X1 w4 K, X) u
# 第二步:如果不是自动登录方式,就会在/etc/sysconfig/desktop中搜寻用户偏爱的登录方式
% ~/ Z9 \. P& G. s1 }
......
5 n! H% O) O6 L" i* z
# 可以是kdm、gdm以及xdm,并运行相应的kdm、gdm以及xdm。
/ S% j C6 N& ? o( O/ \8 z" }8 P/ c
......
: k# ^3 k6 D8 w8 @1 D7 ?
& I! |9 W& _; _
8 L9 b+ y4 x/ I6 P
|, w$ H' D8 l
* g% U! O" ]/ h& x( e8 A$ p, ]
二、自动登录的实现(autologin的实现)
: i& o: I; ~% L' U& e
* ~6 I( N2 e0 E2 n9 I8 J
在/etc/X11/prefdm脚本中,是否实现自动登录有一个条件测试开关,事实上,可以在这里注释掉测试开关,直接执行启动X window的操作。
7 e. i) }$ u# c# Y
' u/ P9 _% L4 t' L: U+ a
自动登录实质上就是绕过身份验证,直接启动X window。X window的启动可以由xinit来完成。
; X# {. s: y7 l: n0 y/ \
. |% U; u$ C$ m1 r2 {# Q! Z
Xinit用来启动X window系统服务器以及系统上的第一个客户程序,可以通过为xinit传递命令行参数的形式指定要启动的服务器及客户程序。如果不传递参数给xinit,它将在用户的根目录下寻找并运行 .xinitrc脚本来启动客户程序;在用户的根目录下寻找并运行 .xserverrc脚本来启动服务器。如果xinit在用户的根目录下找不到.xinitrc、.xserverrc,xinit将使用缺省的X :0。
5 d/ e1 x, |- r9 A: o
实际上,用startx来启动X更为方便。对于运行单一会话的X window 系统,startx提供了更为良好的用户接口。同样,startx首先在用户的根目录下寻找 .xinitrc及.xserverrc脚本,如果找不到这两个脚本,startx将使用/etc/X11/xinit/xinitrc以及/etc/X11/xinit/xserverrc脚本。
/ _* c/ M5 O" L# S7 x! O+ x8 _
startx脚本的最基本框架是:
6 i+ N6 W# i8 f
; ]( X$ j, Y; y
a、 寻找.xinitrc,如果没有则使用xinitrc;
, x% M, b# t7 `( d: \& @- E/ R: E1 P
b、 寻找.xserverrc,如果没有则使用xserverrc;
# i% c; v0 N& x/ p- V. [! i, B6 q! q
c、 根据找到的脚本确定xinit的参数;
2 V* v) o2 Z# j6 @ f2 n
. n- _: W9 C1 W) |
由此可看出,startx在不需要传递任何参数的情况下,可以完成启动X的任务,因此,可以如下修改/etc/X11/prefdm脚本来实现自动登录:
( G8 |$ r6 I5 d- w2 q
. ^. f) N) N9 s( B$ n6 f1 o5 g
: j) E# @5 Q: L* E: c. A2 F" u
#!/bin/sh
4 s* j+ {/ ~6 {
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin
6 d% P7 ~$ }9 f, K7 R
. /etc/profile.d/lang.sh
- [, y0 j/ {; X4 Y
# 第一步:查看是否为自动登录
) x: o. s% G3 }) Q" p1 U4 |4 X
#if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
& U5 ]$ K/ Z" x. k
#注释掉上边的条件测试,直接运行startx
; I: m9 p7 f: k
if /usr/X11R6/bin/startx; then
) V2 D5 ~# }; n J s. w
exit 0
& ?% `" ~, n+ N, v$ v
fi
2 K$ @3 a& F$ F: n/ g9 E
#fi
% G5 B8 u: N. P0 L/ l" F$ q5 `
# a* A6 V) ]' d6 W) J
. T. e. Y+ Q6 E
5 D$ ^2 }9 x( h/ l" V
( B# E& c6 a; K6 Y8 @6 C+ J; D
当然,应确保/etc/inittab中的启动级别为5。
+ ? A* U, s' t& R# s3 M
5 T8 i9 c2 R0 Z
重新启动系统,会发现系统不验证用户身份,直接进入X window,此时的用户身份为root。但是,如果原来root有自己的桌面、默认shell时,上述方法启动X不一定保证还能拥有原来的设置。为了在启动X后,在避免验证身份的同时,又不改变用户原来的设置,那么在运行startx之前,还有工作要做。
# z2 t$ f9 S/ i5 d$ I3 C
: [. B; g5 V. }
三、自动登录后,保持用户原来的配置(桌面、shell以及其它的一些环境变量)。
2 R, E& q7 m8 f
( M, h+ m2 E* C# A% o0 b# q
观察原来/etc/X11/prefdm脚本的自动登录部分:
$ ?# r) Y( C2 y! T9 @0 a, `( a5 d
% a1 r- g+ W+ W/ H# L# {9 l
* ~6 H" u& ~5 s I/ x
......
/ b& V* x! }, `6 X: `, V& _
# 第一步:查看是否为自动登录
7 t }* \. v* I
if [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
- i) w: v, [( N- Y: [. A+ a
if /usr/sbin/autologin; then
- U# M( }3 k! V2 p3 n* W
exit 0
. }/ T6 v, ~& x6 B! Y
fi
: l! J) S y6 b3 u& V& v4 F
fi
* Z7 K" c# r6 [) e
......
4 O# E" z4 ~5 b- f" H
: l9 K1 K# V. k4 [0 R# E( u( W
1 y$ x2 B; N. J6 }
* f6 S6 i* \: B/ V6 d
3 y0 @1 l& X0 d) ~
不难看出,脚本中保留了自动登录的接口:一个可执行文件/usr/sbin/autologin以及一个配置文件/etc/sysconfig/autologin。
# F5 e$ l, ~+ z8 c. ?& C& l
7 ?* |# I; n0 k4 e* f, [4 }
1、/etc/sysconfig/autologin配置文件的实现:
& H9 H0 c* Y; Y9 q
/ T8 J1 ?& p: [1 L
% v& o' X, B* [ U4 j9 m. x' X& g' t
#config for autologin
1 M! s# f6 U' o" }8 v
USER=root
$ b$ }4 Q! v3 L3 e
EXEC=/usr/X11R6/bin/startx
/ H3 q: Z6 V. j6 ] U/ o
说明,USER指定自动登录时的用户名;EXEC指定启动X要运行的程序。
6 |2 y2 X4 N! Y+ c& o& C M
( h/ o; \/ a# @3 J* e* G
( ~2 b/ m- V$ y' Q1 f/ I
+ z% d, d4 p. ]& I6 D
5 q; r9 M6 C4 H3 z2 J. m% s
2、/usr/sbin/autologin可执行文件的实现:
# T3 Y5 j2 \0 }" G7 s1 h
9 c1 h& @; S- ^2 B
" V3 ~5 {: t. n
/*********************
' O) _+ h/ v ~6 V Y
**** autologin.c ****
1 L9 o( S0 p/ G+ |( I: ]1 \- x
*********************/
# Y% p- t2 M4 h# e% s$ D
#include <stdio.h>
; a( t; R) |7 \3 q6 b
#include <unistd.h>
# N* |9 ^! h* C$ u6 V
#include <string.h>
' q# z2 i- O Q; G* ^
#include <errno.h>
7 \- H) _, ], ] w8 v* z6 h% e) e
#include <sys/types.h>
! _$ p" Q! I# @. F% I3 _9 c# p
#include <sys/stat.h>
6 z& M( k) ~: Q9 C
#include <pwd.h>
: a: X- j( B7 R$ W. x7 k
2 ]9 W( `0 ~+ p
int main(int argc, char **argv)
~8 ]0 T0 `' \( I8 k6 T. S( Y
{
7 k8 F% {: M4 s$ x J! |7 V
struct stat st;
' p0 {# @* H7 I
FILE *f;
6 e/ A9 ?8 E9 i. f( r) h- R
char *cfg;
( [* d0 |3 e1 i, D
struct passwd *pw;
! O: H6 b# o, E4 O
uid_t uid;
, f2 N. B' D5 F8 d1 r) f' K1 [
gid_t gid;
/ ?( N2 x* a3 T
char *dir, *shell;
( _7 P! ?6 `$ F/ K. [6 [
char *user=NULL;
3 H( W" E K" N4 V
char *cmd=NULL;
r8 y' b6 I& J0 @' J& }7 s5 u
- F7 b F3 E! K! `, ?4 W# t0 k
user="root";
! f6 M' b4 |3 V7 N6 N+ J6 n9 \: u
/*为了能说明问题又保持程序简洁,这里默认登录用户为root,实际上,
8 j6 y. [/ `( S* i7 a- Q
登陆用户名应该从/etc/sysconfig/autologin中得到,
g& V H$ V3 q) x1 p" _" G7 |
程序实现时要注意过滤掉/etc/sysconfig/autologin中的无效用户名*/
# k+ r1 c+ d6 g. y ^3 G2 z ^
cmd="/usr/X11R6/bin/startx";
( @4 O2 s D/ }5 x
/*同样,这里直接指定启动X window的程序,实际上,该程序应该从/etc/sysconfig/autologin中得到*/
& x' D* z, j, j. Y- J& h# }- n2 ?
1 M2 O! `3 P, g) _0 N5 y/ U/ d* R
pw = getpwnam(user);
# G+ P# U) S( h3 j
//getpwnam返回包含用户信息的passwd结构(该结构在pwd.h中定义)。
1 x* G' u" |1 `: J, G+ D e# F
if(pw) {
6 y4 |5 T3 w0 F: O) q
uid=pw->pw_uid;
9 L7 S6 x' T/ w6 @% ^! J
gid=pw->pw_gid; dir=strdup(pw->pw_dir);
/ i, M/ V4 u4 C6 _& k
shell=strdup(pw->pw_shell);
5 X2 Z. X, N+ k& o
}
5 A1 O) n e1 i9 s, ?# j
//获得用户相关信息
r1 _, L$ H. a/ m1 ?- l
else {
" k% x. J8 v$ ^0 L! v' \ ~
printf("ERROR: No such user %s!\n", user);
0 w( i" B6 {5 A2 C
return 1;
6 k' I( }% v& E* E6 f7 j- [' f
}
' G ^; M( L2 h, }8 j7 y
' ~3 o# k. W- [9 \# S
chown("/dev/console", uid, gid);
( w6 G1 ~) T% a. ?) t3 T. g' @" k( r
chown("/dev/tty", uid, gid);
3 q {# u8 \- f: r4 ]
//为控制台和终端设置用户ID及组ID
' }$ n" C# O4 T+ V3 t: z1 F
/ ]4 y. q0 M3 P. u2 Q
//下面是设置用户相关ID
$ ^1 X* X9 E8 t y5 l1 Q- V
setregid(gid, gid);
) t( @/ n/ Z7 A4 x
setegid(gid);
. c5 l' j+ h2 m( w. J2 g
setgid(gid);
/ o9 x: H8 O! Z( Y$ h
setreuid(uid, uid);
# D- v. @; M. S3 P2 B
seteuid(uid);
1 o1 N+ n$ G/ a) h5 D
setuid(uid);
7 F. W3 @8 R7 G: B* W7 b( K% v
! a4 r+ V4 F- t/ r5 Y
setenv("HOME", dir, 1);
9 p% g! I5 N0 f* w; g4 L
setenv("SHELL", shell, 1);
; ^( w% D0 _# c8 U, a' @
setenv("USER", user, 1);
' b& U) s9 p+ O
setenv("LOGNAME", user, 1);
+ p% m0 \5 v& h7 R) W# Q0 s
//设置用户相关环境变量
u" a1 ]/ {) t# ~* A
/ [( v, E3 n$ }- K! Y
chdir(dir);
' A* U$ q8 V2 t9 v/ C& W3 Y* I
//切换到用户根目录
& {# u5 l" j# l) H( _) Z1 o3 j
user=NULL;
7 U7 F0 {; J: A' Y r8 u
4 T: R6 v" O. _2 }9 u
execvp(cmd, argv);
# w7 b# x4 p4 j# ~+ w- {, }
/*在配置完用户的相关信息后,执行启动X window操作。注意这里默认执行/usr/X11R6/bin/startx */
8 I3 C8 N, C$ \- ~
printf("ERROR: Couldn't exec %s: %s\n", cmd, strerror(errno));
9 N& X$ Q2 b2 u9 h3 R
return 2;
& m* \# P4 j. p1 r0 U# P# W: m
}
) i F. `7 Q6 Y h, b4 e, V3 t
1 [) m- W- U Q& h
' k! w2 e4 R: Z# t5 Y2 k: ^; R
3 S. t1 I0 R1 x3 o8 w
, g _" J2 s) A4 G9 v+ z" I# W* P& ~
运行gcc -o autologin autologin.c,拷贝autologin可执行文件到/usr/sbin/autologin,拷贝autologin配置文件到/etc/sysconfig/autologin。 重新启动系统,会直接进入X window并保留用户原来所有的风格。
* {: ?1 K6 ?: \" m( r
/ b# M* n; J( u& P- ]
如果不需要自动登录的配置文件/etc/sysconfig/autologin,所有的操作都在/usr/sbin/autologin以默认的方式实现(比如,默认登录身份为root,默认执行操作为/usr/X11R6/bin/startx等),那么,/etc/X11/prefdm脚本的自动登录部分可简化如下:
! x1 L3 |$ J) K" k n, }- W6 m& t
6 M& Q9 i- u9 t
w- U- L* A: A$ S
......
d) Z" C( d) z$ n$ F- Z4 f$ D
# 第一步:查看是否为自动登录
3 D+ Z) p& D- L+ `; d
if /usr/sbin/autologin; then
6 E' v, f, [- H( e) V5 }$ D
exit 0
/ x8 J. b% z* r/ K. a7 ~
fi
! }5 r0 ~- O% ^6 L: {( \
//第二步 ......
6 E6 u y9 ]1 K. ~: t" t
......
9 h* G; l( z1 r+ V" `+ X
9 A2 o; C! h) W& r# e" k
2 R: G. {' t4 L
7 G7 ]7 T. ]7 K) d4 D, o
% a1 \' f7 t1 g) G$ B7 }
即在脚本中去掉条件测试开关,直接执行/usr/sbin/autologin,这时,只需要拷贝autologin可执行文件到/usr/sbin/autologin,不再需要拷贝autologin配置文件到/etc/sysconfig/autologin。
+ m1 `! t3 g, ^+ r4 @0 x# F
, g) |& e" y- M( S a7 |: K+ O. S
四、选择进入kde或者gnome,并自动启动X window应用程序
& p. [1 m4 f& v' J( e5 a
' S7 W/ U0 D7 S# z) D" `# e7 f- `
如果重新启动后系统进入了kde,而用户需要进入gnome,只需运行switchdesk gnome在重新启动系统即可,以后每次启动时会自动进入gnome;反之亦然。
6 M- x4 D: S1 P3 }& @: H2 b9 D
一般系统自动登录的目的是启动X window 后自动运行某个X window程序。如果系统默认的启动级别为3,那么如果要在系统启动后自动运行某些应用程序,只需要在某些脚本中加入相应命令即可,不再详述。在X window启动后自动运行应用程序要复杂一些,幸好,kde和gnome都为此留下了自动启动接口。如果在kde桌面环境下自动启动应用程序,只需要把应用程序名字加入/root/.kde/Autostart/目录下即可(这里注意不同用户的根目录可能不同,如用户zyx的根目录可能为/home/zyx)。如果在gnome桌面环境下自动启动应用程序,只需把应用程序的名字加入/主菜单/程序/设置/会话/会话特性及启动程序的startup programs属性页中即可。
! \* [' m5 t! N" [1 N1 g
1 M! @. w! ^# U/ H
; r+ @7 c' _& y/ p
http://www-900.ibm.com/developerWorks/cn/linux/l-tip-prompt/tip20/index.shtml
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5