active directory 學習和概念整理


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

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

     但是,當我們需要額外的管理模型,其實作為一個組織,更可能的是,需要一個公共的中央控制主機,這就是域模型。域模型中,會提供一個域控制器,域控制器上存儲了這個域內的所有賬戶信息,也就是一個賬戶數據庫Active Directory。這也就導致,資源、賬戶、機器的概念開始分離。

  

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

     然后在創建Active Directory時,其實是從 這個域名***.com開始,讓***.com成為一個域的起始節點,術語是“新林中域”,因為從邏輯上將按照ldap的方法,現有域林,然后又域,最后才有域。

  

  第三,創建好之后,我們就來看一下這個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備份出來。

  第六,就是基於如ad域這樣的ldap服務器,和普通的數據庫表內容存取賬戶信息之間的性能差異有多少呢?恩,據說,當數據量達到上萬時,會很可觀。但是我在這里采用它,則考慮的是它是作為標准協議而存在。  

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

/**
 * @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();
    }
}

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM