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

 

  

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值