Bug 15774 - Running "gpo manage motd set" twice fails with backtrace
Summary: Running "gpo manage motd set" twice fails with backtrace
Status: NEW
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: Other (show other bugs)
Version: 4.19.5
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Douglas Bagnall
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2024-12-20 19:21 UTC by Andreas Hasenack
Modified: 2025-01-12 06:55 UTC (History)
1 user (show)

See Also:


Attachments
fix crash when updating an MOTD GPO (739 bytes, patch)
2025-01-09 12:25 UTC, Andreas Hasenack
no flags Details
fix crash when updating an MOTD GPO (1.61 KB, patch)
2025-01-10 14:44 UTC, Andreas Hasenack
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andreas Hasenack 2024-12-20 19:21:23 UTC
Saw this in 4.19.5, but given the code, I believe it also still happens in master.

root@n-ad:~# samba-tool gpo manage motd set {177F310B-5416-48A9-8A39-EA8919EB7964} "Welcome" -U Administrator%Passw0rd
WARNING: Using passwords on command line is insecure. Installing the setproctitle python module will hide these from shortly after program start.

root@n-ad:~# samba-tool gpo manage motd set {177F310B-5416-48A9-8A39-EA8919EB7964} "Welcome" -U Administrator%Passw0rd
WARNING: Using passwords on command line is insecure. Installing the setproctitle python module will hide these from shortly after program start.
ERROR(<class 'UnboundLocalError'>): uncaught exception - cannot access local variable 'data' where it is not associated with a value
  File "/usr/lib/python3/dist-packages/samba/netcmd/__init__.py", line 279, in _run
    return self.run(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/samba/netcmd/gpo.py", line 3829, in run
    text = ET.SubElement(data, 'text')
                         ^^^^

        try:
            xml_data = ET.fromstring(conn.loadfile(vgp_xml))
        except NTSTATUSError as e:
            if e.args[0] in [NT_STATUS_OBJECT_NAME_INVALID,
                             NT_STATUS_OBJECT_NAME_NOT_FOUND,
                             NT_STATUS_OBJECT_PATH_NOT_FOUND]:
                # The file doesn't exist, so create the xml structure
                xml_data = ET.ElementTree(ET.Element('vgppolicy'))
                policysetting = ET.SubElement(xml_data.getroot(),
                                              'policysetting')
                pv = ET.SubElement(policysetting, 'version')
                pv.text = '1'
                name = ET.SubElement(policysetting, 'name')
                name.text = 'Text File'
                description = ET.SubElement(policysetting, 'description')
                description.text = 'Represents a Generic Text File'
                apply_mode = ET.SubElement(policysetting, 'apply_mode')
                apply_mode.text = 'replace'
                data = ET.SubElement(policysetting, 'data')
                filename = ET.SubElement(data, 'filename')
                filename.text = 'motd'
            elif e.args[0] == NT_STATUS_ACCESS_DENIED:
                raise CommandError("The authenticated user does "
                                   "not have sufficient privileges")
            else:
                raise

        text = ET.SubElement(data, 'text')

When the file doesn't exist yet, it's created, and then we have "data" populated, and it can be used outside the try/except block.

If, however, the policy file exists already, no exception is raised, and we jump straight to the "text" assignment, which then fails because "data" is not defined.
Comment 1 Andreas Hasenack 2024-12-20 20:00:23 UTC
Would this be a fix? I copied it from other similar functions without too much testing:

diff --git a/python/samba/netcmd/gpo.py b/python/samba/netcmd/gpo.py
index 96fce917f0f..fe9b7caacb2 100644
--- a/python/samba/netcmd/gpo.py
+++ b/python/samba/netcmd/gpo.py
@@ -3808,7 +3808,9 @@ samba-tool gpo manage motd set {31B2F340-016D-11D2-945F-00C04FB984F9} "Message f
             return
 
         try:
-            xml_data = ET.fromstring(conn.loadfile(vgp_xml))
+            xml_data = ET.ElementTree(ET.fromstring(conn.loadfile(vgp_xml)))
+            policysetting = xml_data.getroot().find('policysetting')
+            data = policysetting.find('data')
         except NTSTATUSError as e:
             if e.args[0] in [NT_STATUS_OBJECT_NAME_INVALID,
                              NT_STATUS_OBJECT_NAME_NOT_FOUND,
Comment 2 Andreas Hasenack 2024-12-25 14:23:25 UTC
Yeah, this seems to work, and be correct.
Comment 3 Douglas Bagnall 2025-01-09 03:46:41 UTC
According to comment four of https://bugs.launchpad.net/bugs/2092308, the fix in comment 1 here is not quite right (it appends text rather than replaces).
Comment 4 Andreas Hasenack 2025-01-09 12:25:37 UTC
Created attachment 18527 [details]
fix crash when updating an MOTD GPO
Comment 5 Andreas Hasenack 2025-01-09 12:26:19 UTC
> According to comment four of https://bugs.launchpad.net/bugs/2092308, the fix 
> in comment 1 here is not quite right (it appends text rather than replaces).

You are right, I forgot to update the patch here. New version attached.
Comment 6 Douglas Bagnall 2025-01-09 21:56:57 UTC
(In reply to Andreas Hasenack from comment #5)
> New version attached.

Thanks.

If you are able to format the patch with a commit message using `git commit -s` and `git format-patch`, this will ease its path upstream.

(I think you have already done the contributor paperwork at https://www.samba.org/samba/devel/copyright-policy.html).
Comment 7 Andreas Hasenack 2025-01-10 14:33:26 UTC
> (I think you have already done the contributor paperwork at 
> https://www.samba.org/samba/devel/copyright-policy.html).


I did, on May 19, 2022, I just located the email I sent, and its confirmation.
Comment 8 Andreas Hasenack 2025-01-10 14:44:13 UTC
Created attachment 18530 [details]
fix crash when updating an MOTD GPO