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