/etc/passwd默認SHELL被修改後,沒法登陸的處理辦法 java
系統環境:AIX6.1 64bit shell
操做:修改root用戶的默認shell ->ksh,使用bash作爲默認登陸shell 數據庫
修改時順帶把普通用戶的shell也改爲了bash bash
問題:/etc/passwd文件修改爲功,但沒有安裝bash,結果可想而知,全部用戶不能正常登陸。 服務器
錯誤:沒法使用任何方式登陸aix,ftp、ssh、sftp、scp、telnet不能登陸。 oracle
這種狀況己經沒法進行遠程管理,對系統的維護將無從下手,而惟一的處理辦法就是經過機房重啓系統,並在啓動時用維護模式進行修改,把root的/usr/bin/bash改回默認的/usr/bin/ksh app
可是,該服務器在運行着數據庫服務,業務要求不能間斷,意味着你不能爲所欲爲的進行重啓單用戶維護,那麼如今的狀況很糟糕: ssh
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', '<<ALL FILES>>', 'execute' );
call dbms_java.grant_permission('SYSTEM','java.io.FilePermission','<<ALL FILES>>','read,write');
即便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系統配置文件的修改操做成功。
轉載CU上的討論帖,附件本站下載地址:http://www.oschina.net/action/code/download?code=16402&id=27052