Platform SDK: Active Directory, ADSI, and Directory Services

Enabling Schema Changes at the Schema Master

Schema modification is disabled by default on all Windows 2000 domain controllers. To enable schema modification at a particular DC, you must insert a value (or ensure that it is greater than zero if it already exists) into the registry on that DC. You must add the value "Schema Update Allowed" as a REG_DWORD value and set the value to 1 (or any value greater than 0). This value must be added to the following registry key:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NTDS\Parameters

Note that If the "Schema Update Allowed" registry value is set to zero (0), then schema modification is turned off.

The Schema Manager MMC snap-in provides a checkbox that sets or clears this registry key.

Example

The following function does checks and if necessary sets the Schema Update Allowed value:

  1. Connects to the registry of the specified computer.
  2. Tries to read the Schema Update Allowed value
  3. If that value does not exist or if the value is not greater than 0, asks the user if the value should be set. If Yes, attempts to create the value (if necessary) and set it to 1.
  4. Returns S_OK if value is set or S_FALSE if it is not.

C/C++

HRESULT IsSchemaMasterWritable(LPOLESTR szSchemaMasterComputerName)
{
  if (!szSchemaMasterComputerName)
    return E_POINTER;
  HRESULT hr = E_FAIL;
  LONG lReturn;
  HKEY hKey,hKeyTarget;
  LPOLESTR szRelKeyPath = L"System\\CurrentControlSet\\Services\\NTDS\\Parameters";
  LPOLESTR szValueName = L"Schema Update Allowed";
  LPOLESTR szPath = new OLECHAR[MAX_PATH];
  LPOLESTR szBuffer = new OLECHAR[MAX_PATH];
  ULONG lSize = sizeof(DWORD);
  DWORD dwType,dwValue;
  wcscpy(szPath,L"\\\\");
  wcscat(szPath,szSchemaMasterComputerName);
  lReturn = RegConnectRegistry(szPath,HKEY_LOCAL_MACHINE,&hKey);
  if (ERROR_SUCCESS==lReturn)
  {
    lReturn = RegOpenKeyEx(hKey,szRelKeyPath,0,KEY_READ,&hKeyTarget);
    if (ERROR_SUCCESS==lReturn)
    {
      lReturn = RegQueryValueEx(hKeyTarget,szValueName,0,&dwType,(LPBYTE)&dwValue,&lSize);
      if (ERROR_SUCCESS==lReturn)
      {
        if (dwValue>0)
          hr = S_OK;
        else
          hr = S_FALSE;
      }
      //if the value could not be found, return S_FALSE.
      else if (ERROR_FILE_NOT_FOUND==lReturn)
      {
        hr = S_FALSE;
      }
 
      if (S_FALSE==hr)
      {
        RegCloseKey(hKeyTarget);
        int iSetIfNotWritable = MessageBox(NULL,L"The schema master is not writeable. Do you want to make it writeable?",L"Extend Schema Wizard",MB_YESNO|MB_ICONEXCLAMATION);
        if (iSetIfNotWritable==IDYES)
        {
          lReturn = RegOpenKeyEx(hKey,szRelKeyPath,0,KEY_WRITE,&hKeyTarget);
          if (ERROR_SUCCESS==lReturn)
          {
            //Set the value to 1.
            dwValue = 1L;
            lReturn = RegSetValueEx(hKeyTarget,szValueName,0L,REG_DWORD,(LPBYTE)&dwValue,lSize);
            if (ERROR_SUCCESS==lReturn)
            {
              hr = S_OK;
            }
            else
            {
               MessageBox(NULL,L"Could not set the Schema Master as writeable.",L"Extend Schema Wizard",MB_OK|MB_ICONEXCLAMATION);
            }
          }
        }
      }
    }
    RegCloseKey(hKeyTarget);
  }
  RegCloseKey(hKey);
  return hr;
}