引言
对于广大的scounix操作系统管理员来说,最不可原谅的过失之一就是忘记了管理员口令(即超级用户口令)。这个过失会导致极其严重的后果,对此凡是具备unix 操作系统常识的人都应该知道。然而令人遗憾的是,时至今日铸错者依然大有人在。看来,对他们固然要责备,但既然问题客观存在,我们就总还须面对现实,想办法去解决才是。
长期以来,许多人就超级用户口令被忘记的问题发表了各种看法。一部分人认为,一旦忘记了超级用户口令,只能重装操作系统,此外别无它法。另一部分人则坚决反对这种“重装论“,他们提出了一些经过成功实践的解决方案,使得“重装论“者败下阵来。现在我们可以肯定地说,忘记超级用户口令是有办法解决的。
但同时我们也不得不承认,现行的解决方案有很大的局限性,这些局限性决定了现有方案无论怎样变化和发展也不可能成为一种有着强大生命力的最彻底的解决方案。
传统解决方案的局限性
上面已经谈到,目前有多种针对超级用户口令被忘记问题的解决方案。为了叙述上的方便,本文将这些方案统称为传统解决方案。传统方案乍看起来似乎各不相同,但经过认真分析和归纳后就会发现,它们实际上大同小异,都有以下共同点:必须有一套(两张)emergencybootfloppy(紧急启动软盘)。这套软盘均为文件系统格式,必须在scounix上制作,并且在不同类型机器上制作的紧急启动软盘相互不能通用。
用紧急启动软盘启动后,将硬盘根文件系统mount到某个目录下(一般为/mnt目录),然后进入该目录(即进入硬盘根文件系统的根目录),修改相关目录下与超级用户口令有关的信息(各种方案的不同之处主要体现于此)。最后回到软盘根目录,拆卸/dev/hd0root,重启机器。
这些共同点实际上反映了传统方案的局限性:
一、操作平台局限性:要求自始至终必须在scounix操作系统平台上实施。
二、操作工具局限性:对紧急启动软盘的依赖性太大。万一软盘发生损毁,必须找一台类型相同的机器再制作一套,这就是前面所说的“专盘专用“的限制。
三、操作对象局限性:必须依靠硬盘根文件系统的支持。即操作者与修改对象(指与超级用户口令有关的信息)被文件系统隔开,操作者不能直接修改对象,只能调用文件系统提供的服务修改。这种方式本是信息科学中倡导的层次化思想的一种体现,在正常情况下应予称道;但任何事物都是有两面性的,在非常情况下--诸如解决忘记超级用户口令这一类问题时--该方式反而有可能带来麻烦。
三大局限性说明了传统解决方案可行性的脆弱和狭窄,也决定了它们作为凌驾于文件系统之上的高层方案所必然具有的弊端。于是,打破这些局限性,探索出一种全新的解决方案,就成为了摆在一切unix研究者面前的新课题。
新课题
所谓新课题,就是找到一种能够突破传统方案局限性的新方案。究竟从何处下手呢?让我们再来看一看三大局限性。
操作平台局限性似乎不好突破,因为其它操作系统识别不了unix的文件系统格式。
操作工具局限性好象就更难了,因为紧急启动软盘既要在unix上制作,又要在unix上使用,所以如果操作平台局限性突破不了,它就更突破不了。
最后看看操作对象局限性。操作对象完全由文件系统管理,操作者必须通过文件系统访问它们。万一文件系统崩溃,那么即使它下面的文件完好无损,操作者也只能认为这些文件已全部丢失--因为文件系统无法访问(例如mount不上来)。其实这个时候还是有办法找到那些文件的,方法就是直接访问物理硬盘。道理很简单:就本质而言,文件系统只不过是一个构筑于物理硬盘之上的逻辑组织,平时我们是通过它来访问物理硬盘的;现在这个组织寿终正寝,不能再为我们服务了,于是我们只好“自己动手,丰衣足食“。直接访问物理硬盘不但可以使文件“失“而复得,而且还有另外一个重要意义突破了操作对象局限性。
操作对象局限性一旦突破,我们就会惊奇地发现突破另外两大局限性简直可以说是顺理成章了。因为虽然其它操作系统识别不了unix的文件系统格式,但在任何操作系统上,我们都可以访问物理硬盘;而只要是带有访问物理硬盘功能的软件,都可以成为我们的操作工具。
现在我们要做的仅仅是:找一个大家最熟悉的操作系统和一个最易寻觅的可以访问物理硬盘的软件。
大家最熟悉的操作系统无疑是dos。可以访问物理硬盘的软件很多,但最易寻觅的莫过debug.exe。所谓最易寻觅,是因为debug是dos本身的一条外部命令,可以说只要是在安装了dos的机器上都可以找到它。对debug略知一二的人可能会指出该命令并没有提供访问物理硬盘的选项,但请不要忘记debug是dos提供给用户的一个汇编语言调试程序,我们完全可以利用它编写、调试和执行一个汇编小程序去访问物理硬盘。应该说,这对一个能够取得系统管理员身份的人并不困难。
综上所述,在dos上运行debug来破除unix管理员口令,这就是本文提出的解决scounix超级用户口令被忘记问题的新方案。
新方案的应用
新方案已经提出,下面我们来看看它是如何应用于实践的。
首先需要指出,由于文章篇幅和性质的限制,本文不可能将新方案实施过程中涉及到的所有知识以“入门讲座“的方式加以介绍。因此,在阅读本小节前,读者应具备下列基础:熟悉硬盘主引导扇区和unix分区及unix文件系统的构造(这对unix系统管理员来说不成问题)、了解中断13h入口参数含义、使用过debug命令。
一台compaqdeskproxl/466服务器,主板内含pciscsi-2控制器一个,上接富士通硬盘一只,该硬盘主要参数为:1041柱面,64头,32扇。硬盘上装有scounixsystemv/386release3.2operatingsystemversion4.2。现在假设其超级用户口令被忘记。
首先,随便找一台安装了dos的计算机,制作一张dos系统盘,并在系统盘上拷贝一个debug.exe文件。
c:\dosformat/sa:
c:\doscopydebug.exea:
然后将该盘插入compaq服务器a驱,开机启动dos操作系统,执行debug命令。
a:\debug
现在我们就编写一段汇编语言程序(以下简称app),来读出硬盘0柱0头1扇区的内容。该扇区存放的是主引导记录,读出它是为了确定scounix分区的起始位置。app是调用中断13h实现的,以后我们还要反复用到它,当然入口参数将随所读内容物理地址的变化而变化。
-a
2039:0100movax,0201
2039:0103movbx,1000
2039:0106movcx,0001
2039:0109movdx,0080
2039:010cint13
2039:010eint20
2039:0110
-g
programterminatednormally
现在我们可以用“dump“命令查看被读到内存里的扇区内容。从偏移11beh处开始是分区表,其中类型标志字节为63h的分区是scounix分区。该分区起始于1柱面0磁头1扇。
下面,读出unix根文件系统i-node表的第一个扇区,以确定根目录的物理位置。
根据unix分区起始位置可知根文件系统始于2柱0头1扇。并且,由于2柱0头1扇是引导块,2扇是超级块,3、4扇为间隔,所以i-node表必定始于第5扇。
我们用app读出它(cx的赋值应改为“0205“)。
读出后用“dump“命令查看偏移1040h至107fh的64个字节,这就是2号i-node,即根目录的i-node。
下面我们就根据i-node计算根目录在硬盘上的物理地址。
我们从偏移1040h看起:
ed41h表示文件类型与存取权限为“drwxr-xr-x“;
1000h表示文件连结数为16;
0000h表示文件属主id为0;
0200h表示文件组id为2;
80020000h表示文件字节数为640个;
da0500h表示第一个数据块地址。由于其它12个数据块地址均为0,所以可断定根目录在硬盘上只占了一个数据块。现在我们必须依据da0500h计算出这个数据块存放在硬盘的第几柱面、第几磁头、第几扇区。计算公式如下:
c=trunc(p/(h*s))
c1=c0+c
h1=trunc((p-c*h*s)/s)
s1=p-c*h*s-h1*s+1
其中:
c1、h1、s1分别为数据块物理地址柱面号、磁头号、扇区号
p等于数据块地址翻译成十进制数后再乘以2
h为硬盘磁头数
s为每磁头扇区数
c0为根文件系统起始柱面
c只是一个中间量
将da0500h代入上述公式,并根据h=64,s=32,c0=2,可算出c1=3,h1=29,s1=21。因此根目录在硬盘上的物理地址为:3柱面29头21扇。
用app把它读出来(cx和dx的赋值应分别改为“0315“和“1d80“)。
读出后用“dump“命令查看,可以发现偏移1050h至105fh是/etc目录的i-node号和文件名,其中i-node号为22h,即34d。因为每个扇区有8个i-node,所以34号i-node必定在2柱面0头9扇。
用app读出它(cx和dx的赋值分别改为“0209“和“0080“)。
用“dump“命令可看出偏移1040h至107fh正是/etc目录的i-node。我们把它的数据块也读出来。先计算第一个数据块的物理地址。将2d0700h代入公式,算出/etc第一个数据块物理地址是3柱面50头27扇。
用app读出它(cx和dx的赋值分别改为“031b“和“3280“)。
用“dump“命令可看出偏移11a0h至11afh是/etc目录下的passwd文件名。我们用“enter“命令把它改成zls,然后再运行app(ax的赋值应改为0301)。
现在退出debug命令。
取出软盘,重启机器,引导unix操作系统。
按照引导顺序,unix显示出硬件配置信息后就该提问超级用户口令了,但就在此时它却突然发现/etc/passwd文件失踪了!(其实只是被改名为zls,但unix对此一无所知。)没有了这个文件,unix无法