可能就是这篇文章的题目吸引了你,也可能你曾经也有过同样的心愿—管理并限制Windows网络中的用户登录限制。而且你曾经为此一筹莫展,渴望解决Windows网络中因为用户任意登录所导致资源管理,用户管理,安全审核等一系列问题。我在这里(包括下文,有时也会称为并发登录)所提到的任意登录是指同一时间,同一个用户账号在不同的计算机上同时登录的现象,或者说是在一台计算机登录,在完成工作后并未注册但又在另一台计算机上登录的现象,并不是指任何时间,任何地点在一台计算机上登录的现象。如果你曾经管理过Novell网络,后来转换到Windows网络,你会因为Windows没有提供这种机制而对那些不守规矩的用户行为感到无可奈何。因为作为一名Novell管理员非常清楚,限制用户账号的并发登录,仅仅是NDS(Novell Directory Service,Novell目录服务,与Windows 2000中的Active Directory一样,旨在提供一种单点登录,统一资源管理的手段,都是基于X.500标准设计,但NDS的某些方面可能强于Windows 2000的Active Directory,并发登录限制就是一个典型)对象的一个“Check Box”,唯一要做的是Enable或者是Disable。 用户账号在同一时间内并发登录,所产生的最大问题还是与内部或者外部网络的安全相关。例如,你是一个网络的管理员,你为自己创建了一个登录账号,因为平时管理工作的需要,你给这个账号添加了足够的权限,而且你坚信:我的网络是安全的,我的同事也是相互尊重,不会利用别人的账号作任何事情的。为了自己方便记忆(或者说登录时输入简单),你设置了一个很容易记忆(比如,123456或者与你的用户名相同),但就是因为Windows网络没有并发登录限制机制,那些对网络特权账户充满好奇心(因为他知道有特权可以做很多事情),或者平时对你稍有不满的用户试图利用你的账号做什么事情(因为你设置的密码简单,容易被猜到,而且你还相信他们不会做什么),你都无法知道,这尤如恶梦一般。那怕你设置了安全审核,但审核结果还是你自己的登录账号,这显然是Windows没有并发登录限制所导致的问题。 直到现在的Windows 2000为止,Microsoft都没有在系统中内置限制用户并发登录的机制(如果你已经预览过Windows Server 2003,你会发现它也没有这种机制)。当然,Microsoft并不是没有倾听用户的心声,因此,Microsoft在他的Windows 2000 Resource Kit中提供了一个程序来实现这种功能,试图来掩盖普天之下众多Windows管理员的谴责声。显然,Microsoft在这方面已经向前迈进了一大步,通过本文你会了解到,到目前为止,Microsoft究竟提供了一个怎么样的解决方案,这个解决方案是否已经一呼百应,实现了Window管理员多年来的夙愿,当然包括我。首先,我们来回顾一下在没有Microsoft自己的解决方案之前,我们Windows管理员自己是如何尝试着解决这个问题的。 一、脚本程序 作为一名Windows管理员,想必你肯定知道脚本在日常管理工作中的重要性,比如,批量创建用户。而且我们还知道,利用脚本可以为用户创建登录脚本,在登录脚本中,你可以为用户映射网络驱动器,连接打印机等等。聪明的Windows管理员就是利用脚本第一次实现了并发登录限制,让我们一起看看是如何实现的。 使用Kixtart脚本处理器制作如下的一个脚本程序。Kixtart是一个可以运行在Windows各个版本上增强的脚本处理引擎。如果你要测试文章中的脚本程序,你需要安装Kixtart程序。有关Kixtart的详细信息,可以访问http://kixtart.org/站点。与Kixtart配合使用的部分程序,请到对应的操作系统安装盘中相应的support目录或者Resource中查找。 注意,脚本程序中的Onlyonce.txt是保存在Netlogon共享目录中,它一般包括一些警告与说明信息,可以任意定义。 这个脚本看起来有点复杂。但是,它工作得很好。除了程序本身,管理员还需要做二项工作。首先,为每个用户的主目录(Home Directory)创建一个隐藏共享,指定只有这个用户可以访问并且仅允许一个用户访问(这个很重要)。其次,在用户主目录中创建一个%username%.txt文件,并且指定仅对这个用户具有读取权限。 从上面简单的解释中大家应该已经猜到脚本实现的原理,非常简单:限制主目录仅允许一个用户访问,如果同一个用户在没有注销的前提下尝试登录,映射网络驱动器将失败,系统显示Onlyonce.txt中的内容,然后调用shutdown防止用户登录。 我想精明的读者已经发现NTName/NTName2正常运行时会受到的威胁—主目录的服务器关闭时,用户将可以任何登录,你再也无法阻止他们的这种行为。另一个缺陷就是当另一个用户故意或者偶然地连接到其他用户的主目录,在他不离开(尽管拒绝他访问,但已经连接)的情况下,主目录的所有者将不能登录(因为已经设置同时仅限一个用户连接)。 二、一个更简单的手段 Windows管理员们在不断地寻找更好的解决方案。所有的努力并没有白白浪费,终于有了更好的选择。NTName—一个Windows NT网络中限制用户账号并发登录的实用程序,我们可能不记得是由哪位Windows管理员编写的,但我们肯定可以发现这个比前面的脚本程序有很大的进步。与NTName程序配套使用的是Logout程序,一个强制注销的程序。让我们粗略地看一下NTName的实现。 当你登录到NT网络时,计算机会添加一个由你的用户名组成的NetBIOS名字,名字是唯一的,因此同一时间内它只能存在于一台计算机上,在计算机中的Byte 16值等于0x03,这个名字用来在网络中广播信息,比如,假设你已经要求打印作业完成后显示消息,Windows网络就根据你登录时产生的NetBIOS名字决定你当前登录的计算机,并显示已经完成的消息(你可以测试,假如你并发登录20个用户,只会有一台计算机接到这个消息。)。NTName就是根据这个原理来实现的,在程序运行时,它把用户名作为一个参数处理,检查这个名字是否属于当前计算机所有。如果没有任何输出,就返回ErrorLevel 0。如果输入了名字所属的系统名称,返回ErrorLevel 1,这往往意味着指定的用户名已经在另一台计算机中登录,当然你可以要求另一台计算机注销。为此,你可以在用户的登录脚本中添加以下几行:
NTName %USERNAME% >%TEMP%\LOGONEDPC.TXT ;重定向到logonedpc.txt文件 If not errorlevel 1 goto Logon_OK For /f %%f in(‘TYPE %TEMP%\LOGONEDPC.TXT’) do @echo 已经登录到%%f %0..\logout.exe :Logon_OK
当然,你还可以使用前面提到的Kixtart修饰一下这个程序。但有一点要注意,如果允许用户看提示信息的时间过长,意味着用户有足够的时间来终止logout.exe的执行。 但是,这个NTName存在明显的不足,就是在多域的情况下,它会影响另一个域中同名账号的登录。比如,Sales域中的John没有注销,Markets域中的John将不能登录。然而,我们还是找到了解决的办法。NTName2支持自定义的NetBIOS名字,如前所述,这个名字是你登录时是由系统自动添加的。但NTName2允许你自己指定一个值,默认值为Byte 16=oxCE。由于程序需要根据这个值来确定名字冲突,这样执行速度稍微会有一点慢,另一个美中不足的是,自定义的Byte 16值可能与其他NetBIOS应用程序发生冲突。 三、Microsoft 事实上,很多Windows管理员都希望Microsoft提供一个自己的解决方案。最终,Microsoft在Windows 2000 Server Resource Kit中提供了一个命名为CConnect的程序。注意,CConnect虽然在Windows 2000中才出现,但它支持Windows NT,但对系统方面有些特殊需求,主要包括必须是NT SP4或者更高,Windows Script Host,WBEM,MDAC 2.0以上版本。Windows 2000本身已经满足这些条件。这也是目前唯一由Microsoft自己实现的一个解决方案,主要提供了这些功能: ? 跟踪所有用户已经登录的计算机 ? 允许把并发连接限制到每用户或者每组方式 ? 所有的信息被保存地SQL数据库中 ? 跟踪用户最后登录的计算机 ? 监视用户已经登录到哪台服务器 程序以典型的客户/服务器方式运行。因此,它要求在客户端正确地配置组策略并安装客户端软件,如图1所示。这些组策略选项由CConnect软件包中的CConnect.adm文件提供,并不是由Windows 2000自带的。因此,你必须把这个文件添加到相应的组策略中。打开活动目录用户与计算机管理单元,选择适当的组策略(只有这个策略受到作用的用户才会生效,所以一般我们选择Default Domain Policy),展开用户配置,右击管理员模板*属性*添加,从相应的文件夹中找到CConnect.adm文件,最后,从查看菜单中清除“仅显示策略”。图1中看到的是Windows 2000中组策略选项配置界面,如果你使用的是WinNT 4.0,应该使用Poledit.exe程序打开这个模板。每位管理员可以根据实际要求来配置这些选项,决定启用哪些功能。策略中提供调试与日志记录功能,这对高要求的环境提供了进一步的支持,当然,你可能需要做进一步的配置,如指定日志记录的位置。策略中的“Track Last User”是非常有意思的,有时候计算机可能意外停机(如停电),导致用户没有及时注销,此时用户登录的信息仍然保留在数据库中,此时如果用户试图登录到其他计算机,登录将被拒绝,因为策略认为你仍然登录在另一台计算机上,此时你必须从数据库中搜索相关信息,并予以删除后方可登录。但如果你是登录到同一台计算机(来电后重新登录),数据库信息会被自动更新,并不需要额外的工作。
图1:Con-Connect Limiter提供的组策略选项 对于服务器端,你还需要正确配置SQL服务器,为CConnect指定一个具有与sa平等权限的登录账号,这些账号登录信息被保存在每台计算机的下列位置: HKEY_CURRENT_USER\Software\Microsoft\CConnect\SQLSERVER HKEY_CURRENT_USER\Software\Microsoft\CConnect\SQLUSER HKEY_CURRENT_USER\Software\Microsoft\CConnect\SQLPASSWORD Windows 2000的客户计算机可以从VB Script中获益。CConnect软件包中提供了CConnect.vbs(登录)与CClogoff.vbs(注销)两个脚本文件。脚本程序可以实现简单的并发登录限制与远程注销功能,但如果你希望实现CConnect实现的所有功能,建议你安装CConnect Client程序。 图2显示的是CConnect的管理界面,很容易看出可以实现什么功能。在这里我不再详细地描述整个配置过程,有兴趣的读者可以使用随CConnect提供的文档来配置。总体来说,还是非常简单的。 但我们从上面的一些关键信息的描述中不难看出CConnect中存在的问题:安全—所有的SQL连接信息以明文方式被保存在注册表中,这显然是一件令人提心吊胆的事。其次,对于略通注册表的用户,通过修改注册表就可以解除登录限制,除非你在组策略中限制用户修改注册表。但从解决并发登录限制角度来说,CConnect从可管理性角度讲,是一个不错的选择,而且最新版本( 2.0)还实现对终端用户的限制支持。
以上是对并发登录限制三个方案的简单比较,很明显,不论是Windows管理员自己还是Microsoft,都在进步,我们期待更完美的解决方案。如果你有更好的方案,不妨与我们共享一下?
CLS AT (1,1) If @INWIN = 2 ; 表示客户计算机是Windows 95/98 $L = "@LSERVER" + "\" + "NETLOGON" + "\" + "WINSET.EXE" shell "$L USERNAME=@USERID" shell "$L HOMEDRIVE=X:" ; 你为用户映射的网络驱动器 shell "$L HOMEPATH=@HOMEDIR" shell "$L HOMESHARE=@HOMESHR" shell "$L COMPUTERNAME=@WKSTA" shell "$L USERDOMAIN=@DOMAIN" shell "$L LOGONSERVER=@LSERVER" shell "$L USERPROFILE=@HOMESHR" shell "$L OS=Windows_98" setl "USERNAME=@USERID" setl "HOMEDRIVE=X:" setl "HOMEPATH=@HOMEDIR" setl "HOMESHARE=@HOMESHR" setl "COMPUTERNAME=@WKSTA" setl "USERDOMAIN=@DOMAIN" setl "LOGONSERVER=@LSERVER" setl "USERPROFILE=@HOMESHR" setl "OS=Windows_98" endif If @WKSTA <> "@LSERVER" ; 如果客户的工作站不是这台计算机 settime "@LSERVER" ; 把工作站的时间设置成服务器时间 endif use X: "@HOMESHR" ;这是Kixtart中自带的Net use命令 $S = "@LSERVER" + "\" + "NETLOGON" + "\" + "users.txt" IF INGROUP("users") and EXIST("$S") Display "$S" AT (23,1) "按任何键继续" GET $A endif $B = "@LSERVER" + "\" + "NETLOGON" + "\" + "LOGBAT.BAT" shell "$B" CLS BIG $X = 1 DO COLOR w/n AT ( $X,$X*2 ) "@USERID" $X = $X+1 UNTIL $X = 6 COLOR g+/n AT ( $X,$X*2 ) "@USERID" sleep 3 AT (23,0) SMALL $K=”@LSERVER”+”\”+”NETLOGON”+”\”+Onlyonce.txt” $J=”x:\”+”@USERID”+”.txt” if exist(“J$”) goto done endif CLS Display “$K” Sleep 3 $RC=shutdown(“”,”正在关闭系统!”,0,1,0) :done cookie1 ; 需要通知Windows 98计算机当通过LMSCRIPT时脚本已经运行完毕 exit
|