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 会随着数据库的填充而不断增大。但是,日志的大小却是固定的 ( MB)。对数据库进行的任何更改都会被追加到当前的日志文件中,而且其磁盘映像会不断保持更新。 Edb.log 是当前的日志文件。对数据库进行更改后,会将该更改写入到 Edb.log 文件中。当 Edb.log 文件充满事务之后,它会被重新命名为 Edbxxxxx.log。(从 开始,并使用十六进制累加。) 由于 Active Directory 使用循环记录,所以在旧日志文件写入数据库之后,这些旧日志文件会及时删除。在任何时刻都可以找到 edb.log 文件,而且还可能有一个或多个 Edbxxxxx.log 文件。 Res1.log 和 Res2.log 是“占位符”— 用来在此驱动器上预留(在此情况下)最后的 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();
}
}

active directory 学习和概念整理的更多相关文章
- Active Directory的基本概念
前言 本文是面对准备加入Active Directory编程的初学者的一份文章,主要是讲解Active Directory(活动目录)的一些概念和相关知识.这篇文章本来是不想写下来的,因为概念性内容的 ...
- python深度学习培训概念整理
对于公司组织的人工智能学习,每周日一天课程共计五周,已经上了三次,一天课程下来讲了两本书的知识.发现老师讲的速度太快,深度不够,而且其他公司学员有的没有接触过python知识,所以有必要自己花时间多看 ...
- Active Directory网域
Active Directory网域 3.1Windows网络的管理方式 3.1.1工作组模式 工作组由一组用网络连接在一起的计算机组成,他们将计算机内的资源共享给用户访问.工作组网络也被称为“对等式 ...
- 域知识深入学习一:Active Directory 域服务
AD DS用来组织,管理,控制网络资源 1.1 Active Directory 域服务概述 AD内的directorydatabase(目录数据库)用来存储用户账户,计算机账户,打印机与共享文件 ...
- 建立 Active Directory域 ----学习笔记
第五章 建立 Active Directory域 1.工作组和域的理解 a.工作组是一种平等身份环境,各个计算机之间各个为一个独立体,不方便管理和资源共享. b.域环境一般情况下满足两类需求, ...
- Active Directory组织单位(Organizational Unit)操作汇总
前言 本章聊Active Directory的组织单位(OU)的新增.修改.移动等操作,使用.NET Framework 为我们提供的System.DirectoryServices程序集. 不积跬步 ...
- Azure AD(五)使用多租户应用程序模式让任何 Azure Active Directory 用户登录
一,引言 距离上次分享关于 “Azure AD" 的知识过去差不多2个多月了, 今天最近刚好也是学习,分享一下关于Azure AD 使用多租户应用程序模式让任何 Azure Active D ...
- TFS 与活动目录AD(Active Directory)的同步机制
TFS用户管理机制 TFS系统与企业域服务器用户系统(或本地计算机用户系统)高度集成在一起,使用域服务器验证系统用户的账户和密码,从而在企业中实现单一用户,单点登录.也就是说,TFS系统自身并没有用户 ...
- 移动服务和 Azure Active Directory 中基于角色的访问控制
编辑人员注释:本文章由 Matthew Henderson撰写 去年 11月,我们发布了 Azure Active Directory (AAD) 预览版作为移动服务身份提供程序.此举旨在为企业开 ...
随机推荐
- javax.servlet.ServletException: Servlet execution threw an exception 异常解决之一
配置JDBC连接的JDBC.properties文件不存在(那天很奇怪配置文件不存在了,我也没有去移动那个文件.诡异呀)也会导致这个异常. 然后就报javax.servlet.ServletExcep ...
- struts2基于Convention插件的约定映射使用
一.首先说明一点:所谓的基于Convention插件的约定优于配置的使用,并不是严格意义上的零配置,struts.xml文件并不能完全舍弃. 获得Convention插件功能,所必需的jar包有:|a ...
- jQuery如何阻止子元素继承父元素事件?
<a> <b></b> </a> $("a").click(...); 这种绑定的话,b也会响应一次事件,如何只对a元素绑定事件,而 ...
- [Java][20160707]Java语言介绍
Java最早的名称叫"oak"后来改名叫"Java". Java最早是属于"Sun"公司的, 后来被"Oracle"公司 ...
- Codevs 5059 一起去打CS
5059 一起去打CS 时间限制: 1 s 空间限制: 32000 KB 题目等级 : 钻石 Diamond 题目描述 Description 早就和lyk约好了去打cs,一直没找着时间,终于今天我家 ...
- caffe源码阅读(2)-Layer
神经网络是由层组成的,深度神经网络就是层数多了.layer对应神经网络的层.数据以Blob的形式,在不同的layer之间流动.caffe定义的神经网络已protobuf形式定义.例如: layer { ...
- (poj)3414 Pots (输出路径的广搜)
Description You are given two pots, having the volume of A and B liters respectively. The following ...
- IOS 学习笔记 2015-03-22 OC-API-日期
一 API 1 NSdate 2 NSDateFormatter 二 适用场景 1 获取当前日期 2 增加时间差 3 比较时间差 4 返回较早时间 5 日期格式话 6 日期转字符串 7 字符串转日期 ...
- 基于HTML5和JSP实现的图片Ajax上传和预览
本文对如何实现使用Ajax提交"multipart/form"格式的表单数据,已经如何在图片上传之前,在浏览器上进行预览.使用的主要相关技术HTML5的FILE API,XMLHt ...
- 如何在Ubuntu上创建及管理LXC容器?
将LXC安装到Ubuntu上 $ sudo apt-get install lxc 安装完毕之后,运行lxc-checkconifg工具,检查当前Linux内核支持LXC的情况.要是一切都已被启用,内 ...