Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

5021 lines
141 KiB

/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
dstree.cxx
Abstract:
This module is a development tool. It creates dummy entries in the DS.
The file replication service treats the dummy entries as a topology.
Without this tool, creating interesting topologies would require many
more machines than I have on hand.
The command is run as, "dstree <command-file". command-file is a list
of command lines and comment lines.
Command lines are read from standard in, parsed, and then shipped
off to the command subroutines. The command line syntax is:
command,site,settings,server,connection,fromserver
"command" is any of add|delete|list|show|quit. Leading whitespace is
ignored. Whitespace between commas counts. The comma separated strings
following "command" are optional. The command line can stop anytime
after "command" and the command will on be applied to that portion
of the "Distinquished Name".
Comment lines are empty lines or lines that begin with /, #, or !.
The files dstree.add and dstree.del are command files. They create
and delete a bogus topology.
Author:
Billy J. Fuller 3-Mar-1997 (From Jim McNelis)
Environment
User mode winnt
--*/
#include <ntreppch.h>
#pragma hdrstop
#include <frs.h>
#include <lmcons.h>
#include <lmapibuf.h>
#include <winsock2.h>
#include <ntdsapi.h>
#define FREE(_x_) { if (_x_) free(_x_); _x_ = NULL; }
//
// Some useful DS object classes and object attributes
// that are not included in frs.h
//
#define CN_TEST_SETTINGS L"NTFRS Test Settings"
#define ATTR_SYSTEM_FLAGS L"systemFlags"
#define ATTR_SYSTEM_MAY_CONTAIN L"systemMayContain"
#define ATTR_SYSTEM_MUST_CONTAIN L"systemMustContain"
#define ATTR_SYSTEM_POSS_SUPERIORS L"systemPossSuperiors"
#define SCHEMA_NAMING_CONTEXT L"cn=schema"
#define ATTR_TRUE L"TRUE"
#define ATTR_OPTIONS_0 L"0"
//
// For DumpValues
//
PWCHAR GuidAttrs[] = {
L"objectGUID",
L"schemaIDGUID",
L"frsVersionGUID",
NULL
};
PWCHAR BerAttrs[] = {
L"replPropertyMetaData",
L"invocationId",
L"defaultSecurityDescriptor",
L"objectSid",
L"lmPwdHistory",
L"ntPwdHistory",
L"oMObjectClass",
NULL
};
//
// For HammerSchema
//
struct AlterAttr {
PWCHAR Attr;
PWCHAR Value;
};
struct AlterClass {
PWCHAR Cn;
struct AlterAttr AlterAttrs[32];
};
struct AlterClass Computer = {
L"Computer",
L"mayContain", L"frsComputerReferenceBL",
NULL, NULL
};
struct AlterClass NtFrsSettings = {
L"NTFRS-Settings",
L"possSuperiors", L"container",
L"possSuperiors", L"organization",
L"possSuperiors", L"organizationalUnit",
L"mayContain", L"managedBy",
L"mayContain", L"frsExtensions",
NULL, NULL
};
struct AlterClass NtFrsReplicaSet = {
L"NTFRS-Replica-Set",
L"mayContain", L"frsVersionGuid",
L"mayContain", L"FrsReplicaSetGuid",
L"mayContain", L"frsPrimaryMember",
L"mayContain", L"managedBy",
L"mayContain", L"frsReplicaSetType",
L"mayContain", L"frsDirectoryFilter",
L"mayContain", L"frsDSPoll",
L"mayContain", L"frsExtensions",
L"mayContain", L"frsFileFilter",
L"mayContain", L"frsFlags",
L"mayContain", L"frsLevelLimit",
L"mayContain", L"frsPartnerAuthLevel",
L"mayContain", L"frsRootSecurity",
L"mayContain", L"frsServiceCommand",
NULL, NULL
};
struct AlterClass NtDsConnection = {
L"NTDS-Connection",
L"possSuperiors", L"nTFRSMember",
NULL, NULL
};
struct AlterClass Dump = {
L"Server-Reference",
L"systemFlags", L"",
NULL, NULL
};
//
// ATTRIBUTES
//
struct AlterClass FrsExtensions = {
L"Frs-Extensions",
L"cn", L"Frs-Extensions",
L"adminDisplayName", L"Frs-Extensions",
L"adminDescription", L"Frs-Extensions",
L"lDAPDisplayName", L"frsExtensions",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.82",
L"oMSyntax", L"4",
L"attributeSyntax", L"2.5.5.10",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"1",
L"rangeUpper", L"65536",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsVersionGuid = {
L"Frs-Version-GUID",
L"cn", L"Frs-Version-GUID",
L"adminDisplayName", L"Frs-Version-GUID",
L"adminDescription", L"Frs-Version-GUID",
L"lDAPDisplayName", L"frsVersionGUID",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.83",
L"oMSyntax", L"4",
L"attributeSyntax", L"2.5.5.10",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsReplicaSetGuid = {
L"Frs-Replica-Set-GUID",
L"cn", L"Frs-Replica-Set-GUID",
L"adminDisplayName", L"Frs-Replica-Set-GUID",
L"adminDescription", L"Frs-Replica-Set-GUID",
L"lDAPDisplayName", L"frsReplicaSetGUID",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.84",
L"oMSyntax", L"4",
L"attributeSyntax", L"2.5.5.10",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"16",
L"rangeUpper", L"16",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsDsPoll = {
L"Frs-DS-Poll",
L"cn", L"Frs-DS-Poll",
L"adminDisplayName", L"Frs-DS-Poll",
L"adminDescription", L"Frs-DS-Poll",
L"lDAPDisplayName", L"frsDSPoll",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.85",
L"oMSyntax", L"2",
L"attributeSyntax", L"2.5.5.9",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
//
// replica set types
//
struct AlterClass FrsReplicaSetType = {
L"Frs-Replica-Set-Type",
L"cn", L"Frs-Replica-Set-Type",
L"adminDisplayName", L"Frs-Replica-Set-Type",
L"adminDescription", L"Frs-Replica-Set-Type",
L"lDAPDisplayName", L"frsReplicaSetType",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.86",
L"oMSyntax", L"2",
L"attributeSyntax", L"2.5.5.9",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsDirectoryFilter = {
L"Frs-Directory-Filter",
L"cn", L"Frs-Directory-Filter",
L"adminDisplayName", L"Frs-Directory-Filter",
L"adminDescription", L"bjf l;kjlkj xyz",
L"lDAPDisplayName", L"frsDirectoryFilter",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.87",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"1",
L"rangeUpper", L"1024",
L"hideFromAB", L"TRUE",
NULL, NULL
};
//
// OIDs out of sequence
//
struct AlterClass FrsControlDataCreation = {
L"Frs-Control-Data-Creation",
L"cn", L"Frs-Control-Data-Creation",
L"adminDisplayName", L"Frs-Control-Data-Creation",
L"adminDescription", L"bob",
L"lDAPDisplayName", L"frsControlDataCreation",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7002.00",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"32",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsControlInboundBacklog = {
L"Frs-Control-Inbound-Backlog",
L"cn", L"Frs-Control-Inbound-Backlog",
L"adminDisplayName", L"Frs-Control-Inbound-Backlog",
L"adminDescription", L"george",
L"lDAPDisplayName", L"frsControlInboundBacklog",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7002.01",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"32",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsControlOutboundBacklog = {
L"Frs-Control-Outbound-Backlog",
L"cn", L"Frs-Control-Outbound-Backlog",
L"adminDisplayName", L"Frs-Control-Outbound-Backlog",
L"adminDescription", L"Frs-Control-Outbound-Backlog",
L"lDAPDisplayName", L"frsControlOutboundBacklog",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7002.02",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"32",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsFaultCondition = {
L"Frs-Fault-Condition",
L"cn", L"Frs-Fault-Condition",
L"adminDisplayName", L"Frs-Fault-Condition",
L"adminDescription", L"Frs-Fault-Condition",
L"lDAPDisplayName", L"frsFaultCondition",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7002.03",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"1",
L"rangeUpper", L"16",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsVersion = {
L"Frs-Version",
L"cn", L"Frs-Version",
L"adminDisplayName", L"Frs-Version",
L"adminDescription", L"Frs-Version",
L"lDAPDisplayName", L"frsVersion",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7002.04",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"32",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsPrimaryMember = {
L"Frs-Primary-Member",
L"cn", L"Frs-Primary-Member",
L"adminDisplayName", L"Frs-Primary-Member",
L"adminDescription", L"Frs-Primary-Member",
L"lDAPDisplayName", L"frsPrimaryMember",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7002.05",
L"oMSyntax", L"127",
L"attributeSyntax", L"2.5.5.1",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"systemFlags", L"2",
L"linkID", L"104",
L"hideFromAB", L"TRUE",
NULL, NULL
};
//
// END OIDs out of sequence
//
struct AlterClass FrsFileFilter = {
L"Frs-File-Filter",
L"cn", L"Frs-File-Filter",
L"adminDisplayName", L"Frs-File-Filter",
L"adminDescription", L"sue and and and",
L"lDAPDisplayName", L"frsFileFilter",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.88",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"1",
L"rangeUpper", L"1024",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsFlags = {
L"Frs-Flags",
L"cn", L"Frs-Flags",
L"adminDisplayName", L"Frs-Flags",
L"adminDescription", L"Frs-Flags",
L"lDAPDisplayName", L"frsFlags",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.89",
L"oMSyntax", L"2",
L"attributeSyntax", L"2.5.5.9",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsLevelLimit = {
L"Frs-Level-Limit",
L"cn", L"Frs-Level-Limit",
L"adminDisplayName", L"Frs-Level-Limit",
L"adminDescription", L"Frs-Level-Limit",
L"lDAPDisplayName", L"frsLevelLimit",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.90",
L"oMSyntax", L"2",
L"attributeSyntax", L"2.5.5.9",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsPartnerAuthLevel = {
L"Frs-Partner-Auth-Level",
L"cn", L"Frs-Partner-Auth-Level",
L"adminDisplayName", L"Frs-Partner-Auth-Level",
L"adminDescription", L"Frs-Partner-Auth-Level",
L"lDAPDisplayName", L"frsPartnerAuthLevel",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.91",
L"oMSyntax", L"2",
L"attributeSyntax", L"2.5.5.9",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsRootSecurity = {
L"Frs-Root-Security",
L"cn", L"Frs-Root-Security",
L"adminDisplayName", L"Frs-Root-Security",
L"adminDescription", L"Frs-Root-Security",
L"lDAPDisplayName", L"frsRootSecurity",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.92",
L"oMSyntax", L"66",
L"attributeSyntax", L"2.5.5.15",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsServiceCommand = {
L"Frs-Service-Command",
L"cn", L"Frs-Service-Command",
L"adminDisplayName", L"Frs-Service-Command",
L"adminDescription", L"Frs-Service-Command",
L"lDAPDisplayName", L"frsServiceCommand",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.93",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"512",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsUpdateTimeout = {
L"Frs-Update-Timeout",
L"cn", L"Frs-Update-Timeout",
L"adminDisplayName", L"Frs-Update-Timeout",
L"adminDescription", L"Frs-Update-Timeout",
L"lDAPDisplayName", L"frsUpdateTimeout",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.94",
L"oMSyntax", L"2",
L"attributeSyntax", L"2.5.5.9",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsWorkingPath = {
L"Frs-Working-Path",
L"cn", L"Frs-Working-Path",
L"adminDisplayName", L"Frs-Working-Path",
L"adminDescription", L"Frs-Working-Path",
L"lDAPDisplayName", L"frsWorkingPath",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.95",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"512",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsStagingPath = {
L"Frs-Staging-Path",
L"cn", L"Frs-Staging-Path",
L"adminDisplayName", L"Frs-Staging-Path",
L"adminDescription", L"Frs-Staging-Path",
L"lDAPDisplayName", L"frsStagingPath",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.96",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"512",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsServiceCommandStatus = {
L"Frs-Service-Command-Status",
L"cn", L"Frs-Service-Command-Status",
L"adminDisplayName", L"Frs-Service-Command-Status",
L"adminDescription", L"frsServiceCommandStatus",
L"lDAPDisplayName", L"frsServiceCommandStatus",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.98",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"512",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsTimeLastCommand = {
L"Frs-Time-Last-Command",
L"cn", L"Frs-Time-Last-Command",
L"adminDisplayName", L"Frs-Time-Last-Command",
L"adminDescription", L"Frs-Time-Last-Command",
L"lDAPDisplayName", L"frsTimeLastCommand",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7000.99",
L"oMSyntax", L"23",
L"attributeSyntax", L"2.5.5.11",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsTimeLastConfigChange = {
L"Frs-Time-Last-Config-Change",
L"cn", L"Frs-Time-Last-Config-Change",
L"adminDisplayName", L"Frs-Time-Last-Config-Change",
L"adminDescription", L"Frs-Time-Last-Config-Change",
L"lDAPDisplayName", L"frsTimeLastConfigChange",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7001.01",
L"oMSyntax", L"23",
L"attributeSyntax", L"2.5.5.11",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsRootPath = {
L"Frs-Root-Path",
L"cn", L"Frs-Root-Path",
L"adminDisplayName", L"Frs-Root-Path",
L"adminDescription", L"Frs-Root-Path",
L"lDAPDisplayName", L"frsRootPath",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7001.02",
L"oMSyntax", L"64",
L"attributeSyntax", L"2.5.5.12",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"rangeLower", L"0",
L"rangeUpper", L"512",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsComputerReference = {
L"Frs-Computer-Reference",
L"cn", L"Frs-Computer-Reference",
L"adminDisplayName", L"Frs-Computer-Reference",
L"adminDescription", L"Frs-Computer-Reference",
L"lDAPDisplayName", L"frsComputerReference",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7001.03",
L"oMSyntax", L"127",
L"attributeSyntax", L"2.5.5.1",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"systemFlags", L"2",
L"linkID", L"100",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsComputerReferenceBl = {
L"Frs-Computer-Reference-BL",
L"cn", L"Frs-Computer-Reference-BL",
L"adminDisplayName", L"Frs-Computer-Reference-BL",
L"adminDescription", L"Frs-Computer-Reference-BL",
L"lDAPDisplayName", L"frsComputerReferenceBL",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7001.04",
L"oMSyntax", L"127",
L"attributeSyntax", L"2.5.5.1",
L"isSingleValued", L"FALSE",
L"systemOnly", L"FALSE",
L"linkID", L"101",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsMemberReference = {
L"Frs-Member-Reference",
L"cn", L"Frs-Member-Reference",
L"adminDisplayName", L"Frs-Member-Reference",
L"adminDescription", L"Frs-Member-Reference",
L"lDAPDisplayName", L"frsMemberReference",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7001.05",
L"oMSyntax", L"127",
L"attributeSyntax", L"2.5.5.1",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"systemFlags", L"2",
L"linkID", L"102",
L"hideFromAB", L"TRUE",
NULL, NULL
};
struct AlterClass FrsMemberReferenceBl = {
L"Frs-Member-Reference-BL",
L"cn", L"Frs-Member-Reference-BL",
L"adminDisplayName", L"Frs-Member-Reference-BL",
L"adminDescription", L"Frs-Member-Reference-BL",
L"lDAPDisplayName", L"frsMemberReferenceBL",
L"objectClass", L"attributeSchema",
L"attributeId", L"1.2.840.113556.1.4.7001.06",
L"oMSyntax", L"127",
L"attributeSyntax", L"2.5.5.1",
L"isSingleValued", L"TRUE",
L"systemOnly", L"FALSE",
L"linkID", L"103",
L"hideFromAB", L"TRUE",
NULL, NULL
};
//
// CLASSES
//
struct AlterClass NtFrsMember = {
L"NTFRS-Member",
L"cn", L"NTFRS-Member",
L"adminDisplayName", L"NTFRS-Member",
L"adminDescription", L"NTFRS-Member",
L"lDAPDisplayName", L"nTFRSMember",
L"objectClass", L"classSchema",
L"rDNAttID", L"cn",
L"defaultHidingValue", L"TRUE",
L"hideFromAB", L"TRUE",
L"subClassOf", L"leaf",
L"systemOnly", L"FALSE",
L"governsId", L"1.2.840.113556.1.4.7001.07",
L"objectClassCategory", L"1",
NULL, NULL
};
struct AlterClass NtFrsSubscriptions = {
L"NTFRS-Subscriptions",
L"cn", L"NTFRS-Subscriptions",
L"adminDisplayName", L"NTFRS-Subscriptions",
L"adminDescription", L"NTFRS-Subscriptions",
L"lDAPDisplayName", L"nTFRSSubscriptions",
L"objectClass", L"classSchema",
L"rDNAttID", L"cn",
L"defaultHidingValue", L"TRUE",
L"hideFromAB", L"TRUE",
L"subClassOf", L"leaf",
L"systemOnly", L"FALSE",
L"governsId", L"1.2.840.113556.1.4.7001.08",
L"objectClassCategory", L"1",
NULL, NULL
};
struct AlterClass NtFrsSubscriber = {
L"NTFRS-Subscriber",
L"cn", L"NTFRS-Subscriber",
L"adminDisplayName", L"NTFRS-Subscriber",
L"adminDescription", L"NTFRS-Subscriber",
L"lDAPDisplayName", L"nTFRSSubscriber",
L"objectClass", L"classSchema",
L"rDNAttID", L"cn",
L"defaultHidingValue", L"TRUE",
L"hideFromAB", L"TRUE",
L"subClassOf", L"leaf",
L"systemOnly", L"FALSE",
L"governsId", L"1.2.840.113556.1.4.7001.09",
L"objectClassCategory", L"1",
NULL, NULL
};
struct AlterClass NtFrsMemberEx = {
L"NTFRS-Member",
L"possSuperiors", L"nTFRSReplicaSet",
L"mayContain", L"frsExtensions",
L"mayContain", L"frsPartnerAuthLevel",
L"mayContain", L"frsRootSecurity",
L"mayContain", L"frsServiceCommand",
L"mayContain", L"schedule",
L"mayContain", L"frsComputerReference",
L"mayContain", L"ServerReference",
L"mayContain", L"frsMemberReferenceBL",
L"mayContain", L"frsUpdateTimeout",
L"mayContain", L"frsControlDataCreation",
L"mayContain", L"frsControlInboundBacklog",
L"mayContain", L"frsControlOutboundBacklog",
L"mayContain", L"frsFlags",
NULL, NULL
};
struct AlterClass NtFrsSubscriptionsEx = {
L"NTFRS-Subscriptions",
L"possSuperiors", L"computer",
L"possSuperiors", L"nTFRSSubscriptions",
L"mayContain", L"frsWorkingPath",
L"mayContain", L"frsVersion",
L"mayContain", L"frsExtensions",
NULL, NULL
};
struct AlterClass NtFrsSubscriberEx = {
L"NTFRS-Subscriber",
L"possSuperiors", L"nTFRSSubscriptions",
L"mustContain", L"frsRootPath",
L"mustContain", L"frsStagingPath",
L"mayContain", L"frsExtensions",
L"mayContain", L"frsFlags",
L"mayContain", L"frsFaultCondition",
L"mayContain", L"frsMemberReference",
L"mayContain", L"frsUpdateTimeout",
L"mayContain", L"frsServiceCommand",
L"mayContain", L"frsServiceCommandStatus",
L"mayContain", L"schedule",
L"mayContain", L"frsTimeLastCommand",
L"mayContain", L"frsTimeLastConfigChange",
NULL, NULL
};
//
// CREATE ATTRIBUTES
//
struct AlterClass *CreateAttributes[] = {
&FrsExtensions,
&FrsVersionGuid,
&FrsReplicaSetGuid,
&FrsDsPoll,
&FrsReplicaSetType,
&FrsDirectoryFilter,
&FrsFileFilter,
&FrsFlags,
&FrsLevelLimit,
&FrsPartnerAuthLevel,
&FrsRootSecurity,
&FrsServiceCommand,
&FrsUpdateTimeout,
&FrsWorkingPath,
&FrsStagingPath,
&FrsServiceCommandStatus,
&FrsTimeLastCommand,
&FrsTimeLastConfigChange,
&FrsRootPath,
&FrsComputerReference,
&FrsComputerReferenceBl,
&FrsMemberReference,
&FrsMemberReferenceBl,
&FrsControlDataCreation,
&FrsControlInboundBacklog,
&FrsControlOutboundBacklog,
&FrsFaultCondition,
&FrsVersion,
&FrsPrimaryMember,
NULL
};
//
// CREATE CLASSES
//
struct AlterClass *CreateClasses[] = {
&NtFrsMember,
&NtFrsSubscriptions,
&NtFrsSubscriber,
NULL
};
//
// ALTER EXISTING CLASSES
//
struct AlterClass *AlterSchema[] = {
&Computer,
&NtFrsSettings,
&NtFrsReplicaSet,
&NtDsConnection,
&NtFrsMemberEx,
&NtFrsSubscriptionsEx,
&NtFrsSubscriberEx,
NULL
};
PWCHAR
MakeRdn(
IN PWCHAR DN
)
/*++
Routine Description:
Extract the base component (relative distinguished name) from a
distinguished name. The distinguished name is assumed to be in
DS format (CN=xyz,CN=next one,...). In this case, the returned
RDN is "xyz".
Arguments:
DN - distinguished name
Return Value:
A zero-terminated string. The string is freed with FREE_NO_HEADER().
--*/
{
DWORD RDNLen;
PWCHAR RDN;
if (DN == NULL) {
return NULL;
}
// Skip the first CN=; if any
RDN = wcsstr(DN, L"CN=");
if (RDN == DN)
DN += 3;
// Return the string up to the first delimiter or EOS
RDNLen = wcscspn(DN, L",");
RDN = (PWCHAR)malloc(sizeof(WCHAR) * (RDNLen + 1));
wcsncpy(RDN, DN, RDNLen);
RDN[RDNLen] = L'\0';
return RDN;
}
PWCHAR
FrsDsMakeParentDn(
IN PWCHAR Dn
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
DWORD PLen;
if (Dn == NULL) {
return NULL;
}
PLen = wcscspn(Dn, L",");
if (Dn[PLen] != L',') {
return NULL;
}
return FrsWcsDup(&Dn[PLen + 1]);
}
VOID
AddMod(
IN PWCHAR AttrType,
IN PWCHAR AttrValue,
IN OUT LDAPMod ***pppMod
)
/*++
Routine Description:
Add an attribute (plus values) to a structure that will eventually be
used in an ldap_add() function to add an object to the DS. The null-
terminated array referenced by pppMod grows with each call to this
routine. The array is freed by the caller using FreeMod().
Arguments:
AttrType - The object class of the object.
AttrValue - The value of the attribute.
pppMod - Address of an array of pointers to "attributes". Don't
give me that look -- this is an LDAP thing.
Return Value:
The pppMod array grows by one entry. The caller must free it with
FreeMod().
--*/
{
DWORD NumMod; // Number of entries in the Mod array
LDAPMod **ppMod; // Address of the first entry in the Mod array
LDAPMod *Attr; // An attribute structure
PWCHAR *Values; // An array of pointers to bervals
if (AttrValue == NULL)
return;
//
// The null-terminated array doesn't exist; create it
//
if (*pppMod == NULL) {
*pppMod = (LDAPMod **)malloc(sizeof (*pppMod));
**pppMod = NULL;
}
//
// Increase the array's size by 1
//
for (ppMod = *pppMod, NumMod = 2; *ppMod != NULL; ++ppMod, ++NumMod);
*pppMod = (LDAPMod **)realloc(*pppMod, sizeof (*pppMod) * NumMod);
//
// Add the new attribute + value to the Mod array
//
Values = (PWCHAR *)malloc(sizeof (PWCHAR) * 2);
Values[0] = _wcsdup(AttrValue);
Values[1] = NULL;
Attr = (LDAPMod *)malloc(sizeof (*Attr));
Attr->mod_values = Values;
Attr->mod_type = _wcsdup(AttrType);
Attr->mod_op = LDAP_MOD_ADD;
(*pppMod)[NumMod - 1] = NULL;
(*pppMod)[NumMod - 2] = Attr;
}
VOID
AddBerMod(
IN PWCHAR AttrType,
IN PCHAR AttrValue,
IN DWORD AttrValueLen,
IN OUT LDAPMod ***pppMod
)
/*++
Routine Description:
Add an attribute (plus values) to a structure that will eventually be
used in an ldap_add() function to add an object to the DS. The null-
terminated array referenced by pppMod grows with each call to this
routine. The array is freed by the caller using FreeMod().
Arguments:
AttrType - The object class of the object.
AttrValue - The value of the attribute.
AttrValueLen - length of the attribute
pppMod - Address of an array of pointers to "attributes". Don't
give me that look -- this is an LDAP thing.
Return Value:
The pppMod array grows by one entry. The caller must free it with
FreeMod().
--*/
{
DWORD NumMod; // Number of entries in the Mod array
LDAPMod **ppMod; // Address of the first entry in the Mod array
LDAPMod *Attr; // An attribute structure
PLDAP_BERVAL Berval;
PLDAP_BERVAL *Values; // An array of pointers to bervals
if (AttrValue == NULL)
return;
//
// The null-terminated array doesn't exist; create it
//
if (*pppMod == NULL) {
*pppMod = (LDAPMod **)malloc(sizeof (*pppMod));
**pppMod = NULL;
}
//
// Increase the array's size by 1
//
for (ppMod = *pppMod, NumMod = 2; *ppMod != NULL; ++ppMod, ++NumMod);
*pppMod = (LDAPMod **)realloc(*pppMod, sizeof (*pppMod) * NumMod);
//
// Construct a berval
//
Berval = (PLDAP_BERVAL)malloc(sizeof(LDAP_BERVAL));
Berval->bv_len = AttrValueLen;
Berval->bv_val = (PCHAR)malloc(AttrValueLen);
CopyMemory(Berval->bv_val, AttrValue, AttrValueLen);
//
// Add the new attribute + value to the Mod array
//
Values = (PLDAP_BERVAL *)malloc(sizeof (PLDAP_BERVAL) * 2);
Values[0] = Berval;
Values[1] = NULL;
Attr = (LDAPMod *)malloc(sizeof (*Attr));
Attr->mod_bvalues = Values;
Attr->mod_type = _wcsdup(AttrType);
Attr->mod_op = LDAP_MOD_BVALUES | LDAP_MOD_REPLACE;
(*pppMod)[NumMod - 1] = NULL;
(*pppMod)[NumMod - 2] = Attr;
}
VOID
FreeMod(
IN OUT LDAPMod ***pppMod
)
/*++
Routine Description:
Free the structure built by successive calls to AddMod().
Arguments:
pppMod - Address of a null-terminated array.
Return Value:
*pppMod set to NULL.
--*/
{
DWORD i, j;
LDAPMod **ppMod;
if (!pppMod || !*pppMod) {
return;
}
//
// For each attibute
//
ppMod = *pppMod;
for (i = 0; ppMod[i] != NULL; ++i) {
//
// For each value of the attribute
//
for (j = 0; (ppMod[i])->mod_values[j] != NULL; ++j) {
//
// Free the value
//
if (ppMod[i]->mod_op & LDAP_MOD_BVALUES) {
free(ppMod[i]->mod_bvalues[j]->bv_val);
}
free((ppMod[i])->mod_values[j]);
}
free((ppMod[i])->mod_values); // Free the array of pointers to values
free((ppMod[i])->mod_type); // Free the string identifying the attribute
free(ppMod[i]); // Free the attribute
}
free(ppMod); // Free the array of pointers to attributes
*pppMod = NULL; // Now ready for more calls to AddMod()
}
BOOL
LdapSearch(
IN PLDAP ldap,
IN PWCHAR Base,
IN ULONG Scope,
IN PWCHAR Filter,
IN PWCHAR Attrs[],
IN ULONG AttrsOnly,
IN LDAPMessage **Res,
IN BOOL Quiet
)
/*++
Routine Description:
Issue the ldap ldap_search_s call, check for errors, and check for
a shutdown in progress.
Arguments:
ldap
Base
Scope
Filter
Attrs
AttrsOnly
Res
Return Value:
The ldap array of values or NULL if the Base, DesiredAttr, or its values
does not exist. The ldap array is freed with ldap_value_free().
--*/
{
DWORD LStatus;
//
// Issue the ldap search
//
LStatus = ldap_search_s(ldap, Base, Scope, Filter, Attrs, AttrsOnly, Res);
//
// Check for errors
//
if (LStatus != LDAP_SUCCESS) {
if (!Quiet) {
fprintf(stderr, "WARN - Error searching %ws for %ws; LStatus %d: %ws\n",
Base, Filter, LStatus, ldap_err2string(LStatus));
}
return FALSE;
}
//
// Return TRUE if not shutting down
//
return TRUE;
}
BOOL
FrsDsVerifySchedule(
IN PWCHAR Name,
IN ULONG ScheduleLength,
IN PSCHEDULE Schedule
)
/*++
Routine Description:
Check the schedule for consistency
Arguments:
Name
Schedule
Return Value:
None.
--*/
{
ULONG i, j;
ULONG Num;
ULONG Len;
ULONG NumType;
PUCHAR NewScheduleData;
PUCHAR OldScheduleData;
if (!Schedule) {
return TRUE;
}
//
// Too many schedules
//
Num = Schedule->NumberOfSchedules;
if (Num > 3) {
fprintf(stderr, "%ws has %d schedules\n", Name, Num);
return FALSE;
}
//
// Too few schedules
//
if (Num < 1) {
fprintf(stderr, "%ws has %d schedules\n", Name, Num);
return FALSE;
}
//
// Not enough memory
//
Len = sizeof(SCHEDULE) +
(sizeof(SCHEDULE_HEADER) * (Num - 1)) +
(SCHEDULE_DATA_BYTES * Num);
if (ScheduleLength < Len) {
fprintf(stderr, "%ws is short (ds) by %d bytes (%d - %d), %d\n",
Name,
Len - ScheduleLength,
Len,
ScheduleLength,
Schedule->Size);
return FALSE;
}
if (Schedule->Size < Len) {
fprintf(stderr, "%ws is short (size) by %d bytes (%d - %d), %d\n",
Name,
Len - Schedule->Size,
Len,
Schedule->Size,
Schedule->Size);
return FALSE;
}
Schedule->Size = Len;
//
// Invalid type
//
for (i = 0; i < Num; ++i) {
switch (Schedule->Schedules[i].Type) {
case SCHEDULE_INTERVAL:
break;
case SCHEDULE_BANDWIDTH:
break;
case SCHEDULE_PRIORITY:
break;
default:
fprintf(stderr, "%ws has an invalid schedule type (%d)\n",
Name,
Schedule->Schedules[i].Type);
return FALSE;
}
}
//
// Only 0 or 1 interval
//
for (NumType = i = 0; i < Num; ++i)
if (Schedule->Schedules[i].Type == SCHEDULE_INTERVAL)
++NumType;
if (NumType > 1) {
fprintf(stderr, "%ws has %d interval schedules\n",
Name,
NumType);
return FALSE;
}
//
// Only 0 or 1 bandwidth
//
for (NumType = i = 0; i < Num; ++i)
if (Schedule->Schedules[i].Type == SCHEDULE_BANDWIDTH)
++NumType;
if (NumType > 1) {
fprintf(stderr, "%ws has %d bandwidth schedules\n",
Name,
NumType);
return FALSE;
}
//
// Only 0 or 1 priority
//
for (NumType = i = 0; i < Num; ++i)
if (Schedule->Schedules[i].Type == SCHEDULE_PRIORITY)
++NumType;
if (NumType > 1) {
fprintf(stderr, "%ws has %d priority schedules\n",
Name,
NumType);
return FALSE;
}
//
// Invalid offset
//
for (i = 0; i < Num; ++i) {
if (Schedule->Schedules[i].Offset >
ScheduleLength - SCHEDULE_DATA_BYTES) {
fprintf(stderr, "%ws has an invalid offset (%d)\n",
Name,
Schedule->Schedules[i].Offset);
return FALSE;
}
}
return TRUE;
}
VOID
PrintShortSchedule(
IN PWCHAR Indent,
IN PSCHEDULE Schedule,
IN ULONG ScheduleLen
)
/*++
Routine Description:
Print a short form of the schedule
Arguments:
Return Value:
None.
--*/
{
ULONG i;
if (!FrsDsVerifySchedule(L"<unknown>", ScheduleLen, Schedule)) {
return;
}
if (!Schedule || !Schedule->NumberOfSchedules) {
printf("%wsSchedule=\n", Indent);
return;
}
for (i = 0; i < Schedule->NumberOfSchedules; ++i) {
if (!i) {
printf("%wsSchedule=Type %d", Indent, Schedule->Schedules[i].Type);
} else {
printf(", %d", Schedule->Schedules[i].Type);
}
}
printf("\n");
}
VOID
PrintLongSchedule(
IN PWCHAR Indent1,
IN PWCHAR Indent2,
IN PSCHEDULE Schedule,
IN ULONG ScheduleLen
)
/*++
Routine Description:
Print a short form of the schedule
Arguments:
Return Value:
None.
--*/
{
ULONG i;
ULONG Day;
ULONG Hour;
BOOL PrintIt;
PUCHAR ScheduleData;
if (!FrsDsVerifySchedule(L"<unknown>", ScheduleLen, Schedule)) {
return;
}
if (!Schedule || !Schedule->NumberOfSchedules) {
printf("%ws%wsSchedule=\n", Indent1, Indent2);
return;
}
for (i = 0; i < Schedule->NumberOfSchedules; ++i) {
if (!i) {
printf("%ws%wsSchedule=Type %d",
Indent1,
Indent2,
Schedule->Schedules[i].Type);
} else {
printf(", %d", Schedule->Schedules[i].Type);
}
}
printf("\n");
for (i = 0; i < Schedule->NumberOfSchedules; ++i) {
ScheduleData = ((PUCHAR)Schedule) + Schedule->Schedules[i].Offset;
if (Schedule->Schedules[i].Type != SCHEDULE_INTERVAL) {
continue;
}
for (Day = 0; Day < 7; ++Day) {
if (Day) {
PrintIt = FALSE;
for (Hour = 0; Hour < 24; ++Hour) {
if (*(ScheduleData + (Day * 24) + Hour) !=
*(ScheduleData + ((Day - 1) * 24) + Hour)) {
PrintIt = TRUE;
break;
}
}
} else {
PrintIt = TRUE;
}
if (!PrintIt) {
continue;
}
printf("%ws%ws Day %1d: ", Indent1, Indent2, Day + 1);
for (Hour = 0; Hour < 24; ++Hour) {
printf("%1x", *(ScheduleData + (Day * 24) + Hour) & 0x0F);
}
printf("\n");
}
printf("\n");
}
}
VOID
PrintSchedule(
IN PSCHEDULE Schedule
)
/*++
Routine Description:
Print the schedule
Arguments:
Schedule
Return Value:
None.
--*/
{
ULONG i;
if (Schedule) for (i = 0; i < Schedule->NumberOfSchedules; ++i) {
printf(" Schedule %d\n", i);
printf(" Type : %d\n", Schedule->Schedules[i].Type);
printf(" Offset: %d\n", Schedule->Schedules[i].Offset);
}
}
PCHAR
FrsWtoA(
PWCHAR Wstr
)
/*++
Routine Description:
Translate a wide char string into a newly allocated char string.
Arguments:
Wstr - wide char string
Return Value:
Duplicated string. Free with FrsFree().
--*/
{
PCHAR Astr;
//
// E.g., when duplicating NodePartner when none exists
//
if (Wstr == NULL)
return NULL;
Astr = (PCHAR)malloc(wcslen(Wstr) + 1);
sprintf(Astr, "%ws", Wstr);
return Astr;
}
PWCHAR
FrsAtoW(
PCHAR Astr
)
/*++
Routine Description:
Translate a wide char string into a newly allocated char string.
Arguments:
Wstr - wide char string
Return Value:
Duplicated string. Free with FrsFree().
--*/
{
PWCHAR Wstr;
//
// E.g., when duplicating NodePartner when none exists
//
if (Astr == NULL) {
return NULL;
}
Wstr = (PWCHAR)malloc((strlen(Astr) + 1) * sizeof(WCHAR));
swprintf(Wstr, L"%hs", Astr);
return Wstr;
}
PWCHAR
FrsWcsDup(
PWCHAR OldStr
)
/*++
Routine Description:
Duplicate a string using our memory allocater
Arguments:
OldArg - string to duplicate
Return Value:
Duplicated string. Free with FrsFree().
--*/
{
PWCHAR NewStr;
//
// E.g., when duplicating NodePartner when none exists
//
if (OldStr == NULL)
return NULL;
NewStr = (PWCHAR)malloc((wcslen(OldStr) + 1) * sizeof(WCHAR));
wcscpy(NewStr, OldStr);
return NewStr;
}
PWCHAR
FrsWcsCat(
PWCHAR First,
PWCHAR Second
)
/*++
Routine Description:
Concatenate two strings into a new string using our memory allocater
Arguments:
First - First string in the concat
Second - Second string in the concat
Return Value:
Duplicated and concatentated string. Free with FrsFree().
--*/
{
DWORD Bytes;
PWCHAR New;
// size of new string
Bytes = (wcslen(First) + wcslen(Second) + 1) * sizeof(WCHAR);
New = (PWCHAR)malloc(Bytes);
// Not as efficient as I would like but this routine is seldom used
wcscpy(New, First);
wcscat(New, Second);
return New;
}
ULONG NumSchedules;
VOID
ConditionalBuildSchedule(
PSCHEDULE *Schedule,
PULONG ScheduleLength
)
/*++
Routine Description:
Build a schedule with the specified number of schedules
Arguments:
Schedule
ScheduleLength
Return Value:
Schedule or NULL. Free with free();
--*/
{
PBYTE ScheduleData;
ULONG j;
//
// No schedule, yet
//
*Schedule = NULL;
*ScheduleLength = 0;
//
// Create variable sized schedules
//
++NumSchedules;
if (NumSchedules > 3) {
NumSchedules = 1; // shouldn't always create schedule
}
if (NumSchedules == 0) {
return;
}
//
// Construct a phoney schedule; always "on"
//
*ScheduleLength = sizeof(SCHEDULE) +
((NumSchedules - 1) * sizeof(SCHEDULE_HEADER)) +
(NumSchedules * SCHEDULE_DATA_BYTES);
*Schedule = (PSCHEDULE)malloc(*ScheduleLength);
ZeroMemory(*Schedule, *ScheduleLength);
(*Schedule)->Size = *ScheduleLength;
(*Schedule)->NumberOfSchedules = NumSchedules;
(*Schedule)->Schedules[0].Type = SCHEDULE_INTERVAL;
(*Schedule)->Schedules[0].Offset = sizeof(SCHEDULE) +
((NumSchedules - 1) * sizeof(SCHEDULE_HEADER)) +
(0 * SCHEDULE_DATA_BYTES);
if (NumSchedules == 1) {
goto setschedule;
}
(*Schedule)->Schedules[1].Type = SCHEDULE_PRIORITY;
(*Schedule)->Schedules[1].Offset = sizeof(SCHEDULE) +
((NumSchedules - 1) * sizeof(SCHEDULE_HEADER)) +
(1 * SCHEDULE_DATA_BYTES);
if (NumSchedules == 2) {
goto setschedule;
}
(*Schedule)->Schedules[2].Type = SCHEDULE_BANDWIDTH;
(*Schedule)->Schedules[2].Offset = sizeof(SCHEDULE) +
((NumSchedules - 1) * sizeof(SCHEDULE_HEADER)) +
(2 * SCHEDULE_DATA_BYTES);
if (NumSchedules == 3) {
goto setschedule;
}
setschedule:
ScheduleData = ((PBYTE)(*Schedule));
for (j = 0; j < (SCHEDULE_DATA_BYTES * NumSchedules); ++j) {
*(ScheduleData + (*Schedule)->Schedules[0].Offset + j) = 0xff;
}
}
DWORD
FrsDsGetDcInfo(
IN PDOMAIN_CONTROLLER_INFO *DcInfo,
IN DWORD Flags
)
/*++
Routine Description:
Open and bind to a dc
Arguments:
DcInfo - Dc Info
Flags - DsGetDcName(Flags)
Return Value:
DsGetDcName
--*/
{
DWORD WStatus;
WStatus = DsGetDcName(NULL, // Computer to remote to
NULL, // Domain - use our own
NULL, // Domain Guid
NULL, // Site Guid
Flags,
DcInfo); // Return info
//
// Report the error and retry for any DC
//
if (!WIN_SUCCESS(WStatus)) {
fprintf(stderr, "ERROR - Could not get DC Info; WStatus %d\n", WStatus);
return WStatus;
}
printf("DCINFO for %08x:\n", Flags);
printf("\tDomainControllerName : %ws\n", (*DcInfo)->DomainControllerName);
printf("\tDomainControllerAddress: %ws\n", (*DcInfo)->DomainControllerAddress);
printf("\tDomainControllerType : %08x\n",(*DcInfo)->DomainControllerAddressType);
printf("\tDomainName : %ws\n", (*DcInfo)->DomainName);
// printf("\tForestName : %ws\n", (*DcInfo)->DnsForestName);
printf("\tDcSiteName : %ws\n", (*DcInfo)->DcSiteName);
printf("\tClientSiteName : %ws\n", (*DcInfo)->ClientSiteName);
printf("\tFlags : %08x\n",(*DcInfo)->Flags);
return WStatus;
}
PLDAP
FrsDsOpenDs(
VOID
)
/*++
Routine Description:
Open and bind to the a primary domain controller.
Arguments:
None.
Return Value:
The address of a open, bound LDAP port or NULL if the operation was
unsuccessful. The caller must free the structure with ldap_unbind().
--*/
{
DWORD WStatus;
PLDAP ldap = NULL; // ldap handle
PWCHAR DcAddr;
PWCHAR DcDnsName;
PDOMAIN_CONTROLLER_INFO DcInfo;
ULONG ulOptions;
//
// Get Info about a Global Catalogue
// Domain Controller (need the IP address)
//
// (Nope; try to live without it, Billy)
//
bugbug("FORCE_REDISCOVERY was removed per Herron")
WStatus = FrsDsGetDcInfo(&DcInfo,
DS_DIRECTORY_SERVICE_REQUIRED | // Flags
DS_WRITABLE_REQUIRED);
//
// Report the error and retry for any DC
//
if (!WIN_SUCCESS(WStatus)) {
printf("Retrying FrsDsGetDcInfo with force rediscovery\n");
FrsDsGetDcInfo(&DcInfo,
DS_DIRECTORY_SERVICE_REQUIRED | // Flags
DS_WRITABLE_REQUIRED |
DS_FORCE_REDISCOVERY);
}
if (!WIN_SUCCESS(WStatus)) {
fprintf(stderr, "ERROR - Could not get DC Info; WStatus %d\n", WStatus);
}
DcAddr = DcInfo->DomainControllerAddress;
DcDnsName = DcInfo->DomainControllerName;
//
// if ldap_open is called with a server name the api will call DsGetDcName
// passing the server name as the domainname parm...bad, because
// DsGetDcName will make a load of DNS queries based on the server name,
// it is designed to construct these queries from a domain name...so all
// these queries will be bogus, meaning they will waste network bandwidth,
// time to fail, and worst case cause expensive on demand links to come up
// as referrals/forwarders are contacted to attempt to resolve the bogus
// names. By setting LDAP_OPT_AREC_EXCLUSIVE to on using ldap_set_option
// after the ldap_init but before any other operation using the ldap
// handle from ldap_init, the delayed connection setup will not call
// DsGetDcName, just gethostbyname, or if an IP is passed, the ldap client
// will detect that and use the address directly.
//
//
// DC's DNS name (w/o the leading \\)
//
if (!ldap &&
DcDnsName &&
(wcslen(DcDnsName) > 2) &&
DcDnsName[0] == L'\\' &&
DcDnsName[1] == L'\\') {
// ldap = ldap_open(DcDnsName + 2, LDAP_PORT);
ldap = ldap_init(DcDnsName + 2, LDAP_PORT);
if (!ldap) {
// fprintf(stderr, "WARN - ldap_open(DcDnsName + 2 %ws); WStatus %d\n",
// DcDnsName + 2,
// WStatus);
fprintf(stderr, "WARN - ldap_init(DcDnsName + 2 %ws); WStatus %d\n",
DcDnsName + 2,
WStatus);
} else {
// printf("ldap_open(DcDnsName + 2 %ws) succeeded\n", DcDnsName + 2);
printf("ldap_init(DcDnsName + 2 %ws) succeeded\n", DcDnsName + 2);
}
}
//
// DC's IP Address (w/o the leading \\)
//
if (!ldap &&
DcAddr &&
(wcslen(DcAddr) > 2) &&
DcAddr[0] == L'\\' &&
DcAddr[1] == L'\\') {
// ldap = ldap_open(DcAddr + 2, LDAP_PORT);
ldap = ldap_init(DcAddr + 2, LDAP_PORT);
if (!ldap) {
// fprintf(stderr, "WARN - ldap_open(DcAddr + 2 %ws); WStatus %d\n",
// DcAddr + 2,
// WStatus);
fprintf(stderr, "WARN - ldap_init(DcAddr + 2 %ws); WStatus %d\n",
DcAddr + 2,
WStatus);
} else {
// printf("ldap_open(DcAddr + 2 %ws) succeeded\n", DcAddr + 2);
printf("ldap_init(DcAddr + 2 %ws) succeeded\n", DcAddr + 2);
}
}
//
// DC's DNS name
//
if (!ldap && DcDnsName) {
// ldap = ldap_open(DcDnsName, LDAP_PORT);
ldap = ldap_init(DcDnsName, LDAP_PORT);
if (!ldap) {
// fprintf(stderr, "WARN - ldap_open(DcDnsName %ws); WStatus %d\n",
// DcDnsName,
// WStatus);
fprintf(stderr, "WARN - ldap_init(DcDnsName %ws); WStatus %d\n",
DcDnsName,
WStatus);
} else {
// printf("ldap_open(DcDnsName %ws) succeeded\n", DcDnsName);
printf("ldap_init(DcDnsName %ws) succeeded\n", DcDnsName);
}
}
//
// DC's IP Address
//
if (!ldap && DcAddr) {
// ldap = ldap_open(DcAddr, LDAP_PORT);
ldap = ldap_init(DcAddr, LDAP_PORT);
if (!ldap) {
// fprintf(stderr, "WARN - ldap_open(DcAddr %ws); WStatus %d\n",
// DcAddr,
// WStatus);
fprintf(stderr, "WARN - ldap_init(DcAddr %ws); WStatus %d\n",
DcAddr,
WStatus);
} else {
// printf("ldap_open(DcAddr %ws) succeeded\n", DcAddr);
printf("ldap_init(DcAddr %ws) succeeded\n", DcAddr);
}
}
//
// Whatever it is, we can't find it.
//
if (!ldap) {
// fprintf(stderr, "ERROR - ldap_open(DNS %ws, IP %ws); WStatus %d\n",
// DcDnsName,
// DcAddr,
// WStatus);
fprintf(stderr, "ERROR - ldap_init(DNS %ws, IP %ws); WStatus %d\n",
DcDnsName,
DcAddr,
WStatus);
return NULL;
}
//
// set the option as explained in the comment above.
//
ulOptions = PtrToUlong(LDAP_OPT_ON);
ldap_set_option(ldap, LDAP_OPT_AREC_EXCLUSIVE, &ulOptions);
//
// ldap cannot be used until after the bind operation
//
WStatus = ldap_bind_s(ldap, NULL, NULL, LDAP_AUTH_NEGOTIATE);
if (WStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - ldap_bind_s: %ws\n", ldap_err2string(WStatus));
ldap_unbind(ldap);
return NULL;
}
return ldap;
}
PWCHAR *
GetValues(
IN PLDAP Ldap,
IN PWCHAR Dn,
IN PWCHAR DesiredAttr,
IN BOOL Quiet
)
/*++
Routine Description:
Return the DS values for one attribute in an object.
Arguments:
ldap - An open, bound ldap port.
Base - The "pathname" of a DS object.
DesiredAttr - Return values for this attribute.
Quiet
Return Value:
An array of char pointers that represents the values for the attribute.
The caller must free the array with ldap_value_free(). NULL if unsuccessful.
--*/
{
PWCHAR Attr;
BerElement *Ber;
PLDAPMessage LdapMsg;
PLDAPMessage LdapEntry;
PWCHAR Attrs[2];
PWCHAR *Values = NULL;
//
// Search Base for all of its attributes + values
//
Attrs[0] = DesiredAttr;
Attrs[1] = NULL;
//
// Issue the ldap search
//
if (!LdapSearch(Ldap, Dn, LDAP_SCOPE_BASE, CATEGORY_ANY,
Attrs, 0, &LdapMsg, Quiet)) {
return NULL;
}
LdapEntry = ldap_first_entry(Ldap, LdapMsg);
if (LdapEntry) {
Attr = ldap_first_attribute(Ldap, LdapEntry, &Ber);
if (Attr) {
Values = ldap_get_values(Ldap, LdapEntry, Attr);
}
}
ldap_msgfree(LdapMsg);
return Values;
}
VOID
GuidToStr(
IN GUID *pGuid,
OUT PWCHAR s
)
/*++
Routine Description:
Convert a GUID to a string.
Arguments:
pGuid - ptr to the GUID.
s - The output character buffer.
Must be at least GUID_CHAR_LEN (36 bytes) long.
Function Return Value:
None.
--*/
{
if (pGuid != NULL) {
swprintf(s, L"%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x",
pGuid->Data1,
pGuid->Data2,
pGuid->Data3,
pGuid->Data4[0],
pGuid->Data4[1],
pGuid->Data4[2],
pGuid->Data4[3],
pGuid->Data4[4],
pGuid->Data4[5],
pGuid->Data4[6],
pGuid->Data4[7]);
} else {
swprintf(s, L"<null>");
}
}
PWCHAR
GetRootDn(
IN PLDAP Ldap,
IN PWCHAR NamingContext
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
PWCHAR Root; // DS pathname of configuration container
PWCHAR *Values; // values from the attribute "namingContexts"
DWORD NumVals; // number of values
//
// Return all of the values for the attribute namingContexts
//
Values = GetValues(Ldap, CN_ROOT, ATTR_NAMING_CONTEXTS, FALSE);
if (Values == NULL)
return NULL;
//
// Find the naming context that begins with CN=Configuration
//
NumVals = ldap_count_values(Values);
while (NumVals--) {
_wcslwr(Values[NumVals]);
Root = wcsstr(Values[NumVals], NamingContext);
if (Root != NULL && Root == Values[NumVals]) {
Root = FrsWcsDup(Root);
ldap_value_free(Values);
return Root;
}
}
printf("ERROR - COULD NOT FIND %ws\n", NamingContext);
ldap_value_free(Values);
return NULL;
}
PWCHAR
ExtendDn(
IN PWCHAR Dn,
IN PWCHAR Cn
)
/*++
Routine Description:
Extend an existing DN with a new CN= component.
Arguments:
Dn - distinguished name
Cn - common name
Return Value:
CN=Cn,Dn
--*/
{
ULONG Len;
PWCHAR NewDn;
if (!Dn || !Cn) {
return NULL;
}
Len = wcslen(L"CN=,") + wcslen(Dn) + wcslen(Cn) + 1;
NewDn = (PWCHAR)malloc(Len * sizeof(WCHAR));
wcscpy(NewDn, L"CN=");
wcscat(NewDn, Cn);
wcscat(NewDn, L",");
wcscat(NewDn, Dn);
return NewDn;
}
PVOID *
FindValues(
IN PLDAP Ldap,
IN PLDAPMessage LdapEntry,
IN PWCHAR DesiredAttr,
IN BOOL DoBerValues
)
/*++
Routine Description:
Return the DS values for one attribute in an entry.
Arguments:
Ldap - An open, bound ldap port.
LdapEntry - An ldap entry returned by ldap_search_s()
DesiredAttr - Return values for this attribute.
DoVerValues - Return the bervals
Return Value:
An array of char pointers that represents the values for the attribute.
The caller must free the array with ldap_value_free(). NULL if unsuccessful.
--*/
{
PWCHAR LdapAttr; // Retrieved from an ldap entry
BerElement *Ber; // Needed for scanning attributes
//
// Search the entry for the desired attribute
//
for (LdapAttr = ldap_first_attribute(Ldap, LdapEntry, &Ber);
LdapAttr != NULL;
LdapAttr = ldap_next_attribute(Ldap, LdapEntry, Ber)) {
if (_wcsicmp(DesiredAttr, LdapAttr) == 0) {
//
// Return the values for DesiredAttr
//
if (DoBerValues) {
return (PVOID *)ldap_get_values_len(Ldap, LdapEntry, LdapAttr);
} else {
return (PVOID *)ldap_get_values(Ldap, LdapEntry, LdapAttr);
}
}
}
return NULL;
}
PWCHAR
FindValue(
IN PLDAP Ldap,
IN PLDAPMessage LdapEntry,
IN PWCHAR DesiredAttr
)
/*++
Routine Description:
Return a copy of the first DS value for one attribute in an entry.
Arguments:
Ldap - An open, bound ldap port.
LdapEntry - An ldap entry returned by ldap_search_s()
DesiredAttr - Return values for this attribute.
Return Value:
A zero-terminated string or NULL if the attribute or its value
doesn't exist. The string is freed with FREE_NO_HEADER().
--*/
{
PWCHAR Val;
PWCHAR *Values;
// Get ldap's array of values
Values = (PWCHAR *)FindValues(Ldap, LdapEntry, DesiredAttr, FALSE);
// Copy the first value (if any)
Val = (Values) ? FrsWcsDup(Values[0]) : NULL;
// Free ldap's array of values
ldap_value_free(Values);
return Val;
}
BOOL
FindBerValue(
IN PLDAP ldap,
IN PLDAPMessage Entry,
IN PWCHAR DesiredAttr,
OUT ULONG *Len,
OUT VOID **Value
)
/*++
Routine Description:
Return a copy of the attributes object's schedule
Arguments:
ldap - An open, bound ldap port.
Entry - An ldap entry returned by ldap_search_s()
DesiredAttr - desired attribute
Len - length of Value
Value - binary value
Return Value:
The address of a schedule or NULL. Free with FrsFree().
--*/
{
PLDAP_BERVAL *Values;
PSCHEDULE Schedule;
*Len = 0;
*Value = NULL;
//
// Get ldap's array of values
//
Values = (PLDAP_BERVAL *)FindValues(ldap, Entry, DesiredAttr, TRUE);
if (!Values) {
return FALSE;
}
//
// Return a copy of the schedule
//
*Len = Values[0]->bv_len;
if (*Len) {
*Value = (PWCHAR)malloc(*Len);
CopyMemory(*Value, Values[0]->bv_val, *Len);
}
ldap_value_free_len(Values);
return TRUE;
}
VOID
DumpValues(
IN PLDAP Ldap,
IN PWCHAR Dn,
IN DWORD Scope,
IN PWCHAR Class,
IN PWCHAR Attrs[],
IN BOOL IfEmpty
)
/*++
Routine Description:
Print the values and attributes for an object in the DS.
Arguments:
ldap - An open, bound ldap port.
Base - The "pathname" of a DS object.
Scope - Dump the values about the object (LDAP_SCOPE_BASE) or
about the objects contained in this object (LDAP_SCOPE_ONELEVEL)
Return Value:
None.
--*/
{
PWCHAR Attr; // Retrieved from an ldap entry
BerElement *Ber; // Needed for scanning attributes
PLDAPMessage Msg; // Opaque stuff from ldap subsystem
PLDAPMessage Entry; // Opaque stuff from ldap subsystem
PWCHAR *Values; // Array of values for desired attribute
PLDAP_BERVAL *Balues; // Array of values for desired attribute
DWORD NumVals; // Number of entries in Values
PWCHAR Rdn; // An entries "pathname" in the DS
WCHAR GuidStr[GUID_CHAR_LEN + 1];
PWCHAR EntryDn;
ULONG i;
//
// Search Base for all of the attributes + values of Class
//
if (!LdapSearch(Ldap, Dn, Scope, Class,
Attrs, 0, &Msg, !IfEmpty)) {
return;
}
//
// Scan the entries returned from ldap_search
//
for (Entry = ldap_first_entry(Ldap, Msg);
Entry != NULL;
Entry = ldap_next_entry(Ldap, Entry)) {
EntryDn = FindValue(Ldap, Entry, ATTR_DN);
if (EntryDn) {
Attr = ldap_first_attribute(Ldap, Entry, &Ber);
if (Attr) {
Attr = ldap_next_attribute(Ldap, Entry, Ber);
}
if (!IfEmpty && !Attr) {
continue;
}
Rdn = MakeRdn(EntryDn);
printf("%ws\n", Rdn);
FREE(EntryDn);
FREE(Rdn);
} else {
Attr = ldap_first_attribute(Ldap, Entry, &Ber);
if (!IfEmpty && !Attr) {
continue;
}
printf("Entry has no distinguished name\n");
}
//
// Scan the attributes of an entry
//
for (Attr = ldap_first_attribute(Ldap, Entry, &Ber);
Attr != NULL;
Attr = ldap_next_attribute(Ldap, Entry, Ber)) {
//
// Printed above; don't repeat
//
if (!wcscmp(Attr, ATTR_DN)) {
continue;
}
//
// Print the values
//
printf(" %ws\n", Attr);
for (i = 0; GuidAttrs[i]; ++i) {
if (!wcscmp(Attr, GuidAttrs[i])) {
Balues = ldap_get_values_len(Ldap, Entry, Attr);
NumVals = ldap_count_values_len(Balues);
if (NumVals) {
GuidToStr((GUID *)Balues[0]->bv_val, GuidStr);
printf(" Length %d; %ws\n",
Balues[0]->bv_len, GuidStr);
}
ldap_value_free_len(Balues);
break;
}
}
if (GuidAttrs[i]) {
continue;
}
for (i = 0; BerAttrs[i]; ++i) {
if (!wcscmp(Attr, BerAttrs[i])) {
Balues = ldap_get_values_len(Ldap, Entry, Attr);
NumVals = ldap_count_values_len(Balues);
if (NumVals) {
printf(" Length %d\n",
Balues[0]->bv_len);
}
ldap_value_free_len(Balues);
break;
}
}
if (BerAttrs[i]) {
continue;
}
if (!wcscmp(Attr, L"schedule")) {
Balues = ldap_get_values_len(Ldap, Entry, Attr);
NumVals = ldap_count_values_len(Balues);
if (NumVals) {
printf(" Length %d; Number %d\n",
NumVals,
Balues[0]->bv_len,
((PSCHEDULE)(Balues[0]->bv_val))->NumberOfSchedules);
}
ldap_value_free_len(Balues);
continue;
}
Values = ldap_get_values(Ldap, Entry, Attr);
NumVals = ldap_count_values(Values);
while (NumVals--) {
printf(" %ws\n", Values[NumVals]);
}
ldap_value_free(Values);
}
}
ldap_msgfree(Msg);
}
DWORD
GetDnsName(
IN PWCHAR Server,
OUT PWCHAR *DnsName
)
/*++
Routine Description:
Retrieve this machine's DNS name.
Arguments:
Server
DnsName - wide char version of dns name
Return Value:
WSA Status
--*/
{
INT SStatus;
WORD DnsVersion = MAKEWORD(1, 1);
struct hostent *Host;
WSADATA WSAData;
PCHAR DnsNameA;
PCHAR ServerA;
*DnsName = NULL;
//
// Get this machine's DNS name
//
//
// Initialize the socket subsystem
//
if (SStatus = WSAStartup(DnsVersion, &WSAData)) {
fprintf(stderr, "Can't get DNS name; Socket startup error %d\n",
SStatus);
return SStatus;
};
//
// Get the DNS name
//
ServerA = FrsWtoA(Server);
Host = gethostbyname(ServerA);
FREE(ServerA);
if (Host == NULL) {
SStatus = WSAGetLastError();
fprintf(stderr, "Can't get DNS name for %ws; gethostbyname error %d\n",
Server, SStatus);
return SStatus;
}
if (Host->h_name == NULL) {
fprintf(stderr, "DNS name for %ws is NULL\n", Server);
return WSAEFAULT;
}
//
// Return both the ASCII and UNICODE versions
//
*DnsName = FrsAtoW(Host->h_name);
WSACleanup();
return 0;
}
PWCHAR
GetNextDn(
IN PLDAP Ldap,
PLDAPMessage LdapEntry,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR Cn = NULL;
PWCHAR Dn = NULL;
Cn = FindValue(Ldap, LdapEntry, ATTR_CN);
if (Cn) {
Dn = ExtendDn(ParentDn, Cn);
FREE(Cn)
}
return Dn;
}
PWCHAR
DumpAttrs(
IN PLDAP Ldap,
PLDAPMessage LdapEntry,
IN PWCHAR ParentDn,
IN PWCHAR *Attrs,
IN PWCHAR Indent
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
DWORD NumVals;
ULONG ScheduleLen;
ULONG ExtensionsLen;
PSCHEDULE Schedule = NULL;
PCHAR Extensions = NULL;
PWCHAR Val = NULL;
PWCHAR Rdn = NULL;
PWCHAR Pdn = NULL;
PWCHAR PRdn = NULL;
PWCHAR *Values = NULL;
if (!Attrs) {
return NULL;
}
while (*Attrs) {
//
// Don't bother, the Cn will do
//
if (!wcscmp(*Attrs, ATTR_DN)) {
++Attrs;
continue;
}
if (!wcscmp(*Attrs, ATTR_COMPUTER_REF_BL)) {
Values = ldap_get_values(Ldap, LdapEntry, *Attrs);
NumVals = ldap_count_values(Values);
while (NumVals--) {
Rdn = MakeRdn(Values[NumVals]);
Pdn = FrsDsMakeParentDn(Values[NumVals]);
PRdn = MakeRdn(Pdn);
printf(" %ws%ws=%ws\\%ws\n", Indent, *Attrs, PRdn, Rdn);
FREE(Rdn);
FREE(Pdn);
FREE(PRdn);
}
ldap_value_free(Values);
} else if (!wcscmp(*Attrs, ATTR_SCHEDULE)) {
FindBerValue(Ldap,
LdapEntry,
ATTR_SCHEDULE,
&ScheduleLen,
(VOID **)&Schedule);
if (Schedule) {
// PrintShortSchedule(Indent, Schedule, ScheduleLen);
PrintLongSchedule(L" ", Indent, Schedule, ScheduleLen);
FREE(Schedule);
} else {
printf(" %wsSchedule=\n", Indent);
}
} else if (!wcscmp(*Attrs, ATTR_EXTENSIONS)) {
FindBerValue(Ldap,
LdapEntry,
ATTR_EXTENSIONS,
&ExtensionsLen,
(VOID **)&Extensions);
if (Extensions) {
FREE(Extensions);
printf(" %wsExtensions=%d\n", Indent, ExtensionsLen);
} else {
printf(" %wsExtensions=\n", Indent);
}
} else if (!wcscmp(*Attrs, ATTR_NAMING_CONTEXTS)) {
Values = ldap_get_values(Ldap, LdapEntry, *Attrs);
NumVals = ldap_count_values(Values);
while (NumVals--) {
printf(" %ws%ws=%ws\n", Indent, *Attrs, Values[NumVals]);
}
ldap_value_free(Values);
} else {
Val = FindValue(Ldap, LdapEntry, *Attrs);
if (Val) {
if (!wcscmp(*Attrs, ATTR_CN)) {
printf("%ws%ws\n", Indent, Val);
} else if (!wcscmp(*Attrs, ATTR_FROM_SERVER) ||
!wcscmp(*Attrs, ATTR_PRIMARY_MEMBER) ||
!wcscmp(*Attrs, ATTR_COMPUTER_REF) ||
!wcscmp(*Attrs, ATTR_COMPUTER_REF_BL) ||
!wcscmp(*Attrs, ATTR_MEMBER_REF) ||
!wcscmp(*Attrs, ATTR_MEMBER_REF_BL) ||
!wcscmp(*Attrs, ATTR_SERVER_REF_BL) ||
!wcscmp(*Attrs, ATTR_SERVER_REF)) {
Rdn = MakeRdn(Val);
Pdn = FrsDsMakeParentDn(Val);
PRdn = MakeRdn(Pdn);
printf(" %ws%ws=%ws\\%ws\n", Indent, *Attrs, PRdn, Rdn);
FREE(Rdn);
FREE(Pdn);
FREE(PRdn);
} else {
printf(" %ws%ws=%ws\n", Indent, *Attrs, Val);
}
FREE(Val);
} else {
printf(" %ws%ws=\n", Indent, *Attrs);
}
}
++Attrs;
}
return GetNextDn(Ldap, LdapEntry, ParentDn);
}
VOID
DumpCxtions(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
//
// Cxtions
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_FROM_SERVER;
DesiredAttrs[2] = ATTR_SCHEDULE;
DesiredAttrs[3] = ATTR_ENABLED_CXTION;
DesiredAttrs[4] = NULL;
if (LdapSearch(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_CXTION,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, ParentDn, DesiredAttrs, L" ");
if (NextDn) {
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
DumpMembers(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
//
// Servers
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_COMPUTER_REF;
DesiredAttrs[2] = ATTR_MEMBER_REF_BL;
DesiredAttrs[3] = ATTR_SERVER_REF;
DesiredAttrs[4] = NULL;
// DesiredAttrs[4] = ATTR_CONTROL_CREATION;
// DesiredAttrs[5] = ATTR_INBOUND_BACKLOG;
// DesiredAttrs[6] = ATTR_OUTBOUND_BACKLOG;
// DesiredAttrs[7] = ATTR_SERVICE_COMMAND;
// DesiredAttrs[8] = ATTR_UPDATE_TIMEOUT;
// DesiredAttrs[9] = ATTR_EXTENSIONS;
// DesiredAttrs[10] = ATTR_FLAGS;
// DesiredAttrs[11] = ATTR_AUTH_LEVEL;
DesiredAttrs[12] = NULL;
if (LdapSearch(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_MEMBER,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, ParentDn, DesiredAttrs, L" ");
if (NextDn) {
DumpCxtions(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
DumpSets(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
//
// Sets
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_PRIMARY_MEMBER;
DesiredAttrs[2] = ATTR_SET_TYPE;
DesiredAttrs[3] = ATTR_SCHEDULE;
DesiredAttrs[4] = ATTR_DIRECTORY_FILTER;
DesiredAttrs[5] = ATTR_FILE_FILTER;
DesiredAttrs[6] = NULL;
// DesiredAttrs[7] = ATTR_DS_POLL;
// DesiredAttrs[8] = ATTR_EXTENSIONS;
// DesiredAttrs[9] = ATTR_FLAGS;
// DesiredAttrs[10] = ATTR_LEVEL_LIMIT;
// DesiredAttrs[11] = ATTR_AUTH_LEVEL;
DesiredAttrs[12] = NULL;
if (LdapSearch(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_REPLICA_SET,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, ParentDn, DesiredAttrs, L" ");
if (NextDn) {
DumpMembers(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
DumpContexts(
IN PLDAP Ldap
)
/*++
Routine Description:
Dump every ds object related to replication
Arguments:
Ldap
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PWCHAR NextDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
//
// Setting
//
DesiredAttrs[0] = ATTR_NAMING_CONTEXTS;
DesiredAttrs[1] = ATTR_DEFAULT_NAMING_CONTEXT;
DesiredAttrs[2] = NULL;
if (LdapSearch(Ldap, CN_ROOT, LDAP_SCOPE_BASE, CATEGORY_ANY,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, CN_ROOT, DesiredAttrs, L"");
if (NextDn) {
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
DumpAdminWorld(
IN PLDAP Ldap
)
/*++
Routine Description:
Dump every ds object related to replication
Arguments:
Ldap
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PWCHAR ConfigDn = NULL;
PWCHAR ServicesDn = NULL;
PWCHAR NextDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
//
// Services
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return;
}
ServicesDn = ExtendDn(ConfigDn, CN_SERVICES);
//
// Setting
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = NULL;
// DesiredAttrs[1] = ATTR_EXTENSIONS;
DesiredAttrs[2] = NULL;
if (LdapSearch(Ldap, ServicesDn, LDAP_SCOPE_ONELEVEL, CATEGORY_NTFRS_SETTINGS,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, ServicesDn, DesiredAttrs, L"");
if (NextDn) {
DumpSets(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
FREE(ServicesDn);
FREE(ConfigDn);
}
VOID
DumpSubscribers(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
//
// Subscribers
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_REPLICA_ROOT;
DesiredAttrs[2] = ATTR_REPLICA_STAGE;
DesiredAttrs[3] = ATTR_MEMBER_REF;
DesiredAttrs[4] = ATTR_SCHEDULE;
DesiredAttrs[5] = NULL;
// DesiredAttrs[4] = ATTR_EXTENSIONS;
// DesiredAttrs[5] = ATTR_FAULT_CONDITION;
// DesiredAttrs[6] = ATTR_FLAGS;
// DesiredAttrs[7] = ATTR_SERVICE_COMMAND;
// DesiredAttrs[8] = ATTR_SERVICE_COMMAND_STATUS;
// DesiredAttrs[9] = ATTR_UPDATE_TIMEOUT;
DesiredAttrs[10] = NULL;
if (LdapSearch(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_SUBSCRIBER,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, ParentDn, DesiredAttrs, L" ");
if (NextDn) {
DumpSubscribers(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
DumpSubscriptions(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
//
// Servers
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_WORKING;
DesiredAttrs[2] = NULL;
// DesiredAttrs[2] = ATTR_EXTENSIONS;
// DesiredAttrs[3] = ATTR_VERSION;
DesiredAttrs[4] = NULL;
if (LdapSearch(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_SUBSCRIPTIONS,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, ParentDn, DesiredAttrs, L" ");
if (NextDn) {
DumpSubscribers(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
DumpUserWorld(
IN PLDAP Ldap
)
/*++
Routine Description:
Dump every ds object related to replication
Arguments:
Ldap
Return Value:
None.
--*/
{
DWORD WStatus;
PWCHAR DesiredAttrs[16];
DWORD NumVals;
PWCHAR *Values = NULL;
PWCHAR NextDn = NULL;
PWCHAR DefaultDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
HANDLE Handle = NULL;
DS_NAME_RESULT *Cracked = NULL;
WCHAR **Crackee;
PDOMAIN_CONTROLLER_INFO DcInfo;
//
// Return all of the values for the attribute namingContexts
//
Values = GetValues(Ldap, CN_ROOT, ATTR_DEFAULT_NAMING_CONTEXT, TRUE);
if (!Values) {
fprintf(stderr, "ERROR - Can't find %ws in %ws\n",
ATTR_DEFAULT_NAMING_CONTEXT,
CN_ROOT);
return;
}
DefaultDn = FrsWcsDup(Values[0]);
ldap_value_free(Values);
//
// Get Info about a Primary Domain Controller (need the IP address)
//
WStatus = FrsDsGetDcInfo(&DcInfo,
DS_DIRECTORY_SERVICE_REQUIRED | // Flags
DS_WRITABLE_REQUIRED);
//
// Report the error and carry on
//
if (!WIN_SUCCESS(WStatus)) {
fprintf(stderr, "ERROR - Could not get DC Info; WStatus %d\n",
WStatus);
} else {
WStatus = DsBind(DcInfo->DomainControllerName, NULL, &Handle);
if (!WIN_SUCCESS(WStatus)) {
fprintf(stderr, "ERROR - DsBind(%ws); WStatus %d %08x\n",
DcInfo->DomainControllerName,
WStatus,
WStatus);
WStatus = DsBind(DcInfo->DomainControllerAddress, NULL, &Handle);
if (!WIN_SUCCESS(WStatus)) {
fprintf(stderr, "ERROR - DsBind(%ws); WStatus %d %08x\n",
DcInfo->DomainControllerAddress,
WStatus,
WStatus);
} else {
printf("DsBind(%ws) succeeded\n", DcInfo->DomainControllerAddress);
}
} else {
printf("DsBind(%ws) succeeded\n", DcInfo->DomainControllerName);
}
}
//
// Find the naming context that begins with CN=Configuration
//
//
// Computers
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_SAM;
DesiredAttrs[2] = ATTR_DNS_HOST_NAME;
DesiredAttrs[3] = ATTR_DN;
DesiredAttrs[4] = ATTR_COMPUTER_REF_BL;
DesiredAttrs[5] = ATTR_SERVER_REF;
DesiredAttrs[6] = ATTR_SERVER_REF_BL;
DesiredAttrs[7] = ATTR_USER_ACCOUNT_CONTROL;
DesiredAttrs[8] = NULL;
if (LdapSearch(Ldap, DefaultDn, LDAP_SCOPE_SUBTREE, CATEGORY_COMPUTER,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, DefaultDn, DesiredAttrs, L"");
FREE(NextDn);
NextDn = FindValue(Ldap, LdapEntry, ATTR_DN);
if (NextDn && HANDLE_IS_VALID(Handle)) {
Crackee = &NextDn;
WStatus = DsCrackNames(Handle,
DS_NAME_NO_FLAGS,
// DS_NAME_FLAG_SYNTACTICAL_ONLY,
DS_FQDN_1779_NAME,
DS_NT4_ACCOUNT_NAME,
//DS_CANONICAL_NAME,
1,
Crackee,
&Cracked);
if (!WIN_SUCCESS(WStatus)) {
printf("ERROR - Cracking name; WStatus %d\n", WStatus);
} else if (Cracked &&
Cracked->cItems &&
Cracked->rItems) {
if (Cracked->rItems->status) {
printf(" ERROR - Can't crack name; status %d\n",
Cracked->rItems->status);
} else {
printf(" Cracked Domain : %ws\n",
Cracked->rItems->pDomain);
printf(" Cracked Account: %ws\n",
Cracked->rItems->pName);
}
DsFreeNameResult(Cracked);
Cracked = NULL;
}
}
if (NextDn) {
DumpSubscriptions(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
//out:
if (HANDLE_IS_VALID(Handle)) {
DsUnBind(&Handle);
}
FREE(DefaultDn);
}
VOID
DumpDsDsa(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
//
// Servers
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_DN;
DesiredAttrs[2] = ATTR_SCHEDULE;
DesiredAttrs[3] = ATTR_SERVER_REF;
DesiredAttrs[4] = NULL;
if (LdapSearch(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_NTDS_DSA,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, ParentDn, DesiredAttrs, L" ");
if (NextDn) {
DumpCxtions(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
DumpSysVolWorld(
IN PLDAP Ldap
)
/*++
Routine Description:
Arguments:
Ldap
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PWCHAR NextDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR ConfigDn = NULL;
PWCHAR SitesDn = NULL;
//
// Return all of the values for the attribute namingContexts
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return;
}
SitesDn = ExtendDn(ConfigDn, CN_SITES);
//
// Setting
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_DNS_HOST_NAME;
DesiredAttrs[2] = ATTR_DN;
DesiredAttrs[3] = ATTR_SERVER_REF;
DesiredAttrs[4] = ATTR_SERVER_REF_BL;
DesiredAttrs[5] = NULL;
if (LdapSearch(Ldap, SitesDn, LDAP_SCOPE_SUBTREE, CATEGORY_SERVER,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = DumpAttrs(Ldap, LdapEntry, SitesDn, DesiredAttrs, L"");
if (NextDn) {
FREE(NextDn);
}
NextDn = FindValue(Ldap, LdapEntry, ATTR_DN);
if (NextDn) {
DumpDsDsa(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
//out:
FREE(ConfigDn);
FREE(SitesDn);
}
VOID
ScriptCxtions(
IN PLDAP Ldap,
IN PWCHAR Set,
IN PWCHAR ServerDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
PWCHAR From = NULL;
PWCHAR Partner = NULL;
PWCHAR Partners = NULL;
PWCHAR Server = NULL;
PWCHAR Tmp = NULL;
Server = MakeRdn(ServerDn);
//
// Cxtions
//
DesiredAttrs[0] = ATTR_FROM_SERVER;
DesiredAttrs[1] = NULL;
if (LdapSearch(Ldap, ServerDn, LDAP_SCOPE_ONELEVEL, CATEGORY_CXTION,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
From = FindValue(Ldap, LdapEntry, ATTR_FROM_SERVER);
if (From) {
Partner = MakeRdn(From);
if (Partner) {
if (Partners) {
Tmp = Partners;
Partners = FrsWcsCat(Tmp, L" ");
FREE(Tmp);
Tmp = Partners;
Partners = FrsWcsCat(Tmp, Partner);
FREE(Tmp);
FREE(Partner);
} else {
Partners = Partner;
}
}
FREE(From);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
if (Partners) {
printf("dstree /i %ws %ws %ws\n", Set, Server, Partners);
}
FREE(Server);
}
VOID
GetRootAndStage(
IN PLDAP Ldap,
IN PWCHAR SubscriberDn,
OUT PWCHAR *Root,
OUT PWCHAR *Stage
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
*Root = NULL;
*Stage = NULL;
//
// Subscriber
//
DesiredAttrs[0] = ATTR_REPLICA_ROOT;
DesiredAttrs[1] = ATTR_REPLICA_STAGE;
DesiredAttrs[2] = NULL;
if (LdapSearch(Ldap, SubscriberDn, LDAP_SCOPE_BASE, CATEGORY_SUBSCRIBER,
DesiredAttrs, 0, &LdapMsg, TRUE)) {
LdapEntry = ldap_first_entry(Ldap, LdapMsg);
if (LdapEntry) {
*Root = FindValue(Ldap, LdapEntry, ATTR_REPLICA_ROOT);
*Stage = FindValue(Ldap, LdapEntry, ATTR_REPLICA_STAGE);
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
ScriptMembers(
IN PLDAP Ldap,
IN PWCHAR SetDn,
IN BOOL ScriptingServers
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
PWCHAR Set = NULL;
PWCHAR Cn = NULL;
PWCHAR Root = NULL;
PWCHAR Stage = NULL;
PWCHAR MemberBl = NULL;
Set = MakeRdn(SetDn);
//
// Servers
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = ATTR_REPLICA_ROOT;
DesiredAttrs[2] = ATTR_REPLICA_STAGE;
DesiredAttrs[3] = ATTR_MEMBER_REF_BL;
DesiredAttrs[4] = NULL;
if (LdapSearch(Ldap, SetDn, LDAP_SCOPE_ONELEVEL, CATEGORY_MEMBER,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
if (ScriptingServers) {
Cn = FindValue(Ldap, LdapEntry, ATTR_CN);
MemberBl = FindValue(Ldap, LdapEntry, ATTR_MEMBER_REF_BL);
if (MemberBl) {
GetRootAndStage(Ldap, MemberBl, &Root, &Stage);
}
if (Cn) {
if (Root && Stage) {
printf("dstree /c %ws %ws %ws %ws\n", Set, Cn, Root, Stage);
} else {
printf("dstree /c %ws %ws\n", Set, Cn);
}
FREE(Cn);
FREE(Root);
FREE(Stage);
FREE(MemberBl);
}
} else {
NextDn = GetNextDn(Ldap, LdapEntry, SetDn);
if (NextDn) {
ScriptCxtions(Ldap, Set, NextDn);
FREE(NextDn);
}
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
FREE(Set);
}
VOID
ScriptSets(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR NextDn = NULL;
//
// Sets
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = NULL;
if (LdapSearch(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_REPLICA_SET,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = GetNextDn(Ldap, LdapEntry, ParentDn);
if (NextDn) {
ScriptMembers(Ldap, NextDn, TRUE);
FREE(NextDn);
}
}
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = GetNextDn(Ldap,
LdapEntry,
ParentDn);
if (NextDn) {
ScriptMembers(Ldap, NextDn, FALSE);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
}
VOID
ScriptReplicationWorld(
VOID
)
/*++
Routine Description:
Arguments:
None.
Return Value:
None.
--*/
{
PWCHAR DesiredAttrs[16];
PLDAP Ldap = NULL;
PWCHAR ConfigDn = NULL;
PWCHAR ServicesDn = NULL;
PWCHAR NextDn = NULL;
PWCHAR SettingsDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
//
// Services
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return;
}
ServicesDn = ExtendDn(ConfigDn, CN_SERVICES);
SettingsDn = ExtendDn(ServicesDn, CN_TEST_SETTINGS);
ScriptSets(Ldap, SettingsDn);
#if 0
Don't script all of the settings; only the test settings
//
// Setting
//
DesiredAttrs[0] = ATTR_CN;
DesiredAttrs[1] = NULL;
if (LdapSearch(Ldap, ServicesDn, LDAP_SCOPE_ONELEVEL, CATEGORY_NTFRS_SETTINGS,
DesiredAttrs, 0, &LdapMsg, FALSE)) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = GetNextDn(Ldap, LdapEntry, ServicesDn);
if (NextDn) {
ScriptSets(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
LdapMsg = NULL;
}
#endif 0
ldap_unbind(Ldap);
FREE(ServicesDn);
FREE(ConfigDn);
FREE(SettingsDn);
}
VOID
DoListSchema(
IN PLDAP Ldap,
IN PWCHAR SchemaDn,
IN struct AlterClass *Lists[]
)
/*++
Routine Description:
Dump schema
Arguments:
None.
Return Value:
None.
--*/
{
ULONG i, j;
ULONG NumAttrs;
DWORD LStatus;
PWCHAR Attrs[64];
PWCHAR Dn = NULL;
for (j = 0; Lists[j]; ++j) {
Dn = ExtendDn(SchemaDn, Lists[j]->Cn);
NumAttrs = 0;
for (i = 0; Lists[j]->AlterAttrs[i].Attr; ++i) {
if (NumAttrs) {
if (!wcscmp(Attrs[NumAttrs - 1],
Lists[j]->AlterAttrs[i].Attr)) {
continue;
}
}
Attrs[NumAttrs++] = Lists[j]->AlterAttrs[i].Attr;
}
if (NumAttrs) {
Attrs[NumAttrs + 0] = ATTR_DN;
Attrs[NumAttrs + 1] = ATTR_SYSTEM_FLAGS;
Attrs[NumAttrs + 2] = ATTR_SYSTEM_MAY_CONTAIN;
Attrs[NumAttrs + 3] = ATTR_SYSTEM_MUST_CONTAIN;
Attrs[NumAttrs + 4] = ATTR_SYSTEM_POSS_SUPERIORS;
Attrs[NumAttrs + 5] = NULL;
DumpValues(Ldap, Dn, LDAP_SCOPE_BASE, CATEGORY_ANY, Attrs, FALSE);
}
FREE(Dn);
}
}
VOID
ListSchema(
VOID
)
/*++
Routine Description:
Dump schema
Arguments:
None.
Return Value:
None.
--*/
{
ULONG i, j;
ULONG NumAttrs;
DWORD LStatus;
PLDAP Ldap = NULL;
PWCHAR SchemaDn = NULL;
PWCHAR Dn = NULL;
LDAPMod **Mod = NULL;
PWCHAR Attrs[64];
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
SchemaDn = GetRootDn(Ldap, SCHEMA_NAMING_CONTEXT);
if (!SchemaDn) {
return;
}
DoListSchema(Ldap, SchemaDn, AlterSchema);
DoListSchema(Ldap, SchemaDn, CreateClasses);
DoListSchema(Ldap, SchemaDn, CreateAttributes);
ldap_unbind(Ldap);
FREE(SchemaDn);
}
VOID
CreateSchema(
IN PLDAP Ldap,
IN PWCHAR SchemaDn,
IN struct AlterClass *Creates[],
IN DWORD ExpectedError
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
DWORD LStatus;
ULONG i, j;
PWCHAR Dn = NULL;
LDAPMod **Mod = NULL;
//
// CREATE ATTRIBUTES OR CLASSES
//
for (j = 0; Creates[j]; ++j) {
Dn = ExtendDn(SchemaDn, Creates[j]->Cn);
printf(" %-30ws: CRE\n", Creates[j]->Cn);
for (i = 0; Creates[j]->AlterAttrs[i].Attr; ++i) {
AddMod(Creates[j]->AlterAttrs[i].Attr,
Creates[j]->AlterAttrs[i].Value,
&Mod);
}
LStatus = ldap_add_s(Ldap, Dn, Mod);
if (LStatus != LDAP_SUCCESS &&
LStatus != ExpectedError) {
fprintf(stderr, "%-30ws ERROR %ws\n",
L"", ldap_err2string(LStatus));
}
FreeMod(&Mod);
FREE(Dn);
}
}
VOID
UpdateSchema(
IN PLDAP Ldap,
IN PWCHAR SchemaDn,
IN BOOL Hammering,
IN struct AlterClass *Updates[]
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
DWORD LStatus;
ULONG i, j;
PWCHAR Dn = NULL;
LDAPMod **Mod = NULL;
//
// ALTER EXISTING CLASSES
//
for (j = 0; Updates[j]; ++j) {
Dn = ExtendDn(SchemaDn, Updates[j]->Cn);
for (i = 0; Updates[j]->AlterAttrs[i].Attr; ++i) {
AddMod(Updates[j]->AlterAttrs[i].Attr,
Updates[j]->AlterAttrs[i].Value,
&Mod);
if (Hammering) {
printf(" %-30ws: ADD %ws = %ws\n",
Updates[j]->Cn,
Updates[j]->AlterAttrs[i].Attr,
Updates[j]->AlterAttrs[i].Value);
LStatus = ldap_modify_s(Ldap, Dn, Mod);
if (LStatus != LDAP_SUCCESS &&
LStatus != LDAP_ATTRIBUTE_OR_VALUE_EXISTS) {
fprintf(stderr, "%-30ws ERROR %ws\n",
L"", ldap_err2string(LStatus));
}
} else {
printf(" %-30ws: DEL %ws = %ws\n",
Updates[j]->Cn,
Updates[j]->AlterAttrs[i].Attr,
Updates[j]->AlterAttrs[i].Value);
Mod[0]->mod_op = LDAP_MOD_DELETE;
LStatus = ldap_modify_s(Ldap, Dn, Mod);
if (LStatus != LDAP_SUCCESS &&
LStatus != LDAP_NO_SUCH_ATTRIBUTE &&
LStatus != LDAP_NO_SUCH_OBJECT) {
fprintf(stderr, "%-30ws ERROR %ws\n",
L"", ldap_err2string(LStatus));
}
}
FreeMod(&Mod);
}
FREE(Dn);
}
}
VOID
DeleteSchema(
IN PLDAP Ldap,
IN PWCHAR SchemaDn,
IN struct AlterClass *Deletes[],
IN DWORD ExpectedError
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
PWCHAR Dn = NULL;
DWORD LStatus;
ULONG j;
//
// DELETE ATTRIBUTES OR CLASSES
//
for (j = 0; Deletes[j]; ++j) {
Dn = ExtendDn(SchemaDn, Deletes[j]->Cn);
printf(" %-30ws: DEL\n", Deletes[j]->Cn);
LStatus = ldap_delete_s(Ldap, Dn);
if (LStatus != LDAP_SUCCESS &&
LStatus != ExpectedError) {
fprintf(stderr, "%-30ws ERROR %ws\n",
L"", ldap_err2string(LStatus));
}
FREE(Dn);
}
}
VOID
RefreshSchema(
IN PLDAP Ldap
)
/*++
Routine Description:
Arguments:
None.
Return Value:
None.
--*/
{
DWORD LStatus;
LDAPMod **Mod = NULL;
AddMod(L"schemaUpdateNow", L"1", &Mod);
LStatus = ldap_modify_s(Ldap, L"", Mod);
FreeMod(&Mod);
if (LStatus != LDAP_SUCCESS) {
fprintf(stderr, "Can't force schema update; %ws\n",
ldap_err2string(LStatus));
printf("Waiting 5 minutes for schema updates to take effect\n");
Sleep(5 * 60 * 1000);
}
}
#define NTDS_SERVICE L"NTDS"
#define NTDS_ROOT L"System\\CurrentControlSet\\Services\\" NTDS_SERVICE
#define NTDS_PARAMETERS NTDS_ROOT L"\\Parameters"
#define NTDS_UPDATE_SCHEMA L"Schema Update Allowed"
#define NTDS_DELETE_SCHEMA L"Schema Delete Allowed"
BOOL
PutRegDWord(
IN PWCHAR FQKey,
IN PWCHAR Value,
IN DWORD DWord
)
/*++
Routine Description:
This function writes a keyword value into the registry.
Arguments:
HKey - Key to be read
Param - value string to update
DWord - dword to be written
Return Value:
TRUE - Success
FALSE - Not
--*/
{
#define DEBSUB "PutRegDWord:"
HKEY HKey;
DWORD WStatus;
//
// Open the key
//
WStatus = RegOpenKey(HKEY_LOCAL_MACHINE, FQKey, &HKey);
if (!WIN_SUCCESS(WStatus)) {
fprintf(stderr, "[%ws] \"%ws\" Could not open. WStatus %d\n",
FQKey, Value, WStatus);
return FALSE;
}
//
//
// Write the value
//
WStatus = RegSetValueEx(HKey,
Value,
0,
REG_DWORD,
(PUCHAR)&DWord,
sizeof(DWord));
if (!WIN_SUCCESS(WStatus)) {
fprintf(stderr, "%ws: Value not written; WStatus %d\n", Value, WStatus);
return FALSE;
}
return TRUE;
}
VOID
HammerSchema(
IN BOOL Hammering
)
/*++
Routine Description:
Arguments:
None.
Return Value:
None.
--*/
{
DWORD LStatus;
PLDAP Ldap = NULL;
PWCHAR SchemaDn = NULL;
PWCHAR Dn = NULL;
LDAPMod **Mod = NULL;
ULONG i, j;
if (Hammering) {
printf("UPDATING SCHEMA...\n");
if (!PutRegDWord(NTDS_PARAMETERS, NTDS_UPDATE_SCHEMA, 1)) {
fprintf(stderr, "Could not enable schema update\n");
return;
}
} else {
printf("RESTORING SCHEMA...\n");
if (!PutRegDWord(NTDS_PARAMETERS, NTDS_UPDATE_SCHEMA, 1)) {
fprintf(stderr, "Could not enable schema update\n");
return;
}
if (!PutRegDWord(NTDS_PARAMETERS, NTDS_DELETE_SCHEMA, 1)) {
fprintf(stderr, "Could not enable schema deletes\n");
return;
}
}
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
SchemaDn = GetRootDn(Ldap, SCHEMA_NAMING_CONTEXT);
if (!SchemaDn) {
return;
}
//
// CREATE/DELETE ATTRIBUTES AND CLASSES
//
if (Hammering) {
CreateSchema(Ldap,
SchemaDn,
CreateAttributes,
LDAP_ALREADY_EXISTS);
RefreshSchema(Ldap);
CreateSchema(Ldap,
SchemaDn,
CreateClasses,
LDAP_ALREADY_EXISTS);
RefreshSchema(Ldap);
UpdateSchema(Ldap,
SchemaDn,
Hammering,
AlterSchema);
} else {
UpdateSchema(Ldap,
SchemaDn,
Hammering,
AlterSchema);
RefreshSchema(Ldap);
DeleteSchema(Ldap,
SchemaDn,
CreateClasses,
LDAP_NO_SUCH_OBJECT);
RefreshSchema(Ldap);
DeleteSchema(Ldap,
SchemaDn,
CreateAttributes,
LDAP_NO_SUCH_OBJECT);
}
RefreshSchema(Ldap);
if (Hammering) {
printf("SCHEMA UPDATE COMPLETE\n");
} else {
printf("SCHEMA RESTORE COMPLETE\n");
}
ldap_unbind(Ldap);
FREE(SchemaDn);
return;
}
PWCHAR
GetCoDn(
IN PLDAP Ldap,
IN PWCHAR Member,
OUT PWCHAR *ServerDn
)
/*++
Routine Description:
Find the computer object for Member
Arguments:
Ldap
Member
ServerDn
Return Value:
Dn of computer object or NULL. Free with FREE.
--*/
{
PWCHAR *Values = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PWCHAR CoDn = NULL;
PWCHAR Attrs[16];
WCHAR Filter[MAX_PATH + 1];
//
// Find the default naming context
//
Values = GetValues(Ldap, CN_ROOT, ATTR_DEFAULT_NAMING_CONTEXT, TRUE);
if (!Values) {
return NULL;
}
//
// Find the computer object with class=computer
//
swprintf(Filter,
L"(&%s(sAMAccountName=%s$))",
CATEGORY_COMPUTER,
Member);
Attrs[0] = ATTR_DN;
Attrs[1] = ATTR_SERVER_REF;
Attrs[2] = ATTR_SERVER_REF_BL;
Attrs[3] = NULL;
if (LdapSearch(Ldap, Values[0], LDAP_SCOPE_SUBTREE, Filter,
Attrs, 0, &LdapMsg, FALSE)) {
LdapEntry = ldap_first_entry(Ldap, LdapMsg);
if (LdapEntry) {
CoDn = FindValue(Ldap, LdapEntry, ATTR_DN);
if (ServerDn) {
*ServerDn = FindValue(Ldap, LdapEntry, ATTR_SERVER_REF_BL);
if (!*ServerDn) {
*ServerDn = FindValue(Ldap, LdapEntry, ATTR_SERVER_REF);
}
}
}
ldap_msgfree(LdapMsg);
}
if (CoDn) {
return CoDn;
}
//
// Find the computer object with class=computer (possible after
// an NT4 to NT5 upgrade.
//
swprintf(Filter,
L"(&%s(sAMAccountName=%s$))",
CATEGORY_USER,
Member);
Attrs[0] = ATTR_DN;
Attrs[1] = ATTR_SERVER_REF;
Attrs[2] = ATTR_SERVER_REF_BL;
Attrs[3] = NULL;
if (LdapSearch(Ldap, Values[0], LDAP_SCOPE_SUBTREE, Filter,
Attrs, 0, &LdapMsg, FALSE)) {
LdapEntry = ldap_first_entry(Ldap, LdapMsg);
if (LdapEntry) {
CoDn = FindValue(Ldap, LdapEntry, ATTR_DN);
if (ServerDn) {
*ServerDn = FindValue(Ldap, LdapEntry, ATTR_SERVER_REF_BL);
if (!*ServerDn) {
*ServerDn = FindValue(Ldap, LdapEntry, ATTR_SERVER_REF);
}
}
}
ldap_msgfree(LdapMsg);
}
ldap_value_free(Values);
return CoDn;
}
PWCHAR
GetSiteName(
IN PWCHAR Member
)
/*++
Routine Description:
Retrieve this machine's site name. We assume the site name
matches the site container's name in the DS.
Arguments:
Member - corresponds to site container's name
Return Value:
Site name or NULL. Free with FREE.
--*/
{
DWORD WStatus;
PWCHAR Name;
PWCHAR Site;
//
// Get this machine's DNS name
//
WStatus = DsGetSiteName(Member, &Name);
if (!WIN_SUCCESS(WStatus)) {
return NULL;
}
Site = FrsWcsDup(Name);
NetApiBufferFree(Name);
return Site;
}
PWCHAR
GetServerDn(
IN PLDAP Ldap,
IN PWCHAR Member
)
/*++
Routine Description:
Find our server object (assumes that machine name == server name)
Arguments:
Ldap
Member
Return Value:
Server DN (if any)
--*/
{
PWCHAR *Values = NULL;
PWCHAR ConfigDn = NULL;
PWCHAR SitesDn = NULL;
PWCHAR Site = NULL;
PWCHAR SiteDn = NULL;
PWCHAR ServersDn = NULL;
PWCHAR ServerDn = NULL;
PWCHAR SettingsDn = NULL;
PWCHAR RealServerDn = NULL;
//
// Return all of the values for the attribute namingContexts
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return NULL;
}
SitesDn = ExtendDn(ConfigDn, CN_SITES);
Site = GetSiteName(Member);
if (!Site) {
goto out;
}
SiteDn = ExtendDn(SitesDn, Site);
ServersDn = ExtendDn(SiteDn, CN_SERVERS);
ServerDn = ExtendDn(ServersDn, Member);
SettingsDn = ExtendDn(ServerDn, CN_NTDS_SETTINGS);
Values = GetValues(Ldap, SettingsDn, ATTR_DN, TRUE);
if (!Values) {
goto out;
}
RealServerDn = FrsWcsDup(Values[0]);
out:
FREE(ConfigDn);
FREE(SitesDn);
FREE(SiteDn);
FREE(Site);
FREE(ServersDn);
FREE(ServerDn);
FREE(SettingsDn);
return RealServerDn;
}
#define SIZEOF_EXTENSIONS 127
VOID
CreateReplicationWorld(
IN DWORD argc,
IN PWCHAR *Argv,
IN BOOL IsPrimary
)
/*++
Routine Description:
Create the required objects
Arguments:
Return Value:
None.
--*/
{
DWORD WStatus;
DWORD LStatus;
ULONG ScheduleLength;
PWCHAR Member;
PWCHAR Set;
PWCHAR Root;
PWCHAR Stage;
GUID NewGuid;
GUID OldGuid;
CHAR Extensions[SIZEOF_EXTENSIONS];
PLDAP Ldap = NULL;
PWCHAR CoDn = NULL;
PWCHAR SubsDn = NULL;
PWCHAR SubDn = NULL;
PWCHAR Subscriber = NULL;
PWCHAR ConfigDn = NULL;
PWCHAR ServerDn = NULL;
PWCHAR ServicesDn = NULL;
PWCHAR SettingsDn = NULL;
PWCHAR SetDn = NULL;
PWCHAR MemberDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PSCHEDULE Schedule = NULL;
PWCHAR Cn = NULL;
LDAPMod **Mod = NULL;
Set = Argv[2];
if (argc > 2) {
Member = Argv[3];
}
if (argc > 3) {
Root = Argv[4];
Stage = Argv[5];
}
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
//
// ADMIN SIDE
//
//
// Services Dn
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return;
}
ServicesDn = ExtendDn(ConfigDn, CN_SERVICES);
SettingsDn = ExtendDn(ServicesDn, CN_TEST_SETTINGS);
//
// Settings
//
UuidCreateNil(&OldGuid);
AddMod(ATTR_CLASS, ATTR_NTFRS_SETTINGS, &Mod);
// AddBerMod(ATTR_EXTENSIONS, Extensions, SIZEOF_EXTENSIONS, &Mod);
LStatus = ldap_add_s(Ldap, SettingsDn, Mod);
FreeMod(&Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
//
// May be a new schema that lacks the old version guid
//
AddBerMod(ATTR_OLD_VERSION_GUID, (PCHAR)&OldGuid, sizeof(GUID), &Mod);
AddMod(ATTR_CLASS, ATTR_NTFRS_SETTINGS, &Mod);
// AddBerMod(ATTR_EXTENSIONS, Extensions, sizeof(SIZEOF_EXTENSIONS), &Mod);
LStatus = ldap_add_s(Ldap, SettingsDn, Mod);
FreeMod(&Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't create %ws: %ws\n",
SettingsDn, ldap_err2string(LStatus));
goto out;
}
}
//
// Set
//
SetDn = ExtendDn(SettingsDn, Set);
AddMod(ATTR_CLASS, ATTR_REPLICA_SET, &Mod);
AddMod(ATTR_SET_TYPE, FRS_RSTYPE_OTHERW, &Mod);
// AddMod(ATTR_DIRECTORY_FILTER, ATTR_DIRECTORY_FILTER, &Mod);
// AddMod(ATTR_FILE_FILTER, ATTR_FILE_FILTER, &Mod);
// AddMod(ATTR_DS_POLL, L"17", &Mod);
// AddMod(ATTR_FLAGS, L"18", &Mod);
// AddMod(ATTR_LEVEL_LIMIT, L"18", &Mod);
// AddMod(ATTR_AUTH_LEVEL, L"18", &Mod);
// AddBerMod(ATTR_EXTENSIONS, Extensions, SIZEOF_EXTENSIONS, &Mod);
// AddBerMod(ATTR_NEW_SET_GUID, (PCHAR)&NewGuid, sizeof(GUID), &Mod);
// AddBerMod(ATTR_NEW_VERSION_GUID, (PCHAR)&NewGuid, sizeof(GUID), &Mod);
ConditionalBuildSchedule(&Schedule, &ScheduleLength);
if (Schedule) {
AddBerMod(ATTR_SCHEDULE, (PCHAR)Schedule, ScheduleLength, &Mod);
}
LStatus = ldap_add_s(Ldap, SetDn, Mod);
FreeMod(&Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
//
// May be a new schema that lacks the old set guid
//
AddMod(ATTR_CLASS, ATTR_REPLICA_SET, &Mod);
AddMod(ATTR_SET_TYPE, FRS_RSTYPE_OTHERW, &Mod);
// AddMod(ATTR_DIRECTORY_FILTER, ATTR_DIRECTORY_FILTER, &Mod);
// AddMod(ATTR_FILE_FILTER, ATTR_FILE_FILTER, &Mod);
// AddMod(ATTR_DS_POLL, L"17", &Mod);
// AddMod(ATTR_FLAGS, L"18", &Mod);
// AddMod(ATTR_LEVEL_LIMIT, L"18", &Mod);
// AddMod(ATTR_AUTH_LEVEL, L"18", &Mod);
// AddBerMod(ATTR_EXTENSIONS, Extensions, SIZEOF_EXTENSIONS, &Mod);
AddBerMod(ATTR_OLD_SET_GUID, (PCHAR)&OldGuid, sizeof(GUID), &Mod);
AddBerMod(ATTR_NEW_SET_GUID, (PCHAR)&NewGuid, sizeof(GUID), &Mod);
AddBerMod(ATTR_NEW_VERSION_GUID, (PCHAR)&NewGuid, sizeof(GUID), &Mod);
ConditionalBuildSchedule(&Schedule, &ScheduleLength);
if (Schedule) {
AddBerMod(ATTR_SCHEDULE, (PCHAR)Schedule, ScheduleLength, &Mod);
}
LStatus = ldap_add_s(Ldap, SetDn, Mod);
FreeMod(&Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't create %ws: %ws\n",
SetDn, ldap_err2string(LStatus));
goto out;
}
}
if (argc < 4) {
goto out;
}
//
// Member
//
CoDn = GetCoDn(Ldap, Member, &ServerDn);
if (!CoDn) {
fprintf(stderr, "ERROR - Can't get computer object for %ws\n", Member);
goto out;
}
//
// The CO doesn't have a server reference; create one
//
if (!ServerDn) {
ServerDn = GetServerDn(Ldap, Member);
if (ServerDn) {
AddMod(ATTR_SERVER_REF, ServerDn, &Mod);
LStatus = ldap_modify_s(Ldap, CoDn, Mod);
FreeMod(&Mod);
if (LStatus != LDAP_ATTRIBUTE_OR_VALUE_EXISTS &&
LStatus != LDAP_SUCCESS) {
AddMod(ATTR_SERVER_REF, CoDn, &Mod);
LStatus = ldap_modify_s(Ldap, ServerDn, Mod);
FreeMod(&Mod);
if (LStatus != LDAP_ATTRIBUTE_OR_VALUE_EXISTS &&
LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't update server reference for %ws: %ws\n",
CoDn, ldap_err2string(LStatus));
fprintf(stderr, "ERROR - Server %ws\n", ServerDn);
FREE(ServerDn);
}
}
}
}
MemberDn = ExtendDn(SetDn, Member);
AddMod(ATTR_CLASS, ATTR_MEMBER, &Mod);
AddMod(ATTR_COMPUTER_REF, CoDn, &Mod);
// AddMod(ATTR_CONTROL_CREATION, ATTR_CONTROL_CREATION, &Mod);
// AddMod(ATTR_INBOUND_BACKLOG, ATTR_INBOUND_BACKLOG, &Mod);
// AddMod(ATTR_OUTBOUND_BACKLOG, ATTR_OUTBOUND_BACKLOG, &Mod);
// AddMod(ATTR_SERVICE_COMMAND, ATTR_SERVICE_COMMAND, &Mod);
// AddMod(ATTR_UPDATE_TIMEOUT, L"50", &Mod);
// AddMod(ATTR_AUTH_LEVEL, L"18", &Mod);
// AddMod(ATTR_FLAGS, L"3", &Mod);
// AddBerMod(ATTR_EXTENSIONS, Extensions, SIZEOF_EXTENSIONS, &Mod);
if (ServerDn) {
AddMod(ATTR_SERVER_REF, ServerDn, &Mod);
}
LStatus = ldap_add_s(Ldap, MemberDn, Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't create %ws: %ws\n",
MemberDn, ldap_err2string(LStatus));
goto out;
}
FreeMod(&Mod);
//
// Primary member reference on set
//
if (IsPrimary) {
AddMod(ATTR_PRIMARY_MEMBER, MemberDn, &Mod);
Mod[0]->mod_op = LDAP_MOD_REPLACE;
LStatus = ldap_modify_s(Ldap, SetDn, Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't set primary member to %ws for %ws: %ws\n",
MemberDn, SetDn, ldap_err2string(LStatus));
goto out;
}
FreeMod(&Mod);
}
//
// USER SIDE
//
//
// Subscriptions
//
SubsDn = ExtendDn(CoDn, CN_SUBSCRIPTIONS);
AddMod(ATTR_CLASS, ATTR_SUBSCRIPTIONS, &Mod);
// AddMod(ATTR_WORKING, L"%SystemRoot%\\ntfrs", &Mod);
// AddMod(ATTR_VERSION, ATTR_VERSION, &Mod);
// AddBerMod(ATTR_EXTENSIONS, Extensions, SIZEOF_EXTENSIONS, &Mod);
LStatus = ldap_add_s(Ldap, SubsDn, Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't create %ws: %ws\n",
SubsDn, ldap_err2string(LStatus));
goto out;
}
FreeMod(&Mod);
//
// Subscriber
//
Subscriber = FrsWcsCat(Set, Member);
SubDn = ExtendDn(SubsDn, Subscriber);
AddMod(ATTR_CLASS, ATTR_SUBSCRIBER, &Mod);
AddMod(ATTR_REPLICA_ROOT, Root, &Mod);
AddMod(ATTR_REPLICA_STAGE, Stage, &Mod);
AddMod(ATTR_MEMBER_REF, MemberDn, &Mod);
// AddBerMod(ATTR_EXTENSIONS, Extensions, SIZEOF_EXTENSIONS, &Mod);
// AddMod(ATTR_FAULT_CONDITION, L"NONE", &Mod);
// AddMod(ATTR_FLAGS, L"1", &Mod);
// AddMod(ATTR_SERVICE_COMMAND, ATTR_SERVICE_COMMAND, &Mod);
// AddMod(ATTR_SERVICE_COMMAND_STATUS, L"100", &Mod);
// AddMod(ATTR_UPDATE_TIMEOUT, L"100", &Mod);
ConditionalBuildSchedule(&Schedule, &ScheduleLength);
if (Schedule) {
AddBerMod(ATTR_SCHEDULE, (PCHAR)Schedule, ScheduleLength, &Mod);
FREE(Schedule);
}
LStatus = ldap_add_s(Ldap, SubDn, Mod);
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't create %ws: %ws\n",
SubDn, ldap_err2string(LStatus));
goto out;
}
FreeMod(&Mod);
out:
ldap_unbind(Ldap);
if (LdapMsg) {
ldap_msgfree(LdapMsg);
}
FREE(Schedule);
FREE(Cn);
FREE(ConfigDn);
FREE(ServicesDn);
FREE(SetDn);
FREE(SettingsDn);
FREE(MemberDn);
FREE(CoDn);
FREE(SubsDn);
FREE(Subscriber);
FREE(SubDn);
FREE(ServerDn);
FreeMod(&Mod);
}
PWCHAR DupNames[] = {L"_A", L"_B", L"_C", L"_D", L"_E", L"_F", L"_G", L"_H", NULL};
VOID
CreateInbounds(
IN DWORD argc,
IN WCHAR **Argv
)
/*++
Routine Description:
Arguments:
Return Value:
None.
--*/
{
ULONG i;
DWORD LStatus;
ULONG ScheduleLength;
ULONG dupx;
PLDAP Ldap = NULL;
PWCHAR Cxtion = NULL;
PWCHAR ConfigDn = NULL;
PWCHAR ServicesDn = NULL;
PWCHAR SettingsDn = NULL;
PWCHAR SetDn = NULL;
PWCHAR ServerDn = NULL;
PWCHAR CxtionDn = NULL;
PWCHAR CxtionDnDup = NULL;
PWCHAR PartnerDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
PSCHEDULE Schedule = NULL;
LDAPMod **Mod = NULL;
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
//
// Server Dn
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return;
}
ServicesDn = ExtendDn(ConfigDn, CN_SERVICES);
SettingsDn = ExtendDn(ServicesDn, CN_TEST_SETTINGS);
SetDn = ExtendDn(SettingsDn, Argv[2]);
ServerDn = ExtendDn(SetDn, Argv[3]);
for (i = 4; i < argc; ++i) {
PartnerDn = ExtendDn(SetDn, Argv[i]);
Cxtion = FrsWcsCat(L"From_", Argv[i]);
CxtionDn = ExtendDn(ServerDn, Cxtion);
FREE(Cxtion);
//
// Inbounds
//
AddMod(ATTR_CLASS, ATTR_CXTION, &Mod);
AddMod(ATTR_FROM_SERVER, PartnerDn, &Mod);
AddMod(ATTR_ENABLED_CXTION, ATTR_TRUE, &Mod);
AddMod(ATTR_OPTIONS, ATTR_OPTIONS_0, &Mod);
ConditionalBuildSchedule(&Schedule, &ScheduleLength);
if (Schedule) {
AddBerMod(ATTR_SCHEDULE, (PCHAR)Schedule, ScheduleLength, &Mod);
FREE(Schedule);
}
LStatus = ldap_add_s(Ldap, CxtionDn, Mod);
dupx = 0;
while ((LStatus == LDAP_ALREADY_EXISTS) && (DupNames[dupx] != NULL)) {
//
// Try to create a duplicate connection object by putting a suffix on the name.
//
Cxtion = FrsWcsCat(L"From_", Argv[i]);
CxtionDnDup = FrsWcsCat(Cxtion, DupNames[dupx]);
CxtionDn = ExtendDn(ServerDn, CxtionDnDup);
FREE(Cxtion);
FREE(CxtionDnDup);
LStatus = ldap_add_s(Ldap, CxtionDn, Mod);
if (LStatus != LDAP_ALREADY_EXISTS) {
//
// Dup cxtion created.
//
break;
}
dupx++;
}
if (LStatus != LDAP_ALREADY_EXISTS && LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't create %ws: %ws\n",
CxtionDn, ldap_err2string(LStatus));
}
FreeMod(&Mod);
FREE(PartnerDn);
FREE(CxtionDn);
}
FREE(ServerDn);
FREE(SetDn);
FREE(SettingsDn);
FREE(ServicesDn);
FREE(ConfigDn);
if (Ldap) {
ldap_unbind(Ldap);
}
}
BOOL
DeleteUserSubTree(
IN PLDAP Ldap,
IN PWCHAR Dn
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
DWORD LStatus;
PWCHAR DesiredAttrs[16];
PWCHAR Bl = NULL;
PWCHAR Co = NULL;
PWCHAR SubsDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
DesiredAttrs[0] = ATTR_MEMBER_REF_BL;
DesiredAttrs[1] = ATTR_COMPUTER_REF;
DesiredAttrs[2] = ATTR_CLASS;
DesiredAttrs[3] = NULL;
LStatus = ldap_search_s(Ldap, Dn, LDAP_SCOPE_BASE, CATEGORY_ANY,
DesiredAttrs, 0, &LdapMsg);
if (LStatus == LDAP_SUCCESS) {
LdapEntry = ldap_first_entry(Ldap, LdapMsg);
Co = FindValue(Ldap, LdapEntry, ATTR_COMPUTER_REF);
Bl = FindValue(Ldap, LdapEntry, ATTR_MEMBER_REF_BL);
if (Bl && Dn) {
LStatus = ldap_delete_s(Ldap, Bl);
if (LStatus != LDAP_SUCCESS && LStatus != LDAP_NO_SUCH_OBJECT) {
fprintf(stderr, "ERROR - Can't delete BL: %ws\n",
ldap_err2string(LStatus));
fprintf(stderr, " %ws\n", Dn);
fprintf(stderr, " BL %ws\n", Bl);
FREE(Bl);
FREE(Dn);
FREE(Co);
return FALSE;
}
}
if (Co) {
SubsDn = ExtendDn(Co, CN_SUBSCRIPTIONS);
LStatus = ldap_delete_s(Ldap, SubsDn);
if (LStatus != LDAP_NO_SUCH_OBJECT &&
LStatus != LDAP_SUCCESS &&
LStatus != LDAP_NOT_ALLOWED_ON_NONLEAF) {
fprintf(stderr, "ERROR - Can't delete: %ws\n", ldap_err2string(LStatus));
fprintf(stderr, " %ws\n", SubsDn);
FREE(SubsDn);
FREE(Bl);
FREE(Dn);
FREE(Co);
return FALSE;
}
FREE(SubsDn);
}
FREE(Bl);
FREE(Dn);
FREE(Co);
ldap_msgfree(LdapMsg);
} else if (LStatus != LDAP_NO_SUCH_OBJECT) {
fprintf(stderr, "ERROR - Can't find: %ws\n", ldap_err2string(LStatus));
fprintf(stderr, " %ws\n", Dn);
}
return TRUE;
}
VOID
FrsDsDeleteSubTree(
IN PLDAP Ldap,
IN PWCHAR ParentDn
)
/*++
Routine Description:
Arguments:
None.
Return Value:
None.
--*/
{
DWORD LStatus;
PWCHAR DesiredAttrs[16];
PWCHAR NextDn = NULL;
PLDAPMessage LdapMsg = NULL;
PLDAPMessage LdapEntry = NULL;
DesiredAttrs[0] = ATTR_DN;
DesiredAttrs[1] = NULL;
LStatus = ldap_search_s(Ldap, ParentDn, LDAP_SCOPE_ONELEVEL, CATEGORY_ANY,
DesiredAttrs, 0, &LdapMsg);
if (LStatus == LDAP_SUCCESS) {
//
// Scan the entries returned from ldap_search
//
for (LdapEntry = ldap_first_entry(Ldap, LdapMsg);
LdapEntry != NULL;
LdapEntry = ldap_next_entry(Ldap, LdapEntry)) {
NextDn = FindValue(Ldap, LdapEntry, ATTR_DN);
if (NextDn) {
FrsDsDeleteSubTree(Ldap, NextDn);
FREE(NextDn);
}
}
ldap_msgfree(LdapMsg);
if (DeleteUserSubTree(Ldap, ParentDn)) {
LStatus = ldap_delete_s(Ldap, ParentDn);
if (LStatus != LDAP_SUCCESS) {
fprintf(stderr, "ERROR - Can't delete: %ws\n", ldap_err2string(LStatus));
fprintf(stderr, " %ws\n", ParentDn);
}
}
} else if (LStatus != LDAP_NO_SUCH_OBJECT) {
fprintf(stderr, "ERROR - Can't find: %ws\n", ldap_err2string(LStatus));
fprintf(stderr, " %ws\n", ParentDn);
}
}
VOID
DeleteReplicationWorld(
IN DWORD argc,
IN PWCHAR *Argv,
IN PWCHAR Settings
)
/*++
Routine Description:
Create the required objects
Arguments:
None.
Return Value:
None.
--*/
{
PWCHAR Dn;
PWCHAR ConfigDn = NULL;
PWCHAR ServicesDn = NULL;
PWCHAR SettingsDn = NULL;
PWCHAR SetDn = NULL;
PWCHAR ServerDn = NULL;
PWCHAR Cxtion = NULL;
PWCHAR CxtionDn = NULL;
PLDAP Ldap = NULL;
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
//
// Services
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return;
}
ServicesDn = ExtendDn(ConfigDn, CN_SERVICES);
SettingsDn = ExtendDn(ServicesDn, Settings);
Dn = SettingsDn;
if (argc > 2) {
SetDn = ExtendDn(SettingsDn, Argv[2]);
Dn = SetDn;
}
if (argc > 3) {
ServerDn = ExtendDn(SetDn, Argv[3]);
Dn = ServerDn;
}
if (argc > 4) {
Cxtion = FrsWcsCat(L"From_", Argv[4]);
CxtionDn = ExtendDn(ServerDn, Cxtion);
Dn = CxtionDn;
}
FrsDsDeleteSubTree(Ldap, Dn);
// out:
ldap_unbind(Ldap);
FREE(CxtionDn);
FREE(Cxtion);
FREE(ServerDn);
FREE(SetDn);
FREE(SettingsDn);
FREE(ServicesDn);
FREE(ConfigDn);
}
VOID
ModifyFilter(
IN DWORD argc,
IN PWCHAR *Argv
)
/*++
Routine Description:
Change the file and directory filter for the replica set specified.
Arguments:
argc - From main
argv - From main
Return Value:
None.
--*/
{
DWORD LStatus = LDAP_SUCCESS;
PWCHAR Set;
PWCHAR NewFilter;
PWCHAR ConfigDn = NULL;
PWCHAR ServicesDn = NULL;
PWCHAR SettingsDn = NULL;
PWCHAR SetDn = NULL;
PLDAP Ldap = NULL;
LDAPMod **Mod = NULL;
Set = Argv[3];
if(argc > 4){
NewFilter = Argv[4];
}
else{
NewFilter = L" ";
}
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
//
// ADMIN SIDE
//
//
// Services Dn
//
ConfigDn = GetRootDn(Ldap, CONFIG_NAMING_CONTEXT);
if (!ConfigDn) {
return;
}
ServicesDn = ExtendDn(ConfigDn, CN_SERVICES);
SettingsDn = ExtendDn(ServicesDn, CN_TEST_SETTINGS);
SetDn = ExtendDn(SettingsDn, Set);
if(!wcscmp(Argv[2],L"/clear")){
if(!wcscmp(Argv[1],L"/dirfilter")){
AddMod(ATTR_DIRECTORY_FILTER, L" ", &Mod);
(*Mod)->mod_op = LDAP_MOD_REPLACE;
}
else {
AddMod(ATTR_FILE_FILTER, L" ", &Mod);
(*Mod)->mod_op = LDAP_MOD_REPLACE;
}
LStatus = ldap_modify_s(Ldap, SetDn, Mod);
}
else if(!wcscmp(Argv[2],L"/set")){
if(!wcscmp(Argv[1],L"/dirfilter")){
AddMod(ATTR_DIRECTORY_FILTER, NewFilter, &Mod);
(*Mod)->mod_op = LDAP_MOD_REPLACE;
}
else {
AddMod(ATTR_FILE_FILTER, NewFilter, &Mod);
(*Mod)->mod_op = LDAP_MOD_REPLACE;
}
LStatus = ldap_modify_s(Ldap, SetDn, Mod);
}
else {
// Usage(Argv);
}
if (LStatus != LDAP_SUCCESS) {
fprintf(stderr, "Can't change filter; %ws\n",
ldap_err2string(LStatus));
}
FreeMod(&Mod);
ldap_unbind(Ldap);
FREE(SetDn);
FREE(SettingsDn);
FREE(ServicesDn);
FREE(ConfigDn);
}
PWCHAR *
ConvertArgv(
DWORD argc,
PCHAR *argv
)
/*++
Routine Description:
Convert short char argv into wide char argv
Arguments:
argc - From main
argv - From main
Return Value:
Address of the new argv
--*/
{
PWCHAR *wideargv;
wideargv = (PWCHAR *)malloc((argc + 1) * sizeof(PWCHAR));
wideargv[argc] = NULL;
while (argc-- >= 1) {
wideargv[argc] = (PWCHAR)malloc((strlen(argv[argc]) + 1) * sizeof(WCHAR));
wsprintf(wideargv[argc], L"%hs", argv[argc]);
// _wcslwr(wideargv[argc]);
}
return wideargv;
}
VOID
Usage(
IN PWCHAR *Argv
)
/*++
Routine Description:
Usage messages.
Arguments:
None.
Return Value:
None.
--*/
{
printf("%-24s%ws\n", "Pretty Print", Argv[0]);
printf("%-24s%ws /dumpcontexts\n", "dumpcontexts", Argv[0]);
printf("%-24s%ws /dumpcomputers\n", "dumpcomputers", Argv[0]);
printf("%-24s%ws /dumpservers\n", "dumpservers", Argv[0]);
printf("%-24s%ws /dumpsets\n", "dumpsets", Argv[0]);
printf("%-24s%ws /?\n", "Help", Argv[0]);
printf("%-24s%ws /h\n", "Hammer the schema", Argv[0]);
printf("%-24s%ws /r\n", "Restore the schema", Argv[0]);
printf("%-24s%ws /l\n", "List the schema", Argv[0]);
printf("%-24s%ws /s\n", "Produce script", Argv[0]);
printf("%-24s%ws /d [Set [Server [Partner]]]\n", "Delete", Argv[0]);
printf("%-24s%ws /c Set [Server [Root Stage]]\n", "Create sets and servers", Argv[0]);
printf("%-24s%ws /i Set Server Partner ...\n", "Create inbound cxtions", Argv[0]);
printf("%-24s%ws [/filefilter |/dirfilter] [/set |/clear] Set FilterString\n", "Modify filters", Argv[0]);
fflush(stdout);
ExitProcess(0);
}
#define DUMP_ALL (0)
#define DUMP_CONTEXTS (1)
#define DUMP_SETS (2)
#define DUMP_COMPUTERS (3)
#define DUMP_SERVERS (4)
VOID
DumpWorld(
DWORD Dump
)
/*++
Routine Description:
Dump every ds object related to replication
Arguments:
Dump - what to dump.
Return Value:
None.
--*/
{
PLDAP Ldap;
//
// Bind to the ds
//
Ldap = FrsDsOpenDs();
if (!Ldap) {
return;
}
if (Dump == DUMP_ALL || Dump == DUMP_CONTEXTS) {
printf("***** CONTEXTS\n");
DumpContexts(Ldap);
}
if (Dump == DUMP_ALL || Dump == DUMP_SETS) {
printf("***** REPLICA SETS\n");
DumpAdminWorld(Ldap);
}
if (Dump == DUMP_ALL || Dump == DUMP_COMPUTERS) {
printf("\n***** COMPUTERS\n");
DumpUserWorld(Ldap);
}
if (Dump == DUMP_ALL || Dump == DUMP_SERVERS) {
printf("\n***** SERVERS\n");
DumpSysVolWorld(Ldap);
}
ldap_unbind(Ldap);
}
VOID _cdecl
main(
IN DWORD argc,
IN PCHAR *argv
)
/*++
Routine Description:
Get access to the DS via ldap. Then read command lines from standard
in, parse them, and ship them off to the command subroutines. The
command line is:
command,site,settings,server,connection,fromserver
command is any of add|delete|list|show|quit. Leading whitespace is
ignored. Whitespace between commas counts. The command line can
stop anytime after "command" and the command will on be applied
to that portion of the "Distinquished Name".
Arguments:
None.
Return Value:
Exits with 0 if everything went okay. Otherwise, 1.
--*/
{
PWCHAR *Argv;
ULONG i;
ULONG OptLen;
Argv = ConvertArgv(argc, argv);
if (argc == 1) {
DumpWorld(DUMP_ALL);
fflush(stdout);
ExitProcess(0);
}
for (i = 1; i < argc; ++i) {
OptLen = wcslen(Argv[i]);
if (OptLen == 2 &&
((wcsstr(Argv[i], L"/?") == Argv[i]) ||
(wcsstr(Argv[i], L"-?") == Argv[i]))) {
Usage(Argv);
} else if (OptLen == 2 &&
((wcsstr(Argv[i], L"/s") == Argv[i]) ||
(wcsstr(Argv[i], L"-s") == Argv[i]))) {
ScriptReplicationWorld();
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 2 &&
((wcsstr(Argv[i], L"/d") == Argv[i]) ||
(wcsstr(Argv[i], L"-d") == Argv[i]))) {
if (argc < 2 || argc > 5) {
Usage(Argv);
}
DeleteReplicationWorld(argc, Argv, CN_TEST_SETTINGS);
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 9 &&
((wcsstr(Argv[i], L"/dsysvols") == Argv[i]) ||
(wcsstr(Argv[i], L"-dsysvols") == Argv[i]))) {
if (argc < 2 || argc > 5) {
Usage(Argv);
}
DeleteReplicationWorld(argc, Argv, CN_SYSVOLS);
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 2 &&
((wcsstr(Argv[i], L"/h") == Argv[i]) ||
(wcsstr(Argv[i], L"-h") == Argv[i]))) {
HammerSchema(TRUE);
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 2 &&
((wcsstr(Argv[i], L"/r") == Argv[i]) ||
(wcsstr(Argv[i], L"-r") == Argv[i]))) {
HammerSchema(FALSE);
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 2 &&
((wcsstr(Argv[i], L"/l") == Argv[i]) ||
(wcsstr(Argv[i], L"-l") == Argv[i]))) {
ListSchema();
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 2 &&
((wcsstr(Argv[i], L"/i") == Argv[i]) ||
(wcsstr(Argv[i], L"-i") == Argv[i]))) {
if (argc < 5) {
Usage(Argv);
}
CreateInbounds(argc, Argv);
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 2 &&
((wcsstr(Argv[i], L"/c") == Argv[i]) ||
(wcsstr(Argv[i], L"-c") == Argv[i]))) {
if (argc != 2 && argc != 3 && argc != 6) {
Usage(Argv);
}
CreateReplicationWorld(argc, Argv, FALSE);
fflush(stdout);
ExitProcess(0);
} else if (OptLen == 3 &&
((wcsstr(Argv[i], L"/cp") == Argv[i]) ||
(wcsstr(Argv[i], L"-cp") == Argv[i]))) {
if (argc != 2 && argc != 3 && argc != 6) {
Usage(Argv);
}
CreateReplicationWorld(argc, Argv, TRUE);
fflush(stdout);
ExitProcess(0);
} else if (OptLen >= 10 &&
((wcsstr(Argv[i], L"/filefilter") == Argv[i]) ||
(wcsstr(Argv[i], L"-filefilter") == Argv[i]) ||
(wcsstr(Argv[i], L"/dirfilter") == Argv[i]) ||
(wcsstr(Argv[i], L"-dirfilter") == Argv[i]))) {
if (argc != 4 && argc != 5) {
Usage(Argv);
}
ModifyFilter(argc, Argv);
fflush(stdout);
ExitProcess(0);
} else if ((wcsstr(Argv[i], L"/dumpcontexts") == Argv[i]) ||
(wcsstr(Argv[i], L"-dumpcontexts") == Argv[i])) {
DumpWorld(DUMP_CONTEXTS);
fflush(stdout);
ExitProcess(0);
} else if ((wcsstr(Argv[i], L"/dumpsets") == Argv[i]) ||
(wcsstr(Argv[i], L"-dumpsets") == Argv[i])) {
DumpWorld(DUMP_SETS);
fflush(stdout);
ExitProcess(0);
} else if ((wcsstr(Argv[i], L"/dumpcomputers") == Argv[i]) ||
(wcsstr(Argv[i], L"-dumpcomputers") == Argv[i])) {
DumpWorld(DUMP_COMPUTERS);
fflush(stdout);
ExitProcess(0);
} else if ((wcsstr(Argv[i], L"/dumpservers") == Argv[i]) ||
(wcsstr(Argv[i], L"-dumpservers") == Argv[i])) {
DumpWorld(DUMP_SERVERS);
fflush(stdout);
ExitProcess(0);
} else if ((wcsstr(Argv[i], L"/") == Argv[i]) ||
(wcsstr(Argv[i], L"-") == Argv[i])) {
fprintf(stderr, "ERROR - Don't understand %ws\n", Argv[i]);
Usage(Argv);
} else {
Usage(Argv);
}
}
fflush(stdout);
ExitProcess(0);
}