Hello community,

here is the log from the commit of package yast2-gpmc for openSUSE:Factory 
checked in at 2019-09-30 15:59:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-gpmc (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-gpmc.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-gpmc"

Mon Sep 30 15:59:15 2019 rev:7 rq:733762 version:1.5.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-gpmc/yast2-gpmc.changes    2019-09-25 
08:28:38.846382608 +0200
+++ /work/SRC/openSUSE:Factory/.yast2-gpmc.new.2352/yast2-gpmc.changes  
2019-09-30 15:59:15.925237946 +0200
@@ -1,0 +2,8 @@
+Fri Sep 27 21:18:31 UTC 2019 - [email protected]
+
+- Create a stub smb.conf for s3_lp if no smb.conf exists.
+- Fix broken gpo creation by reusing samba code; (bsc#1152357);
+- Use samba-tool code to delete links/gpos.
+- 1.5.0
+
+-------------------------------------------------------------------

Old:
----
  yast2-gpmc-1.4.8.tar.bz2

New:
----
  yast2-gpmc-1.5.0.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ yast2-gpmc.spec ++++++
--- /var/tmp/diff_new_pack.8ccH0b/_old  2019-09-30 15:59:16.433236594 +0200
+++ /var/tmp/diff_new_pack.8ccH0b/_new  2019-09-30 15:59:16.437236584 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-gpmc
-Version:        1.4.8
+Version:        1.5.0
 Release:        0
 Summary:        Group Policy Management Console for YaST
 License:        GPL-3.0-only

++++++ yast2-gpmc-1.4.8.tar.bz2 -> yast2-gpmc-1.5.0.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.4.8/package/yast2-gpmc.changes 
new/yast2-gpmc-1.5.0/package/yast2-gpmc.changes
--- old/yast2-gpmc-1.4.8/package/yast2-gpmc.changes     2019-09-23 
22:44:08.000000000 +0200
+++ new/yast2-gpmc-1.5.0/package/yast2-gpmc.changes     2019-09-27 
23:28:34.000000000 +0200
@@ -1,4 +1,12 @@
 -------------------------------------------------------------------
+Fri Sep 27 21:18:31 UTC 2019 - [email protected]
+
+- Create a stub smb.conf for s3_lp if no smb.conf exists.
+- Fix broken gpo creation by reusing samba code; (bsc#1152357);
+- Use samba-tool code to delete links/gpos.
+- 1.5.0
+
+-------------------------------------------------------------------
 Mon Sep 23 20:35:24 UTC 2019 - [email protected]
 
 - Fix copy/paste typo in fix for bug 1151733; (bsc#1151738);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.4.8/package/yast2-gpmc.spec 
new/yast2-gpmc-1.5.0/package/yast2-gpmc.spec
--- old/yast2-gpmc-1.4.8/package/yast2-gpmc.spec        2019-09-23 
22:44:08.000000000 +0200
+++ new/yast2-gpmc-1.5.0/package/yast2-gpmc.spec        2019-09-27 
23:28:34.000000000 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           yast2-gpmc
-Version:        1.4.8
+Version:        1.5.0
 Release:        0
 Summary:        Group Policy Management Console for YaST
 License:        GPL-3.0-only
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-1.4.8/src/include/gpmc/complex.py 
new/yast2-gpmc-1.5.0/src/include/gpmc/complex.py
--- old/yast2-gpmc-1.4.8/src/include/gpmc/complex.py    2019-09-23 
22:44:08.000000000 +0200
+++ new/yast2-gpmc-1.5.0/src/include/gpmc/complex.py    2019-09-27 
23:28:34.000000000 +0200
@@ -13,7 +13,6 @@
 from samba.net import Net
 from samba.dcerpc import nbt
 from subprocess import Popen, PIPE
-import uuid
 import re
 import traceback
 import ldb
@@ -30,6 +29,11 @@
 from adcommon.yldap import Ldap, LdapException, SCOPE_SUBTREE, SCOPE_ONELEVEL, 
SCOPE_BASE, addlist, modlist
 from adcommon.strings import strcmp, strcasecmp
 from samba import NTSTATUSError
+from tempfile import NamedTemporaryFile
+from optparse import OptionParser
+from samba.netcmd import gpo
+from samba.netcmd import CommandError
+from samba import NTSTATUSError, WERRORError
 
 def open_bytes(filename):
     if six.PY3:
@@ -113,6 +117,25 @@
         ret += "[LDAP://%s;%d]" % (g['dn'], g['options'])
     return ret
 
+def smb_connection(dc_hostname, service, lp, creds, sign=False):
+    # SMB connect to DC
+    # the SMB bindings rely on having a s3 loadparm
+    s3_lp = s3param.get_context()
+    if lp.configfile:
+        s3_lp.load(lp.configfile)
+    else:
+        with NamedTemporaryFile('w') as smb_conf:
+            smb_conf.write('[global]\nREALM = %s' % lp.get('realm'))
+            s3_lp.load(smb_conf.name)
+    try:
+        conn = smb.Conn(dc_hostname, service, lp=s3_lp, creds=creds, sign=sign)
+    except Exception:
+        raise CommandError("Error connecting to '%s' using SMB" % dc_hostname)
+    return conn
+
+# The samba-tool smb_connection function doesn't handle a missing smb.conf
+gpo.smb_connection = smb_connection
+
 class GPConnection(Ldap):
     def __init__(self, lp, creds):
         super().__init__(lp, creds)
@@ -142,10 +165,6 @@
         res = self.ldap_search(self.__well_known_container('users'), 
SCOPE_SUBTREE, '(objectSID=%s)' % sid, stringify_ldap(attrs))
         return res[0][1]
 
-    def get_domain_sid(self):
-        res = self.ldap_search(self.realm_to_dn(self.realm), SCOPE_BASE, 
"(objectClass=*)", [])
-        return ndr_unpack(security.dom_sid, res[0][1]["objectSid"][0])
-
     def gpo_list(self, displayName=None, attrs=[]):
         result = None
         res = self.__well_known_container('system')
@@ -160,125 +179,25 @@
         self.ldap_modify(dn, stringify_ldap([(1, key, None), (0, key, value)]))
 
     def create_gpo(self, displayName, container=None):
-        msg = self.gpo_list(displayName)
-        if len(msg) > 0:
-            ycpbuiltins.y2debug("A GPO already existing with name '%s'" % 
displayName)
-            return
-
-        gpouuid = uuid.uuid4()
-        realm_dn = self.realm_to_dn(self.realm)
-        name = '{%s}' % str(gpouuid).upper()
-        dn = 'CN=%s,CN=Policies,CN=System,%s' % (name, realm_dn)
-        unc_path = "\\\\%s\\sysvol\\%s\\Policies\\%s" % (self.realm, 
self.realm, name)
-        ldap_mod = { 'displayName': [displayName.encode('utf-8')], 
'gPCFileSysPath': [unc_path.encode('utf-8')], 'objectClass': 
[b'groupPolicyContainer'], 'gPCFunctionalityVersion': [b'2'], 'flags': [b'0'], 
'versionNumber': [b'0'] }
-        # gPCMachineExtensionNames MUST be assigned as gpos are modified 
(currently not doing this!)
-
-        machine_dn = 'CN=Machine,%s' % dn
-        user_dn = 'CN=User,%s' % dn
-        sub_ldap_mod = { 'objectClass': [b'container'] }
-
-        gpo = GPOConnection(self.lp, self.creds, unc_path)
-        try:
-            self.ldap_add(dn, addlist(ldap_mod))
-            self.ldap_add(machine_dn, addlist(stringify_ldap(sub_ldap_mod)))
-            self.ldap_add(user_dn, addlist(stringify_ldap(sub_ldap_mod)))
-        except LdapException as e:
-            ycpbuiltins.y2error(traceback.format_exc())
-            ycpbuiltins.y2error('ldap.add_s: %s\n' % e.info if e.info else 
e.msg)
-        gpo.initialize_empty_gpo(displayName)
+        cmd_create = gpo_create(self.lp, self.creds, self)
+        ycpbuiltins.y2debug(cmd_create.run(displayName))
+        cmd_setlink = gpo_setlink(self.lp, self.creds, self)
         if container:
-            self.set_link(dn, container)
-
-    def set_link(self, gpo_dn, container_dn, disabled=False, enforced=False):
-        gplink_options = 0
-        if disabled:
-            gplink_options |= (1 << 0)
-        if enforced:
-            gplink_options |= (1 << 1)
-
-        # Check if valid Container DN
-        msg = self.ldap_search(container_dn, SCOPE_BASE,
-                               "(objectClass=*)",
-                               stringify_ldap(['gPLink']))[0][1]
-
-        # Update existing GPlinks or Add new one
-        existing_gplink = False
-        if 'gPLink' in msg:
-            gplist = parse_gplink(msg['gPLink'][0])
-            gplist = [gplist[k] for k in gplist]
-            existing_gplink = True
-            found = False
-            for g in gplist:
-                if strcasecmp(g['dn'], gpo_dn):
-                    found = True
-                    break
-            if found:
-                ycpbuiltins.y2debug("GPO '%s' already linked to this 
container" % gpo)
-                return
-            else:
-                gplist.insert(0, { 'dn' : gpo_dn, 'options' : gplink_options })
-        else:
-            gplist = []
-            gplist.append({ 'dn' : gpo_dn, 'options' : gplink_options })
-
-        gplink_str = encode_gplink(gplist)
-
-        if existing_gplink:
-            self.ldap_modify(container_dn, stringify_ldap([(1, 'gPLink', 
None), (0, 'gPLink', [gplink_str.encode('utf-8')])]))
-        else:
-            self.ldap_modify(container_dn, stringify_ldap([(0, 'gPLink', 
[gplink_str.encode('utf-8')])]))
+            ycpbuiltins.y2debug(cmd_setlink.run(container, 
cmd_create.get_name()))
 
     def delete_link(self, gpo_dn, container_dn):
-        # Check if valid Container DN
-        msg = self.ldap_search(container_dn, SCOPE_BASE,
-                               "(objectClass=*)",
-                               stringify_ldap(['gPLink']))[0][1]
-
-        found = False
-        if 'gPLink' in msg:
-            gplist = parse_gplink(msg['gPLink'][0])
-            gplist = [gplist[k] for k in gplist]
-            for g in gplist:
-                if strcasecmp(g['dn'], gpo_dn):
-                    gplist.remove(g)
-                    found = True
-                    break
-        else:
-            raise Exception("No GPO(s) linked to this container")
-
-        if not found:
-            raise Exception("GPO '%s' not linked to this container" % gpo_dn)
-
-        if gplist:
-            gplink_str = encode_gplink(gplist)
-            self.ldap_modify(container_dn, stringify_ldap([(1, 'gPLink', 
None), (0, 'gPLink', [gplink_str.encode('utf-8')])]))
-        else:
-            self.ldap_modify(container_dn, stringify_ldap([(1, 'gPLink', 
None)]))
+        cmd_dellink = gpo_dellink(self.lp, self.creds, self)
+        gpo_cn = re.split(',?\w\w=', gpo_dn)[1]
+        ycpbuiltins.y2debug(cmd_dellink.run(container_dn, gpo_cn))
 
     def delete_gpo(self, displayName):
-        msg = self.gpo_list(displayName)
+        msg = self.gpo_list(displayName, attrs=['cn'])
         if len(msg) == 0:
             raise Exception("GPO '%s' does not exist" % displayName)
+        gpo_cn = msg[0][1]['cn'][0]
 
-        unc_path = msg[0][1]['gPCFileSysPath'][0]
-        gpo_dn = msg[0][1]['distinguishedName'][0]
-
-        # Remove links before deleting
-        linked_containers = self.get_gpo_containers(gpo_dn)
-        for container in linked_containers:
-            self.delete_link(gpo_dn, 
container['distinguishedName'][0].decode())
-
-        # Remove LDAP entries
-        self.ldap_delete("CN=User,%s" % str(gpo_dn))
-        self.ldap_delete("CN=Machine,%s" % str(gpo_dn))
-        self.ldap_delete(gpo_dn)
-        try:
-            # Remove GPO files
-            gpo = GPOConnection(self.lp, self.creds, unc_path)
-            gpo.cleanup_gpo()
-        except Exception as e:
-            ycpbuiltins.y2error(traceback.format_exc())
-            ycpbuiltins.y2error(str(e))
+        cmd_del = gpo_del(self.lp, self.creds, self)
+        ycpbuiltins.y2debug(cmd_del.run(gpo_cn))
 
     def get_gpo_containers(self, gpo):
         '''lists dn of containers for a GPO'''
@@ -327,15 +246,11 @@
         self.name = gpo_path.split('\\')[-1]
         self.realm_dn = self.realm_to_dn(self.realm)
         self.gpo_dn = 'CN=%s,CN=Policies,CN=System,%s' % (self.name, 
self.realm_dn)
-        # the SMB bindings rely on having a s3 loadparm
-        s3_lp = s3param.get_context()
-        s3_lp.load(self.lp.configfile)
-        s3_lp.set('realm', self.lp.get('realm'))
         try:
-            self.conn = smb.Conn(self.dc_hostname, service, lp=s3_lp, 
creds=self.creds, sign=True)
-        except Exception as e:
+            self.conn = smb_connection(self.dc_hostname, service, self.lp, 
self.creds, sign=True)
+        except CommandError as e:
             ycpbuiltins.y2error(traceback.format_exc())
-            ycpbuiltins.y2error("Exception %s"%str(e))
+            ycpbuiltins.y2error(e.args[-1])
             self.conn = None
 
     def update_machine_gpe_ini(self, extension):
@@ -359,32 +274,6 @@
         ini_conf.set('General', 'MachineExtensionVersions', 
machine_extension_versions)
         self.write('Group Policy\\GPE.INI', ini_conf)
 
-    def initialize_empty_gpo(self, displayName):
-        # Get new security descriptor
-        ds_sd_flags = ( security.SECINFO_OWNER |
-                        security.SECINFO_GROUP |
-                        security.SECINFO_DACL )
-        msg = self.gpo_list(displayName, 
attrs=stringify_ldap(['nTSecurityDescriptor']))
-        ds_sd_ndr = msg[0][1]['nTSecurityDescriptor'][0]
-        ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl()
-
-        # Create a file system security descriptor
-        domain_sid = self.get_domain_sid()
-        sddl = dsacl2fsacl(ds_sd, domain_sid)
-        fs_sd = security.descriptor.from_sddl(sddl, domain_sid)
-
-        self.__smb_mkdir_p('\\'.join([self.path, 'MACHINE']))
-        self.__smb_mkdir_p('\\'.join([self.path, 'USER']))
-
-        # Set ACL
-        sio = ( security.SECINFO_OWNER |
-                security.SECINFO_GROUP |
-                security.SECINFO_DACL |
-                security.SECINFO_PROTECTED_DACL )
-        self.conn.set_acl(self.path, fs_sd, sio)
-
-        self.__increment_gpt_ini()
-
     def cleanup_gpo(self):
         self.conn.deltree(self.path)
 
@@ -625,3 +514,96 @@
                 else:
                     ycpbuiltins.y2error(e.args[1])
             return filename
+
+class SambaOptions():
+    def __init__(self, lp):
+        self.lp = lp
+
+    def get_loadparm(self):
+        return self.lp
+
+class CredentialsOptions():
+    def __init__(self, creds):
+        self.creds = creds
+
+    def get_credentials(self, *args, **kwargs):
+        return self.creds
+
+class gpo_create(gpo.cmd_create):
+    def __init__(self, lp, creds, samdb):
+        super().__init__()
+        self.sambaopts = SambaOptions(lp)
+        self.credopts = CredentialsOptions(creds)
+        self.samdb = samdb
+        self.outf = StringIO()
+
+    def samdb_connect(self):
+        pass # Our samdb is already connected
+
+    def get_name(self):
+        return self.gpo_name
+
+    def run(self, displayname):
+        try:
+            super().run(displayname, sambaopts=self.sambaopts, 
credopts=self.credopts)
+        except (CommandError, NTSTATUSError, WERRORError, Exception) as e:
+            ycpbuiltins.y2error(traceback.format_exc())
+            ycpbuiltins.y2error(str(e))
+        return self.outf.getvalue()
+
+class gpo_setlink(gpo.cmd_setlink):
+    def __init__(self, lp, creds, samdb):
+        super().__init__()
+        self.sambaopts = SambaOptions(lp)
+        self.credopts = CredentialsOptions(creds)
+        self.samdb = samdb
+        self.outf = StringIO()
+
+    def samdb_connect(self):
+        pass # Our samdb is already connected
+
+    def run(self, container_dn, gpo):
+        try:
+            super().run(container_dn, gpo, sambaopts=self.sambaopts, 
credopts=self.credopts)
+        except (CommandError, NTSTATUSError, WERRORError, Exception) as e:
+            ycpbuiltins.y2error(traceback.format_exc())
+            ycpbuiltins.y2error(str(e))
+        return self.outf.getvalue()
+
+class gpo_dellink(gpo.cmd_dellink):
+    def __init__(self, lp, creds, samdb):
+        super().__init__()
+        self.sambaopts = SambaOptions(lp)
+        self.credopts = CredentialsOptions(creds)
+        self.samdb = samdb
+        self.outf = StringIO()
+
+    def samdb_connect(self):
+        pass # Our samdb is already connected
+
+    def run(self, container, gpo):
+        try:
+            super().run(container, gpo, sambaopts=self.sambaopts, 
credopts=self.credopts)
+        except (CommandError, NTSTATUSError, WERRORError, Exception) as e:
+            ycpbuiltins.y2error(traceback.format_exc())
+            ycpbuiltins.y2error(str(e))
+        return self.outf.getvalue()
+
+class gpo_del(gpo.cmd_del):
+    def __init__(self, lp, creds, samdb):
+        super().__init__()
+        self.sambaopts = SambaOptions(lp)
+        self.credopts = CredentialsOptions(creds)
+        self.samdb = samdb
+        self.outf = StringIO()
+
+    def samdb_connect(self):
+        pass # Our samdb is already connected
+
+    def run(self, gpo):
+        try:
+            super().run(gpo, sambaopts=self.sambaopts, credopts=self.credopts)
+        except (CommandError, NTSTATUSError, WERRORError, Exception) as e:
+            ycpbuiltins.y2error(traceback.format_exc())
+            ycpbuiltins.y2error(str(e))
+        return self.outf.getvalue()


Reply via email to