Directory Services

Enabling Schema Changes at the Schema Master

By default, schema modification is disabled on all Windows 2000 domain controllers. The ability to update the schema is controlled by the following registry value on the schema master domain controller:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters\Schema Update Allowed

This registry value is a REG_DWORD value. If this value is not present or contains zero (0), then schema modification is disabled. If this value is present and contains a value other than zero, then schema modification is enabled.

The Schema Manager MMC snap-in provides the user with the ability to manually enable or disable schema modification. Schema modification can be enabled or disabled programmatically by modifying this registry value on the schema master domain controller.

The following function shows how to determine if the schema can be modified on a specified schema master.

[C++]
HRESULT IsSchemaUpdateEnabled(LPTSTR pszSchemaMasterComputerName, BOOL *pfEnabled)
{
	if (IsBadReadPtr(pszSchemaMasterComputerName, 1) || IsBadWritePtr(pfEnabled, sizeof(BOOL)))
	{
		return E_POINTER;
}

	*pfEnabled = FALSE;
  
	LPTSTR szPrefix = "\\\\";
	LPTSTR pszPath = new TCHAR[lstrlen(szPrefix) + lstrlen(pszSchemaMasterComputerName) + 1];
	if(!pszPath)
	{
		return E_OUTOFMEMORY;
}

	HRESULT hr = E_FAIL;
	LONG lReturn;
	HKEY hKeyMachine;

	lstrcpy(pszPath, szPrefix);
	lstrcat(pszPath, pszSchemaMasterComputerName);
	lReturn = RegConnectRegistry(pszPath, HKEY_LOCAL_MACHINE, &hKeyMachine);

	delete [] pszPath;

	if (ERROR_SUCCESS == lReturn)
	{
		HKEY hKeyParameters;
		LPTSTR szKeyPath = TEXT("System\\CurrentControlSet\\Services\\NTDS\\Parameters");
		LPTSTR szValueName = TEXT("Schema Update Allowed");

		lReturn = RegOpenKeyEx(hKeyMachine, szKeyPath, 0, KEY_READ, &hKeyParameters);
		if (ERROR_SUCCESS == lReturn)
		{
			DWORD dwType;
			DWORD dwValue;
			DWORD dwSize;

			dwSize = sizeof(dwValue);
			lReturn = RegQueryValueEx(hKeyParameters, szValueName, 0, &dwType, (LPBYTE)&dwValue, &dwSize);
			if (ERROR_SUCCESS == lReturn)
			{
				*pfEnabled = (0 != dwValue);
			
				hr = S_OK;
		}
		
			RegCloseKey(hKeyParameters);
	}

		RegCloseKey(hKeyMachine);
}
  
	return hr;
}

The following function shows how to enable or disable schema modification on a specified schema master.

[C++]
HRESULT EnableSchemaUpdate(LPTSTR pszSchemaMasterComputerName, BOOL fEnabled)
{
	if (IsBadReadPtr(pszSchemaMasterComputerName, 1))
	{
		return E_POINTER;
}

	LPTSTR szPrefix = "\\\\";
	LPTSTR pszPath = new TCHAR[lstrlen(szPrefix) + lstrlen(pszSchemaMasterComputerName) + 1];
	if(!pszPath)
	{
		return E_OUTOFMEMORY;
}

	HRESULT hr = E_FAIL;
	LONG lReturn;
	HKEY hKeyMachine;

	lstrcpy(pszPath, szPrefix);
	lstrcat(pszPath, pszSchemaMasterComputerName);
	lReturn = RegConnectRegistry(pszPath, HKEY_LOCAL_MACHINE, &hKeyMachine);

	delete [] pszPath;

	if (ERROR_SUCCESS == lReturn)
	{
		HKEY hKeyParameters;
		LPTSTR szRelKeyPath = TEXT("System\\CurrentControlSet\\Services\\NTDS\\Parameters");
		LPTSTR szValueName = TEXT("Schema Update Allowed");

		lReturn = RegOpenKeyEx(hKeyMachine, szRelKeyPath, 0, KEY_SET_VALUE, &hKeyParameters);
		if (ERROR_SUCCESS == lReturn)
		{
			DWORD dwValue;
			DWORD dwSize;

			if(fEnabled)
			{
				dwValue = 1;
		}
			else
			{
				dwValue = 0;
		}
		
			dwSize = sizeof(dwValue);
			lReturn = RegSetValueEx(hKeyParameters, szValueName, 0L, REG_DWORD, (LPBYTE)&dwValue, dwSize);
			if (ERROR_SUCCESS == lReturn)
			{
				hr = S_OK;
		}
		
			RegCloseKey(hKeyParameters);
	}

		RegCloseKey(hKeyMachine);
}

	return hr;
}