数学建模社区-数学中国

标题: 如何自动登录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 }& L1 {: 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 y440 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  v3 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+ iLogin程序主要可以分为以下几个主要部分:
. ]* a# q4 W0 U- e* ?
/ L4 e/ `9 g* P( Q5 }5 l1.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 O3.经过前两步测试后,login接下来将提示输入登录密码(由getpass()调用完成,有兴趣的读者可参考其手册页面),并进行验证,如果密码不对,则提示重新登录。  
4 s1 z: K0 z/ u8 ]( h4.顺利经过密码验证后,login还将检查是否存在.hushlogin文件,如果该文件存在,则执行一次"quiet"登录(所谓的quiet登录指的是,登录时不再提示邮件mail,不再显示最后一次登录时间,不输出任何消息。启动级别为3时,正常情况下输出这些信息)  
) F. o* d8 a# z$ b6 d6 I1 w; L5.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( Y402 fflag = hflag = pflag = 0; //login.c文件402行 ' M% J5 L2 b3 j. e) p
403 //passwd_req = 1   //缺省时,要求进行密码验证,注释掉本行
1 a2 {/ g4 K8 B9 c' X404 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+ Y1 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% D8 t3 o! c8 J# x
[b:804aea7097]四、结论[/b:804aea7097]
" N) ?# b4 M- f+ o6 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" L1.login手册页面  
, K' A( v8 m! E% {3 ^& u+ b2.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; ^& Olinux 在启动过程的最后阶段(具体启动步骤略),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: rPATH=/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) _+ Oif [ -f /etc/sysconfig/autologin -a -x /usr/sbin/autologin ]; then
0 {9 @5 L8 r( A/ }; Dif /usr/sbin/autologin; then 3 ^* i2 H) L( N4 e% u
exit 0
" K" |/ i3 ?: Y, `' ~3 v, Lfi ( 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: O0 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! WXinit用来启动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' Sa、 寻找.xinitrc,如果没有则使用xinitrc;
: E* d4 r) N* N0 H& T. Cb、 寻找.xserverrc,如果没有则使用xserverrc;
- l' P+ z. s1 `& ?# w1 z5 Qc、 根据找到的脚本确定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- nPATH=/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" cexit 0
; ]6 _6 u  T! R; N7 c7 F% Bfi * 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 Bif /usr/sbin/autologin; then ( I: r% @- S8 D$ j) Q* g. o; V5 m
exit 0
9 B7 G* @: L- t: lfi 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 VEXEC=/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 &lt;stdio.h&gt; 9 @* q/ d. d% g% Z# h. W8 i
#include &lt;unistd.h&gt;
% m" t. N# ^7 I#include &lt;string.h&gt; # }, q$ a+ T9 l- n/ z
#include &lt;errno.h&gt;
9 [8 y1 J8 I: g& ~! z4 m#include &lt;sys/types.h&gt;
+ I* a* J8 [" p; _7 H6 p#include &lt;sys/stat.h&gt;
% P0 s; f8 w& h0 |: @0 r2 B#include &lt;pwd.h&gt;
, 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 Lstruct 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) mchar *user=NULL; " ?) Z* F* j- f' t
char *cmd=NULL;
  ]0 u# g3 D" K- _7 ]1 Z4 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-&gt;pw_uid; ! `( P  w/ e( B
gid=pw-&gt;pw_gid; dir=strdup(pw-&gt;pw_dir);
. Z+ K3 `, u+ ~8 s. O. |  j/ bshell=strdup(pw-&gt;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* mprintf("ERROR: No such user %s!\n", user);
, i( Q4 Z7 Z% Ereturn 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. vchown("/dev/console", uid, gid);
$ L1 S: M" d& H2 Nchown("/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 asetregid(gid, gid);
/ s# c) B7 Q0 @* H& b% M( Asetegid(gid);
& e' ^8 I+ W) m- psetgid(gid);
% e; h2 f/ w# o+ |" a6 L; isetreuid(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+ Nsetenv("HOME", dir, 1); $ H4 S3 \$ f" h  A7 u. A
setenv("SHELL", shell, 1);
& _8 @/ C' j7 ?/ r5 [9 N5 F) B3 |7 lsetenv("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; y7 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 Jprintf("ERROR: Couldn't exec %s: %s\n", cmd, strerror(errno));
. v4 {# T/ ^+ j% b  w2 w/ Treturn 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- Hif /usr/sbin/autologin; then
: `. a- |7 o* V: v# S. E% H" ^exit 0
7 x& j1 H$ ?, r, T+ Ofi
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