Hello community,

here is the log from the commit of package yast2-gpmc for openSUSE:Factory 
checked in at 2019-04-28 20:01:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/yast2-gpmc (Old)
 and      /work/SRC/openSUSE:Factory/.yast2-gpmc.new.5536 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "yast2-gpmc"

Sun Apr 28 20:01:16 2019 rev:2 rq:694808 version:1.4.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/yast2-gpmc/yast2-gpmc.changes    2018-11-13 
18:30:16.812925169 +0100
+++ /work/SRC/openSUSE:Factory/.yast2-gpmc.new.5536/yast2-gpmc.changes  
2019-04-28 20:01:19.570867155 +0200
@@ -1,0 +2,16 @@
+Fri Mar 15 16:18:08 UTC 2019 - [email protected]
+
+- Use libsmb instead of the deprecated smb library
+
+-------------------------------------------------------------------
+Thu Mar 14 15:30:58 UTC 2019 - [email protected]
+
+- Update to 1.4.2:
+  + Move module to Network Services
+  + Use samba preg file pack/unpack (Requires samba 4.10)
+  + Unconfigured/Enable/Disable policy states
+  + Use common adcommon password prompt (Requires yast2-adcommon-python)
+  + Add a unified file/actions menu, instead of various buttons
+  + Allow switching domains
+
+-------------------------------------------------------------------

Old:
----
  _service
  yast2-gpmc-v1.4.1+git.11.e264ccc.tar.bz2

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

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

Other differences:
------------------
++++++ yast2-gpmc.spec ++++++
--- /var/tmp/diff_new_pack.f4qwdg/_old  2019-04-28 20:01:21.190866178 +0200
+++ /var/tmp/diff_new_pack.f4qwdg/_new  2019-04-28 20:01:21.194866175 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package yast2-gpmc
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,19 +17,20 @@
 
 
 Name:           yast2-gpmc
-Version:        1.4.1+git.11.e264ccc
+Version:        1.4.2
 Release:        0
 Summary:        Group Policy Management Console for YaST
 License:        GPL-3.0-only
 Group:          Productivity/Networking/Samba
-Url:            http://www.github.com/dmulder/yast2-gpmc
-Source:         %{name}-v%{version}.tar.bz2
+Url:            http://www.github.com/yast-samba/yast2-gpmc
+Source:         %{name}-%{version}.tar.bz2
 BuildArch:      noarch
 Requires:       krb5-client
 Requires:       python3-ldap
 Requires:       samba-client
-Requires:       samba-python3
+Requires:       samba-python3 >= 4.10.0
 Requires:       yast2
+Requires:       yast2-adcommon-python
 Requires:       yast2-python3-bindings >= 4.0.0
 BuildRequires:  autoconf
 BuildRequires:  automake
@@ -47,10 +48,10 @@
 modifying Group Policy Objects in Active Directory.
 
 %prep
-%setup -q -n %{name}-v%{version}
+%setup -q
 
 %build
-autoreconf -if
+make -f Makefile.cvs all
 
 CONFIGURE_OPTIONS="\
 %if 0%{?is_opensuse}
@@ -59,23 +60,19 @@
         --disable-experimental \
 %endif
 "
-
 %configure ${CONFIGURE_OPTIONS}
-make %{?_smp_mflags}
+make
 
 %install
-%make_install
+%yast_install
 
 %files
 %defattr(-,root,root)
-%dir %{_datadir}/YaST2/include/gpmc
-%{_datadir}/YaST2/clients/gpmc.py
-%{_datadir}/YaST2/include/gpmc/complex.py
-%{_datadir}/YaST2/include/gpmc/dialogs.py
-%{_datadir}/YaST2/include/gpmc/wizards.py
-%{_datadir}/YaST2/include/gpmc/defaults.py
-%{_datadir}/applications/YaST2/gpmc.desktop
-%dir %{_datadir}/doc/yast2-gpmc
-%{_datadir}/doc/yast2-gpmc/COPYING
+%dir %{yast_yncludedir}/gpmc
+%{yast_yncludedir}/gpmc/*
+%{yast_clientdir}/*.py
+%{yast_desktopdir}/gpmc.desktop
+%doc %{yast_docdir}
+%license COPYING
 
 %changelog

++++++ yast2-gpmc-v1.4.1+git.11.e264ccc.tar.bz2 -> yast2-gpmc-1.4.2.tar.bz2 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/.travis.yml 
new/yast2-gpmc-1.4.2/.travis.yml
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/.travis.yml    1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.4.2/.travis.yml    2019-03-15 17:19:21.000000000 +0100
@@ -0,0 +1,11 @@
+sudo: required
+language: bash
+services:
+  - docker
+
+before_install:
+  - docker build -t yast2-gpmc-image .
+script:
+  # the "yast-travis-cpp" script is included in the base yastdevel/cpp image
+  # see https://github.com/yast/docker-yast-cpp/blob/master/yast-travis-cpp
+  - docker run -it -e TRAVIS=1 -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" 
yast2-gpmc-image yast-travis-cpp
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/Dockerfile 
new/yast2-gpmc-1.4.2/Dockerfile
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/Dockerfile     1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.4.2/Dockerfile     2019-03-15 17:19:21.000000000 +0100
@@ -0,0 +1,2 @@
+FROM yastdevel/cpp
+COPY . /usr/src/app
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/Makefile.am 
new/yast2-gpmc-1.4.2/Makefile.am
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/Makefile.am    2018-11-12 
08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/Makefile.am    1970-01-01 01:00:00.000000000 +0100
@@ -1,163 +0,0 @@
-# Emacs: -*- makefile -*-
-#
-# Toplevel Makefile.am for a YaST2 subproject
-#
-# -- This file is generated by y2automake - DO NOT EDIT! --
-#    (Edit ./SUBDIRS instead)
-#
-
-#where devtools are
-Y2TOOL = $(Y2DEVTOOLS_PREFIX)/bin/y2tool
-
-RPMNAME                = $(shell cat $(srcdir)/RPMNAME)
-VERSION                        = $(shell grep -m 1 '^[[:space:]]*Version:' 
$(srcdir)/package/$(RPMNAME).spec | sed -e 
's/Version:[[:space:]]*\([[:print:]]\+\)/\1/')
-SUBDIRS_FILE           = $(shell test -e $(srcdir)/SUBDIRS      && echo 
SUBDIRS)
-ACINCLUDE_FILE         = $(shell test -e $(srcdir)/acinclude.m4 && echo 
acinclude.m4)
-
-COPYRIGHT_files    = COPYING
-doc_DATA = $(COPYRIGHT_files)
-
-# do we do Makefile.am for devtools? It is a little special...
-IS_DEVTOOLS            = $(findstring yast2-devtools,$(RPMNAME))
-
-DEVTOOLS_DIR           = $(if 
$(IS_DEVTOOLS),$(srcdir),$(Y2DEVTOOLS_PREFIX)/share/YaST2/data/devtools)
-
-# less strict; prefer bzip2
-AUTOMAKE_OPTIONS = foreign dist-bzip2 no-dist-gzip
-# where devtools install m4 snippets
-# argh, executed literally
-#ACLOCAL_AMFLAGS = -I $(Y2DEVTOOLS_PREFIX)/share/aclocal
-ACLOCAL_AMFLAGS = -I . -I $(if test -d ./build-tools; then echo ./build-tools; 
else pkg-config --print-errors --variable=datadir yast2-devtools; fi)/aclocal
-
-# create bzip2ed tar and make some sanity checks
-$(RPMNAME)-$(VERSION).tar.bz2: checkpo dist-bzip2
-       @if [ $(bunzip2 -c $(RPMNAME)-$(VERSION).tar.bz2 | wc --bytes) = 0 ] ; 
then \
-           echo "Error: created tar is empty" ; \
-           exit 1 ; \
-       fi
-
-CLEANFILES =
-MAINTAINERCLEANFILES = package/$(RPMNAME)-$(VERSION).tar.bz2 
package/$(RPMNAME).spec
-
-POT_DST = $(shell find -type d -name testsuite -prune , \
-       -type f -name "*.pot") 
-
-EXTRA_DIST = \
-       RPMNAME MAINTAINER configure.in.in                      \
-       $(COPYRIGHT_files)                                      \
-       $(SUBDIRS_FILE) $(ACINCLUDE_FILE)                       \
-       $(if $(IS_DEVTOOLS),$(POT_DST))
-
-show-extra-dist:
-       @echo $(EXTRA_DIST)
-
-# info '(automake)Conditionals'
-if CREATE_PKGCONFIG
-# create the file here instead of by configure
-# because the prerequisite is made here (not anymore!)
-# and we don't want any paths in y2autoconf
-# info '(autoconf)config.status Invocation'
-$(RPMNAME).pc: $(RPMNAME).pc.in config.status
-       ./config.status --file=$@:$<
-
-if CREATE_PKGCONFIG_NOARCH
-pkgconfigdatadir = .
-pkgconfigdata_DATA = $(RPMNAME).pc
-else
-pkgconfigdir = .
-pkgconfig_DATA = $(RPMNAME).pc
-endif
-
-EXTRA_DIST += $(RPMNAME).pc.in
-endif
-
-LIBTOOL_DEPS = @LIBTOOL_DEPS@
-
-libtool: $(LIBTOOL_DEPS)
-       $(SHELL) ./config.status libtool
-
-pot:
-       $(Y2TOOL) y2makepot -s $(srcdir)
-
-install-pot: pot
-       @POT_DST=$(find -type d -name testsuite -prune , \
-               -type f -name "*.pot") ; \
-       if [ -n "$$POT_DST" ] ; then \
-           echo "mkdir -p $(DESTDIR)$(potdir)" ; \
-           mkdir -p $(DESTDIR)$(potdir) ; \
-           list="$$POT_DST"; \
-           for I in $$list ; \
-           do \
-               echo $$I ; \
-               if [ "$$I" == "pot" ] ; then \
-                       continue ; \
-               fi ; \
-               echo "$(INSTALL_DATA) $$I $(DESTDIR)$(potdir)" ; \
-               $(INSTALL_DATA) $$I $(DESTDIR)$(potdir) ; \
-           done ; \
-       fi
-
-spellcheck: pot
-       $(Y2TOOL) pot-spellcheck
-
-# all-local: $(if $(IS_DEVTOOLS),,$(POT_DST))
-
-package-local: check-parse $(if $(IS_DEVTOOLS),,$(POT_DST)) 
$(RPMNAME)-$(VERSION).tar.bz2
-       rm -f package/$(RPMNAME)-*.tar.bz2
-       rm -f package/*~
-       rm -f package/*.bak
-       rm -f package/*.auto
-       mv $(RPMNAME)-$(VERSION).tar.bz2 package/
-       if ! test -x $(Y2TOOL); then \
-           echo "$(Y2TOOL): not found."; \
-           echo "You have to install yast2-devtools to making a package"; \
-           false; \
-       fi
-       here=$(pwd); \
-       cd $(srcdir) && for i in $(RPMNAME)*.spec.in; do \
-           if [ -f "$$i" ]; then \
-               newname="$(echo "$$i" | sed "s/\.in$$//g")"; \
-               $(Y2TOOL) create-spec < $$i > $$here/package/$${newname} ; \
-           fi \
-       done
-
-package: check-up-to-date check-tagversion check-textdomain package-local
-
-TAGVERSION      = $(Y2TOOL) tagversion
-
-# check if there is no modified files and all commits were pushed
-check-up-to-date:
-       if [ $(git status --short --branch | sed '/##[^[]*$/d;/^??/d' | wc -l) 
-gt 0 ]; then \
-         (echo "ERROR: Source is not commited and pushed. See `git status`"; 
false) \
-       fi
-
-check-tagversion:
-       cd $(srcdir) && $(TAGVERSION) --check >/dev/null; \
-       [ $$? = 0 ] || ( echo "ERROR: Please run 'tagversion' first"; false )
-
-check-parse-old:
-       @if [ $(find -type f -name "*.ycp" | wc -l) -gt 0 -a "$(RPMNAME)" != 
"yast2-core" ] ; then \
-               echo "Running parseycp..." ; \
-               parseycp -q -R ; \
-       else \
-               echo "Not running parseycp." ; \
-       fi
-
-check-parse:
-       @echo "Not running parseycp."
-
-check-textdomain:
-       $(Y2TOOL) check-textdomain $(srcdir)
-
-stable: checkin-stable
-
-checkin-stable: package
-       $(Y2TOOL) checkin-stable
-
-
-# For po/ modules
-checkpo:
-       test ! -f $(srcdir)/po/Makefile || $(MAKE) -C po checkpo
-#      test ! -f $(srcdir)/po/Makefile || $(MAKE) -C po checkpo make-pox
-# No ./SUBDIRS file found - assuming default: All direct subdirs with 
Makefile.am
-SUBDIRS = agents doc src
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/Makefile.cvs 
new/yast2-gpmc-1.4.2/Makefile.cvs
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/Makefile.cvs   1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.4.2/Makefile.cvs   2019-03-15 17:19:21.000000000 +0100
@@ -0,0 +1,23 @@
+#
+# Makefile.cvs
+#
+
+LIB = $(shell y2tool get-lib)
+
+PREFIX = /usr
+
+configure: all
+       ./configure --prefix=$(PREFIX) --libdir=$(PREFIX)/$(LIB)
+
+all:
+       y2tool y2autoconf
+       y2tool y2automake
+       autoreconf --force --install
+
+install: configure
+       make
+       make install
+
+reconf: all
+       ./config.status --recheck
+       ./config.status
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/Rakefile 
new/yast2-gpmc-1.4.2/Rakefile
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/Rakefile       1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.4.2/Rakefile       2019-03-15 17:19:21.000000000 +0100
@@ -0,0 +1,6 @@
+require "yast/rake"
+
+Yast::Tasks.configuration do |conf|
+  #lets ignore license check for now
+  conf.skip_license_check << /.*/
+end
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/SUBDIRS 
new/yast2-gpmc-1.4.2/SUBDIRS
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/SUBDIRS        1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.4.2/SUBDIRS        2019-03-15 17:19:21.000000000 +0100
@@ -0,0 +1,2 @@
+doc src
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/configure.ac 
new/yast2-gpmc-1.4.2/configure.ac
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/configure.ac   2018-11-12 
08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/configure.ac   1970-01-01 01:00:00.000000000 +0100
@@ -1,77 +0,0 @@
-dnl configure.ac for yast2-gpmc
-dnl
-dnl -- This file is generated by y2autoconf  - DO NOT EDIT! --
-dnl    (edit configure.ac.in or configure.in.in instead)
-
-AC_INIT([yast2-gpmc],[1.0],[http://bugs.opensuse.org/],[yast2-gpmc])
-AM_INIT_AUTOMAKE
-AM_PATH_PYTHON([2.7])
-
-dnl Checks for programs.
-AC_PROG_INSTALL
-dnl The YCP interpreter checks whether dependent ybc files are older
-dnl so we must preserve their timestamps
-INSTALL="${INSTALL} -p"
-AC_PROG_LN_S
-AC_PROG_MAKE_SET
-
-dnl pkgconfig
-AC_ARG_VAR([PKG_CONFIG_PATH], [where to search for pkg-config files])
-dnl devtools
-dnl ...
-
-AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental], [Enable 
experimental features]))
-
-if test "x$enable_experimental" = "xyes"; then
-AC_SUBST([experimental], ['True'])
-else
-AC_SUBST([experimental], ['False'])
-fi
-
-dnl no need for AC_ARG_VAR
-AC_PATH_PROG(XGETTEXT, xgettext)
-if test -z "$XGETTEXT" ; then
-    AC_MSG_ERROR(xgettext is missing; please install gettext-tools.)
-fi
-
-Y2DEVTOOLS_PREFIX=`pkg-config --print-errors --variable=prefix yast2-devtools`
-AC_SUBST(Y2DEVTOOLS_PREFIX)
-devtools_ybindir=`pkg-config --print-errors --variable=ybindir yast2-devtools`
-devtools_yast2dir=`pkg-config --print-errors --variable=yast2dir 
yast2-devtools`
-
-dnl producing pkg-config for others?
-AM_CONDITIONAL(CREATE_PKGCONFIG, test "x${CREATE_PKGCONFIG}" != x)
-AM_CONDITIONAL(CREATE_PKGCONFIG_NOARCH, test "x${CREATE_PKGCONFIG}" = xnoarch)
-
-dbdir=${devtools_yast2dir}/data/docbook
-STYLESHEET_HTML=${dbdir}/stylesheets/customize-html.xsl
-STYLESHEET_PDF=${dbdir}/stylesheets/customize-fo.xsl
-STYLESHEET_CSS=${dbdir}/css/yast2docs.css
-AC_SUBST(STYLESHEET_HTML)
-AC_SUBST(STYLESHEET_PDF)
-AC_SUBST(STYLESHEET_CSS)
-
-
-AC_CHECK_FILE($devtools_yast2dir/data/testsuite/Makefile.testsuite, [], [
-    AC_MSG_WARN([yast2-testsuite.rpm is not installed])
-])
-
-# handle .dep files in Makefile.am.common if any YCP module is present
-AC_MSG_CHECKING([for YCP modules])
-
-# YCP module file name starts with an upper case letter
-[find . -type f | grep -q "[[:upper:]][^/]*\.ycp$" && has_ycp_modules=1]
-AM_CONDITIONAL([HAS_YCP_MODULES], [test -n "$has_ycp_modules"])
-
-if test -n "$has_ycp_modules"; then
-  AC_MSG_RESULT([found])
-else
-  AC_MSG_RESULT([not found])
-fi
-
-
-AC_CONFIG_FILES(Makefile agents/Makefile
-doc/Makefile
-src/Makefile)
-AC_OUTPUT
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/configure.in.in 
new/yast2-gpmc-1.4.2/configure.in.in
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/configure.in.in        1970-01-01 
01:00:00.000000000 +0100
+++ new/yast2-gpmc-1.4.2/configure.in.in        2019-03-15 17:19:21.000000000 
+0100
@@ -0,0 +1,20 @@
+## YCP module configure.in.in
+
+## Initialize
+@YAST2-INIT-COMMON@
+@YAST2-INIT-YCP@
+
+## some common checks
+@YAST2-CHECKS-COMMON@
+@YAST2-CHECKS-YCP@
+
+AC_ARG_ENABLE([experimental], AS_HELP_STRING([--enable-experimental], [Enable 
experimental features]))
+
+if test "x$enable_experimental" = "xyes"; then
+AC_SUBST([experimental], ['True'])
+else
+AC_SUBST([experimental], ['False'])
+fi
+
+## and generate the output...
+@YAST2-OUTPUT@
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-gpmc-v1.4.1+git.11.e264ccc/package/yast2-gpmc.changes 
new/yast2-gpmc-1.4.2/package/yast2-gpmc.changes
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/package/yast2-gpmc.changes     
2018-11-12 08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/package/yast2-gpmc.changes     2019-03-15 
17:19:21.000000000 +0100
@@ -1,4 +1,20 @@
 -------------------------------------------------------------------
+Fri Mar 15 16:18:08 UTC 2019 - [email protected]
+
+- Use libsmb instead of the deprecated smb library
+
+-------------------------------------------------------------------
+Thu Mar 14 15:30:58 UTC 2019 - [email protected]
+
+- Update to 1.4.2:
+  + Move module to Network Services
+  + Use samba preg file pack/unpack (Requires samba 4.10)
+  + Unconfigured/Enable/Disable policy states
+  + Use common adcommon password prompt (Requires yast2-adcommon-python)
+  + Add a unified file/actions menu, instead of various buttons
+  + Allow switching domains
+
+-------------------------------------------------------------------
 Thu Nov  1 21:50:27 UTC 2018 - [email protected]
 
 - Disable experimental features in sle
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/yast2-gpmc-v1.4.1+git.11.e264ccc/package/yast2-gpmc.spec 
new/yast2-gpmc-1.4.2/package/yast2-gpmc.spec
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/package/yast2-gpmc.spec        
2018-11-12 08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/package/yast2-gpmc.spec        2019-03-15 
17:19:21.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package yast2-gpmc
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -12,25 +12,26 @@
 # license that conforms to the Open Source Definition (Version 1.9)
 # published by the Open Source Initiative.
 
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
 
 Name:           yast2-gpmc
-Version:        1.4.1
+Version:        1.4.2
 Release:        0
 Summary:        Group Policy Management Console for YaST
-License:        GPL-3.0
+License:        GPL-3.0-only
 Group:          Productivity/Networking/Samba
-Url:            http://www.github.com/dmulder/yast2-gpmc
-Source:         %{name}-v%{version}.tar.bz2
+Url:            http://www.github.com/yast-samba/yast2-gpmc
+Source:         %{name}-%{version}.tar.bz2
 BuildArch:      noarch
 Requires:       krb5-client
 Requires:       python3-ldap
 Requires:       samba-client
-Requires:       samba-python3
+Requires:       samba-python3 >= 4.10.0
 Requires:       yast2
 Requires:       yast2-python3-bindings >= 4.0.0
+Requires:       yast2-adcommon-python
 BuildRequires:  autoconf
 BuildRequires:  automake
 BuildRequires:  perl-XML-Writer
@@ -47,10 +48,10 @@
 modifying Group Policy Objects in Active Directory.
 
 %prep
-%setup -q -n %{name}-v%{version}
+%setup -q
 
 %build
-autoreconf -if
+make -f Makefile.cvs all
 
 CONFIGURE_OPTIONS="\
 %if 0%{?is_opensuse}
@@ -59,23 +60,19 @@
         --disable-experimental \
 %endif
 "
-
 %configure ${CONFIGURE_OPTIONS}
-make %{?_smp_mflags}
+make
 
 %install
-%make_install
+%yast_install
 
 %files
 %defattr(-,root,root)
-%dir %{_datadir}/YaST2/include/gpmc
-%{_datadir}/YaST2/clients/gpmc.py
-%{_datadir}/YaST2/include/gpmc/complex.py
-%{_datadir}/YaST2/include/gpmc/dialogs.py
-%{_datadir}/YaST2/include/gpmc/wizards.py
-%{_datadir}/YaST2/include/gpmc/defaults.py
-%{_datadir}/applications/YaST2/gpmc.desktop
-%dir %{_datadir}/doc/yast2-gpmc
-%{_datadir}/doc/yast2-gpmc/COPYING
+%dir %{yast_yncludedir}/gpmc
+%{yast_yncludedir}/gpmc/*
+%{yast_clientdir}/*.py
+%{yast_desktopdir}/gpmc.desktop
+%doc %{yast_docdir}
+%license COPYING
 
 %changelog
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/complex.py 
new/yast2-gpmc-1.4.2/src/complex.py
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/complex.py 2018-11-12 
08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/src/complex.py 2019-03-15 17:19:21.000000000 +0100
@@ -1,6 +1,5 @@
 from __future__ import absolute_import, division, print_function, 
unicode_literals
-import ldap, ldap.modlist, ldap.sasl
-from samba import smb
+from samba.samba3 import libsmb_samba_internal as smb, param as s3param
 import six
 if six.PY3:
     def ConfigParser(**kwargs):
@@ -15,47 +14,21 @@
 from samba.dcerpc import nbt
 from subprocess import Popen, PIPE
 import uuid
-from ldap.modlist import addModlist as addlist
-from ldap.modlist import modifyModlist as modlist
 import re
 import traceback
 import ldb
 from samba.dcerpc import security
-from samba.ndr import ndr_unpack
 import samba.security
 from samba.ntacls import dsacl2fsacl
 from yast import ycpbuiltins
 import struct
 from samba import registry
 from collections import OrderedDict
-
-def strcmp(first, second):
-    if six.PY3:
-        if isinstance(first, six.string_types):
-            first = six.binary_type(first, 'utf8')
-        if isinstance(second, six.string_types):
-            second = six.binary_type(second, 'utf8')
-    return first == second
-
-def strcasecmp(first, second):
-    if six.PY3:
-        if isinstance(first, six.string_types):
-            first = six.binary_type(first, 'utf8')
-        if isinstance(second, six.string_types):
-            second = six.binary_type(second, 'utf8')
-    return first.lower() == second.lower()
-
-class LdapException(Exception):
-    def __init__(self, *args, **kwargs):
-        Exception.__init__(self, *args, **kwargs)
-        if len(self.args) > 0:
-            self.msg = self.args[0]
-        else:
-            self.msg = None
-        if len(self.args) > 1:
-            self.info = self.args[1]
-        else:
-            self.info = None
+from samba.ndr import ndr_unpack, ndr_pack
+from samba.dcerpc import preg
+from adcommon.creds import kinit_for_gssapi
+from adcommon.yldap import Ldap, LdapException, SCOPE_SUBTREE, SCOPE_ONELEVEL, 
SCOPE_BASE, addlist, modlist
+from adcommon.strings import strcmp, strcasecmp
 
 def open_bytes(filename):
     if six.PY3:
@@ -144,132 +117,10 @@
         ret += "[LDAP://%s;%d]" % (g['dn'], g['options'])
     return ret
 
-REGFILE_SIGNATURE = 0x67655250
-REGISTRY_FILE_VERSION = 1
-def unpack_registry_pol(data):
-    pol_conf = OrderedDict()
-    sig = struct.unpack('<L', data[:4])[0]
-    if sig != REGFILE_SIGNATURE:
-        raise IOError('Registry file signature did not match')
-    vers = struct.unpack('<L', data[4:8])[0]
-    if vers != REGISTRY_FILE_VERSION:
-        raise IOError('Registry file version did not match')
-    o = 7
-    while o < len(data)-1:
-        obrack = data[o:o+2].decode('utf-16-be')
-        if obrack != '[':
-            raise IOError('Failed unpacking data from registry pol')
-        o += 2
-        rk_epos = data[o:].find(b';')-1
-        if rk_epos < 0:
-            raise IOError('Failed unpacking data from registry pol')
-        try:
-            reg_key = data[o:o+rk_epos-2].decode('utf-16-be')
-        except UnicodeDecodeError:
-            raise IOError('Failed unpacking data from registry pol')
-        if not reg_key in pol_conf.keys():
-            pol_conf[reg_key] = {}
-        o += rk_epos
-        osep = data[o:o+2].decode('utf-16-be')
-        if osep != ';':
-            raise IOError('Failed unpacking data from registry pol')
-        o += 2
-        rk_epos = data[o:].find(b';')-1
-        if rk_epos < 0:
-            raise IOError('Failed unpacking data from registry pol')
-        key = data[o:o+rk_epos-2].decode('utf-16-be')
-        o += rk_epos
-        osep = data[o:o+2].decode('utf-16-be')
-        if osep != ';':
-            raise IOError('Failed unpacking data from registry pol')
-        o += 2
-        rk_epos = data[o:].find(b';')-1
-        if rk_epos < 0:
-            raise IOError('Failed unpacking data from registry pol')
-        ntype = struct.unpack(">Hxx", data[o:o+rk_epos])[0]
-        rtype = registry.str_regtype(ntype)
-        o += rk_epos
-        osep = data[o:o+2].decode('utf-16-be')
-        if osep != ';':
-            raise IOError('Failed unpacking data from registry pol')
-        o += 2
-        rsize = struct.unpack("<xHx", data[o:o+4])[0]
-        o += 4
-        osep = data[o:o+2].decode('utf-16-be')
-        if osep != ';':
-            raise IOError('Failed unpacking data from registry pol')
-        o += 2
-        if rtype == 'REG_SZ':
-            val = data[o:o+rsize][:-2].decode('utf-16-be')
-        elif rtype == 'REG_DWORD':
-            val = struct.unpack("<xHx", data[o:o+rsize])[0]
-        elif rtype == 'REG_BINARY':
-            val = data[o:o+rsize]
-        elif rtype == 'REG_NONE':
-            val = None
-        else:
-            ycpbuiltins.y2warning('%s Not Implemented' % rtype)
-            raise IOError('Failed unpacking value from registry pol')
-        o += rsize
-        cbrack = data[o:o+2]
-        if cbrack != b'\x00]' and cbrack != b'<]':
-            raise IOError('Failed unpacking data from registry pol')
-        o += 2
-
-        pol_conf[reg_key][key] = {}
-        pol_conf[reg_key][key]['value'] = val
-        pol_conf[reg_key][key]['type'] = ntype
-        pol_conf[reg_key][key]['size'] = rsize
-    return pol_conf
-
-def pack_registry_pol(pol_conf):
-    ret = struct.pack('<L', REGFILE_SIGNATURE)
-    ret += struct.pack('<Hx', REGISTRY_FILE_VERSION)
-    for reg_key in pol_conf.keys():
-        for key in pol_conf[reg_key].keys():
-            ret += b'\x00['
-            ret += reg_key.encode('utf-16-be')
-            ret += b'\x00\x00'
-            ret += b'\x00;'
-            ret += key.encode('utf-16-be')
-            ret += b'\x00\x00'
-            ret += b'\x00;'
-            ret += struct.pack(">Hxx", pol_conf[reg_key][key]['type'])
-            ret += b'\x00;'
-            ret += struct.pack("<xHx", pol_conf[reg_key][key]['size'])
-            ret += b'\x00;'
-            rtype = registry.str_regtype(pol_conf[reg_key][key]['type'])
-            if rtype == 'REG_SZ':
-                ret += pol_conf[reg_key][key]['value'].encode('utf-16-be') + 
b'\x00\x00'
-            elif rtype == 'REG_DWORD':
-                ret += struct.pack("<xHx", pol_conf[reg_key][key]['value'])
-            elif rtype == 'REG_BINARY':
-                ret += pol_conf[reg_key][key]['value']
-            elif rtype == 'REG_NONE':
-                pass
-            else:
-                raise IOError('Failed packing value for registry pol')
-            if rtype == 'REG_BINARY':
-                ret += b'<]'
-            else:
-                ret += b'\x00]'
-    ret += b'\x00'
-    return ret
-
-class GPConnection:
+class GPConnection(Ldap):
     def __init__(self, lp, creds):
-        self.lp = lp
-        self.creds = creds
-        self.realm = lp.get('realm')
+        super().__init__(lp, creds)
         self.kinit = False
-        self.__ldap_connect()
-
-    def __kinit_for_gssapi(self):
-        p = Popen(['kinit', '%s@%s' % (self.creds.get_username(), self.realm) 
if not self.realm in self.creds.get_username() else self.creds.get_username()], 
stdin=PIPE, stdout=PIPE, stderr=PIPE)
-        p.stdin.write(('%s\n' % self.creds.get_password()).encode())
-        p.stdin.flush()
-        self.kinit = p.wait() == 0
-        return self.kinit
 
     def realm_to_dn(self, realm):
         return ','.join(['DC=%s' % part for part in realm.lower().split('.')])
@@ -284,7 +135,7 @@
             wkguiduc = 'A361B2FFFFD211D1AA4B00C04FD7D83A'
         elif strcmp(container, 'users'):
             wkguiduc = 'A9D1CA15768811D1ADED00C04FD8D5CD'
-        result = self.ldap_search_s('<WKGUID=%s,%s>' % (wkguiduc, 
self.realm_to_dn(self.realm)), ldap.SCOPE_SUBTREE, '(objectClass=container)', 
stringify_ldap(['distinguishedName']))
+        result = self.ldap_search_s('<WKGUID=%s,%s>' % (wkguiduc, 
self.realm_to_dn(self.realm)), SCOPE_SUBTREE, '(objectClass=container)', 
stringify_ldap(['distinguishedName']))
         result = stringify_ldap(result)
         if result and len(result) > 0 and len(result[0]) > 1 and 
'distinguishedName' in result[0][1] and len(result[0][1]['distinguishedName']) 
> 0:
             res = result[0][1]['distinguishedName'][-1]
@@ -292,11 +143,11 @@
         return stringify_ldap(res)
 
     def user_from_sid(self, sid, attrs=[]):
-        res = self.ldap_search(self.__well_known_container('users'), 
ldap.SCOPE_SUBTREE, '(objectSID=%s)' % sid, stringify_ldap(attrs))
+        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), ldap.SCOPE_BASE, 
"(objectClass=*)", [])
+        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=[]):
@@ -305,7 +156,7 @@
         search_expr = '(objectClass=groupPolicyContainer)'
         if displayName is not None:
             search_expr = 
'(&(objectClass=groupPolicyContainer)(displayname=%s))' % 
ldb.binary_encode(displayName)
-        result = self.ldap_search(res, ldap.SCOPE_SUBTREE, search_expr, 
stringify_ldap(attrs))
+        result = self.ldap_search(res, SCOPE_SUBTREE, search_expr, 
stringify_ldap(attrs))
         result = stringify_ldap(result)
         return result
 
@@ -332,7 +183,7 @@
 
         gpo = GPOConnection(self.lp, self.creds, unc_path)
         try:
-            self.ldap_add(dn, addlist(stringify_ldap(ldap_mod)))
+            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:
@@ -350,7 +201,7 @@
             gplink_options |= (1 << 1)
 
         # Check if valid Container DN
-        msg = self.ldap_search(container_dn, ldap.SCOPE_BASE,
+        msg = self.ldap_search(container_dn, SCOPE_BASE,
                                "(objectClass=*)",
                                stringify_ldap(['gPLink']))[0][1]
 
@@ -383,7 +234,7 @@
 
     def delete_link(self, gpo_dn, container_dn):
         # Check if valid Container DN
-        msg = self.ldap_search(container_dn, ldap.SCOPE_BASE,
+        msg = self.ldap_search(container_dn, SCOPE_BASE,
                                "(objectClass=*)",
                                stringify_ldap(['gPLink']))[0][1]
 
@@ -437,7 +288,7 @@
         '''lists dn of containers for a GPO'''
 
         search_expr = "(&(objectClass=*)(gPLink=*%s*))" % gpo
-        msg = self.ldap_search(self.realm_to_dn(self.realm), 
ldap.SCOPE_SUBTREE, search_expr, [])
+        msg = self.ldap_search(self.realm_to_dn(self.realm), SCOPE_SUBTREE, 
search_expr, [])
         if not msg:
             return []
 
@@ -445,7 +296,7 @@
 
     def get_gpos_for_container(self, container_dn):
         search_expr = '(distinguishedName=%s)' % container_dn
-        msg = self.ldap_search(self.realm_to_dn(self.realm), 
ldap.SCOPE_SUBTREE, search_expr, [])
+        msg = self.ldap_search(self.realm_to_dn(self.realm), SCOPE_SUBTREE, 
search_expr, [])
         if not msg:
             return None
 
@@ -456,112 +307,19 @@
             gpos = []
         for gpo in gpos:
             search_expr = '(distinguishedName=%s)' % gpos[gpo]['dn']
-            msg = self.ldap_search(self.realm_to_dn(self.realm), 
ldap.SCOPE_SUBTREE, search_expr, [])
+            msg = self.ldap_search(self.realm_to_dn(self.realm), 
SCOPE_SUBTREE, search_expr, [])
             results.append(msg[0])
 
         return results
 
     def get_containers_with_gpos(self):
         search_expr = "(|(objectClass=organizationalUnit)(objectClass=domain))"
-        msg = self.ldap_search(self.realm_to_dn(self.realm), 
ldap.SCOPE_SUBTREE, search_expr, [])
+        msg = self.ldap_search(self.realm_to_dn(self.realm), SCOPE_SUBTREE, 
search_expr, [])
         if not msg:
             return []
 
         return [res[1] for res in msg if type(res[1]) is dict]
 
-    def __ldap_exc_msg(self, e):
-        if len(e.args) > 0 and \
-          type(e.args[-1]) is dict and \
-          'desc' in e.args[-1]:
-            return e.args[-1]['desc']
-        else:
-            return str(e)
-
-    def __ldap_exc_info(self, e):
-        if len(e.args) > 0 and \
-          type(e.args[-1]) is dict and \
-          'info' in e.args[-1]:
-            return e.args[-1]['info']
-        else:
-            return ''
-
-    def __ldap_connect(self):
-        self.net = Net(creds=self.creds, lp=self.lp)
-        cldap_ret = self.net.finddc(domain=self.realm, 
flags=(nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS | nbt.NBT_SERVER_WRITABLE))
-        self.dc_hostname = cldap_ret.pdc_dns_name
-        self.l = ldap.initialize('ldap://%s' % cldap_ret.pdc_dns_name)
-        if self.kinit or self.__kinit_for_gssapi():
-            auth_tokens = ldap.sasl.gssapi('')
-            self.l.sasl_interactive_bind_s('', auth_tokens)
-        else:
-            ycpbuiltins.y2error('Failed to initialize ldap connection')
-            raise Exception('Failed to initialize ldap connection')
-
-    def ldap_search_s(self, *args):
-        try:
-            try:
-                return self.l.search_s(*args)
-            except ldap.SERVER_DOWN:
-                self.__ldap_connect()
-                return self.l.search_s(*args)
-        except Exception as e:
-            ycpbuiltins.y2error(traceback.format_exc())
-            ycpbuiltins.y2error('ldap.search_s: %s\n' % self.__ldap_exc_msg(e))
-
-    def ldap_search(self, *args):
-        result = []
-        try:
-            try:
-                res_id = self.l.search(*args)
-            except ldap.SERVER_DOWN:
-                self.__ldap_connect()
-                res_id = self.l.search(*args)
-            while 1:
-                t, d = self.l.result(res_id, 0)
-                if d == []:
-                    break
-                else:
-                    if t == ldap.RES_SEARCH_ENTRY:
-                        result.append(d[0])
-        except ldap.LDAPError:
-            pass
-        except Exception as e:
-            ycpbuiltins.y2error(traceback.format_exc())
-            ycpbuiltins.y2error('ldap.search: %s\n' % self.__ldap_exc_msg(e))
-        return result
-
-    def ldap_add(self, *args):
-        try:
-            try:
-                return self.l.add_s(*args)
-            except ldap.SERVER_DOWN:
-                self.__ldap_connect()
-                return self.l.add_s(*args)
-        except Exception as e:
-            raise LdapException(self.__ldap_exc_msg(e), 
self.__ldap_exc_info(e))
-
-    def ldap_modify(self, *args):
-        try:
-            try:
-                return self.l.modify(*args)
-            except ldap.SERVER_DOWN:
-                self.__ldap_connect()
-                return self.l.modify(*args)
-        except Exception as e:
-            ycpbuiltins.y2error(traceback.format_exc())
-            ycpbuiltins.y2error('ldap.modify: %s\n' % self.__ldap_exc_msg(e))
-
-    def ldap_delete(self, *args):
-        try:
-            try:
-                return self.l.delete_s(*args)
-            except ldap.SERVER_DOWN:
-                self.__ldap_connect()
-                return self.l.delete_s(*args)
-        except Exception as e:
-            ycpbuiltins.y2error(traceback.format_exc())
-            ycpbuiltins.y2error('ldap.delete_s: %s\n' % self.__ldap_exc_msg(e))
-
 class GPOConnection(GPConnection):
     def __init__(self, lp, creds, gpo_path):
         GPConnection.__init__(self, lp, creds)
@@ -573,8 +331,12 @@
         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.SMB(self.dc_hostname, service, lp=self.lp, 
creds=self.creds)
+            self.conn = smb.Conn(self.dc_hostname, service, lp=s3_lp, 
creds=self.creds, sign=True)
         except Exception as e:
             ycpbuiltins.y2error(traceback.format_exc())
             ycpbuiltins.y2error("Exception %s"%str(e))
@@ -694,7 +456,7 @@
 
     def __parse_dn(self, dn):
         dn = dn % self.gpo_dn
-        resp = self.ldap_search(dn, ldap.SCOPE_SUBTREE, 
'(objectCategory=packageRegistration)', [])
+        resp = self.ldap_search(dn, SCOPE_SUBTREE, 
'(objectCategory=packageRegistration)', [])
         resp = stringify_ldap(resp)
         if resp:
             keys = ['objectClass', 'msiFileList', 'msiScriptPath', 
'displayName', 'versionNumberHi', 'versionNumberLo']
@@ -784,9 +546,9 @@
             try:
                 path = os.path.relpath(os.path.join(self.path, 
filename).replace('\\', '/')).replace('/', '\\')
                 raw = self.conn.loadfile(path)
-                pol_conf = unpack_registry_pol(raw)
+                pol_conf = ndr_unpack(preg.file, raw)
             except:
-                pol_conf = None
+                pol_conf = preg.file()
         return pol_conf
 
     def __smb_mkdir_p(self, path):
@@ -817,6 +579,7 @@
         if six.PY3 and type(text) is str:
             text = text.encode('utf-8')
         try:
+            self.conn.unlink(path)
             self.conn.savefile(path, text)
         except Exception as e:
             if e.args[0] == 0xC000003A: # STATUS_OBJECT_PATH_NOT_FOUND
@@ -835,7 +598,7 @@
         self.__write(filename, value)
 
     def __write_reg(self, filename, pol_conf):
-        buf = pack_registry_pol(pol_conf)
+        buf = ndr_pack(pol_conf)
         self.__write(filename, buf)
 
     def upload_file(self, local, remote_dir):
@@ -847,6 +610,7 @@
             if six.PY3 and type(value) is str:
                 value = value.encode('utf-8')
             try:
+                self.conn.unlink(filename)
                 self.conn.savefile(filename, value)
             except Exception as e:
                 if e.args[0] == 0xC0000035: # STATUS_OBJECT_NAME_COLLISION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/defaults.py 
new/yast2-gpmc-1.4.2/src/defaults.py
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/defaults.py        2018-11-12 
08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/src/defaults.py        2019-03-15 17:19:21.000000000 
+0100
@@ -3,10 +3,57 @@
 import uuid
 import os.path
 from subprocess import Popen, PIPE
+from complex import strcmp
+from samba.dcerpc import preg
+import six
 
 from yast import import_module
 import_module('UI')
 from yast import UI
+
+def delete_admx_value(conf, reg_key, key):
+    entries = []
+    for x in conf.entries:
+        if not (strcmp(x.keyname, reg_key) and strcmp(x.valuename, key)):
+            entries.append(x)
+    conf.num_entries = len(entries)
+    conf.entries = entries
+
+def set_admx_value(conf, reg_key, key, val, val_type):
+    if val == None:
+        return delete_admx_value(conf, reg_key, key)
+    e = preg.entry()
+    e.keyname = six.b(reg_key)
+    e.valuename = six.b(key)
+    if val_type == 'TextEntry':
+        e.type = 1
+        e.data = six.b(val)
+    elif val_type == 'IntField':
+        e.type = 4
+        e.data = int(val)
+    elif val_type == 'CheckBox':
+        e.type = 4
+        e.data = 1 if val else 0
+    entries = []
+    for x in conf.entries:
+        if not (strcmp(x.keyname, reg_key) and strcmp(x.valuename, key)):
+            entries.append(x)
+    entries.append(e)
+    conf.num_entries = len(entries)
+    conf.entries = entries
+
+def get_admx_value(conf, reg_key, key):
+    for e in conf.entries:
+        if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key):
+            return e.data
+    return None
+
+def get_admx_configured(conf, reg_key, key):
+    for e in conf.entries:
+        if strcmp(e.keyname, reg_key) and strcmp(e.valuename, key):
+            return True
+    return False
+
 def select_script(title, policy, conn):
     full_path = UI.AskForExistingFile('/', '*.sh *.py *.pl', title)
     if policy == 'comp_scripts_shutdown':
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/dialogs.py.in 
new/yast2-gpmc-1.4.2/src/dialogs.py.in
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/dialogs.py.in      2018-11-12 
08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/src/dialogs.py.in      2019-03-15 17:19:21.000000000 
+0100
@@ -1,6 +1,7 @@
 from __future__ import absolute_import, division, print_function, 
unicode_literals
-from defaults import Policies, fetch_inf_value
-from complex import GPConnection, GPOConnection, dn_to_path, parse_gplink, 
strcmp, strcasecmp
+from defaults import Policies, fetch_inf_value, set_admx_value, 
get_admx_value, get_admx_configured
+from complex import GPConnection, GPOConnection, dn_to_path, parse_gplink
+from adcommon.strings import strcmp, strcasecmp
 from yast import import_module
 import_module('Wizard')
 import_module('UI')
@@ -13,36 +14,30 @@
 from samba.ntacls import dsacl2fsacl
 import os.path
 from itertools import chain
+from samba.dcerpc import preg
+import six
+from adcommon.creds import YCreds, switch_domains
+from adcommon.ui import CreateMenu, DeleteButtonBox
 
 ENABLE_EXPERIMENTAL = @ENABLE_EXPERIMENTAL@
 
-def have_x():
-    from subprocess import Popen, PIPE
-    p = Popen(['xset', '-q'], stdout=PIPE, stderr=PIPE)
-    return p.wait() == 0
-have_advanced_gui = have_x()
-
 selected_gpo = None
 
-def set_admx_value(conf, reg_key, key, val):
-    conf[reg_key][key]['value'] = val
-
 class GPME:
     def __init__(self, lp, creds):
         global selected_gpo
         self.conn = GPOConnection(lp, creds, 
selected_gpo[1]['gPCFileSysPath'][-1])
 
     def __reset(self):
-        global have_advanced_gui
-        if not have_advanced_gui:
-            Wizard.RestoreNextButton()
         UI.SetApplicationTitle('Group Policy Management Editor')
         Wizard.SetContentsButtons('Group Policy Management Editor', 
self.__gpme_page(), 'Group Policy Management Editor', '', 'Close')
-        if have_advanced_gui:
-            Wizard.HideNextButton()
-        else:
-            Wizard.HideAbortButton()
-            Wizard.HideBackButton()
+        self.__setup_menus()
+        DeleteButtonBox()
+
+    def __setup_menus(self):
+        menus = [{'title': '&File', 'id': 'file', 'type': 'Menu'},
+                 {'title': 'Exit', 'id': 'abort', 'type': 'MenuEntry', 
'parent': 'file'}]
+        CreateMenu(menus)
 
     def Show(self):
         if not self.conn:
@@ -75,10 +70,17 @@
                     subret = UI.UserInput()
                     if str(subret) == 'ok_change_setting' or str(subret) == 
'apply_change_setting':
                         for k in values.keys():
-                            if values[k]['set'] or 
values[k]['input']['options']:
-                                value = UI.QueryWidget('entry_%s' % k, 'Value')
-                            if values[k]['input']['options']:
-                                value = 
values[k]['input']['options'][value.strip()]
+                            if 'configurable' in values[k]['input'] and 
values[k]['input']['configurable']:
+                                configured = UI.QueryWidget('configured_%s' % 
k, 'Value')
+                                if configured or configured == None:
+                                    value = UI.QueryWidget('entry_%s' % k, 
'Value')
+                                else:
+                                    value = None
+                            else:
+                                if values[k]['set'] or 
values[k]['input']['options']:
+                                    value = UI.QueryWidget('entry_%s' % k, 
'Value')
+                                if values[k]['input']['options']:
+                                    value = 
values[k]['input']['options'][value.strip()]
                             if values[k]['set']:
                                 if type(value) is str:
                                     value = value.strip()
@@ -99,6 +101,9 @@
                         break
                 UI.ReplaceWidget('rightPane', self.__display_policy(policy))
                 UI.SetFocus(str(ret))
+            elif str(ret) == 'delete_policy':
+                selection = UI.QueryWidget(str(ret), 'CurrentItem')
+                Policies[policy]['delete'](conf, selection)
 
         return Symbol(ret)
 
@@ -122,8 +127,15 @@
             if not value[-1]['input']:
                 continue
             if strcmp(value[-1]['input']['type'], 'TextEntry'):
+                configurable = Empty()
+                configured = value[-1]['get'] != None
+                if 'configurable' in value[-1]['input'] and 
value[-1]['input']['configurable']:
+                    configurable = CheckBox(Id('configured_%s' % k), 
Opt('hstretch'), 'Configured', configured)
                 items.append(Top(MinWidth(30, Left(
-                    ReplacePoint(Id('text_entry_%s' % k), 
TextEntry(Id('entry_%s' % k), Opt('hstretch'), value[-1]['title'], 
value[-1]['get'] if value[-1]['get'] else '')),
+                    ReplacePoint(Id('text_entry_%s' % k), VBox(
+                        configurable,
+                        TextEntry(Id('entry_%s' % k), Opt('hstretch'), 
value[-1]['title'], value[-1]['get'] if value[-1]['get'] else '')
+                    )),
                 ))))
             elif strcmp(value[-1]['input']['type'], 'ComboBox'):
                 combo_options = []
@@ -147,13 +159,30 @@
                     )
                 ))))
             elif strcmp(value[-1]['input']['type'], 'IntField'):
+                configurable = Empty()
+                configured = value[-1]['get'] != None
+                if 'configurable' in value[-1]['input'] and 
value[-1]['input']['configurable']:
+                    configurable = CheckBox(Id('configured_%s' % k), 
Opt('hstretch'), 'Configured', configured)
                 items.append(Top(MinWidth(30, Left(
-                    ReplacePoint(Id('int_field_%s' % k), 
IntField(Id('entry_%s' % k), Opt('hstretch'), value[-1]['title'], 0, 999999999, 
value[-1]['get'] if value[-1]['get'] else 0))
+                    ReplacePoint(Id('int_field_%s' % k), VBox(
+                        configurable,
+                        IntField(Id('entry_%s' % k), Opt('hstretch'), 
value[-1]['title'], 0, 999999999, value[-1]['get'] if value[-1]['get'] else 0)
+                    ))
                 ))))
             elif strcmp(value[-1]['input']['type'], 'CheckBox'):
-                items.append(Top(Left(
-                    ReplacePoint(Id('check_box_%s' % k), 
CheckBox(Id('entry_%s' % k), Opt('hstretch'), value[-1]['title'], 
bool(value[-1]['get']) if value[-1]['get'] else False))
-                )))
+                if 'configurable' in value[-1]['input'] and 
value[-1]['input']['configurable']:
+                    disp = value[-1]['valstr'](value[-1]['get'])
+                    items.append(Top(Left(
+                        ReplacePoint(Id('check_box_%s' % k), 
RadioButtonGroup(Id('entry_%s' % k), VBox(
+                            Left(RadioButton(Id(None), 'Not Configured', 
strcmp(disp, 'Not configured'))),
+                            Left(RadioButton(Id(True), 'Enabled', strcmp(disp, 
'Enabled'))),
+                            Left(RadioButton(Id(False), 'Disabled', 
strcmp(disp, 'Disabled')))
+                        )))
+                    )))
+                else:
+                    items.append(Top(Left(
+                        ReplacePoint(Id('check_box_%s' % k), 
CheckBox(Id('entry_%s' % k), Opt('hstretch'), value[-1]['title'], 
bool(value[-1]['get']) if value[-1]['get'] else False))
+                    )))
         if reverse:
             items.reverse()
         items = tuple(items)
@@ -197,7 +226,8 @@
         buttons = []
         if terms['add']:
             buttons.append(PushButton(Id('add_policy'), 'Add'))
-        buttons.append(PushButton(Id('delete_policy'), 'Delete'))
+        if 'delete' in terms.keys():
+            buttons.append(PushButton(Id('delete_policy'), 'Delete'))
         buttons = tuple(buttons)
 
         return VBox(
@@ -277,7 +307,7 @@
                     Policies[parent]['add'] = None
                     Policies[parent]['header'] = (lambda : ['Setting', 
'Value'])
                     Policies[parent]['values'] = \
-                            (lambda conf, reg_key, key, desc, valstr, _input : 
{
+                            (lambda conf, reg_key, key, desc, valstr, 
val_type, _input : {
                                 'setting' : {
                                     'order' : 0,
                                     'title' : 'Setting',
@@ -293,9 +323,9 @@
                                 'value' : {
                                     'order' : 1,
                                     'title' : key,
-                                    'get' : conf[reg_key][key]['value'] if 
reg_key in conf and key in conf[reg_key] else '',
-                                    'set' : (lambda v : set_admx_value(conf, 
reg_key, key, v)),
-                                    'valstr' : valstr,
+                                    'get' : get_admx_value(conf, reg_key, key),
+                                    'set' : (lambda v : set_admx_value(conf, 
reg_key, key, v, val_type)),
+                                    'valstr' : (lambda v : valstr(v) if 
get_admx_configured(conf, reg_key, key) else 'Not configured'),
                                     'input' : _input,
                                 },
                             } )
@@ -310,19 +340,21 @@
                             values[disp] = {}
                             val_type = None
                             elements = policy.find('elements')
+                            defined = get_admx_configured(conf, 
policy.attrib['key'], disp)
                             if elements.find('text') is not None:
                                 val_type = 'TextEntry'
-                                val_str = (lambda v : v if v else 'Not 
Defined')
+                                val_str = (lambda v : v if v else '')
                             elif elements.find('decimal') is not None:
                                 val_type = 'IntField'
-                                val_str = (lambda v : v if v else 'Not 
Defined')
+                                val_str = (lambda v : v)
                             elif elements.find('boolean') is not None:
                                 val_type = 'CheckBox'
-                                val_str = (lambda v : 'Not Defined' if not v 
else 'Disabled' if int(v) == 0 else 'Enabled')
+                                val_str = (lambda v : 'Disabled' if int(v) == 
0 else 'Enabled')
                             values[disp]['values'] = 
Policies[parent]['values'](
-                                conf, policy.attrib['key'], disp, desc, 
val_str,
+                                conf, policy.attrib['key'], disp, desc, 
val_str, val_type,
                                 {
                                     'type' : val_type,
+                                    'configurable' : True,
                                     'options' : None,
                                 },
                             )
@@ -374,12 +406,12 @@
                     os_settings_items
             )
         )
-        if ENABLE_EXPERIMENTAL:
-            policy_items.append(
-                Item('Administrative Templates', False,
-                    admin_templates
-                )
+
+        policy_items.append(
+            Item('Administrative Templates', False,
+                admin_templates
             )
+        )
 
         computer_config = [
             Item('Policies', False,
@@ -442,66 +474,52 @@
 
 class GPMC:
     def __init__(self, lp, creds):
-        global selected_gpo, have_advanced_gui
+        global selected_gpo
         self.realm = lp.get('realm')
         self.lp = lp
         self.creds = creds
         self.gpos = []
         selected_gpo = None
         self.__setup_menus()
-        if have_advanced_gui:
-            Wizard.HideAbortButton()
-            Wizard.HideBackButton()
-            Wizard.HideNextButton()
-        self.got_creds = self.__get_creds(creds)
-        while self.got_creds:
+        DeleteButtonBox()
+        ycred = YCreds(creds, auto_krb5_creds=False)
+        def cred_valid():
             try:
                 self.q = GPConnection(lp, creds)
                 self.gpos = self.q.gpo_list()
                 self.realm_dn = self.q.realm_to_dn(self.realm)
-                break
+                return True
             except Exception as e:
                 ycpbuiltins.y2error(str(e))
-                creds.set_password('')
-                self.got_creds = self.__get_creds(creds)
+            return False
+        self.cred_valid = cred_valid
+        self.got_creds = ycred.Show(self.cred_valid)
+
+    def __setup_menus(self, actions=None):
+        menus = [{'title': '&File', 'id': 'file', 'type': 'Menu'},
+                 {'title': 'Change domain...', 'id': 'change_domain', 'type': 
'MenuEntry', 'parent': 'file'},
+                 {'title': 'Exit', 'id': 'abort', 'type': 'MenuEntry', 
'parent': 'file'}]
+        if actions:
+            menus.extend(actions)
+        CreateMenu(menus)
+
+    def __gpo_menus(self, parent=None):
+        menus = [{'title': 'Action', 'id': 'action', 'type': 'Menu'},
+                 {'title': 'Edit...', 'id': 'edit_gpo', 'type': 'MenuEntry', 
'parent': 'action'}]
+        if parent:
+            delete_id = 'context_del_link'
+        else:
+            delete_id = 'context_del_gpo'
+        menus.append({'title': 'Delete', 'id': delete_id, 'type': 'MenuEntry', 
'parent': 'action'})
+        self.__setup_menus(actions=menus)
 
-    def __setup_menus(self):
-        UI.WizardCommand(Term('DeleteMenus'))
-        UI.WizardCommand(Term('AddMenu', '&File', 'file-menu'))
-        UI.WizardCommand(Term('AddMenuEntry', 'file-menu', 'Close', 'abort'))
-
-    def __get_creds(self, creds):
-        if not creds.get_password():
-            UI.SetApplicationTitle('Authenticate')
-            UI.OpenDialog(self.__password_prompt(creds.get_username()))
-            while True:
-                subret = UI.UserInput()
-                if str(subret) == 'creds_ok':
-                    user = UI.QueryWidget('username_prompt', 'Value')
-                    password = UI.QueryWidget('password_prompt', 'Value')
-                    UI.CloseDialog()
-                    if not password:
-                        return False
-                    creds.set_username(user)
-                    creds.set_password(password)
-                    return True
-                if str(subret) == 'creds_cancel':
-                    UI.CloseDialog()
-                    return False
-        return True
-
-    def __password_prompt(self, user):
-        return MinWidth(30, HBox(HSpacing(1), VBox(
-            VSpacing(.5),
-            Left(Label('To continue, type an administrator password')),
-            Left(TextEntry(Id('username_prompt'), Opt('hstretch'), 'Username', 
user)),
-            Left(Password(Id('password_prompt'), Opt('hstretch'), 'Password')),
-            Right(HBox(
-                PushButton(Id('creds_ok'), 'OK'),
-                PushButton(Id('creds_cancel'), 'Cancel'),
-            )),
-            VSpacing(.5)
-        ), HSpacing(1)))
+    def __objs_menus(self, container=None):
+        menus = [{'title': 'Action', 'id': 'action', 'type': 'Menu'}]
+        if container:
+            menus.append({'title': 'Create a GPO in this domain, and Link it 
here...', 'id': 'context_add_gpo_and_link', 'type': 'MenuEntry', 'parent': 
'action'})
+        else:
+            menus.append({'title': 'New', 'id': 'context_add_gpo', 'type': 
'MenuEntry', 'parent': 'action'})
+        self.__setup_menus(actions=menus)
 
     def __find_gpo(self, gpo_guid):
         fgpo = None
@@ -549,20 +567,10 @@
             self.gpos = []
 
     def __reset(self):
-        global have_advanced_gui
-        if not have_advanced_gui:
-            Wizard.RestoreBackButton()
-            Wizard.RestoreNextButton()
-            Wizard.RestoreAbortButton()
         UI.SetApplicationTitle('Group Policy Management Console')
         Wizard.SetContentsButtons('Group Policy Management Console', 
self.__gpmc_page(), self.__help(), 'Back', 'Edit GPO')
-        if have_advanced_gui:
-            Wizard.HideAbortButton()
-            Wizard.HideBackButton()
-            Wizard.HideNextButton()
-        else:
-            Wizard.DisableBackButton()
-            Wizard.DisableNextButton()
+        self.__setup_menus()
+        DeleteButtonBox()
 
     def Show(self):
         global selected_gpo
@@ -599,16 +607,16 @@
                 UI.ReplaceWidget('rightPane', self.__container(gpo_guid))
                 current_page = 'Realm'
             elif ret == 'gpmc_tree' and event['EventReason'] == 
'ContextMenuActivated':
-                parent = UI.QueryWidget('gpmc_tree', 'CurrentBranch')[-2]
                 if gpo_guid == 'Group Policy Objects':
                     UI.OpenContextMenu(self.__objs_context_menu())
                 elif gpo_guid != 'Domains' and self.__find_gpo(gpo_guid):
+                    parent = UI.QueryWidget('gpmc_tree', 'CurrentBranch')[-2]
                     if parent != 'Group Policy Objects' and parent != 
self.realm_dn:
                         UI.OpenContextMenu(self.__gpo_context_menu(parent))
                     else:
                         UI.OpenContextMenu(self.__gpo_context_menu())
                 elif gpo_guid != 'Domains':
-                    UI.OpenContextMenu(self.__objs_context_menu(gpo_guid))
+                    UI.OpenContextMenu(self.__objs_context_menu(gpo_guid, 
realm=(gpo_guid == self.realm_dn)))
             elif ret == 'edit_gpo':
                 selected_gpo = self.__find_gpo(gpo_guid)
                 ret = 'next'
@@ -636,6 +644,10 @@
                 self.__reset()
                 UI.ReplaceWidget('rightPane', Empty())
                 current_page = None
+            elif ret == 'change_domain':
+                if switch_domains(self.lp, self.creds, self.cred_valid):
+                    self.realm = self.lp.get('realm')
+                    self.__reset()
             elif UI.HasSpecialWidget('DumbTab'):
                 if gpo_guid == 'Domains':
                     if current_page != None:
@@ -653,15 +665,27 @@
                         UI.ReplaceWidget(Id('realm_tabContainer'), 
self.__realm_delegation())
                     elif ret == 'Group Policy Inheritance':
                         UI.ReplaceWidget(Id('realm_tabContainer'), 
self.__realm_inheritance())
+                    if event['EventReason'] == 'SelectionChanged':
+                        self.__objs_menus(gpo_guid)
                 elif gpo_guid == 'Group Policy Objects':
                     if current_page != 'Group Policy Objects':
                         Wizard.DisableNextButton()
                         UI.ReplaceWidget('rightPane', Empty())
                         current_page = 'Group Policy Objects'
+                    if event['EventReason'] == 'SelectionChanged':
+                        self.__objs_menus()
                 elif gpo_guid.lower().startswith('ou='):
                     UI.ReplaceWidget('rightPane', self.__container(gpo_guid))
                     current_page = None
+                    if event['EventReason'] == 'SelectionChanged':
+                        self.__objs_menus(gpo_guid)
                 else:
+                    parent = UI.QueryWidget('gpmc_tree', 'CurrentBranch')[-2]
+                    if event['EventReason'] == 'SelectionChanged':
+                        if parent != 'Group Policy Objects' and parent != 
self.realm_dn:
+                            self.__gpo_menus(parent)
+                        else:
+                            self.__gpo_menus()
                     if current_page != 'Dumbtab' or old_gpo_guid != gpo_guid:
                         Wizard.EnableNextButton()
                         selected_gpo = self.__find_gpo(gpo_guid)
@@ -698,15 +722,15 @@
             Item(Id(delete_id), 'Delete')
         ])
 
-    def __objs_context_menu(self, container=None):
+    def __objs_context_menu(self, container=None, realm=False):
+        items = []
+        if realm:
+            items.append(Item(Id('change_domain'), 'Change Domain...'))
         if container:
-            return Term('menu', [
-                Item(Id('context_add_gpo_and_link'), 'Create a GPO in this 
domain, and Link it here...')
-            ])
+            items.append(Item(Id('context_add_gpo_and_link'), 'Create a GPO in 
this domain, and Link it here...'))
         else:
-            return Term('menu', [
-                Item(Id('context_add_gpo'), 'New')
-            ])
+            items.append(Item(Id('context_add_gpo'), 'New'))
+        return Term('menu', items)
 
     def __name_gpo(self):
         return MinWidth(30, VBox(
@@ -852,21 +876,12 @@
         return contents
 
     def __container(self, dn):
-        global have_advanced_gui
-        if have_advanced_gui:
-            buttons = Empty()
-        else:
-            buttons = Right(HBox(
-                PushButton(Id('del_gpo'), 'Delete GPO'),
-                PushButton(Id('add_gpo'), 'Create a GPO')
-            ))
         return VBox(
             Frame(self.realm, DumbTab([
                 'Linked Group Policy Objects',
                 #'Group Policy Inheritance',
                 #'Delegation'
             ], ReplacePoint(Id('realm_tabContainer'), 
self.__container_links(dn)))),
-            buttons,
         )
 
     def __realm_delegation(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/gpmc.desktop.in 
new/yast2-gpmc-1.4.2/src/gpmc.desktop.in
--- old/yast2-gpmc-v1.4.1+git.11.e264ccc/src/gpmc.desktop.in    2018-11-12 
08:54:41.000000000 +0100
+++ new/yast2-gpmc-1.4.2/src/gpmc.desktop.in    2019-03-15 17:19:21.000000000 
+0100
@@ -7,7 +7,7 @@
 X-KDE-Library=yast2
 X-SuSE-YaST-Call=gpmc
 
-X-SuSE-YaST-Group=Misc
+X-SuSE-YaST-Group=Net_advanced
 X-SuSE-YaST-Argument=
 X-SuSE-YaST-RootOnly=true
 X-SuSE-YaST-AutoInst=


Reply via email to