分类: LINUX
2015-03-09 16:52:39
/etc/passwd默认SHELL被修改后,无法登录的处理办法
系统环境:AIX6.1 64bit
操作:修改root用户的默认shell ->ksh,使用bash做为默认登录shell
修改时顺带把普通用户的shell也改成了bash
问题:/etc/passwd文件修改成功,但没有安装bash,结果可想而知,所有用户不能正常登录。
错误:无法使用任何方式登录aix,ftp、ssh、sftp、scp、telnet不能登录。
这种情况己经无法进行远程管理,对系统的维护将无从下手,而唯一的处理办法就是通过机房重启系统,并在启动时用维护模式进行修改,把root的/usr/bin/bash改回默认的/usr/bin/ksh
但是,该服务器在运行着数据库服务,业务要求不能间断,意味着你不能随心所欲的进行重启单用户维护,那么现在的情况很糟糕:
1. 不能用任何方式登录对系统进行维护
2. 保证该服务器正在运行的数据库不能中断业务
3. 要修复/etc/passwd必须重启
在这种情况下,只能通过其它手段来修改/etc/passwd文件,把不存在的bash /usr/bin/bash改为默认的/usr/bin/ksh,这样以来保证可以登录,其次再去安装bash进行系统优化。
在深入分析并测试后发现有以下几个方面值得关注:
1. 运行数据库服务的是oracle用户
2. 数据库服务运行正常,可以进行任何数据库操作
3. 数据库可以写内部JAVA过程
4. JAVA可以操作文件,当然也可以执行系统命令。
5. JAVA将继承运行它的用户属主的权限,可以任意修改oracle的目录及文件。
6. su -s /usr/bin/ksh root 命令可以使用指定的shell进行登录,而忽略/etc/passwd指定的shell
7. AIX系统中有expect
8. AIX系统中有perl
9. root和oracle用户的登录口令都没有改动。
通过以上条件,汇总整理一条可以获得root权限来修改/etc/passwd的流程,如下:
change_passwd.sh脚本获得root权限,并调用perl修改/etc/passwd文件
change_passwd.sh脚本:
要生成change_passwd.sh,需要在JAVA里输入各行内容,在写入时需要注意转义。
需要的权限有:
1. root 权限
2. 数据库权限
需要的role:
connect,resource
3. java操作文件权限
call dbms_java.grant_permission( 'SYSTEM', 'SYS:java.io.FilePermission', '<
call dbms_java.grant_permission('SYSTEM','java.io.FilePermission','<
即使SYSTEM用户也需要执行上述授权才行,要不然无法进行文件处理。
下面编写的2个JAVA过程
java_create_expect用于建立change_passwd.sh文件
java_exec_expect用于执行chang_passwd.sh文件
*********************************************************************
create or replace and compile java source named java_create_expect as
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class Javacreateexpect {
public static void main(String[] args) {
FileOutputStream out = null;
FileOutputStream outSTr = null;
BufferedOutputStream Buff = null;
FileWriter fw = null;
try {
/* 建立/home/oracle/change_passwd.sh脚本文件 */
byte[] str1 = "#!/usr/bin/expect\n".getBytes();
byte[] str2 = "spawn /usr/bin/su -s /usr/bin/ksh root\n".getBytes();
byte[] str3 = "expect \"Password:\";\n".getBytes();
byte[] str4 = "send \"cdr12345\\n\";\n".getBytes();
byte[] str5 = "expect \"#\";\n".getBytes();
// byte[] str6 = "send \"/usr/bin/cp -f /etc/passwd /home/oracle/\\n";\n".getBytes();
byte[] str6 = "send \"/usr/bin/cp -f /etc/passwd /home/oracle/\\n\"\n".getBytes();
byte[] str7 = "send \"/usr/bin/perl -p -i -e s,:/usr/bin/bash,:/usr/bin/ksh, /home/oracle/passwd\\n\"\n".getBytes();
byte[] str8 = "send \"/usr/bin/cat /home/oracle/passwd\\n\"\n".getBytes();
byte[] str9 = "send \"/usr/bin/mv /etc/passwd /etc/passwd.bak_20121123\\n\"\n".getBytes();
byte[] str10 = "send \"/usr/bin/cp /home/oracle/passwd /etc/passwd\\n\"\n".getBytes();
byte[] str11= "send \"exit\\n\";\n".getBytes();
byte[] str12 = "expect eof".getBytes();
out = new FileOutputStream(new File("/home/oracle/change_passwd.sh"));
long begin = System.currentTimeMillis();
out.write(str1);
out.write(str2);
out.write(str3);
out.write(str4);
out.write(str5);
out.write(str6);
out.write(str7);
out.write(str8);
out.write(str9);
out.write(str10);
out.write(str11);
out.write(str12);
out.close();
//System.out.println("hello,world");
/* 修改change_passwd.sh文件属性,添加可执行权限 */
String cmd = "chmod +x /home/oracle/change_passwd.sh";
Process p = Runtime.getRuntime().exec(cmd);
/* System.out.println("hello,earth");*/
/*显示change_oracle.sh文件内容 */
/*String cmd_disp_expect = "cat /home/oracle/ep.sh";
p = Runtime.getRuntime().exec(cmd_disp_expect);
is = p.getInputStream();
br = new java.io.BufferedReader(new java.io.InputStreamReader(is));
sb = new StringBuffer();
do {
sb.setLength(0);
String str = br.readLine();
if (str == null)
break;
if (str.trim().equals(""))
continue;
sb.append(str);
System.out.println(sb.toString());
} while (true);
*/
} catch (Exception e) {
e.printStackTrace();
}
}
}
*********************************************************************
create or replace and compile java source named java_exec_expect as
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.lang.Thread;
import java.lang.Object;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
public class Javaexecexpect {
public static void main(String[] args) {
FileOutputStream out = null;
FileOutputStream outSTr = null;
BufferedOutputStream Buff = null;
FileWriter fw = null;
try {
String cmd_exec_expect = "/usr/bin/expect -f /home/oracle/change_passwd.sh";
Process p = Runtime.getRuntime().exec(cmd_exec_expect);
// 获得返回值
java.io.InputStream stdin = p.getInputStream();
java.io.InputStreamReader isr = new java.io.InputStreamReader(stdin);
java.io.BufferedReader br = new java.io.BufferedReader(isr);
StringBuffer sb = new StringBuffer();
do {
sb.setLength(0);
String str = br.readLine();
if (str == null)
break;
if (str.trim().equals(""))
continue;
sb.append(str);
System.out.println(sb.toString());
// System.err.println(loadStream(p.getErrorStream()));
} while (true);
/*Thread.sleep(1000);*/
int exitVal = p.waitFor();
System.out.println("Process exitValue: " + exitVal);
} catch (Exception e) {
System.err.println("System Monitor Error" + e.toString());
e.printStackTrace();
}
}
}
*********************************************************************
/* 用procedure引用java */
create or replace procedure p_java_create_expect(vv in varchar2) as language java name 'Javacreateexpect.main(java.lang.String[])';
create or replace procedure p_java_exec_expect(vv in varchar2) as language java name 'Javaexecexpect.main(java.lang.String[])';
/* 按顺序执行这2个过程 */
set serverout on;
call dbms_java.set_output(5000);
exec p_java_create_expect ('');
set serverout on;
call dbms_java.set_output(5000);
exec p_java_exec_expect ('');
/*执行完成后,用SSH客户端登录进行测试 */
至此,用oracle对root系统配置文件的修改操作成功。