21 Modifying a Registry.pol File

21.1 Using samba-tool

Samba provides the samba-tool gpo load, samba-tool gpo remove and samba-tool gpo show commands for manipulating Registry.pol policies. These commands format the registry policies as json to simplify the process. For example, a policy which sets the Firefox homepage would like like so:

[
  {
    "keyname": "Software\\Policies\\Mozilla\\Firefox\\Homepage",
    "valuename": "StartPage",
    "class": "MACHINE",
    "type": "REG_SZ",
    "data": "homepage"
  },
  {
    "keyname": "Software\\Policies\\Mozilla\\Firefox\\Homepage",
    "valuename": "URL",
    "class": "MACHINE",
    "type": "REG_SZ",
    "data": "samba.org"
  }
]

To set this policy on a GPO, we either put it in a file, or pass it to samba-tool gpo load in standard input.

> sudo samba-tool gpo load -UAdministrator --content=test.json

21.2 Scripting with python

Samba provides python libraries for manipulating a Registry.pol on Linux. The following python code snippet demonstrates how to open one of these files.

from samba.ndr import ndr_unpack
from samba.dcerpc import preg

raw = open('Registry.pol', 'rb').read()
pol_conf = ndr_unpack(preg.file, raw)

The parsed file contains a list of entries, which you can iterate over. Each entry contains a keyname, valuename, and data.

for e in pol_conf.entries:
    print(e.keyname, e.valuename, e.data)

Writing to the pol_conf can be tricky. If you write the length of the entries prior to writing the entries, it will actually cause memory corruption (this is a bug). So ensure you write to the entries, then to the length. You can create an entry using the preg import from samba.dcerpc.

e = preg.entry()
e.keyname = b'Software\\Policies\\Samba\\smb_conf'
e.valuename = b'apply group policies'
e.type = 4 # REG_DWORD, an integer
e.data = 1

entries = list(pol_data.entries)
entries.append(e)
pol_data.entries = entries
# Ensure you set the new num_entries last
pol_data.num_entries = len(entries)

The data type refers to Microsoft defined registry types:

Registry.type.name Registry.type.value
REG_NONE 0
REG_SZ 1
REG_EXPAND_SZ 2
REG_BINARY 3
REG_DWORD 4
REG_DWORD_BIG_ENDIAN 5
REG_LINK 6
REG_MULTI_SZ 7
REG_RESOURCE_LIST 8
REG_QWORD 11

To write your changes back to the Registry.pol file, you’ll use the following:

from samba.ndr import ndr_pack

with open('Registry.pol', 'wb') as w:
    w.write(ndr_pack(pol_data))