Bug 15839 - gp_cert_auto_enroll_ext.py has problem unpacking GUIDs with prepended 0's
Summary: gp_cert_auto_enroll_ext.py has problem unpacking GUIDs with prepended 0's
Status: RESOLVED FIXED
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: Python (show other bugs)
Version: unspecified
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Jule Anger
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2025-03-24 09:21 UTC by cn
Modified: 2025-04-17 17:16 UTC (History)
2 users (show)

See Also:


Attachments
A simple way to ensure preprended zeros in GUIDs is to add .zfill(length) (1.28 KB, patch)
2025-03-24 09:21 UTC, cn
no flags Details
Test script showing issue and proposed fix (1022 bytes, text/x-python)
2025-03-24 09:26 UTC, cn
no flags Details
patch for 4.21 and 4.22 for bugs 15839, 15829, and 15774 (16.09 KB, patch)
2025-03-25 07:26 UTC, Douglas Bagnall
jsutton: review+
Details

Note You need to log in before you can comment on or make changes to this bug.
Description cn 2025-03-24 09:21:45 UTC
Created attachment 18618 [details]
A simple way to ensure preprended zeros in GUIDs is to add .zfill(length)

We have identified a small bug in: gp_cert_auto_enroll_ext.py, caused by python struct not prepending 0 (zero) to GUID.

In Ubuntu the command: "adsysctl", fails due to python's struct.unpack which don't handle zero padding for GUIDs.

In our AD domain registry this key exists:

   Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy

Has data like this:
   {AAAAAAAA-BBBB-4EA4-8761-0CCCCCCCCCCC}
   (A version 4 GUID Variant 8, with last part starting with value "0C")

Running "adsysctl update -a" fails on above key/data with:

gensec_update_done: spnego[0x17c799f0]: NT_STATUS_OK tevent_req[0x17cc10f0/auth/gensec/spnego.c:1631]: state[2] error[0 (0x0)] state[struct gensec_spnego_update_state (0x17cc12d0)] timer[(nil)] finish[auth/gensec/spnego.c:2116]
Traceback (most recent call last):
  File "<string>", line 142, in <module>
  File "<string>", line 89, in main
  File "<string>", line 20, in enroll
  File "/usr/share/adsys/python/vendor_samba/gp/gp_cert_auto_enroll_ext.py", line 517, in __enroll
    ca_names.extend(self.__read_cep_data(guid, ldb,
TypeError: 'NoneType' object is not iterable

In "gp_cert_auto_enroll_ext.py" "0CCCCCCCCCCC" is unpacked as "CCCCCCCCCCC" - as python won't pad begining/end of structs:

   "Padding is only automatically added between successive structure members. **No padding is added at the beginning or the end of the encoded struct.**"

From:
   https://docs.python.org/3/library/struct.html#byte-order-size-and-alignment

One solution is to zfill(length) to ensure prepended zeros:
   "Return a copy of the string left filled with ASCII '0' digits to make a string of length width"

From:
   https://docs.python.org/3/library/stdtypes.html#str.zfill

Diff: attached
Comment 1 cn 2025-03-24 09:24:20 UTC
Example test.py GUID with double prepended 0 (zeros) - demonstrating issue in original code and effect of proposed zfill change.

Expected output from running attached code: test.py

   Mixed ldb data: b'0\xaaa\n\xbb\xbb\xa4N\x87a\x0c\xcc\xcc\xcc\xcc\xcc'
   Original adsys: a61aa30-bbbb-4ea4-8761-ccccccccccc
   Proposed zfill: 0a61aa30-bbbb-4ea4-8761-0ccccccccccc
Comment 2 cn 2025-03-24 09:26:35 UTC
Created attachment 18619 [details]
Test script showing issue and proposed fix
Comment 3 Douglas Bagnall 2025-03-24 22:16:36 UTC
Thanks.

I think maybe the problems are deeper though. The %02x should zero-fill the numbers to 2 hex digits (i.e. one byte). But most of the fields are 2 byte fields, and two of them are bigger:

    return '%s-%s-%s-%s-%s' % ('%02x' % struct.unpack('<L', data[0:4])[0],
                                 ^^                              ^^^
                               '%02x' % struct.unpack('<H', data[4:6])[0],
                               '%02x' % struct.unpack('<H', data[6:8])[0],
                               '%02x' % struct.unpack('>H', data[8:10])[0],
                               '%02x%02x' % struct.unpack('>HL', data[10:]))
                                 ^^^^^^^                              ^^^

Normally we would use:

from samba.dcerpc import misc
from samba.ndr import ndr_unpack

def octet_string_to_objectGUID(data):
    return str(ndr_unpack(misc.GUID, data))

to stringify a GUID. I think that's what we want here. It works with the example:

>>> b = ndr_pack(misc.GUID('AAAAAAAA-BBBB-4EA4-8761-0CCCCCCCCCCC'))
>>> str(ndr_unpack(misc.GUID, b))
'aaaaaaaa-bbbb-4ea4-8761-0ccccccccccc'
>>> gp_cert_auto_enroll_ext.octet_string_to_objectGUID(b)
'aaaaaaaa-bbbb-4ea4-8761-ccccccccccc'
Comment 4 Samba QA Contact 2025-03-25 05:22:14 UTC
This bug was referenced in samba master:

47ff42232048c008a7b361a948e5ac79311b5458
Comment 5 Douglas Bagnall 2025-03-25 07:26:39 UTC
Created attachment 18620 [details]
patch for 4.21 and 4.22 for bugs 15839, 15829, and 15774

This contains fixes bug for 15839, bug 15829, and bug 15774. The same patch works for 4.22 and 4.21.
Comment 6 cn 2025-03-25 07:55:56 UTC
(In reply to Douglas Bagnall from comment #3)
Good catch - thanks - setting this issue as resolved?
Comment 7 Douglas Bagnall 2025-03-25 08:28:03 UTC
(In reply to cn from comment #6)
Not resolved yet -- it will meander through our processes for backports etc -- but it's on the way.
Comment 8 Jule Anger 2025-04-17 08:10:22 UTC
Pushed to autobuild-v4-{22,21}-test.
Comment 9 Samba QA Contact 2025-04-17 12:50:40 UTC
This bug was referenced in samba v4-22-test:

21f1d226e94c150029ac1117d973cac73b1ea3a6
Comment 10 Samba QA Contact 2025-04-17 12:54:38 UTC
This bug was referenced in samba v4-21-test:

2216a4396054e1e67a0fb98cfb7965b6d20411aa
Comment 11 Jule Anger 2025-04-17 13:05:35 UTC
Closing out bug report.

Thanks!
Comment 12 Samba QA Contact 2025-04-17 17:16:47 UTC
This bug was referenced in samba v4-22-stable (Release samba-4.22.1):

21f1d226e94c150029ac1117d973cac73b1ea3a6