zoukankan      html  css  js  c++  java
  • 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() + "
    ");
                        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() + "
    ");
                    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() + "
    ");
                    }
                }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() + "
    ");
                        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") + "
    ");
                }
            }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() + "
    ");
                    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();
        }
    }

      

  • 相关阅读:
    思维导图 第八章 项目质量管理
    思维导图 第七章 项目成本管理
    redis安装与配置
    思维导图 第六章 项目进度管理
    思维导图 第五章 项目范围管理
    Linux下用户-组权限配置
    意灵魔法馆首页的初步设计
    try catch自定义异常类的使用
    使用freemarker时,生成的html出现乱码
    乱码问题
  • 原文地址:https://www.cnblogs.com/haore147/p/4806485.html
Copyright © 2011-2022 走看看