[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Sat Dec 16 00:57:03 UTC 2017


The branch, master has been updated
       via  7fa91fc smbd: Fix coredump on failing chdir during logoff
       via  0d3000b selftest: Add test for failing chdir call in smbd
       via  b0e1fc7 selftest: Make location of log file available in tests
       via  8b6402f selftest: Add share for error injection testing
       via  24623d5 vfs_error_inject: Add new module
       via  b468245 gpo: Test that unapply works
       via  ac56f87 gpo: Only commit the earliest change to the log
       via  9ace234 gpo: Fix the empty apply log
       via  045d900 libgpo: Remedy some longer lines
       via  8065c2f libgpo: Tidy up some if statements
       via  cb29ccc libgpo: typo credentaials -> credentials
       via  a194fb3 libgpo: Always check for ldap_server argument
      from  964bc8d markdown: Rename ms_markdown.py -> ms_schema_markdown.py

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 7fa91fc4791d076c609eaf119753e38dd3c50a1c
Author: Christof Schmitt <cs at samba.org>
Date:   Wed Dec 13 11:34:23 2017 -0700

    smbd: Fix coredump on failing chdir during logoff
    
    server_exit does an internal tree disconnect which requires a chdir to
    the share directory. In case the file system encountered a problem and
    the chdir call returns an error, this triggers a SERVER_EXIT_ABNORMAL
    which in turn results in a panic and a coredump. As the log already
    indicates the problem (chdir returned an error), avoid the
    SERVER_EXIT_ABNORMAL in this case and not trigger a coredump.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13189
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Sat Dec 16 01:56:06 CET 2017 on sn-devel-144

commit 0d3000be2af8f8c4a37892d95ae694ad834d7b3a
Author: Christof Schmitt <cs at samba.org>
Date:   Wed Dec 13 12:58:18 2017 -0700

    selftest: Add test for failing chdir call in smbd
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13189
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b0e1fc74fdacecb86f46b47e527b3fdf1906d27b
Author: Christof Schmitt <cs at samba.org>
Date:   Wed Dec 13 12:47:31 2017 -0700

    selftest: Make location of log file available in tests
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13189
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 8b6402f3e5ff98c2701e626e47246b2400f76e5f
Author: Christof Schmitt <cs at samba.org>
Date:   Wed Dec 13 11:34:05 2017 -0700

    selftest: Add share for error injection testing
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13189
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 24623d53256c2424563709dedc19af1a106ccc73
Author: Christof Schmitt <cs at samba.org>
Date:   Fri Dec 8 15:29:07 2017 -0700

    vfs_error_inject: Add new module
    
    This module allow injecting errors in vfs calls. It only implements one
    case (return ESTALE from chdir), but the idea is to extend this to more
    vfs functions and more errors when needed.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=13189
    
    Signed-off-by: Christof Schmitt <cs at samba.org>
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit b468245c325bd9078b5a501972aec72533dd0d39
Author: David Mulder <dmulder at suse.com>
Date:   Wed Dec 6 10:16:11 2017 -0700

    gpo: Test that unapply works
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit ac56f870182054942aff462bf226d52edd927468
Author: David Mulder <dmulder at suse.com>
Date:   Fri Dec 1 11:18:55 2017 -0700

    gpo: Only commit the earliest change to the log
    
    Otherwise we overwrite the original value,
    leaving the setting tattooed on unapplied
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 9ace2343ab24829a37bae6cbf0c72cb6d101cb9f
Author: David Mulder <dmulder at suse.com>
Date:   Mon Nov 20 06:41:19 2017 -0700

    gpo: Fix the empty apply log
    
    The apply log wasn't being saved, apparently the pointers to elements
    of the tree were getting lost.
    
    Signed-off-by: David Mulder <dmulder at suse.com>
    Reviewed-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 045d900e8baa4f8b862064c36d9c0d1de0e96697
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Nov 22 11:00:56 2017 +1300

    libgpo: Remedy some longer lines
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit 8065c2f443a60f4d04a5257736ef9af9b3d0f832
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Nov 22 11:00:35 2017 +1300

    libgpo: Tidy up some if statements
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit cb29ccca722f887a1e29dcea72de1eb4037e01d8
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Nov 22 10:58:55 2017 +1300

    libgpo: typo credentaials -> credentials
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

commit a194fb3821ab72b3d5fa9d9047cccd8fa415c4a5
Author: Garming Sam <garming at catalyst.net.nz>
Date:   Wed Nov 22 10:57:18 2017 +1300

    libgpo: Always check for ldap_server argument
    
    Signed-off-by: Garming Sam <garming at catalyst.net.nz>
    Reviewed-by: Jeremy Allison <jra at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 libgpo/pygpo.c                          | 118 +++++++++++++++++++-----------
 python/samba/gpclass.py                 |  67 +++++++++--------
 selftest/selftest.pl                    |   1 +
 selftest/target/Samba3.pm               |   4 ++
 source3/modules/vfs_error_inject.c      | 100 ++++++++++++++++++++++++++
 source3/modules/wscript_build           |   7 ++
 source3/script/tests/test_smbd_error.sh |  56 +++++++++++++++
 source3/selftest/tests.py               |   3 +
 source3/smbd/server_exit.c              |   4 --
 source3/wscript                         |   1 +
 source4/scripting/bin/samba_gpoupdate   |   4 +-
 source4/torture/gpo/apply.c             | 124 +++++++++++++++++++++++++-------
 12 files changed, 386 insertions(+), 103 deletions(-)
 create mode 100644 source3/modules/vfs_error_inject.c
 create mode 100755 source3/script/tests/test_smbd_error.sh


Changeset truncated at 500 lines:

diff --git a/libgpo/pygpo.c b/libgpo/pygpo.c
index d7bb173..7a02a0d 100644
--- a/libgpo/pygpo.c
+++ b/libgpo/pygpo.c
@@ -54,11 +54,14 @@ static PyGetSetDef GPO_setters[] = {
 		NULL},
 	{discard_const_p(char, "file_sys_path"), (getter)GPO_get_file_sys_path,
 		NULL, NULL, NULL},
-	{discard_const_p(char, "display_name"), (getter)GPO_get_display_name, NULL,
-		NULL, NULL},
-	{discard_const_p(char, "name"), (getter)GPO_get_name, NULL, NULL, NULL},
-	{discard_const_p(char, "link"), (getter)GPO_get_link, NULL, NULL, NULL},
-	{discard_const_p(char, "user_extensions"), (getter)GPO_get_user_extensions,
+	{discard_const_p(char, "display_name"), (getter)GPO_get_display_name,
+		NULL, NULL, NULL},
+	{discard_const_p(char, "name"), (getter)GPO_get_name, NULL, NULL,
+		NULL},
+	{discard_const_p(char, "link"), (getter)GPO_get_link, NULL, NULL,
+		NULL},
+	{discard_const_p(char, "user_extensions"),
+		(getter)GPO_get_user_extensions,
 		NULL, NULL, NULL},
 	{discard_const_p(char, "machine_extensions"),
 		(getter)GPO_get_machine_extensions, NULL, NULL, NULL},
@@ -81,7 +84,8 @@ static PyObject *py_gpo_get_unix_path(PyObject *self, PyObject *args,
 					 discard_const_p(char *, kwlist),
 					 &cache_dir)) {
 		PyErr_SetString(PyExc_SystemError,
-				"Failed to parse arguments to gpo_get_unix_path()");
+				"Failed to parse arguments to "
+				"gpo_get_unix_path()");
 		goto out;
 	}
 
@@ -113,7 +117,8 @@ out:
 }
 
 static PyMethodDef GPO_methods[] = {
-	{"get_unix_path", (PyCFunction)py_gpo_get_unix_path, METH_KEYWORDS, NULL },
+	{"get_unix_path", (PyCFunction)py_gpo_get_unix_path, METH_KEYWORDS,
+		NULL },
 	{NULL}
 };
 
@@ -155,18 +160,20 @@ static int py_ads_init(ADS *self, PyObject *args, PyObject *kwds)
 	PyObject *lp_obj = NULL;
 	struct loadparm_context *lp_ctx = NULL;
 
-	static const char *kwlist[] = {"ldap_server", "loadparm_context",
-		"credentials", NULL};
+	static const char *kwlist[] = {
+		"ldap_server", "loadparm_context", "credentials", NULL
+	};
 	if (!PyArg_ParseTupleAndKeywords(args, kwds, "sO|O",
 					 discard_const_p(char *, kwlist),
-					 &ldap_server, &lp_obj, &py_creds))
+					 &ldap_server, &lp_obj, &py_creds)) {
 		return -1;
+	}
 
 	if (py_creds) {
 		if (!py_check_dcerpc_type(py_creds, "samba.credentials",
 					  "Credentials")) {
 			PyErr_Format(PyExc_TypeError,
-				     "Expected samba.credentaials "
+				     "Expected samba.credentials "
 				     "for credentials argument");
 			return -1;
 		}
@@ -192,11 +199,16 @@ static int py_ads_init(ADS *self, PyObject *args, PyObject *kwds)
 	} else {
 		realm = lp_realm();
 		workgroup = lp_workgroup();
-		if (!ldap_server) return -1;
 	}
 
-	if ( !(self->ads_ptr = ads_init(realm, workgroup, ldap_server)) )
+	if (ldap_server == NULL) {
 		return -1;
+	}
+
+	self->ads_ptr = ads_init(realm, workgroup, ldap_server);
+	if (self->ads_ptr == NULL) {
+		return -1;
+	}
 
 	return 0;
 }
@@ -216,35 +228,43 @@ static PyObject* py_ads_connect(ADS *self)
 
 		status = ads_connect_user_creds(self->ads_ptr);
 		if (!ADS_ERR_OK(status)) {
-			PyErr_SetString(PyExc_SystemError, "ads_connect() failed");
+			PyErr_SetString(PyExc_SystemError,
+					"ads_connect() failed");
 			TALLOC_FREE(frame);
 			Py_RETURN_FALSE;
 		}
 	} else {
-		char *passwd;
-
-		if (asprintf(&(self->ads_ptr->auth.user_name), "%s$",
-			     lp_netbios_name()) == -1) {
-			PyErr_SetString(PyExc_SystemError, "Failed to asprintf");
+		char *passwd = NULL;
+		int ret = asprintf(&(self->ads_ptr->auth.user_name), "%s$",
+				   lp_netbios_name());
+		if (ret == -1) {
+			PyErr_SetString(PyExc_SystemError,
+					"Failed to asprintf");
 			TALLOC_FREE(frame);
 			Py_RETURN_FALSE;
-		} else
+		} else {
 			self->ads_ptr->auth.flags |= ADS_AUTH_USER_CREDS;
+		}
+
 		if (!secrets_init()) {
-			PyErr_SetString(PyExc_SystemError, "secrets_init() failed");
+			PyErr_SetString(PyExc_SystemError,
+					"secrets_init() failed");
 			TALLOC_FREE(frame);
 			Py_RETURN_FALSE;
 		}
-		if (!(passwd =
-		      secrets_fetch_machine_password(self->ads_ptr->server.workgroup,
-						     NULL, NULL))) {
+
+		passwd = secrets_fetch_machine_password(self->ads_ptr->server.workgroup,
+							NULL, NULL);
+		if (passwd == NULL) {
 			PyErr_SetString(PyExc_SystemError,
-					"Failed to fetch the machine account password");
+					"Failed to fetch the machine account "
+					"password");
 			TALLOC_FREE(frame);
 			Py_RETURN_FALSE;
 		}
 		self->ads_ptr->auth.password = smb_xstrdup(passwd);
-		self->ads_ptr->auth.realm = smb_xstrdup(self->ads_ptr->server.realm);
+		self->ads_ptr->auth.realm =
+			smb_xstrdup(self->ads_ptr->server.realm);
 		if (!strupper_m(self->ads_ptr->auth.realm)) {
 			PyErr_SetString(PyExc_SystemError, "Failed to strdup");
 			TALLOC_FREE(frame);
@@ -254,7 +274,8 @@ static PyObject* py_ads_connect(ADS *self)
 
 		status = ads_connect(self->ads_ptr);
 		if (!ADS_ERR_OK(status)) {
-			PyErr_SetString(PyExc_SystemError, "ads_connect() failed");
+			PyErr_SetString(PyExc_SystemError,
+					"ads_connect() failed");
 			TALLOC_FREE(frame);
 			SAFE_FREE(passwd);
 			Py_RETURN_FALSE;
@@ -309,14 +330,15 @@ static ADS_STATUS find_samaccount(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
 	char *dn = NULL;
 	uint32_t uac = 0;
 
-	filter = talloc_asprintf(mem_ctx, "(sAMAccountName=%s)", samaccountname);
+	filter = talloc_asprintf(mem_ctx, "(sAMAccountName=%s)",
+				 samaccountname);
 	if (filter == NULL) {
 		status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
 		goto out;
 	}
 
-	status = ads_do_search_all(ads, ads->config.bind_path, LDAP_SCOPE_SUBTREE,
-				   filter, attrs, &res);
+	status = ads_do_search_all(ads, ads->config.bind_path,
+				   LDAP_SCOPE_SUBTREE, filter, attrs, &res);
 
 	if (!ADS_ERR_OK(status)) {
 		goto out;
@@ -344,7 +366,7 @@ static ADS_STATUS find_samaccount(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx,
 
 	if (dn_ret) {
 		*dn_ret = talloc_strdup(mem_ctx, dn);
-		if (!*dn_ret) {
+		if (*dn_ret == NULL) {
 			status = ADS_ERROR(LDAP_NO_MEMORY);
 			goto out;
 		}
@@ -376,22 +398,27 @@ static PyObject *py_ads_get_gpo_list(ADS *self, PyObject *args, PyObject *kwds)
 					 discard_const_p(char *, kwlist),
 					 &samaccountname)) {
 		PyErr_SetString(PyExc_SystemError,
-				"Failed to parse arguments to py_ads_get_gpo_list()");
+				"Failed to parse arguments to "
+				"py_ads_get_gpo_list()");
 		goto out;
 	}
 
 	frame = talloc_stackframe();
 
-	status = find_samaccount(self->ads_ptr, frame, samaccountname, &uac, &dn);
+	status = find_samaccount(self->ads_ptr, frame,
+				 samaccountname, &uac, &dn);
 	if (!ADS_ERR_OK(status)) {
 		TALLOC_FREE(frame);
-		PyErr_SetString(PyExc_SystemError, "Failed to find samAccountName");
+		PyErr_SetString(PyExc_SystemError,
+				"Failed to find samAccountName");
 		goto out;
 	}
 
-	if (uac & UF_WORKSTATION_TRUST_ACCOUNT || uac & UF_SERVER_TRUST_ACCOUNT) {
+	if (uac & UF_WORKSTATION_TRUST_ACCOUNT ||
+	    uac & UF_SERVER_TRUST_ACCOUNT) {
 		flags |= GPO_LIST_FLAG_MACHINE;
-		status = gp_get_machine_token(self->ads_ptr, frame, dn, &token);
+		status = gp_get_machine_token(self->ads_ptr, frame, dn,
+					      &token);
 	} else {
 		status = ads_get_sid_token(self->ads_ptr, frame, dn, &token);
 	}
@@ -444,7 +471,8 @@ out:
 static PyMethodDef ADS_methods[] = {
 	{ "connect", (PyCFunction)py_ads_connect, METH_NOARGS,
 		"Connect to the LDAP server" },
-	{ "get_gpo_list", (PyCFunction)py_ads_get_gpo_list, METH_KEYWORDS, NULL },
+	{ "get_gpo_list", (PyCFunction)py_ads_get_gpo_list, METH_KEYWORDS,
+		NULL },
 	{ NULL }
 };
 
@@ -460,7 +488,8 @@ static PyTypeObject ads_ADSType = {
 };
 
 static PyMethodDef py_gpo_methods[] = {
-	{"gpo_get_sysvol_gpt_version", (PyCFunction) py_gpo_get_sysvol_gpt_version,
+	{"gpo_get_sysvol_gpt_version",
+		(PyCFunction)py_gpo_get_sysvol_gpt_version,
 		METH_VARARGS, NULL},
 	{NULL}
 };
@@ -471,18 +500,25 @@ void initgpo(void)
 	PyObject *m;
 
 	debug_setup_talloc_log();
+
 	/* Instantiate the types */
 	m = Py_InitModule3("gpo", py_gpo_methods, "libgpo python bindings");
-	if (m == NULL) return;
+	if (m == NULL) {
+		return;
+	}
+
 	PyModule_AddObject(m, "version",
 			   PyString_FromString(SAMBA_VERSION_STRING));
 
-	if (PyType_Ready(&ads_ADSType) < 0)
+	if (PyType_Ready(&ads_ADSType) < 0) {
 		return;
+	}
+
 	PyModule_AddObject(m, "ADS_STRUCT", (PyObject *)&ads_ADSType);
 
-	if (pytalloc_BaseObject_PyType_Ready(&GPOType) < 0)
+	if (pytalloc_BaseObject_PyType_Ready(&GPOType) < 0) {
 		return;
+	}
 
 	Py_INCREF((PyObject *)(void *)&GPOType);
 	PyModule_AddObject(m, "GROUP_POLICY_OBJECT",
diff --git a/python/samba/gpclass.py b/python/samba/gpclass.py
index 5a0ca9f..00330eb 100644
--- a/python/samba/gpclass.py
+++ b/python/samba/gpclass.py
@@ -95,10 +95,11 @@ class gp_log:
             self.gpdb = etree.fromstring(db_log)
         else:
             self.gpdb = etree.Element('gp')
-        self.user = self.gpdb.find('user[@name="%s"]' % user)
-        if self.user is None:
-            self.user = etree.SubElement(self.gpdb, 'user')
-            self.user.attrib['name'] = user
+        self.user = user
+        user_obj = self.gpdb.find('user[@name="%s"]' % user)
+        if user_obj is None:
+            user_obj = etree.SubElement(self.gpdb, 'user')
+            user_obj.attrib['name'] = user
 
     def state(self, value):
         ''' Policy application state
@@ -113,7 +114,8 @@ class gp_log:
         '''
         # If we're enforcing, but we've unapplied, apply instead
         if value == GPOSTATE.ENFORCE:
-            apply_log = self.user.find('applylog')
+            user_obj = self.gpdb.find('user[@name="%s"]' % self.user)
+            apply_log = user_obj.find('applylog')
             if apply_log is None or len(apply_log) == 0:
                 self._state = GPOSTATE.APPLY
             else:
@@ -126,14 +128,16 @@ class gp_log:
         param guid          - guid value of the GPO from which we're applying
                               policy
         '''
-        self.guid = self.user.find('guid[@value="%s"]' % guid)
-        if self.guid is None:
-            self.guid = etree.SubElement(self.user, 'guid')
-            self.guid.attrib['value'] = guid
+        self.guid = guid
+        user_obj = self.gpdb.find('user[@name="%s"]' % self.user)
+        obj = user_obj.find('guid[@value="%s"]' % guid)
+        if obj is None:
+            obj = etree.SubElement(user_obj, 'guid')
+            obj.attrib['value'] = guid
         if self._state == GPOSTATE.APPLY:
-            apply_log = self.user.find('applylog')
+            apply_log = user_obj.find('applylog')
             if apply_log is None:
-                apply_log = etree.SubElement(self.user, 'applylog')
+                apply_log = etree.SubElement(user_obj, 'applylog')
             item = etree.SubElement(apply_log, 'guid')
             item.attrib['count'] = '%d' % (len(apply_log)-1)
             item.attrib['value'] = guid
@@ -145,14 +149,15 @@ class gp_log:
         Removes the GPO guid last added to the list, which is the most recently
         applied GPO.
         '''
-        apply_log = self.user.find('applylog')
+        user_obj = self.gpdb.find('user[@name="%s"]' % self.user)
+        apply_log = user_obj.find('applylog')
         if apply_log is not None:
             ret = apply_log.find('guid[@count="%d"]' % (len(apply_log)-1))
             if ret is not None:
                 apply_log.remove(ret)
                 return ret.attrib['value']
-            if len(apply_log) == 0 and apply_log in self.user:
-                self.user.remove(apply_log)
+            if len(apply_log) == 0 and apply_log in user_obj:
+                user_obj.remove(apply_log)
         return None
 
     def store(self, gp_ext_name, attribute, old_val):
@@ -164,16 +169,18 @@ class gp_log:
         '''
         if self._state == GPOSTATE.UNAPPLY or self._state == GPOSTATE.ENFORCE:
             return None
-        assert self.guid is not None, "gpo guid was not set"
-        ext = self.guid.find('gp_ext[@name="%s"]' % gp_ext_name)
+        user_obj = self.gpdb.find('user[@name="%s"]' % self.user)
+        guid_obj = user_obj.find('guid[@value="%s"]' % self.guid)
+        assert guid_obj is not None, "gpo guid was not set"
+        ext = guid_obj.find('gp_ext[@name="%s"]' % gp_ext_name)
         if ext is None:
-            ext = etree.SubElement(self.guid, 'gp_ext')
+            ext = etree.SubElement(guid_obj, 'gp_ext')
             ext.attrib['name'] = gp_ext_name
         attr = ext.find('attribute[@name="%s"]' % attribute)
         if attr is None:
             attr = etree.SubElement(ext, 'attribute')
             attr.attrib['name'] = attribute
-        attr.text = old_val
+            attr.text = old_val
 
     def retrieve(self, gp_ext_name, attribute):
         ''' Retrieve a stored attribute from the gp_log
@@ -182,8 +189,10 @@ class gp_log:
         return              - The value of the attribute prior to policy
                               application
         '''
-        assert self.guid is not None, "gpo guid was not set"
-        ext = self.guid.find('gp_ext[@name="%s"]' % gp_ext_name)
+        user_obj = self.gpdb.find('user[@name="%s"]' % self.user)
+        guid_obj = user_obj.find('guid[@value="%s"]' % self.guid)
+        assert guid_obj is not None, "gpo guid was not set"
+        ext = guid_obj.find('gp_ext[@name="%s"]' % gp_ext_name)
         if ext is not None:
             attr = ext.find('attribute[@name="%s"]' % attribute)
             if attr is not None:
@@ -198,12 +207,14 @@ class gp_log:
         return              - list of (attr, value, apply_func) tuples for
                               unapplying policy
         '''
-        assert self.guid is not None, "gpo guid was not set"
+        user_obj = self.gpdb.find('user[@name="%s"]' % self.user)
+        guid_obj = user_obj.find('guid[@value="%s"]' % self.guid)
+        assert guid_obj is not None, "gpo guid was not set"
         ret = []
         data_maps = {}
         for gp_ext in gp_extensions:
             data_maps.update(gp_ext.apply_map())
-        exts = self.guid.findall('gp_ext')
+        exts = guid_obj.findall('gp_ext')
         if exts is not None:
             for ext in exts:
                 ext_map = {val[0]: val[1] for (key, val) in \
@@ -220,21 +231,19 @@ class gp_log:
                               attribute
         param attribute     - attribute to remove
         '''
-        assert self.guid is not None, "gpo guid was not set"
-        ext = self.guid.find('gp_ext[@name="%s"]' % gp_ext_name)
+        user_obj = self.gpdb.find('user[@name="%s"]' % self.user)
+        guid_obj = user_obj.find('guid[@value="%s"]' % self.guid)
+        assert guid_obj is not None, "gpo guid was not set"
+        ext = guid_obj.find('gp_ext[@name="%s"]' % gp_ext_name)
         if ext is not None:
             attr = ext.find('attribute[@name="%s"]' % attribute)
             if attr is not None:
                 ext.remove(attr)
                 if len(ext) == 0:
-                    self.guid.remove(ext)
+                    guid_obj.remove(ext)
 
     def commit(self):
         ''' Write gp_log changes to disk '''
-        if len(self.guid) == 0 and self.guid in self.user:
-            self.user.remove(self.guid)
-        if len(self.user) == 0 and self.user in self.gpdb:
-            self.gpdb.remove(self.user)
         self.gpostore.store(self.username, etree.tostring(self.gpdb, 'utf-8'))
 
 class GPOStorage:
diff --git a/selftest/selftest.pl b/selftest/selftest.pl
index e16696a..8c41459 100755
--- a/selftest/selftest.pl
+++ b/selftest/selftest.pl
@@ -877,6 +877,7 @@ my @exported_envvars = (
 	"RESOLV_CONF",
 	"UNACCEPTABLE_PASSWORD",
 	"LOCK_DIR",
+	"SMBD_TEST_LOG",
 
 	# nss_wrapper
 	"NSS_WRAPPER_PASSWD",
diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm
index afbc795..229435d 100755
--- a/selftest/target/Samba3.pm
+++ b/selftest/target/Samba3.pm
@@ -2150,6 +2150,10 @@ sub provision($$$$$$$$$)
 [compound_find]
 	copy = tmp
 	smbd:find async delay usec = 10000
+[error_inject]
+	copy = tmp
+	vfs objects = error_inject
+	include = $libdir/error_inject.conf
 	";
 	close(CONF);
 
diff --git a/source3/modules/vfs_error_inject.c b/source3/modules/vfs_error_inject.c
new file mode 100644
index 0000000..bb5477a
--- /dev/null
+++ b/source3/modules/vfs_error_inject.c
@@ -0,0 +1,100 @@
+/*
+ *  Unix SMB/CIFS implementation.
+ *  Samba VFS module for error injection in VFS calls
+ *  Copyright (C) Christof Schmitt 2017
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "includes.h"
+#include "smbd/smbd.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_VFS
+
+struct unix_error_map {
+	const char *err_str;
+	int error;
+} unix_error_map_array[] = {
+	{	"ESTALE",	ESTALE	},
+};
+
+static int find_unix_error_from_string(const char *err_str)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(unix_error_map_array); i++) {
+		struct unix_error_map *m = &unix_error_map_array[i];
+
+		if (strequal(err_str, m->err_str)) {
+			return m->error;
+		}
+	}
+
+	return 0;
+}
+
+static int inject_unix_error(const char *vfs_func, vfs_handle_struct *handle)
+{
+	const char *err_str;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list