active directory 學習和概念整理

  第一,在局域網內,如何管理計算機上的資源,須要一個管理策略。java

     微軟提供了兩種:工做組和域。二者區別就是,工做組是自治的,組內的計算機個個都做爲獨立、對等的自治實體而存在。恩,這也是以太網的設計初衷。數據庫

     可是,當咱們須要額外的管理模型,其實做爲一個組織,更可能的是,須要一個公共的中央控制主機,這就是域模型。域模型中,會提供一個域控制器,域控制器上存儲了這個域內的全部帳戶信息,也就是一個帳戶數據庫Active Directory。這也就致使,資源、帳戶、機器的概念開始分離。windows

  

  第二,在域管理中,正常的思路是,基於域名來定位機器,那麼首先第一條就是創建DNS記錄,或者安裝DNS服務器。服務器

     而後在建立Active Directory時,實際上是從 這個域名***.com開始,讓***.com成爲一個域的起始節點,術語是「新林中域」,由於從邏輯上將按照ldap的方法,現有域林,而後又域,最後纔有域。dom

  

  第三,建立好以後,咱們就來看一下這個active directory數據庫能放哪些數據:函數

  

  表結構看不到,那看一下文件結構吧:工具

Active Directory 是一個事務處理數據庫系統,它使用日誌文件來支持回滾語法,從而確保將事務提交到數據庫中。與 Active Directory 關聯的文件包括:

Ntds.dit — 數據庫。
Edbxxxxx.log — 事務日誌。
Edb.chk — 檢查點文件。
Res1.log 和 Res2.log — 預留的日誌文件。
Ntds.dit 會隨着數據庫的填充而不斷增大。可是,日誌的大小倒是固定的 (10 MB)。對數據庫進行的任何更改都會被追加到當前的日誌文件中,並且其磁盤映像會不斷保持更新。

Edb.log 是當前的日誌文件。對數據庫進行更改後,會將該更改寫入到 Edb.log 文件中。當 Edb.log 文件充滿事務以後,它會被從新命名爲 Edbxxxxx.log。(從 00001 開始,並使用十六進制累加。) 因爲 Active Directory 使用循環記錄,因此在舊日誌文件寫入數據庫以後,這些舊日誌文件會及時刪除。在任什麼時候刻均可以找到 edb.log 文件,並且還可能有一個或多個 Edbxxxxx.log 文件。

Res1.log 和 Res2.log 是「佔位符」— 用來在此驅動器上預留(在此狀況下)最後的 20 MB 磁盤空間。這是爲了給日誌文件提供足夠的空間,以便在其它全部磁盤空間都已使用的狀況下能夠正常關機。

Edb.chk 文件存儲數據庫的檢查點,這些檢查點標識數據庫引擎須要重複播放日誌的點,一般在恢復或初始化時。

出於性能考慮,日誌文件應該位於數據庫所在磁盤之外的其它磁盤上,以減小磁盤爭用狀況。

在進行備份時,可能會建立新的日誌文件。如前所述,因爲要進行循環記錄,因此須要刪除該日誌文件(如常規舊日誌文件)。
幾個很是有用的AD維護工具:ntdsutil.exe; ldp.exe; dcdiag.exe; adsiedit.exe; netdom.exe; replmon.exe; dssite.msc; repadmin.

 

  第四,就是在這個域系統中,是如何進行認證的呢,簡單的密碼和用戶顯然,太單薄了。這裏的解決方式是電子令牌。性能

  第五,備份。windows的備份工具是一體的,可是你能夠選擇備份的內容,就是單獨把active directory備份出來。url

  第六,就是基於如ad域這樣的ldap服務器,和普通的數據庫表內容存取帳戶信息之間的性能差別有多少呢?恩,聽說,當數據量達到上萬時,會很可觀。可是我在這裏採用它,則考慮的是它是做爲標準協議而存在。  spa

  第七,嘗試編寫以下的深度優先遍歷函數,實現了對組織的深度優先遍歷

/**
 * @Description:
 * @comment:wuchao
 * @time:2015年9月10日下午1:57:52
 */

package test;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.NamingEnumeration;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import java.util.Enumeration;

public class ADOperTest {
    public ADOperTest() {
    }

    public void GetADInfo() {

        // ldap 訪問參數設置
        Hashtable HashEnv = new Hashtable();
        String LDAP_URL = "ldap://192.168.1.***:389";
        String adminName = "Administrator@***.cn";
        String adminPassword = "****";
        HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
        HashEnv.put(Context.SECURITY_PRINCIPAL, adminName);
        HashEnv.put(Context.SECURITY_CREDENTIALS, adminPassword);
        HashEnv.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        HashEnv.put(Context.PROVIDER_URL, LDAP_URL);

        try {

            LdapContext ctx = new InitialLdapContext(HashEnv, null);
            SearchControls searchCtls = new SearchControls();
            
            // onelevel 就是爲了深度優先遍歷而設
            searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE);

            // 搜索用戶
            // String searchFilter = "objectClass=User";

            // 搜索組織
            // String searchFilter = "objectClass=organizationalUnit";
            String searchFilter = "objectClass=organizationalUnit";

            // 搜索根節點
            String searchBase = "OU=***,DC=***,DC=cn";

            String returnedAtts[] = { "url", "whenChanged", "employeeID",
                    "name", "userPrincipalName", "physicalDeliveryOfficeName",
                    "departmentNumber", "telephoneNumber", "homePhone",
                    "mobile", "department", "sAMAccountName", "whenChanged",
                    "mail", "userPassword" };

            searchCtls.setReturningAttributes(returnedAtts);

            int i = 0;

            try {
                NamingEnumeration answer = ctx.search(searchBase, searchFilter,
                        searchCtls);

                System.out.println("" + i + ":" + searchBase);
                SearchResult sr;

                i++;
                while (answer.hasMore()) {
                    sr = (SearchResult) answer.next();
                    printspace(i);
                    System.out.print("" + i + ":" + sr.getName() + "\n");
                    recursiveGetChild(ctx, sr.getName() + "," + searchBase,
                            searchCtls, searchFilter, i);
                }
            } catch (NamingException e) {
                e.printStackTrace();
                System.err.println("Throw Exception : " + e);
            }

            ctx.close();

        } catch (NamingException e) {
            e.printStackTrace();
            System.err.println("Throw Exception : " + e);
        }
    }

    // 遞歸函數,遞歸輸出子組織
    void recursiveGetChild(LdapContext ctx, String searchBase,
            SearchControls searchCtls, String searchFilter, int i) {

        SearchResult sr;

        try {
            NamingEnumeration answer = ctx.search(searchBase, searchFilter,
                    searchCtls);
            i++;
            while (answer.hasMore()) {
                sr = (SearchResult) answer.next();
                printspace(i);
                System.out.print("" + i + ":" + sr.getName() + "\n");
                recursiveGetChild(ctx, sr.getName() + "," + searchBase,
                        searchCtls, searchFilter, i);
            }
        } catch (NamingException e) {
            e.printStackTrace();
            System.err.println("Throw Exception : " + e);
        }

    }

    // 格式化輸出
    void printspace(int i) {

        while (i-- > 0) {
            System.out.print("  ");
        }
    }

    public static void main(String args[]) {
        ADOperTest ad = new ADOperTest();
        ad.GetADInfo();
    }
}

結果以下:

  

 

 第八,附帶輸出用戶的代碼是:

/**
 * @Description:
 * @comment:wuchao
 * @time:2015年9月10日下午1:57:52
 */

package test;

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.NamingEnumeration;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import java.util.Enumeration;

public class ADOperTest {
    
    // 搜索用戶
    private String searchUserFilter = "objectClass=User";
    
    public ADOperTest() {
    }

    public void GetADInfo() {

        // ldap 訪問參數設置
        Hashtable HashEnv = new Hashtable();
        String LDAP_URL = "ldap://192.168.1.***:389";
        String adminName = "Administrator@***.cn";
        String adminPassword = "***";
        HashEnv.put(Context.SECURITY_AUTHENTICATION, "simple");
        HashEnv.put(Context.SECURITY_PRINCIPAL, adminName);
        HashEnv.put(Context.SECURITY_CREDENTIALS, adminPassword);
        HashEnv.put(Context.INITIAL_CONTEXT_FACTORY,
                "com.sun.jndi.ldap.LdapCtxFactory");
        HashEnv.put(Context.PROVIDER_URL, LDAP_URL);

        try {

            LdapContext ctx = new InitialLdapContext(HashEnv, null);
            SearchControls searchCtls = new SearchControls();
            
            // onelevel 就是爲了深度優先遍歷而設
            searchCtls.setSearchScope(SearchControls.ONELEVEL_SCOPE);

            // 搜索組織
            String searchFilter = "objectClass=organizationalUnit";

            // 搜索根節點
            String searchBase = "OU=***,DC=****,DC=cn";

            String returnedAtts[] = { "url", "whenChanged", "employeeID",
                    "name", "userPrincipalName", "physicalDeliveryOfficeName",
                    "departmentNumber", "telephoneNumber", "homePhone",
                    "mobile", "department", "sAMAccountName", "whenChanged",
                    "mail", "userPassword" };

            searchCtls.setReturningAttributes(returnedAtts);

            int i = 0;

            System.out.println("" + i + ":" + searchBase);
            i++;
            
            //打印用戶
            try{
                NamingEnumeration answer = ctx.search(searchBase, searchUserFilter,
                        searchCtls);
                
                SearchResult sr;                
                while (answer.hasMore()) {
                    sr = (SearchResult) answer.next();
                    printspace(i);
                    System.out.print("user  " + i + ":" + sr.getName() + "\n");
                }
            }catch(NamingException e){
                e.printStackTrace();
            }            
            
            //打印 組織
            try {
                NamingEnumeration answer = ctx.search(searchBase, searchFilter,
                        searchCtls);

                SearchResult sr;
                while (answer.hasMore()) {
                    sr = (SearchResult) answer.next();
                    printspace(i);
                    System.out.print("" + i + ":" + sr.getName() + "\n");
                    recursiveGetChild(ctx, sr.getName() + "," + searchBase,
                            searchCtls, searchFilter, i);
                }
            } catch (NamingException e) {
                e.printStackTrace();
                System.err.println("Throw Exception : " + e);
            }

            ctx.close();

        } catch (NamingException e) {
            e.printStackTrace();
            System.err.println("Throw Exception : " + e);
        }
    }

    // 遞歸函數,遞歸輸出子組織
    void recursiveGetChild(LdapContext ctx, String searchBase,
            SearchControls searchCtls, String searchFilter, int i) {

        SearchResult sr;

        i++;        
        //打印用戶
        try{
            NamingEnumeration answer = ctx.search(searchBase, searchUserFilter,
                    searchCtls);
            
            while (answer.hasMore()) {
                sr = (SearchResult) answer.next();
                printspace(i);
                sr.getAttributes().get("cn");
                System.out.print("user  " + i + ":" + sr.getAttributes().get("sAMAccountName") + "\n");
            }
        }catch(NamingException e){
            e.printStackTrace();
        }
        
        // 打印組織
        try {
            NamingEnumeration answer = ctx.search(searchBase, searchFilter,
                    searchCtls);
            i++;
            while (answer.hasMore()) {
                sr = (SearchResult) answer.next();
                printspace(i);
                System.out.print("" + i + ":" + sr.getName() + "\n");
                recursiveGetChild(ctx, sr.getName() + "," + searchBase,
                        searchCtls, searchFilter, i);
            }
        } catch (NamingException e) {
            e.printStackTrace();
            System.err.println("Throw Exception : " + e);
        }

    }

    // 格式化輸出
    void printspace(int i) {

        while (i-- > 0) {
            System.out.print("  ");
        }
    }

    public static void main(String args[]) {
        ADOperTest ad = new ADOperTest();
        ad.GetADInfo();
    }
}

相關文章
相關標籤/搜索