diff options
170 files changed, 3174 insertions, 1328 deletions
diff --git a/buildtools/wafsamba/samba_version.py b/buildtools/wafsamba/samba_version.py index f2e26ec4e2..82f882f646 100644 --- a/buildtools/wafsamba/samba_version.py +++ b/buildtools/wafsamba/samba_version.py @@ -78,6 +78,13 @@ also accepted as dictionary entries here SAMBA_VERSION_STRING += ("-GIT-" + self.GIT_COMMIT_ABBREV) + clean = Utils.cmd_output('git diff HEAD | wc -l', silent=True) + if clean == "0\n": + self.GIT_COMMIT_IS_CLEAN = True + else: + self.GIT_COMMIT_IS_CLEAN = False + SAMBA_VERSION_STRING += "+" + self.OFFICIAL_STRING=SAMBA_VERSION_STRING if self.VENDOR_SUFFIX is not None: @@ -117,10 +124,12 @@ also accepted as dictionary entries here string+="#define SAMBA_VERSION_RC_RELEASE %u\n" % self.RC_RELEASE try: - string+="#define SAMBA_VERSION_GIT_COMMIT_ABBREV " + self.GIT_COMMIT_ABBREV + "\n" + string+="#define SAMBA_VERSION_GIT_COMMIT_ABBREV \"" + self.GIT_COMMIT_ABBREV + "\"\n" + string+="#define SAMBA_VERSION_GIT_COMMIT_FULLREV \"" + self.GIT_COMMIT_FULLREV + "\"\n" + string+="#define SAMBA_VERSION_GIT_COMMIT_DATE \"" + self.GIT_COMMIT_DATE + "\"\n" string+="#define SAMBA_VERSION_GIT_COMMIT_TIME " + self.GIT_COMMIT_TIME + "\n" - string+="#define SAMBA_VERSION_GIT_COMMIT_FULLREV " + self.GIT_COMMIT_TIME + "\n" - string+="#define SAMBA_VERSION_GIT_COMMIT_DATE " + self.GIT_COMMIT_DATA + "\n" + if self.GIT_COMMIT_IS_CLEAN: + string+="#define SAMBA_VERSION_GIT_COMMIT_IS_CLEAN 1\n" except AttributeError: pass diff --git a/lib/tdb/pytdb.c b/lib/tdb/pytdb.c index 7a9205b815..f2638db492 100644 --- a/lib/tdb/pytdb.c +++ b/lib/tdb/pytdb.c @@ -77,15 +77,19 @@ static PyObject *PyString_FromTDB_DATA(TDB_DATA data) static PyObject *py_tdb_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) { - char *name; + char *name = NULL; int hash_size = 0, tdb_flags = TDB_DEFAULT, flags = O_RDWR, mode = 0600; TDB_CONTEXT *ctx; PyTdbObject *ret; const char *kwnames[] = { "name", "hash_size", "tdb_flags", "flags", "mode", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|iiii", (char **)kwnames, &name, &hash_size, &tdb_flags, &flags, &mode)) + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|siiii", (char **)kwnames, &name, &hash_size, &tdb_flags, &flags, &mode)) return NULL; + if (name == NULL) { + tdb_flags |= TDB_INTERNAL; + } + ctx = tdb_open(name, hash_size, tdb_flags, flags, mode); if (ctx == NULL) { PyErr_SetFromErrno(PyExc_IOError); @@ -112,6 +116,13 @@ static PyObject *obj_transaction_commit(PyTdbObject *self) Py_RETURN_NONE; } +static PyObject *obj_transaction_prepare_commit(PyTdbObject *self) +{ + int ret = tdb_transaction_prepare_commit(self->ctx); + PyErr_TDB_ERROR_IS_ERR_RAISE(ret, self->ctx); + Py_RETURN_NONE; +} + static PyObject *obj_transaction_start(PyTdbObject *self) { int ret = tdb_transaction_start(self->ctx); @@ -259,6 +270,27 @@ static PyObject *obj_store(PyTdbObject *self, PyObject *args) Py_RETURN_NONE; } +static PyObject *obj_add_flags(PyTdbObject *self, PyObject *args) +{ + unsigned flags; + + if (!PyArg_ParseTuple(args, "I", &flags)) + return NULL; + + tdb_add_flags(self->ctx, flags); + Py_RETURN_NONE; +} + +static PyObject *obj_remove_flags(PyTdbObject *self, PyObject *args) +{ + unsigned flags; + + if (!PyArg_ParseTuple(args, "I", &flags)) + return NULL; + + tdb_remove_flags(self->ctx, flags); + Py_RETURN_NONE; +} typedef struct { PyObject_HEAD @@ -311,6 +343,18 @@ static PyObject *obj_clear(PyTdbObject *self) Py_RETURN_NONE; } +static PyObject *obj_enable_seqnum(PyTdbObject *self) +{ + tdb_enable_seqnum(self->ctx); + Py_RETURN_NONE; +} + +static PyObject *obj_increment_seqnum_nonblock(PyTdbObject *self) +{ + tdb_increment_seqnum_nonblock(self->ctx); + Py_RETURN_NONE; +} + static PyMethodDef tdb_object_methods[] = { { "transaction_cancel", (PyCFunction)obj_transaction_cancel, METH_NOARGS, "S.transaction_cancel() -> None\n" @@ -318,6 +362,9 @@ static PyMethodDef tdb_object_methods[] = { { "transaction_commit", (PyCFunction)obj_transaction_commit, METH_NOARGS, "S.transaction_commit() -> None\n" "Commit the currently active transaction." }, + { "transaction_prepare_commit", (PyCFunction)obj_transaction_prepare_commit, METH_NOARGS, + "S.transaction_prepare_commit() -> None\n" + "Prepare to commit the currently active transaction" }, { "transaction_start", (PyCFunction)obj_transaction_start, METH_NOARGS, "S.transaction_start() -> None\n" "Start a new transaction." }, @@ -341,9 +388,15 @@ static PyMethodDef tdb_object_methods[] = { "Check whether key exists in this database." }, { "store", (PyCFunction)obj_store, METH_VARARGS, "S.store(key, data, flag=REPLACE) -> None" "Store data." }, + { "add_flags", (PyCFunction)obj_add_flags, METH_VARARGS, "S.add_flags(flags) -> None" }, + { "remove_flags", (PyCFunction)obj_remove_flags, METH_VARARGS, "S.remove_flags(flags) -> None" }, { "iterkeys", (PyCFunction)tdb_object_iter, METH_NOARGS, "S.iterkeys() -> iterator" }, { "clear", (PyCFunction)obj_clear, METH_NOARGS, "S.clear() -> None\n" "Wipe the entire database." }, + { "enable_seqnum", (PyCFunction)obj_enable_seqnum, METH_NOARGS, + "S.enable_seqnum() -> None" }, + { "increment_seqnum_nonblock", (PyCFunction)obj_increment_seqnum_nonblock, METH_NOARGS, + "S.increment_seqnum_nonblock() -> None" }, { NULL } }; @@ -365,6 +418,11 @@ static PyObject *obj_get_map_size(PyTdbObject *self, void *closure) return PyInt_FromLong(tdb_map_size(self->ctx)); } +static PyObject *obj_get_freelist_size(PyTdbObject *self, void *closure) +{ + return PyInt_FromLong(tdb_freelist_size(self->ctx)); +} + static PyObject *obj_get_flags(PyTdbObject *self, void *closure) { return PyInt_FromLong(tdb_get_flags(self->ctx)); @@ -375,18 +433,30 @@ static PyObject *obj_get_filename(PyTdbObject *self, void *closure) return PyString_FromString(tdb_name(self->ctx)); } +static PyObject *obj_get_seqnum(PyTdbObject *self, void *closure) +{ + return PyInt_FromLong(tdb_get_seqnum(self->ctx)); +} + + static PyGetSetDef tdb_object_getsetters[] = { { (char *)"hash_size", (getter)obj_get_hash_size, NULL, NULL }, { (char *)"map_size", (getter)obj_get_map_size, NULL, NULL }, + { (char *)"freelist_size", (getter)obj_get_freelist_size, NULL, NULL }, { (char *)"flags", (getter)obj_get_flags, NULL, NULL }, { (char *)"max_dead", NULL, (setter)obj_set_max_dead, NULL }, { (char *)"filename", (getter)obj_get_filename, NULL, (char *)"The filename of this TDB file."}, + { (char *)"seqnum", (getter)obj_get_seqnum, NULL, NULL }, { NULL } }; static PyObject *tdb_object_repr(PyTdbObject *self) { - return PyString_FromFormat("Tdb('%s')", tdb_name(self->ctx)); + if (tdb_get_flags(self->ctx) & TDB_INTERNAL) { + return PyString_FromString("Tdb(<internal>)"); + } else { + return PyString_FromFormat("Tdb('%s')", tdb_name(self->ctx)); + } } static void tdb_object_dealloc(PyTdbObject *self) @@ -497,6 +567,12 @@ void inittdb(void) PyModule_AddObject(m, "NOMMAP", PyInt_FromLong(TDB_NOMMAP)); PyModule_AddObject(m, "CONVERT", PyInt_FromLong(TDB_CONVERT)); PyModule_AddObject(m, "BIGENDIAN", PyInt_FromLong(TDB_BIGENDIAN)); + PyModule_AddObject(m, "NOSYNC", PyInt_FromLong(TDB_NOSYNC)); + PyModule_AddObject(m, "SEQNUM", PyInt_FromLong(TDB_SEQNUM)); + PyModule_AddObject(m, "VOLATILE", PyInt_FromLong(TDB_VOLATILE)); + PyModule_AddObject(m, "ALLOW_NESTING", PyInt_FromLong(TDB_ALLOW_NESTING)); + PyModule_AddObject(m, "DISALLOW_NESTING", PyInt_FromLong(TDB_DISALLOW_NESTING)); + PyModule_AddObject(m, "__docformat__", PyString_FromString("restructuredText")); Py_INCREF(&PyTdb); diff --git a/lib/tdb/python/tests/simple.py b/lib/tdb/python/tests/simple.py index 6b1e840f32..18180e16bd 100644 --- a/lib/tdb/python/tests/simple.py +++ b/lib/tdb/python/tests/simple.py @@ -18,6 +18,7 @@ class OpenTdbTests(TestCase): tdb.DEFAULT, os.O_RDWR) class CloseTdbTests(TestCase): + def test_double_close(self): self.tdb = tdb.Tdb(tempfile.mkstemp()[1], 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) @@ -28,6 +29,15 @@ class CloseTdbTests(TestCase): self.tdb.close() +class InternalTdbTests(TestCase): + + def test_repr(self): + self.tdb = tdb.Tdb() + + # repr used to crash on internal db + self.assertEquals(repr(self.tdb), "Tdb(<internal>)") + + class SimpleTdbTests(TestCase): def setUp(self): @@ -86,6 +96,9 @@ class SimpleTdbTests(TestCase): def test_map_size(self): self.tdb.map_size + def test_freelist_size(self): + self.tdb.freelist_size + def test_name(self): self.tdb.filename @@ -108,11 +121,13 @@ class SimpleTdbTests(TestCase): self.tdb.transaction_commit() self.assertEquals("1", self.tdb["bloe"]) - def test_iterator(self): + def test_transaction_prepare_commit(self): self.tdb["bloe"] = "2" - self.tdb["bla"] = "hoi" - i = iter(self.tdb) - self.assertEquals(set(["bloe", "bla"]), set([i.next(), i.next()])) + self.tdb.transaction_start() + self.tdb["bloe"] = "1" + self.tdb.transaction_prepare_commit() + self.tdb.transaction_commit() + self.assertEquals("1", self.tdb["bloe"]) def test_iterkeys(self): self.tdb["bloe"] = "2" @@ -127,11 +142,22 @@ class SimpleTdbTests(TestCase): self.tdb.clear() self.assertEquals(0, len(list(self.tdb))) + def test_seqnum(self): + self.tdb.enable_seqnum() + seq1 = self.tdb.seqnum + self.tdb.increment_seqnum_nonblock() + seq2 = self.tdb.seqnum + self.assertEquals(seq2-seq1, 1) + def test_len(self): self.assertEquals(0, len(list(self.tdb))) self.tdb["entry"] = "value" self.assertEquals(1, len(list(self.tdb))) + def test_add_flags(self): + self.tdb.add_flags(tdb.NOMMAP) + self.tdb.remove_flags(tdb.NOMMAP) + if __name__ == '__main__': import unittest diff --git a/lib/testtools/NEWS b/lib/testtools/NEWS index dc5e6df8f1..596df0d6a6 100644 --- a/lib/testtools/NEWS +++ b/lib/testtools/NEWS @@ -4,6 +4,15 @@ testtools NEWS NEXT ~~~~ +Improvements +------------ + +* Code duplication between assertEqual and the matcher Equals has been removed. + +* In normal circumstances, a TestCase will no longer share details with clones + of itself. (Andrew Bennetts, bug #637725) + + 0.9.6 ~~~~~ @@ -17,32 +26,32 @@ patches and TestCase.assertEqual gives slightly nicer errors. Improvements ------------ - * 'TestCase.assertEqual' now formats errors a little more nicely, in the - style of bzrlib. +* 'TestCase.assertEqual' now formats errors a little more nicely, in the + style of bzrlib. - * Added `PlaceHolder` and `ErrorHolder`, TestCase-like objects that can be - used to add results to a `TestResult`. +* Added `PlaceHolder` and `ErrorHolder`, TestCase-like objects that can be + used to add results to a `TestResult`. - * 'Mismatch' now takes optional description and details parameters, so - custom Matchers aren't compelled to make their own subclass. +* 'Mismatch' now takes optional description and details parameters, so + custom Matchers aren't compelled to make their own subclass. - * jml added a built-in UTF8_TEXT ContentType to make it slightly easier to - add details to test results. See bug #520044. +* jml added a built-in UTF8_TEXT ContentType to make it slightly easier to + add details to test results. See bug #520044. - * Fix a bug in our built-in matchers where assertThat would blow up if any - of them failed. All built-in mismatch objects now provide get_details(). +* Fix a bug in our built-in matchers where assertThat would blow up if any + of them failed. All built-in mismatch objects now provide get_details(). - * New 'Is' matcher, which lets you assert that a thing is identical to - another thing. +* New 'Is' matcher, which lets you assert that a thing is identical to + another thing. - * New 'LessThan' matcher which lets you assert that a thing is less than - another thing. +* New 'LessThan' matcher which lets you assert that a thing is less than + another thing. - * TestCase now has a 'patch()' method to make it easier to monkey-patching - objects in tests. See the manual for more information. Fixes bug #310770. +* TestCase now has a 'patch()' method to make it easier to monkey-patching + objects in tests. See the manual for more information. Fixes bug #310770. - * MultiTestResult methods now pass back return values from the results it - forwards to. +* MultiTestResult methods now pass back return values from the results it + forwards to. 0.9.5 ~~~~~ diff --git a/lib/testtools/testtools/matchers.py b/lib/testtools/testtools/matchers.py index 6a4c82a2fe..61b5bd74f9 100644 --- a/lib/testtools/testtools/matchers.py +++ b/lib/testtools/testtools/matchers.py @@ -25,6 +25,7 @@ __all__ = [ import doctest import operator +from pprint import pformat class Matcher(object): @@ -178,6 +179,14 @@ class _BinaryMismatch(Mismatch): self.other = other def describe(self): + left = repr(self.expected) + right = repr(self.other) + if len(left) + len(right) > 70: + return "%s:\nreference = %s\nactual = %s\n" % ( + self._mismatch_string, pformat(self.expected), + pformat(self.other)) + else: + return "%s %s %s" % (left, self._mismatch_string,right) return "%r %s %r" % (self.expected, self._mismatch_string, self.other) diff --git a/lib/testtools/testtools/testcase.py b/lib/testtools/testtools/testcase.py index 48eec71d41..959c129691 100644 --- a/lib/testtools/testtools/testcase.py +++ b/lib/testtools/testtools/testcase.py @@ -17,13 +17,16 @@ try: except ImportError: wraps = None import itertools -from pprint import pformat import sys import types import unittest from testtools import content from testtools.compat import advance_iterator +from testtools.matchers import ( + Annotate, + Equals, + ) from testtools.monkey import patch from testtools.runtest import RunTest from testtools.testresult import TestResult @@ -81,7 +84,9 @@ class TestCase(unittest.TestCase): self._traceback_id_gen = itertools.count(0) self.__setup_called = False self.__teardown_called = False - self.__details = {} + # __details is lazy-initialized so that a constructed-but-not-run + # TestCase is safe to use with clone_test_with_new_id. + self.__details = None self.__RunTest = kwargs.get('runTest', RunTest) self.__exception_handlers = [] self.exception_handlers = [ @@ -114,6 +119,8 @@ class TestCase(unittest.TestCase): :param content_object: The content object for this detail. See testtools.content for more detail. """ + if self.__details is None: + self.__details = {} self.__details[name] = content_object def getDetails(self): @@ -121,6 +128,8 @@ class TestCase(unittest.TestCase): For more details see pydoc testtools.TestResult. """ + if self.__details is None: + self.__details = {} return self.__details def patch(self, obj, attribute, value): @@ -230,18 +239,10 @@ class TestCase(unittest.TestCase): :param observed: The observed value. :param message: An optional message to include in the error. """ - try: - return super(TestCase, self).assertEqual(expected, observed) - except self.failureException: - lines = [] - if message: - lines.append(message) - lines.extend( - ["not equal:", - "a = %s" % pformat(expected), - "b = %s" % pformat(observed), - '']) - self.fail('\n'.join(lines)) + matcher = Equals(expected) + if message: + matcher = Annotate(message, matcher) + self.assertThat(observed, matcher) failUnlessEqual = assertEquals = assertEqual diff --git a/lib/testtools/testtools/tests/test_testtools.py b/lib/testtools/testtools/tests/test_testtools.py index 9edc5a5176..5dfb355990 100644 --- a/lib/testtools/testtools/tests/test_testtools.py +++ b/lib/testtools/testtools/tests/test_testtools.py @@ -461,6 +461,15 @@ class TestAssertions(TestCase): 'a = %s' % pformat(a), 'b = %s' % pformat(b), '']) + expected_error = '\n'.join([ + 'Match failed. Matchee: "%r"' % b, + 'Matcher: Annotate(%r, Equals(%r))' % (message, a), + 'Difference: !=:', + 'reference = %s' % pformat(a), + 'actual = %s' % pformat(b), + ': ' + message, + '' + ]) self.assertFails(expected_error, self.assertEqual, a, b, message) self.assertFails(expected_error, self.assertEquals, a, b, message) self.assertFails(expected_error, self.failUnlessEqual, a, b, message) @@ -468,11 +477,12 @@ class TestAssertions(TestCase): def test_assertEqual_formatting_no_message(self): a = "cat" b = "dog" - expected_error = '\n'.join( - ['not equal:', - 'a = %s' % pformat(a), - 'b = %s' % pformat(b), - '']) + expected_error = '\n'.join([ + 'Match failed. Matchee: "dog"', + 'Matcher: Equals(\'cat\')', + 'Difference: \'cat\' != \'dog\'', + '' + ]) self.assertFails(expected_error, self.assertEqual, a, b) self.assertFails(expected_error, self.assertEquals, a, b) self.assertFails(expected_error, self.failUnlessEqual, a, b) @@ -760,6 +770,18 @@ class TestCloneTestWithNewId(TestCase): self.assertEqual(oldName, test.id(), "the original test instance should be unchanged.") + def test_cloned_testcase_does_not_share_details(self): + """A cloned TestCase does not share the details dict.""" + class Test(TestCase): + def test_foo(self): + self.addDetail( + 'foo', content.Content('text/plain', lambda: 'foo')) + orig_test = Test('test_foo') + cloned_test = clone_test_with_new_id(orig_test, self.getUniqueString()) + orig_test.run(unittest.TestResult()) + self.assertEqual('foo', orig_test.getDetails()['foo'].iter_bytes()) + self.assertEqual(None, cloned_test.getDetails().get('foo')) + class TestDetailsProvided(TestWithDetails): diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index 68907aa593..bd08f7efd9 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -266,7 +266,7 @@ static size_t CHARSETNAME ## _pull(void *cd, const char **inbuf, size_t *inbytes char **outbuf, size_t *outbytesleft) \ { \ while (*inbytesleft >= 1 && *outbytesleft >= 2) { \ - *(uint16*)(*outbuf) = to_ucs2[((unsigned char*)(*inbuf))[0]]; \ + SSVAL(*outbuf, 0, to_ucs2[((unsigned char*)(*inbuf))[0]]); \ (*inbytesleft) -= 1; \ (*outbytesleft) -= 2; \ (*inbuf) += 1; \ diff --git a/lib/util/util.c b/lib/util/util.c index 076ddf47fc..11bb315176 100644 --- a/lib/util/util.c +++ b/lib/util/util.c @@ -165,15 +165,50 @@ _PUBLIC_ bool directory_create_or_exist(const char *dname, uid_t uid, Sleep for a specified number of milliseconds. **/ -_PUBLIC_ void msleep(unsigned int t) +_PUBLIC_ void smb_msleep(unsigned int t) { - struct timeval tval; +#if defined(HAVE_NANOSLEEP) + struct timespec ts; + int ret; + + ts.tv_sec = t/1000; + ts.tv_nsec = 1000000*(t%1000); + + do { + errno = 0; + ret = nanosleep(&ts, &ts); + } while (ret < 0 && errno == EINTR && (ts.tv_sec > 0 || ts.tv_nsec > 0)); +#else + unsigned int tdiff=0; + struct timeval tval,t1,t2; + fd_set fds; - tval.tv_sec = t/1000; - tval.tv_usec = 1000*(t%1000); - /* this should be the real select - do NOT replace - with sys_select() */ - select(0,NULL,NULL,NULL,&tval); + GetTimeOfDay(&t1); + t2 = t1; + + while (tdiff < t) { + tval.tv_sec = (t-tdiff)/1000; + tval.tv_usec = 1000*((t-tdiff)%1000); + + /* Never wait for more than 1 sec. */ + if (tval.tv_sec > 1) { + tval.tv_sec = 1; + tval.tv_usec = 0; + } + + FD_ZERO(&fds); + errno = 0; + select(0,&fds,NULL,NULL,&tval); + + GetTimeOfDay(&t2); + if (t2.tv_sec < t1.tv_sec) { + /* Someone adjusted time... */ + t1 = t2; + } + + tdiff = usec_time_diff(&t2,&t1)/1000; + } +#endif } /** diff --git a/lib/util/util.h b/lib/util/util.h index 994fad04d3..c613e65adf 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -655,7 +655,7 @@ _PUBLIC_ int set_blocking(int fd, bool set); /** Sleep for a specified number of milliseconds. **/ -_PUBLIC_ void msleep(unsigned int t); +_PUBLIC_ void smb_msleep(unsigned int t); /** Get my own name, return in talloc'ed storage. diff --git a/libcli/ldap/ldap_ndr.c b/libcli/ldap/ldap_ndr.c index 3b40fbba25..6daaba3604 100644 --- a/libcli/ldap/ldap_ndr.c +++ b/libcli/ldap/ldap_ndr.c @@ -65,7 +65,7 @@ char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid) /* encode a NDR GUID as a ldap filter element */ -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid) +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, const struct GUID *guid) { DATA_BLOB blob; NTSTATUS status; diff --git a/libcli/ldap/ldap_ndr.h b/libcli/ldap/ldap_ndr.h index ee1f702c78..df5ee478cb 100644 --- a/libcli/ldap/ldap_ndr.h +++ b/libcli/ldap/ldap_ndr.h @@ -5,7 +5,7 @@ char *ldap_encode_ndr_uint32(TALLOC_CTX *mem_ctx, uint32_t value); char *ldap_encode_ndr_dom_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); -char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, struct GUID *guid); +char *ldap_encode_ndr_GUID(TALLOC_CTX *mem_ctx, const struct GUID *guid); NTSTATUS ldap_decode_ndr_GUID(TALLOC_CTX *mem_ctx, struct ldb_val val, struct GUID *guid); #endif /* __LIBCLI_LDAP_LDAP_NDR_H__ */ diff --git a/libcli/security/dom_sid.c b/libcli/security/dom_sid.c index 93f887134e..f94d952b4d 100644 --- a/libcli/security/dom_sid.c +++ b/libcli/security/dom_sid.c @@ -98,6 +98,24 @@ bool sid_append_rid(struct dom_sid *sid, uint32_t rid) return false; } +/* + See if 2 SIDs are in the same domain + this just compares the leading sub-auths +*/ +int dom_sid_compare_domain(const struct dom_sid *sid1, + const struct dom_sid *sid2) +{ + int n, i; + + n = MIN(sid1->num_auths, sid2->num_auths); + + for (i = n-1; i >= 0; --i) + if (sid1->sub_auths[i] != sid2->sub_auths[i]) + return sid1->sub_auths[i] - sid2->sub_auths[i]; + + return dom_sid_compare_auth(sid1, sid2); +} + /***************************************************************** Convert a string to a SID. Returns True on success, False on fail. *****************************************************************/ diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h index e89253554e..ac8669d725 100644 --- a/libcli/security/dom_sid.h +++ b/libcli/security/dom_sid.h @@ -26,6 +26,8 @@ #include "librpc/gen_ndr/security.h" int dom_sid_compare(const struct dom_sid *sid1, const struct dom_sid *sid2); +int dom_sid_compare_domain(const struct dom_sid *sid1, + const struct dom_sid *sid2); bool dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2); bool dom_sid_parse(const char *sidstr, struct dom_sid *ret); struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr); diff --git a/libcli/util/werror.h b/libcli/util/werror.h index 3b717d2259..d89cd9c087 100644 --- a/libcli/util/werror.h +++ b/libcli/util/werror.h @@ -48,6 +48,13 @@ typedef uint32_t WERROR; }\ } while (0) +#define W_ERROR_HAVE_NO_MEMORY_AND_FREE(x, ctx) do { \ + if (!(x)) {\ + talloc_free(ctx); \ + return WERR_NOMEM;\ + }\ +} while (0) + #define W_ERROR_IS_OK_RETURN(x) do { \ if (W_ERROR_IS_OK(x)) {\ return x;\ diff --git a/librpc/idl/drsuapi.idl b/librpc/idl/drsuapi.idl index 9010efc23c..8981891455 100644 --- a/librpc/idl/drsuapi.idl +++ b/librpc/idl/drsuapi.idl @@ -952,17 +952,34 @@ interface drsuapi } drsuapi_DsNameFlags; typedef [v1_enum] enum { - DRSUAPI_DS_NAME_FORMAT_UNKNOWN = 0, - DRSUAPI_DS_NAME_FORMAT_FQDN_1779 = 1, - DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT = 2, - DRSUAPI_DS_NAME_FORMAT_DISPLAY = 3, - DRSUAPI_DS_NAME_FORMAT_GUID = 6, - DRSUAPI_DS_NAME_FORMAT_CANONICAL = 7, - DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL = 8, - DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX = 9, - DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL = 10, - DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY = 11, - DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN = 12 + DRSUAPI_DS_NAME_FORMAT_UNKNOWN = 0x00000000, + DRSUAPI_DS_NAME_FORMAT_FQDN_1779 = 0x00000001, + DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT = 0x00000002, + DRSUAPI_DS_NAME_FORMAT_DISPLAY = 0x00000003, + DRSUAPI_DS_NAME_FORMAT_GUID = 0x00000006, + DRSUAPI_DS_NAME_FORMAT_CANONICAL = 0x00000007, + DRSUAPI_DS_NAME_FORMAT_USER_PRINCIPAL = 0x00000008, + DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX = 0x00000009, + DRSUAPI_DS_NAME_FORMAT_SERVICE_PRINCIPAL = 0x0000000A, + DRSUAPI_DS_NAME_FORMAT_SID_OR_SID_HISTORY = 0x0000000B, + DRSUAPI_DS_NAME_FORMAT_DNS_DOMAIN = 0x0000000C, + DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID = 0xFFFFFFEF, + DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX = 0xFFFFFFF0, + DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS = 0xFFFFFFF1, + DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON = 0xFFFFFFF2, + DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE = 0xFFFFFFF3, + DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME = 0xFFFFFFF4, + DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME = 0xFFFFFFF5, + DRSUAPI_DS_NAME_FORMAT_LIST_NCS = 0xFFFFFFF6, + DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS = 0xFFFFFFF7, + DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID = 0xFFFFFFF8, + DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN = 0xFFFFFFF9, + DRSUAPI_DS_NAME_FORMAT_LIST_ROLES = 0xFFFFFFFA, + DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER = 0xFFFFFFFB, + DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE = 0xFFFFFFFC, + DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE = 0xFFFFFFFD, + DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE = 0xFFFFFFFE, + DRSUAPI_DS_NAME_FORMAT_LIST_SITES = 0xFFFFFFFF } drsuapi_DsNameFormat; typedef struct { diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl index 62d2af5588..1685cf9a1e 100644 --- a/librpc/idl/netlogon.idl +++ b/librpc/idl/netlogon.idl @@ -1715,7 +1715,7 @@ interface netlogon uint32 status; } NL_DNS_NAME_INFO; - typedef struct { + typedef [public] struct { uint32 count; [size_is(count)] NL_DNS_NAME_INFO *names; } NL_DNS_NAME_INFO_ARRAY; diff --git a/librpc/idl/wscript_build b/librpc/idl/wscript_build index e8723ce367..b8d11badf4 100644 --- a/librpc/idl/wscript_build +++ b/librpc/idl/wscript_build @@ -20,6 +20,11 @@ bld.SAMBA_PIDL_LIST('PIDL', output_dir='../gen_ndr') bld.SAMBA_PIDL_LIST('PIDL', - 'rap.idl idmap.idl dnsp.idl ntprinting.idl', + 'idmap.idl', + options='--header --ndr-parser --client --python', + output_dir='../gen_ndr') + +bld.SAMBA_PIDL_LIST('PIDL', + 'rap.idl dnsp.idl ntprinting.idl', options='--header --ndr-parser', output_dir='../gen_ndr') diff --git a/source3/Makefile.in b/source3/Makefile.in index 64d0a6a4df..ce8c865cb3 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -620,6 +620,8 @@ REG_INIT_FULL_OBJ = registry/reg_init_full.o REGFIO_OBJ = registry/regfio.o \ $(REG_PARSE_PRS_OBJ) +REG_API_REGF_OBJ = registry/reg_api_regf.o + REGOBJS_OBJ = registry/reg_objects.o REG_BACKENDS_BASE_OBJ = registry/reg_backend_db.o @@ -638,7 +640,6 @@ REG_BACKENDS_EXTRA_OBJ = registry/reg_backend_printing.o \ REG_BASE_OBJ = registry/reg_api.o \ registry/reg_dispatcher.o \ registry/reg_cachehook.o \ - $(REGFIO_OBJ) \ $(REGOBJS_OBJ) \ registry/reg_util_internal.o \ lib/util_nttoken.o \ @@ -647,6 +648,7 @@ REG_BASE_OBJ = registry/reg_api.o \ REG_SMBCONF_OBJ = $(REG_BASE_OBJ) \ registry/reg_util_token.o \ + registry/reg_api_util.o \ $(REG_BACKENDS_SMBCONF_OBJ) \ $(REG_INIT_SMBCONF_OBJ) @@ -756,7 +758,8 @@ PROFILES_OBJ = utils/profiles.o \ $(LIBSMB_ERR_OBJ) \ $(PARAM_OBJ) \ $(LIB_OBJ) $(LIB_DUMMY_OBJ) \ - $(POPT_LIB_OBJ) + $(POPT_LIB_OBJ) \ + $(REGFIO_OBJ) OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \ smbd/oplock_onefs.o @@ -904,6 +907,8 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(SMBLDAP_OBJ) $(LIBNET_OBJ) \ $(LIBSMBCONF_OBJ) \ $(PRIVILEGES_BASIC_OBJ) \ + $(REGFIO_OBJ) \ + $(REG_API_REGF_OBJ) \ $(LIBNDR_XATTR_OBJ) PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \ @@ -1007,6 +1012,7 @@ RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_shutdown.o rpcclient/cmd_test.o \ rpcclient/cmd_wkssvc.o rpcclient/cmd_ntsvcs.o \ rpcclient/cmd_drsuapi.o rpcclient/cmd_eventlog.o \ + rpcclient/cmd_winreg.o \ $(DISPLAY_SEC_OBJ) RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ @@ -1026,6 +1032,7 @@ RPCCLIENT_OBJ = $(RPCCLIENT_OBJ1) \ $(LIBCLI_SRVSVC_OBJ) \ $(LIBCLI_LSA_OBJ) \ $(LIBCLI_SAMR_OBJ) \ + $(LIBCLI_WINREG_OBJ) \ $(LIBCLI_NETLOGON_OBJ) \ $(RPC_CLIENT_SCHANNEL_OBJ) \ rpc_client/init_netlogon.o \ @@ -1162,6 +1169,7 @@ NET_OBJ = $(NET_OBJ1) \ $(REG_SMBCONF_OBJ) \ $(LIBNET_OBJ) $(LIBNET_DSSYNC_OBJ) $(LIBNET_SAMSYNC_OBJ) \ $(LIBSMBCONF_OBJ) \ + $(REGFIO_OBJ) \ $(PRIVILEGES_BASIC_OBJ) \ $(LIB_EVENTLOG_OBJ) localedir.o @@ -1430,6 +1438,7 @@ NTLM_AUTH_OBJ1 = utils/ntlm_auth.o utils/ntlm_auth_diagnostics.o NTLM_AUTH_OBJ = ${NTLM_AUTH_OBJ1} $(LIBSAMBA_OBJ) $(POPT_LIB_OBJ) \ ../lib/util/asn1.o ../libcli/auth/spnego_parse.o libsmb/clikrb5.o libads/kerberos.o \ + libsmb/samlogon_cache.o \ $(LIBADS_SERVER_OBJ) \ $(PASSDB_OBJ) $(LIBTSOCKET_OBJ) $(GROUPDB_OBJ) \ $(SMBLDAP_OBJ) $(LIBNMB_OBJ) \ diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 5e3091c7ae..825452026e 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -26,6 +26,7 @@ #include "../libcli/auth/libcli_auth.h" #include "../lib/crypto/arcfour.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -664,7 +665,7 @@ static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx, /* Domain sid */ sid_copy(&domain_sid, get_global_sam_sid()); - info3->base.domain_sid = sid_dup_talloc(mem_ctx, &domain_sid); + info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid); if (info3->base.domain_sid == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/auth/server_info.c b/source3/auth/server_info.c index e457bd4ae7..690838d779 100644 --- a/source3/auth/server_info.c +++ b/source3/auth/server_info.c @@ -20,6 +20,7 @@ #include "includes.h" #include "../lib/crypto/arcfour.h" #include "../librpc/gen_ndr/netlogon.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH @@ -229,7 +230,7 @@ static NTSTATUS append_netr_SidAttr(TALLOC_CTX *mem_ctx, if (*sids == NULL) { return NT_STATUS_NO_MEMORY; } - (*sids)[t].sid = sid_dup_talloc(*sids, asid); + (*sids)[t].sid = dom_sid_dup(*sids, asid); if ((*sids)[t].sid == NULL) { return NT_STATUS_NO_MEMORY; } @@ -332,7 +333,7 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx, /* check if this is a "Unix Users" domain user, * we need to handle it in a special way if that's the case */ - if (sid_compare_domain(user_sid, &global_sid_Unix_Users) == 0) { + if (dom_sid_compare_domain(user_sid, &global_sid_Unix_Users) == 0) { /* in info3 you can only set rids for the user and the * primary group, and the domain sid must be that of * the sam domain. @@ -358,7 +359,7 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx, /* check if this is a "Unix Groups" domain group, * if so we need special handling */ - if (sid_compare_domain(group_sid, &global_sid_Unix_Groups) == 0) { + if (dom_sid_compare_domain(group_sid, &global_sid_Unix_Groups) == 0) { /* in info3 you can only set rids for the user and the * primary group, and the domain sid must be that of * the sam domain. @@ -467,7 +468,7 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *mem_ctx, pdb_get_domain(samu)); RET_NOMEM(info3->base.domain.string); - info3->base.domain_sid = sid_dup_talloc(info3, &domain_sid); + info3->base.domain_sid = dom_sid_dup(info3, &domain_sid); RET_NOMEM(info3->base.domain_sid); info3->base.acct_flags = pdb_get_acct_ctrl(samu); @@ -547,7 +548,7 @@ struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx, } if (orig->base.domain_sid) { - info3->base.domain_sid = sid_dup_talloc(info3, orig->base.domain_sid); + info3->base.domain_sid = dom_sid_dup(info3, orig->base.domain_sid); RET_NOMEM(info3->base.domain_sid); } @@ -557,7 +558,7 @@ struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx, orig->sidcount); RET_NOMEM(info3->sids); for (i = 0; i < orig->sidcount; i++) { - info3->sids[i].sid = sid_dup_talloc(info3->sids, + info3->sids[i].sid = dom_sid_dup(info3->sids, orig->sids[i].sid); RET_NOMEM(info3->sids[i].sid); info3->sids[i].attributes = @@ -694,7 +695,7 @@ struct netr_SamInfo3 *wbcAuthUserInfo_to_netr_SamInfo3(TALLOC_CTX *mem_ctx, RET_NOMEM(info3->base.domain.string); } - info3->base.domain_sid = sid_dup_talloc(info3, &domain_sid); + info3->base.domain_sid = dom_sid_dup(info3, &domain_sid); RET_NOMEM(info3->base.domain_sid); memcpy(info3->base.LMSessKey.key, info->lm_session_key, 8); diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c index bc7d998341..4385dc400c 100644 --- a/source3/auth/token_util.c +++ b/source3/auth/token_util.c @@ -27,7 +27,7 @@ #include "includes.h" #include "secrets.h" #include "memcache.h" - +#include "../libcli/security/dom_sid.h" #include "../librpc/gen_ndr/netlogon.h" /**************************************************************************** @@ -42,7 +42,7 @@ bool nt_token_check_sid ( const struct dom_sid *sid, const struct security_token return False; for ( i=0; i<token->num_sids; i++ ) { - if ( sid_equal( sid, &token->sids[i] ) ) + if ( dom_sid_equal( sid, &token->sids[i] ) ) return True; } diff --git a/source3/build/dynconfig.py b/source3/build/dynconfig.py index 65798a35ec..7382516e3e 100644 --- a/source3/build/dynconfig.py +++ b/source3/build/dynconfig.py @@ -10,7 +10,8 @@ dir_options = { 'with-lockdir' : [ '${PREFIX}/var/locks', 'where to put lock files' ], 'with-codepagedir' : [ '${PREFIX}/lib/samba', 'where to put codepages' ], 'with-privatedir' : [ '${PREFIX}/private', 'where to put smbpasswd' ], - 'with-cachedir' : [ '${PREFIX}/var/locks', 'where to put temporary cache files' ] + 'with-cachedir' : [ '${PREFIX}/var/locks', 'where to put temporary cache files' ], + 'with-localedir' : [ '${PREFIX}/share/locale', 'Where to put po files' ] } # list of cflags to use for dynconfig.c @@ -37,6 +38,7 @@ dyn_cflags = { 'NTP_SIGND_SOCKET_DIR' : '${NTP_SIGND_SOCKET_DIR}', 'CODEPAGEDIR' : '${CODEPAGEDIR}', 'CACHEDIR' : '${CACHEDIR}', + 'LOCALEDIR' : '${LOCALEDIR}', 'SMB_PASSWD_FILE' : '${PRIVATEDIR}/smbpasswd', } diff --git a/source3/build/wscript b/source3/build/wscript index f27e279d6b..2cbcbe6de1 100644 --- a/source3/build/wscript +++ b/source3/build/wscript @@ -43,6 +43,9 @@ def build(bld): '../dynconfig.c', deps='replace talloc tdb popt', cflags=cflags) + bld.SAMBA_SUBSYSTEM('LOCALE_DIR', + '../localedir.c', + cflags=cflags) def dynconfig_cflags(bld): '''work out the extra CFLAGS for dynconfig.c''' diff --git a/source3/client/client.c b/source3/client/client.c index c911559911..86d64f6afa 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1119,7 +1119,7 @@ static int do_get(const char *rname, const char *lname_in, bool reget) int this_time; clock_gettime_mono(&tp_end); - this_time = TspecDiff(&tp_start,&tp_end); + this_time = nsec_time_diff(&tp_end,&tp_start)/1000000; get_total_time_ms += this_time; get_total_size += nread; @@ -1768,7 +1768,7 @@ static int do_put(const char *rname, const char *lname, bool reput) int this_time; clock_gettime_mono(&tp_end); - this_time = TspecDiff(&tp_start,&tp_end); + this_time = nsec_time_diff(&tp_end,&tp_start)/1000000; put_total_time_ms += this_time; put_total_size += state.nread; diff --git a/source3/groupdb/mapping_tdb.c b/source3/groupdb/mapping_tdb.c index 140fd28d97..dab2520fc1 100644 --- a/source3/groupdb/mapping_tdb.c +++ b/source3/groupdb/mapping_tdb.c @@ -23,6 +23,7 @@ #include "includes.h" #include "groupdb/mapping.h" #include "dbwrap.h" +#include "../libcli/security/dom_sid.h" static struct db_context *db; /* used for driver files */ @@ -340,7 +341,7 @@ static int collect_map(struct db_record *rec, void *private_data) } if ((state->domsid != NULL) && - (sid_compare_domain(state->domsid, &map.sid) != 0)) { + (dom_sid_compare_domain(state->domsid, &map.sid) != 0)) { DEBUG(11,("enum_group_mapping: group %s is not in domain\n", sid_string_dbg(&map.sid))); return 0; @@ -455,7 +456,7 @@ static bool is_aliasmem(const struct dom_sid *alias, const struct dom_sid *membe return False; for (i=0; i<num; i++) { - if (sid_compare(alias, &sids[i]) == 0) { + if (dom_sid_compare(alias, &sids[i]) == 0) { TALLOC_FREE(sids); return True; } @@ -576,7 +577,7 @@ static int collect_aliasmem(struct db_record *rec, void *priv) if (!string_to_sid(&alias, alias_string)) continue; - if (sid_compare(state->alias, &alias) != 0) + if (dom_sid_compare(state->alias, &alias) != 0) continue; /* Ok, we found the alias we're looking for in the membership @@ -656,7 +657,7 @@ static NTSTATUS del_aliasmem(const struct dom_sid *alias, const struct dom_sid * } for (i=0; i<num; i++) { - if (sid_compare(&sids[i], alias) == 0) { + if (dom_sid_compare(&sids[i], alias) == 0) { found = True; break; } diff --git a/source3/include/includes.h b/source3/include/includes.h index 2e45b7964d..a17e014ca9 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -653,18 +653,11 @@ extern void *cmdline_lp_ctx; #include "session.h" #include "module.h" #include "packet.h" -#include "ctdbd_conn.h" #include "../lib/util/talloc_stack.h" #include "serverid.h" -#include "async_smb.h" -#include "../lib/async_req/async_sock.h" #include "../lib/util/smb_threads.h" #include "../lib/util/smb_threads_internal.h" -/* forward declarations from smbldap.c */ - -#include "smbldap.h" - /* * Reasons for cache flush. */ @@ -769,10 +762,6 @@ enum flush_reason_enum { #define PASSWORD_LENGTH 8 #endif -#ifndef HAVE_PIPE -#define SYNC_DNS 1 -#endif - #if defined(HAVE_CRYPT16) && defined(HAVE_GETAUTHUID) #define ULTRIX_AUTH 1 #endif diff --git a/source3/include/proto.h b/source3/include/proto.h index 6fe8f641ba..5bb91c53eb 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -740,43 +740,6 @@ bool share_access_check(const struct security_token *token, const char *sharenam uint32 desired_access); bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, struct security_descriptor **ppsd); -/* The following definitions come from lib/smbldap.c */ - -int smb_ldap_start_tls(LDAP *ldap_struct, int version); -int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri); -int smbldap_search(struct smbldap_state *ldap_state, - const char *base, int scope, const char *filter, - const char *attrs[], int attrsonly, - LDAPMessage **res); -int smbldap_search_paged(struct smbldap_state *ldap_state, - const char *base, int scope, const char *filter, - const char **attrs, int attrsonly, int pagesize, - LDAPMessage **res, void **cookie); -int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[]); -int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[]); -int smbldap_delete(struct smbldap_state *ldap_state, const char *dn); -int smbldap_extended_operation(struct smbldap_state *ldap_state, - LDAP_CONST char *reqoid, struct berval *reqdata, - LDAPControl **serverctrls, LDAPControl **clientctrls, - char **retoidp, struct berval **retdatap); -int smbldap_search_suffix (struct smbldap_state *ldap_state, - const char *filter, const char **search_attr, - LDAPMessage ** result); -void smbldap_free_struct(struct smbldap_state **ldap_state) ; -NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, - const char *location, - struct smbldap_state **smbldap_state); -bool smbldap_has_control(LDAP *ld, const char *control); -bool smbldap_has_extension(LDAP *ld, const char *extension); -bool smbldap_has_naming_context(LDAP *ld, const char *naming_context); -bool smbldap_set_creds(struct smbldap_state *ldap_state, bool anon, const char *dn, const char *secret); - -/* The following definitions come from lib/smbldap_util.c */ - -NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, - LDAPMessage ** result, const char *domain_name, - bool try_add); - /* The following definitions come from lib/smbrun.c */ int smbrun_no_sanitize(const char *cmd, int *outfd); @@ -1153,7 +1116,6 @@ char *unix_clean_name(TALLOC_CTX *ctx, const char *s); char *clean_name(TALLOC_CTX *ctx, const char *s); ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos); int set_blocking(int fd, bool set); -void smb_msleep(unsigned int t); NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx, struct event_context *ev_ctx, struct server_id id, @@ -1332,13 +1294,9 @@ bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid void sid_copy(struct dom_sid *dst, const struct dom_sid *src); bool sid_linearize(char *outbuf, size_t len, const struct dom_sid *sid); bool sid_parse(const char *inbuf, size_t len, struct dom_sid *sid); -int sid_compare(const struct dom_sid *sid1, const struct dom_sid *sid2); -int sid_compare_domain(const struct dom_sid *sid1, const struct dom_sid *sid2); -bool sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2); bool non_mappable_sid(struct dom_sid *sid); char *sid_binstring(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); char *sid_binstring_hex(const struct dom_sid *sid); -struct dom_sid *sid_dup_talloc(TALLOC_CTX *ctx, const struct dom_sid *src); NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, struct dom_sid **sids, uint32_t *num); NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, @@ -3944,17 +3902,17 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods ) ; /* The following definitions come from passdb/pdb_ldap.c */ +struct ldapsam_privates; + const char** get_userattr_list( TALLOC_CTX *mem_ctx, int schema_ver ); -int ldapsam_search_suffix_by_name(struct ldapsam_privates *ldap_state, - const char *user, - LDAPMessage ** result, - const char **attr); NTSTATUS pdb_init_ldapsam_compat(struct pdb_methods **pdb_method, const char *location); NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location); NTSTATUS pdb_ldap_init(void); /* The following definitions come from passdb/pdb_nds.c */ +struct smbldap_state; + int pdb_nds_get_password( struct smbldap_state *ldap_state, char *object_dn, @@ -5677,5 +5635,6 @@ uint32_t ds_uf2acb(uint32_t uf); uint32_t ds_uf2atype(uint32_t uf); uint32_t ds_gtype2atype(uint32_t gtype); enum lsa_SidType ds_atype_map(uint32_t atype); +uint32_t ds_uf2prim_group_rid(uint32_t uf); #endif /* _PROTO_H_ */ diff --git a/source3/include/registry.h b/source3/include/registry.h index 66a364d97d..600fffe679 100644 --- a/source3/include/registry.h +++ b/source3/include/registry.h @@ -169,25 +169,18 @@ WERROR reg_getkeysecurity(TALLOC_CTX *mem_ctx, struct registry_key *key, WERROR reg_setkeysecurity(struct registry_key *key, struct security_descriptor *psecdesc); WERROR reg_getversion(uint32_t *version); -WERROR reg_restorekey(struct registry_key *key, const char *fname); -WERROR reg_savekey(struct registry_key *key, const char *fname); WERROR reg_deleteallvalues(struct registry_key *key); -WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, - uint32 desired_access, const struct security_token *token, - struct registry_key **pkey); WERROR reg_deletekey_recursive(TALLOC_CTX *ctx, struct registry_key *parent, const char *path); WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx, struct registry_key *parent, const char *path); -WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path, - uint32 desired_access, - const struct security_token *token, - enum winreg_CreateAction *paction, - struct registry_key **pkey); -WERROR reg_delete_path(const struct security_token *token, - const char *orig_path); + +/* The following definitions come from registry/reg_api_regf.c */ + +WERROR reg_restorekey(struct registry_key *key, const char *fname); +WERROR reg_savekey(struct registry_key *key, const char *fname); /* The following definitions come from registry/reg_init_basic.c */ diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index e72f2aab68..9f4b345b84 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -144,24 +144,6 @@ #define ENCRYPTION_REQUIRED(conn) ((conn) ? ((conn)->encrypt_level == Required) : false) #define IS_CONN_ENCRYPTED(conn) ((conn) ? (conn)->encrypted_tid : false) -/******************************************************************* -find the difference in milliseconds between two struct timeval -values -********************************************************************/ - -#define TvalDiff(tvalold,tvalnew) \ - (((tvalnew)->tv_sec - (tvalold)->tv_sec)*1000 + \ - ((int)(tvalnew)->tv_usec - (int)(tvalold)->tv_usec)/1000) - -/******************************************************************* -find the difference in milliseconds between two struct timespec -values -********************************************************************/ - -#define TspecDiff(tvalold,tvalnew) \ - (((tvalnew)->tv_sec - (tvalold)->tv_sec)*1000 + \ - ((int)(tvalnew)->tv_nsec - (int)(tvalold)->tv_nsec)/1000000) - /**************************************************************************** true if two IPv4 addresses are equal ****************************************************************************/ diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index 060fcc21eb..ffe618d4f7 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -233,6 +233,43 @@ char *smbldap_talloc_dn(TALLOC_CTX *mem_ctx, LDAP *ld, LDAPMessage *entry); +/* The following definitions come from lib/smbldap.c */ + +int smb_ldap_start_tls(LDAP *ldap_struct, int version); +int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri); +int smbldap_search(struct smbldap_state *ldap_state, + const char *base, int scope, const char *filter, + const char *attrs[], int attrsonly, + LDAPMessage **res); +int smbldap_search_paged(struct smbldap_state *ldap_state, + const char *base, int scope, const char *filter, + const char **attrs, int attrsonly, int pagesize, + LDAPMessage **res, void **cookie); +int smbldap_modify(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[]); +int smbldap_add(struct smbldap_state *ldap_state, const char *dn, LDAPMod *attrs[]); +int smbldap_delete(struct smbldap_state *ldap_state, const char *dn); +int smbldap_extended_operation(struct smbldap_state *ldap_state, + LDAP_CONST char *reqoid, struct berval *reqdata, + LDAPControl **serverctrls, LDAPControl **clientctrls, + char **retoidp, struct berval **retdatap); +int smbldap_search_suffix (struct smbldap_state *ldap_state, + const char *filter, const char **search_attr, + LDAPMessage ** result); +void smbldap_free_struct(struct smbldap_state **ldap_state) ; +NTSTATUS smbldap_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, + const char *location, + struct smbldap_state **smbldap_state); +bool smbldap_has_control(LDAP *ld, const char *control); +bool smbldap_has_extension(LDAP *ld, const char *extension); +bool smbldap_has_naming_context(LDAP *ld, const char *naming_context); +bool smbldap_set_creds(struct smbldap_state *ldap_state, bool anon, const char *dn, const char *secret); + +/* The following definitions come from lib/smbldap_util.c */ + +NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state, + LDAPMessage ** result, const char *domain_name, + bool try_add); + #else #define LDAP void #define LDAPMessage void diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c index ff286148eb..e0682f3a74 100644 --- a/source3/lib/ctdbd_conn.c +++ b/source3/lib/ctdbd_conn.c @@ -24,6 +24,7 @@ #include "librpc/gen_ndr/messaging.h" #include "librpc/gen_ndr/ndr_messaging.h" +#include "ctdbd_conn.h" /* paths to these include files come from --with-ctdb= in configure */ #include "ctdb.h" diff --git a/source3/lib/fault.c b/source3/lib/fault.c index 02e054b680..dd87ae1100 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -319,14 +319,6 @@ void dump_core_setup(const char *progname) #endif #endif -#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) - /* On Linux we lose the ability to dump core when we change our user - * ID. We know how to dump core safely, so let's make sure we have our - * dumpable flag set. - */ - prctl(PR_SET_DUMPABLE, 1); -#endif - /* FIXME: if we have a core-plus-pid facility, configurably set * this up here. */ @@ -382,6 +374,14 @@ void dump_core_setup(const char *progname) umask(~(0700)); dbgflush(); +#if defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE) + /* On Linux we lose the ability to dump core when we change our user + * ID. We know how to dump core safely, so let's make sure we have our + * dumpable flag set. + */ + prctl(PR_SET_DUMPABLE, 1); +#endif + /* Ensure we don't have a signal handler for abort. */ #ifdef SIGABRT CatchSignal(SIGABRT, SIG_DFL); diff --git a/source3/lib/g_lock.c b/source3/lib/g_lock.c index 6e4c6d796c..edb77869cc 100644 --- a/source3/lib/g_lock.c +++ b/source3/lib/g_lock.c @@ -20,6 +20,7 @@ #include "includes.h" #include "g_lock.h" #include "librpc/gen_ndr/messaging.h" +#include "ctdbd_conn.h" static NTSTATUS g_lock_force_unlock(struct g_lock_ctx *ctx, const char *name, struct server_id pid); diff --git a/source3/lib/netapi/examples/netlogon/nltest.c b/source3/lib/netapi/examples/netlogon/nltest.c index e3ced90a20..0c393ea3be 100644 --- a/source3/lib/netapi/examples/netlogon/nltest.c +++ b/source3/lib/netapi/examples/netlogon/nltest.c @@ -58,7 +58,8 @@ enum { OPT_SITE, OPT_ACCOUNT, OPT_RET_DNS, - OPT_RET_NETBIOS + OPT_RET_NETBIOS, + OPT_DSREGDNS }; /**************************************************************** @@ -207,6 +208,7 @@ int main(int argc, const char **argv) char *opt_account = NULL; int opt_ret_dns = 0; int opt_ret_netbios = 0; + int opt_dsregdns = 0; uint32_t query_level = 0; uint8_t *buffer = NULL; uint32_t flags = 0; @@ -244,6 +246,7 @@ int main(int argc, const char **argv) {"account", 0, POPT_ARG_STRING, &opt_account, OPT_ACCOUNT, "ACCOUNT"}, {"ret_dns", 0, POPT_ARG_NONE, &opt_ret_dns, OPT_RET_DNS, NULL}, {"ret_netbios", 0, POPT_ARG_NONE, &opt_ret_netbios, OPT_RET_NETBIOS, NULL}, + {"dsregdns", 0, POPT_ARG_NONE, &opt_dsregdns, OPT_DSREGDNS, "Force registration of all DC-specific DNS records"}, POPT_COMMON_LIBNETAPI_EXAMPLES POPT_TABLEEND }; @@ -363,6 +366,23 @@ int main(int argc, const char **argv) print_netlogon_info_result(query_level, buffer); break; + case OPT_DSREGDNS: + query_level = 1; + status = I_NetLogonControl2(opt_server, + NETLOGON_CONTROL_FORCE_DNS_REG, + query_level, + NULL, + &buffer); + if (status != 0) { + fprintf(stderr, "I_NetlogonControl failed: Status = %d 0x%x %s\n", + status, status, + libnetapi_get_error_string(ctx, status)); + goto done; + } + + print_netlogon_info_result(query_level, buffer); + + break; case OPT_DSGETDC: if (opt_pdc) flags |= DS_PDC_REQUIRED; diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c index 53114b5d7d..6a926953c0 100644 --- a/source3/lib/netapi/group.c +++ b/source3/lib/netapi/group.c @@ -25,6 +25,7 @@ #include "lib/netapi/libnetapi.h" #include "../librpc/gen_ndr/cli_samr.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" /**************************************************************** ****************************************************************/ @@ -603,7 +604,7 @@ static WERROR map_group_info_to_buffer(TALLOC_CTX *mem_ctx, info3.grpi3_name = info->name.string; info3.grpi3_comment = info->description.string; info3.grpi3_attributes = info->attributes; - info3.grpi3_group_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid); + info3.grpi3_group_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid); *buffer = (uint8_t *)talloc_memdup(mem_ctx, &info3, sizeof(info3)); @@ -1086,7 +1087,7 @@ static WERROR convert_samr_disp_groups_to_GROUP_INFO_3_buffer(TALLOC_CTX *mem_ct groups->entries[i].account_name.string); g3[i].grpi3_comment = talloc_strdup(mem_ctx, groups->entries[i].description.string); - g3[i].grpi3_group_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid); + g3[i].grpi3_group_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid); g3[i].grpi3_attributes = groups->entries[i].acct_flags; W_ERROR_HAVE_NO_MEMORY(g3[i].grpi3_name); } diff --git a/source3/lib/netapi/localgroup.c b/source3/lib/netapi/localgroup.c index 69cf974225..c9e1b722bd 100644 --- a/source3/lib/netapi/localgroup.c +++ b/source3/lib/netapi/localgroup.c @@ -27,6 +27,7 @@ #include "../librpc/gen_ndr/cli_lsa.h" #include "rpc_client/cli_lsarpc.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" static NTSTATUS libnetapi_samr_lookup_and_open_alias(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *pipe_cli, @@ -1171,7 +1172,7 @@ static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx, for (i=0; i < r->in.total_entries; i++) { bool already_member = false; for (k=0; k < current_sids.num_sids; k++) { - if (sid_equal(&member_sids[i], + if (dom_sid_equal(&member_sids[i], current_sids.sids[k].sid)) { already_member = true; break; @@ -1193,7 +1194,7 @@ static WERROR NetLocalGroupModifyMembers_r(struct libnetapi_ctx *ctx, for (k=0; k < current_sids.num_sids; k++) { bool keep_member = false; for (i=0; i < r->in.total_entries; i++) { - if (sid_equal(&member_sids[i], + if (dom_sid_equal(&member_sids[i], current_sids.sids[k].sid)) { keep_member = true; break; diff --git a/source3/lib/netapi/netlogon.c b/source3/lib/netapi/netlogon.c index d58b7ccf67..932ab8bb1d 100644 --- a/source3/lib/netapi/netlogon.c +++ b/source3/lib/netapi/netlogon.c @@ -43,6 +43,9 @@ static WERROR construct_data(enum netr_LogonControlCode function_code, case NETLOGON_CONTROL_SET_DBFLAG: data_out->debug_level = atoi((const char *)data_in); break; + case NETLOGON_CONTROL_FORCE_DNS_REG: + ZERO_STRUCTP(data_out); + break; default: return WERR_INVALID_PARAM; } @@ -193,6 +196,7 @@ WERROR I_NetLogonControl2_r(struct libnetapi_ctx *ctx, switch (r->in.function_code) { case NETLOGON_CONTROL_TC_VERIFY: case NETLOGON_CONTROL_SET_DBFLAG: + case NETLOGON_CONTROL_FORCE_DNS_REG: status = rpccli_netr_LogonControl2Ex(pipe_cli, ctx, r->in.server_name, r->in.function_code, diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index 67a7443cd4..de0fc7da6e 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -27,6 +27,7 @@ #include "rpc_client/init_samr.h" #include "../libds/common/flags.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" /**************************************************************** ****************************************************************/ @@ -705,12 +706,12 @@ static NTSTATUS libnetapi_samr_lookup_user(TALLOC_CTX *mem_ctx, for (i=0; i<rid_array->count; i++) { sid_compose(&sid, domain_sid, rid_array->rids[i].rid); - sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid); + sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid); NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid); } sid_compose(&sid, domain_sid, rid); - sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sid); + sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sid); NT_STATUS_HAVE_NO_MEMORY(sid_array.sids[i].sid); status = rpccli_samr_GetAliasMembership(pipe_cli, mem_ctx, @@ -923,7 +924,7 @@ static NTSTATUS info21_to_USER_INFO_4(TALLOC_CTX *mem_ctx, if (!sid_compose(&sid, domain_sid, i21->rid)) { return NT_STATUS_NO_MEMORY; } - i->usri4_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid); + i->usri4_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid); i->usri4_primary_group_id = i21->primary_gid; i->usri4_profile = talloc_strdup(mem_ctx, i21->profile_path.string); i->usri4_home_dir_drive = talloc_strdup(mem_ctx, i21->home_drive.string); @@ -1024,7 +1025,7 @@ static NTSTATUS info21_to_USER_INFO_23(TALLOC_CTX *mem_ctx, if (!sid_compose(&sid, domain_sid, i21->rid)) { return NT_STATUS_NO_MEMORY; } - i->usri23_user_sid = (struct domsid *)sid_dup_talloc(mem_ctx, &sid); + i->usri23_user_sid = (struct domsid *)dom_sid_dup(mem_ctx, &sid); return NT_STATUS_OK; } @@ -2066,7 +2067,7 @@ static NTSTATUS query_USER_MODALS_INFO_2(TALLOC_CTX *mem_ctx, info2->usrmod2_domain_name = talloc_strdup(mem_ctx, dom_info5.domain_name.string); info2->usrmod2_domain_id = - (struct domsid *)sid_dup_talloc(mem_ctx, domain_sid); + (struct domsid *)dom_sid_dup(mem_ctx, domain_sid); NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_name); NT_STATUS_HAVE_NO_MEMORY(info2->usrmod2_domain_id); @@ -3334,7 +3335,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx, goto done; } - sid_array.sids[0].sid = sid_dup_talloc(ctx, &user_sid); + sid_array.sids[0].sid = dom_sid_dup(ctx, &user_sid); if (!sid_array.sids[0].sid) { werr = WERR_NOMEM; goto done; @@ -3348,7 +3349,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx, goto done; } - sid_array.sids[i+1].sid = sid_dup_talloc(ctx, &sid); + sid_array.sids[i+1].sid = dom_sid_dup(ctx, &sid); if (!sid_array.sids[i+1].sid) { werr = WERR_NOMEM; goto done; diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index b9ed955dee..11256817a5 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -22,6 +22,7 @@ #include "includes.h" #include "../librpc/gen_ndr/ndr_security.h" +#include "../libcli/security/dom_sid.h" #define ALL_SECURITY_INFORMATION (SECINFO_OWNER|SECINFO_GROUP|\ SECINFO_DACL|SECINFO_SACL|\ @@ -190,10 +191,10 @@ struct security_descriptor *make_sec_desc(TALLOC_CTX *ctx, dst->sacl = NULL; dst->dacl = NULL; - if(owner_sid && ((dst->owner_sid = sid_dup_talloc(dst,owner_sid)) == NULL)) + if(owner_sid && ((dst->owner_sid = dom_sid_dup(dst,owner_sid)) == NULL)) goto error_exit; - if(grp_sid && ((dst->group_sid = sid_dup_talloc(dst,grp_sid)) == NULL)) + if(grp_sid && ((dst->group_sid = dom_sid_dup(dst,grp_sid)) == NULL)) goto error_exit; if(sacl && ((dst->sacl = dup_sec_acl(dst, sacl)) == NULL)) @@ -607,10 +608,10 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx, } /* The CREATOR sids are special when inherited */ - if (sid_equal(ptrustee, &global_sid_Creator_Owner)) { + if (dom_sid_equal(ptrustee, &global_sid_Creator_Owner)) { creator = &global_sid_Creator_Owner; ptrustee = owner_sid; - } else if (sid_equal(ptrustee, &global_sid_Creator_Group)) { + } else if (dom_sid_equal(ptrustee, &global_sid_Creator_Group)) { creator = &global_sid_Creator_Group; ptrustee = group_sid; } diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index ba27b48206..cafa3bfee4 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -22,6 +22,7 @@ #include "registry.h" #include "registry/reg_backend_db.h" #include "registry/reg_util_token.h" +#include "registry/reg_api_util.h" #include "lib/smbconf/smbconf_init.h" #include "lib/smbconf/smbconf_reg.h" diff --git a/source3/lib/util.c b/source3/lib/util.c index 3303894e0e..28336512df 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -24,6 +24,7 @@ #include "includes.h" #include "popt_common.h" #include "secrets.h" +#include "ctdbd_conn.h" extern char *global_clobber_region_function; extern unsigned int global_clobber_region_line; @@ -823,55 +824,6 @@ ssize_t write_data_at_offset(int fd, const char *buffer, size_t N, SMB_OFF_T pos #endif } -/******************************************************************* - Sleep for a specified number of milliseconds. -********************************************************************/ - -void smb_msleep(unsigned int t) -{ -#if defined(HAVE_NANOSLEEP) - struct timespec tval; - int ret; - - tval.tv_sec = t/1000; - tval.tv_nsec = 1000000*(t%1000); - - do { - errno = 0; - ret = nanosleep(&tval, &tval); - } while (ret < 0 && errno == EINTR && (tval.tv_sec > 0 || tval.tv_nsec > 0)); -#else - unsigned int tdiff=0; - struct timeval tval,t1,t2; - fd_set fds; - - GetTimeOfDay(&t1); - t2 = t1; - - while (tdiff < t) { - tval.tv_sec = (t-tdiff)/1000; - tval.tv_usec = 1000*((t-tdiff)%1000); - - /* Never wait for more than 1 sec. */ - if (tval.tv_sec > 1) { - tval.tv_sec = 1; - tval.tv_usec = 0; - } - - FD_ZERO(&fds); - errno = 0; - sys_select_intr(0,&fds,NULL,NULL,&tval); - - GetTimeOfDay(&t2); - if (t2.tv_sec < t1.tv_sec) { - /* Someone adjusted time... */ - t1 = t2; - } - - tdiff = TvalDiff(&t1,&t2); - } -#endif -} NTSTATUS reinit_after_fork(struct messaging_context *msg_ctx, struct event_context *ev_ctx, diff --git a/source3/lib/util_nttoken.c b/source3/lib/util_nttoken.c index 3130ed89fb..680dd29ba7 100644 --- a/source3/lib/util_nttoken.c +++ b/source3/lib/util_nttoken.c @@ -26,6 +26,7 @@ /* function(s) moved from auth/auth_util.c to minimize linker deps */ #include "includes.h" +#include "../libcli/security/dom_sid.h" /**************************************************************************** Duplicate a SID token. @@ -120,7 +121,7 @@ bool token_sid_in_ace(const struct security_token *token, const struct security_ size_t i; for (i = 0; i < token->num_sids; i++) { - if (sid_equal(&ace->trustee, &token->sids[i])) + if (dom_sid_equal(&ace->trustee, &token->sids[i])) return true; } diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 92218ff2b2..d75c8e2c97 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -244,7 +244,7 @@ bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid return False; } - if (sid_compare_domain(exp_dom_sid, sid)!=0){ + if (dom_sid_compare_domain(exp_dom_sid, sid)!=0){ *rid=(-1); return False; } @@ -308,84 +308,6 @@ bool sid_parse(const char *inbuf, size_t len, struct dom_sid *sid) } /***************************************************************** - Compare the auth portion of two sids. -*****************************************************************/ - -static int sid_compare_auth(const struct dom_sid *sid1, const struct dom_sid *sid2) -{ - int i; - - if (sid1 == sid2) - return 0; - if (!sid1) - return -1; - if (!sid2) - return 1; - - if (sid1->sid_rev_num != sid2->sid_rev_num) - return sid1->sid_rev_num - sid2->sid_rev_num; - - for (i = 0; i < 6; i++) - if (sid1->id_auth[i] != sid2->id_auth[i]) - return sid1->id_auth[i] - sid2->id_auth[i]; - - return 0; -} - -/***************************************************************** - Compare two sids. -*****************************************************************/ - -int sid_compare(const struct dom_sid *sid1, const struct dom_sid *sid2) -{ - int i; - - if (sid1 == sid2) - return 0; - if (!sid1) - return -1; - if (!sid2) - return 1; - - /* Compare most likely different rids, first: i.e start at end */ - if (sid1->num_auths != sid2->num_auths) - return sid1->num_auths - sid2->num_auths; - - for (i = sid1->num_auths-1; i >= 0; --i) - if (sid1->sub_auths[i] != sid2->sub_auths[i]) - return sid1->sub_auths[i] - sid2->sub_auths[i]; - - return sid_compare_auth(sid1, sid2); -} - -/***************************************************************** - See if 2 SIDs are in the same domain - this just compares the leading sub-auths -*****************************************************************/ - -int sid_compare_domain(const struct dom_sid *sid1, const struct dom_sid *sid2) -{ - int n, i; - - n = MIN(sid1->num_auths, sid2->num_auths); - - for (i = n-1; i >= 0; --i) - if (sid1->sub_auths[i] != sid2->sub_auths[i]) - return sid1->sub_auths[i] - sid2->sub_auths[i]; - - return sid_compare_auth(sid1, sid2); -} - -/***************************************************************** - Compare two sids. -*****************************************************************/ - -bool sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) -{ - return sid_compare(sid1, sid2) == 0; -} - -/***************************************************************** Returns true if SID is internal (and non-mappable). *****************************************************************/ @@ -397,10 +319,10 @@ bool non_mappable_sid(struct dom_sid *sid) sid_copy(&dom, sid); sid_split_rid(&dom, &rid); - if (sid_equal(&dom, &global_sid_Builtin)) + if (dom_sid_equal(&dom, &global_sid_Builtin)) return True; - if (sid_equal(&dom, &global_sid_NT_Authority)) + if (dom_sid_equal(&dom, &global_sid_NT_Authority)) return True; return False; @@ -444,25 +366,6 @@ char *sid_binstring_hex(const struct dom_sid *sid) return s; } -/******************************************************************* - Tallocs a duplicate SID. -********************************************************************/ - -struct dom_sid *sid_dup_talloc(TALLOC_CTX *ctx, const struct dom_sid *src) -{ - struct dom_sid *dst; - - if (src == NULL) { - return NULL; - } - dst = talloc_zero(ctx, struct dom_sid); - if (dst == NULL) { - return NULL; - } - sid_copy(dst, src); - return dst; -} - /******************************************************************** Add SID to an array SIDs ********************************************************************/ @@ -494,7 +397,7 @@ NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, size_t i; for (i=0; i<(*num_sids); i++) { - if (sid_compare(sid, &(*sids)[i]) == 0) + if (dom_sid_compare(sid, &(*sids)[i]) == 0) return NT_STATUS_OK; } @@ -515,7 +418,7 @@ void del_sid_from_array(const struct dom_sid *sid, struct dom_sid **sids, size_t /* if we find the SID, then decrement the count and break out of the loop */ - if ( sid_equal(sid, &sid_list[i]) ) { + if ( dom_sid_equal(sid, &sid_list[i]) ) { *num -= 1; break; } @@ -555,7 +458,7 @@ bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx, bool is_null_sid(const struct dom_sid *sid) { static const struct dom_sid null_sid = {0}; - return sid_equal(sid, &null_sid); + return dom_sid_equal(sid, &null_sid); } bool is_sid_in_token(const struct security_token *token, const struct dom_sid *sid) @@ -563,7 +466,7 @@ bool is_sid_in_token(const struct security_token *token, const struct dom_sid *s int i; for (i=0; i<token->num_sids; i++) { - if (sid_compare(sid, &token->sids[i]) == 0) + if (dom_sid_compare(sid, &token->sids[i]) == 0) return true; } return false; diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 46926f6298..2b33816293 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -21,6 +21,7 @@ #include "includes.h" #include "memcache.h" +#include "../lib/async_req/async_sock.h" /**************************************************************************** Get a port number in host byte order from a sockaddr_storage. diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index 97d89dc88d..3525876ecf 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -27,6 +27,7 @@ #include "libads/cldap.h" #include "libads/dns.h" #include "../libds/common/flags.h" +#include "smbldap.h" #ifdef HAVE_LDAP diff --git a/source3/libgpo/gpo_reg.c b/source3/libgpo/gpo_reg.c index f599435e6c..8c05b2f132 100644 --- a/source3/libgpo/gpo_reg.c +++ b/source3/libgpo/gpo_reg.c @@ -22,6 +22,7 @@ #include "libgpo/gpo_proto.h" #include "registry.h" #include "registry/reg_backend_db.h" +#include "registry/reg_api_util.h" /**************************************************************** diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index 34fe3a72ab..28b2f6c654 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -35,6 +35,7 @@ #include "secrets.h" #include "rpc_client/init_lsa.h" #include "krb5_env.h" +#include "../libcli/security/dom_sid.h" /**************************************************************** ****************************************************************/ @@ -744,7 +745,7 @@ static NTSTATUS libnet_join_lookup_dc_rpc(TALLOC_CTX *mem_ctx, r->out.netbios_domain_name = info->dns.name.string; r->out.dns_domain_name = info->dns.dns_domain.string; r->out.forest_name = info->dns.dns_forest.string; - r->out.domain_sid = sid_dup_talloc(mem_ctx, info->dns.sid); + r->out.domain_sid = dom_sid_dup(mem_ctx, info->dns.sid); NT_STATUS_HAVE_NO_MEMORY(r->out.domain_sid); } @@ -758,7 +759,7 @@ static NTSTATUS libnet_join_lookup_dc_rpc(TALLOC_CTX *mem_ctx, } r->out.netbios_domain_name = info->account_domain.name.string; - r->out.domain_sid = sid_dup_talloc(mem_ctx, info->account_domain.sid); + r->out.domain_sid = dom_sid_dup(mem_ctx, info->account_domain.sid); NT_STATUS_HAVE_NO_MEMORY(r->out.domain_sid); } @@ -2008,7 +2009,7 @@ static WERROR libnet_DomainUnjoin(TALLOC_CTX *mem_ctx, "Unable to fetch domain sid: are we joined?"); return WERR_SETUP_NOT_JOINED; } - r->in.domain_sid = sid_dup_talloc(mem_ctx, &sid); + r->in.domain_sid = dom_sid_dup(mem_ctx, &sid); W_ERROR_HAVE_NO_MEMORY(r->in.domain_sid); } diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c index 6668be28b5..1b5b9c3b2f 100644 --- a/source3/libnet/libnet_samsync.c +++ b/source3/libnet/libnet_samsync.c @@ -28,6 +28,7 @@ #include "../libcli/auth/libcli_auth.h" #include "../librpc/gen_ndr/ndr_netlogon.h" #include "../librpc/gen_ndr/cli_netlogon.h" +#include "../libcli/security/dom_sid.h" /** * Fix up the delta, dealing with encryption issues so that the final @@ -72,7 +73,7 @@ NTSTATUS libnet_samsync_init_context(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(ctx); if (domain_sid) { - ctx->domain_sid = sid_dup_talloc(mem_ctx, domain_sid); + ctx->domain_sid = dom_sid_dup(mem_ctx, domain_sid); NT_STATUS_HAVE_NO_MEMORY(ctx->domain_sid); ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid); diff --git a/source3/libnet/libnet_samsync_ldif.c b/source3/libnet/libnet_samsync_ldif.c index 96bad4da32..454f0a9c41 100644 --- a/source3/libnet/libnet_samsync_ldif.c +++ b/source3/libnet/libnet_samsync_ldif.c @@ -25,6 +25,7 @@ #include "includes.h" #include "libnet/libnet_samsync.h" +#include "smbldap.h" #ifdef HAVE_LDAP diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c index 224598a480..a837ecd6dc 100644 --- a/source3/libnet/libnet_samsync_passdb.c +++ b/source3/libnet/libnet_samsync_passdb.c @@ -25,6 +25,7 @@ #include "includes.h" #include "libnet/libnet_samsync.h" +#include "../libcli/security/dom_sid.h" /* Convert a struct samu_DELTA to a struct samu. */ #define STRING_CHANGED (old_string && !new_string) ||\ @@ -608,7 +609,7 @@ static NTSTATUS fetch_alias_info(TALLOC_CTX *mem_ctx, map.gid = grp->gr_gid; map.sid = alias_sid; - if (sid_equal(dom_sid, &global_sid_Builtin)) + if (dom_sid_equal(dom_sid, &global_sid_Builtin)) map.sid_name_use = SID_NAME_WKN_GRP; else map.sid_name_use = SID_NAME_ALIAS; diff --git a/source3/librpc/idl/libnetapi.idl b/source3/librpc/idl/libnetapi.idl index f83896cf72..935256af16 100644 --- a/source3/librpc/idl/libnetapi.idl +++ b/source3/librpc/idl/libnetapi.idl @@ -1936,7 +1936,7 @@ interface libnetapi [in] string server_name, [in] uint32 function_code, [in] uint32 query_level, - [in] uint8 *data, + [in,unique] uint8 *data, [out,ref] uint8 **buffer ); } diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 8e08d6fc40..0aaeea2827 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -18,6 +18,8 @@ */ #include "includes.h" +#include "../lib/async_req/async_sock.h" +#include "async_smb.h" /* * Read an smb packet asynchronously, discard keepalives diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 169bf4f037..92e5bb2021 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -26,6 +26,7 @@ #include "../libcli/auth/ntlmssp.h" #include "libads/kerberos_proto.h" #include "krb5_env.h" +#include "async_smb.h" static const struct { int prot; @@ -1498,7 +1499,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, struct cli_ulogoff_state { struct cli_state *cli; - uint16_t vwv[2]; + uint16_t vwv[3]; }; static void cli_ulogoff_done(struct tevent_req *subreq); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cdf51c75c3..2c49a8b3f0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,6 +20,7 @@ #include "includes.h" #include "smb_signing.h" +#include "async_smb.h" /******************************************************************* Setup the word count and byte count for a client smb message. diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d6b2e31de7..ce8d7a593b 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -19,6 +19,7 @@ */ #include "includes.h" +#include "async_smb.h" /*********************************************************** Common function for pushing stings, used by smb_bytes_push_str() diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 6cbf7104d4..5ca76ac16a 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -21,6 +21,7 @@ #include "includes.h" #include "../libcli/auth/spnego.h" #include "../libcli/auth/ntlmssp.h" +#include "async_smb.h" /**************************************************************************** Get UNIX extensions version info. diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index b580172317..280f876ba7 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "async_smb.h" /**************************************************************************** Calculate a safe next_entry_offset. diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 3777c41482..4c730c4b76 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "async_smb.h" struct cli_message_start_state { uint16_t grp; diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 8904ac973f..09f9869420 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "async_smb.h" /**************************************************************************** send an ack for an oplock break request diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a1b911cfbf..3ac9f4454f 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -23,6 +23,7 @@ #include "../libcli/auth/libcli_auth.h" #include "../librpc/gen_ndr/rap.h" #include "../lib/crypto/arcfour.h" +#include "async_smb.h" /**************************************************************************** Call a remote api diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 24c9d9f681..370c068fe4 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "async_smb.h" /**************************************************************************** Calculate the recommended read buffer size diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index dd0873d824..4379e1480a 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -18,7 +18,7 @@ */ #include "includes.h" - +#include "async_smb.h" /**************************************************************************** Send a SMB trans or trans2 request. diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index cc87715d8f..bc329bf226 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -27,6 +27,7 @@ #include "libsmb_internal.h" #include "../librpc/gen_ndr/ndr_lsa.h" #include "rpc_client/cli_lsarpc.h" +#include "../libcli/security/dom_sid.h" /* @@ -121,8 +122,8 @@ ace_compare(struct security_ace *ace1, return ace2->type - ace1->type; } - if (sid_compare(&ace1->trustee, &ace2->trustee)) { - return sid_compare(&ace1->trustee, &ace2->trustee); + if (dom_sid_compare(&ace1->trustee, &ace2->trustee)) { + return dom_sid_compare(&ace1->trustee, &ace2->trustee); } if (ace1->flags != ace2->flags) { @@ -1608,7 +1609,7 @@ cacl_set(SMBCCTX *context, bool found = False; for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sid_equal(&sd->dacl->aces[i].trustee, + if (dom_sid_equal(&sd->dacl->aces[i].trustee, &old->dacl->aces[j].trustee)) { if (!(flags & SMBC_XATTR_FLAG_CREATE)) { err = EEXIST; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c949d3bcb4..d1fb5ab817 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -307,7 +307,7 @@ NODE_STATUS_STRUCT *node_status_query(int fd, while (1) { struct timespec tp2; clock_gettime_mono(&tp2); - if (TspecDiff(&tp,&tp2) > retry_time) { + if (nsec_time_diff(&tp2,&tp)/1000000 > retry_time) { if (!retries) break; if (!found && !send_packet(&p)) @@ -716,7 +716,7 @@ struct sockaddr_storage *name_query(int fd, struct timespec tp2; clock_gettime_mono(&tp2); - if (TspecDiff(&tp,&tp2) > retry_time) { + if (nsec_time_diff(&tp2,&tp)/1000000 > retry_time) { if (!retries) break; if (!found && !send_packet(&p)) diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 9dd5df87ec..8e61351a1a 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -417,7 +417,7 @@ static void split_afs_acl(struct afs_acl *acl, static bool same_principal(struct afs_ace *x, struct afs_ace *y) { return ( (x->positive == y->positive) && - (sid_compare(&x->sid, &y->sid) == 0) ); + (dom_sid_compare(&x->sid, &y->sid) == 0) ); } static void merge_afs_acls(struct afs_acl *dir_acl, @@ -699,16 +699,16 @@ static bool mappable_sid(const struct dom_sid *sid) { struct dom_sid domain_sid; - if (sid_compare(sid, &global_sid_Builtin_Administrators) == 0) + if (dom_sid_compare(sid, &global_sid_Builtin_Administrators) == 0) return True; - if (sid_compare(sid, &global_sid_World) == 0) + if (dom_sid_compare(sid, &global_sid_World) == 0) return True; - if (sid_compare(sid, &global_sid_Authenticated_Users) == 0) + if (dom_sid_compare(sid, &global_sid_Authenticated_Users) == 0) return True; - if (sid_compare(sid, &global_sid_Builtin_Backup_Operators) == 0) + if (dom_sid_compare(sid, &global_sid_Builtin_Backup_Operators) == 0) return True; string_to_sid(&domain_sid, "S-1-5-21"); @@ -757,22 +757,22 @@ static bool nt_to_afs_acl(const char *filename, continue; } - if (sid_compare(&ace->trustee, + if (dom_sid_compare(&ace->trustee, &global_sid_Builtin_Administrators) == 0) { name = "system:administrators"; - } else if (sid_compare(&ace->trustee, + } else if (dom_sid_compare(&ace->trustee, &global_sid_World) == 0) { name = "system:anyuser"; - } else if (sid_compare(&ace->trustee, + } else if (dom_sid_compare(&ace->trustee, &global_sid_Authenticated_Users) == 0) { name = "system:authuser"; - } else if (sid_compare(&ace->trustee, + } else if (dom_sid_compare(&ace->trustee, &global_sid_Builtin_Backup_Operators) == 0) { diff --git a/source3/modules/vfs_scannedonly.c b/source3/modules/vfs_scannedonly.c index b76bef41b4..ab5a7f4e6c 100644 --- a/source3/modules/vfs_scannedonly.c +++ b/source3/modules/vfs_scannedonly.c @@ -476,13 +476,12 @@ static bool scannedonly_allow_access(vfs_handle_struct * handle, flush_sendbuffer(handle); while (retval != 0 /*&& errno == ENOENT */ && i < recheck_tries) { - struct timespec req = { 0, recheck_time * 10000 }; DEBUG(SCANNEDONLY_DEBUG, ("scannedonly_allow_access, wait (try=%d " "(max %d), %d ms) for %s\n", i, recheck_tries, recheck_time, cache_smb_fname->base_name)); - nanosleep(&req, NULL); + smb_msleep(recheck_time); retval = SMB_VFS_NEXT_STAT(handle, cache_smb_fname); i++; } diff --git a/source3/nmbd/nmbd.h b/source3/nmbd/nmbd.h index 0e8d12edf8..6ccbd930fb 100644 --- a/source3/nmbd/nmbd.h +++ b/source3/nmbd/nmbd.h @@ -1,2 +1,5 @@ +#ifndef HAVE_PIPE +#define SYNC_DNS 1 +#endif #include "nmbd/nmbd_proto.h" diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 4ae699ac2a..4567f3602d 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -62,6 +62,7 @@ #include "smb_signing.h" #include "dbwrap.h" +#include "smbldap.h" #ifdef HAVE_SYS_SYSCTL_H #include <sys/sysctl.h> diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 0e2385f43f..fa855f3467 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -24,6 +24,7 @@ #include "secrets.h" #include "memcache.h" #include "idmap_cache.h" +#include "../libcli/security/dom_sid.h" /***************************************************************** Dissect a user-provided name into domain, name, sid and type. @@ -655,7 +656,7 @@ static bool lookup_as_domain(const struct dom_sid *sid, TALLOC_CTX *mem_ctx, } for (i=0; i<num_domains; i++) { - if (sid_equal(sid, &domains[i]->sid)) { + if (dom_sid_equal(sid, &domains[i]->sid)) { *name = talloc_strdup(mem_ctx, domains[i]->name); return true; @@ -834,7 +835,7 @@ NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids, if (!dom_infos[j].valid) { break; } - if (sid_equal(&sid, &dom_infos[j].sid)) { + if (dom_sid_equal(&sid, &dom_infos[j].sid)) { break; } } @@ -1581,7 +1582,7 @@ NTSTATUS get_primary_group_sid(TALLOC_CTX *mem_ctx, /* We need a sid within our domain */ sid_copy(&domain_sid, group_sid); sid_split_rid(&domain_sid, &rid); - if (sid_equal(&domain_sid, get_global_sam_sid())) { + if (dom_sid_equal(&domain_sid, get_global_sam_sid())) { /* * As shortcut for the expensive lookup_sid call * compare the domain sid part diff --git a/source3/passdb/machine_sid.c b/source3/passdb/machine_sid.c index c3534f7fa7..6e5a970f4c 100644 --- a/source3/passdb/machine_sid.c +++ b/source3/passdb/machine_sid.c @@ -23,6 +23,7 @@ #include "includes.h" #include "secrets.h" #include "dbwrap.h" +#include "../libcli/security/dom_sid.h" /* NOTE! the global_sam_sid is the SID of our local SAM. This is only equal to the domain SID when we are a DC, otherwise its our @@ -113,7 +114,7 @@ static struct dom_sid *pdb_generate_sam_sid(void) return sam_sid; } - if (!sid_equal(&domain_sid, sam_sid)) { + if (!dom_sid_equal(&domain_sid, sam_sid)) { /* Domain name sid doesn't match global sam sid. Re-store domain sid as 'local' sid. */ @@ -232,7 +233,7 @@ void reset_global_sam_sid(void) bool sid_check_is_domain(const struct dom_sid *sid) { - return sid_equal(sid, get_global_sam_sid()); + return dom_sid_equal(sid, get_global_sam_sid()); } /***************************************************************** diff --git a/source3/passdb/pdb_get_set.c b/source3/passdb/pdb_get_set.c index 3e2510e74c..493e9ed0dd 100644 --- a/source3/passdb/pdb_get_set.c +++ b/source3/passdb/pdb_get_set.c @@ -23,6 +23,7 @@ #include "includes.h" #include "../libcli/auth/libcli_auth.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -509,7 +510,7 @@ bool pdb_set_group_sid(struct samu *sampass, const struct dom_sid *g_sid, enum p sid_compose(&dug_sid, get_global_sam_sid(), DOMAIN_RID_USERS); - if (sid_equal(&dug_sid, g_sid)) { + if (dom_sid_equal(&dug_sid, g_sid)) { sid_copy(sampass->group_sid, &dug_sid); } else if (sid_to_gid( g_sid, &gid ) ) { sid_copy(sampass->group_sid, g_sid); diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 4f93b33a54..9f3a1725a4 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -25,6 +25,7 @@ #include "../librpc/gen_ndr/samr.h" #include "memcache.h" #include "nsswitch/winbind_client.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -890,7 +891,7 @@ static bool pdb_user_in_group(TALLOC_CTX *mem_ctx, struct samu *account, } for (i=0; i<num_groups; i++) { - if (sid_equal(group_sid, &sids[i])) { + if (dom_sid_equal(group_sid, &sids[i])) { return True; } } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index 658d774fef..d046a527a6 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -47,6 +47,7 @@ #include "../libcli/auth/libcli_auth.h" #include "secrets.h" #include "idmap_cache.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -1106,7 +1107,7 @@ static bool init_sam_from_ldap(struct ldapsam_privates *ldap_state, gid_to_sid(&mapped_gsid, sampass->unix_pw->pw_gid); primary_gsid = pdb_get_group_sid(sampass); - if (primary_gsid && sid_equal(primary_gsid, &mapped_gsid)) { + if (primary_gsid && dom_sid_equal(primary_gsid, &mapped_gsid)) { store_gid_sid_cache(primary_gsid, sampass->unix_pw->pw_gid); idmap_cache_set_sid2gid(primary_gsid, @@ -2682,7 +2683,7 @@ static bool ldapsam_extract_rid_from_entry(LDAP *ldap_struct, return False; } - if (sid_compare_domain(&sid, domain_sid) != 0) { + if (dom_sid_compare_domain(&sid, domain_sid) != 0) { DEBUG(10, ("SID %s is not in expected domain %s\n", str, sid_string_dbg(domain_sid))); return False; @@ -3055,7 +3056,7 @@ static NTSTATUS ldapsam_enum_group_memberships(struct pdb_methods *methods, } } - if (sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) { + if (dom_sid_compare(&global_sid_NULL, &(*pp_sids)[0]) == 0) { DEBUG(3, ("primary group of [%s] not found\n", pdb_get_username(user))); goto done; @@ -6668,7 +6669,7 @@ NTSTATUS pdb_init_ldapsam(struct pdb_methods **pdb_method, const char *location) } found_sid = secrets_fetch_domain_sid(ldap_state->domain_name, &secrets_domain_sid); - if (!found_sid || !sid_equal(&secrets_domain_sid, + if (!found_sid || !dom_sid_equal(&secrets_domain_sid, &ldap_domain_sid)) { DEBUG(1, ("pdb_init_ldapsam: Resetting SID for domain " "%s based on pdb_ldap results %s -> %s\n", diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index dd89c8e10b..9369726988 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -22,6 +22,7 @@ #include "includes.h" #include "../librpc/gen_ndr/samr.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_PASSDB @@ -1372,7 +1373,7 @@ static NTSTATUS smbpasswd_getsampwsid(struct pdb_methods *my_methods, struct sam return nt_status; /* build_sam_account might change the SID on us, if the name was for the guest account */ - if (NT_STATUS_IS_OK(nt_status) && !sid_equal(pdb_get_user_sid(sam_acct), sid)) { + if (NT_STATUS_IS_OK(nt_status) && !dom_sid_equal(pdb_get_user_sid(sam_acct), sid)) { DEBUG(1, ("looking for user with sid %s instead returned %s " "for account %s!?!\n", sid_string_dbg(sid), sid_string_dbg(pdb_get_user_sid(sam_acct)), diff --git a/source3/passdb/util_builtin.c b/source3/passdb/util_builtin.c index 05a46371b3..cf483bbb96 100644 --- a/source3/passdb/util_builtin.c +++ b/source3/passdb/util_builtin.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../libcli/security/dom_sid.h" struct rid_name_map { uint32 rid; @@ -104,7 +105,7 @@ const char *builtin_domain_name(void) bool sid_check_is_builtin(const struct dom_sid *sid) { - return sid_equal(sid, &global_sid_Builtin); + return dom_sid_equal(sid, &global_sid_Builtin); } /***************************************************************** diff --git a/source3/passdb/util_unixsids.c b/source3/passdb/util_unixsids.c index 0894804c5b..1bd07c7a2f 100644 --- a/source3/passdb/util_unixsids.c +++ b/source3/passdb/util_unixsids.c @@ -18,10 +18,11 @@ */ #include "includes.h" +#include "../libcli/security/dom_sid.h" bool sid_check_is_unix_users(const struct dom_sid *sid) { - return sid_equal(sid, &global_sid_Unix_Users); + return dom_sid_equal(sid, &global_sid_Unix_Users); } bool sid_check_is_in_unix_users(const struct dom_sid *sid) @@ -79,7 +80,7 @@ bool lookup_unix_user_name(const char *name, struct dom_sid *sid) bool sid_check_is_unix_groups(const struct dom_sid *sid) { - return sid_equal(sid, &global_sid_Unix_Groups); + return dom_sid_equal(sid, &global_sid_Unix_Groups); } bool sid_check_is_in_unix_groups(const struct dom_sid *sid) diff --git a/source3/passdb/util_wellknown.c b/source3/passdb/util_wellknown.c index 7f670f9225..4f6f3f308d 100644 --- a/source3/passdb/util_wellknown.c +++ b/source3/passdb/util_wellknown.c @@ -21,6 +21,7 @@ */ #include "includes.h" +#include "../libcli/security/dom_sid.h" struct rid_name_map { uint32 rid; @@ -75,7 +76,7 @@ bool sid_check_is_wellknown_domain(const struct dom_sid *sid, const char **name) int i; for (i=0; special_domains[i].sid != NULL; i++) { - if (sid_equal(sid, special_domains[i].sid)) { + if (dom_sid_equal(sid, special_domains[i].sid)) { if (name != NULL) { *name = special_domains[i].name; } @@ -115,7 +116,7 @@ bool lookup_wellknown_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, } for (i=0; special_domains[i].sid != NULL; i++) { - if (sid_equal(&dom_sid, special_domains[i].sid)) { + if (dom_sid_equal(&dom_sid, special_domains[i].sid)) { *domain = talloc_strdup(mem_ctx, special_domains[i].name); users = special_domains[i].known_users; diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index 0352446e7b..1cbe4661b1 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -53,19 +53,18 @@ * 0x1a winreg_GetVersion reg_getversion * 0x1b winreg_OpenHKCC * 0x1c winreg_OpenHKDD - * 0x1d winreg_QueryMultipleValues + * 0x1d winreg_QueryMultipleValues reg_querymultiplevalues * 0x1e winreg_InitiateSystemShutdownEx * 0x1f winreg_SaveKeyEx * 0x20 winreg_OpenHKPT * 0x21 winreg_OpenHKPN - * 0x22 winreg_QueryMultipleValues2 + * 0x22 winreg_QueryMultipleValues2 reg_querymultiplevalues * */ #include "includes.h" #include "registry.h" #include "reg_cachehook.h" -#include "regfio.h" #include "reg_util_internal.h" #include "reg_backend_db.h" #include "reg_dispatcher.h" @@ -748,277 +747,6 @@ WERROR reg_getversion(uint32_t *version) return WERR_OK; } -/******************************************************************* - Note: topkeypat is the *full* path that this *key will be - loaded into (including the name of the key) - ********************************************************************/ - -static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, - REGF_NK_REC *key) -{ - REGF_NK_REC *subkey; - struct registry_key_handle registry_key; - struct regval_ctr *values; - struct regsubkey_ctr *subkeys; - int i; - char *path = NULL; - WERROR result = WERR_OK; - - /* initialize the struct registry_key_handle structure */ - - registry_key.ops = reghook_cache_find(topkeypath); - if (!registry_key.ops) { - DEBUG(0, ("reg_load_tree: Failed to assign registry_ops " - "to [%s]\n", topkeypath)); - return WERR_BADFILE; - } - - registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath); - if (!registry_key.name) { - DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n")); - return WERR_NOMEM; - } - - /* now start parsing the values and subkeys */ - - result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); - W_ERROR_NOT_OK_RETURN(result); - - result = regval_ctr_init(subkeys, &values); - W_ERROR_NOT_OK_RETURN(result); - - /* copy values into the struct regval_ctr */ - - for (i=0; i<key->num_values; i++) { - regval_ctr_addvalue(values, key->values[i].valuename, - key->values[i].type, - key->values[i].data, - (key->values[i].data_size & ~VK_DATA_IN_OFFSET)); - } - - /* copy subkeys into the struct regsubkey_ctr */ - - key->subkey_index = 0; - while ((subkey = regfio_fetch_subkey( regfile, key ))) { - result = regsubkey_ctr_addkey(subkeys, subkey->keyname); - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(subkeys); - return result; - } - } - - /* write this key and values out */ - - if (!store_reg_values(®istry_key, values) - || !store_reg_keys(®istry_key, subkeys)) - { - DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); - result = WERR_REG_IO_FAILURE; - } - - TALLOC_FREE(subkeys); - - if (!W_ERROR_IS_OK(result)) { - return result; - } - - /* now continue to load each subkey registry tree */ - - key->subkey_index = 0; - while ((subkey = regfio_fetch_subkey(regfile, key))) { - path = talloc_asprintf(regfile->mem_ctx, - "%s\\%s", - topkeypath, - subkey->keyname); - if (path == NULL) { - return WERR_NOMEM; - } - result = reg_load_tree(regfile, path, subkey); - if (!W_ERROR_IS_OK(result)) { - break; - } - } - - return result; -} - -/******************************************************************* - ********************************************************************/ - -static WERROR restore_registry_key(struct registry_key_handle *krecord, - const char *fname) -{ - REGF_FILE *regfile; - REGF_NK_REC *rootkey; - WERROR result; - - /* open the registry file....fail if the file already exists */ - - regfile = regfio_open(fname, (O_RDONLY), 0); - if (regfile == NULL) { - DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno))); - return ntstatus_to_werror(map_nt_error_from_unix(errno)); - } - - /* get the rootkey from the regf file and then load the tree - via recursive calls */ - - if (!(rootkey = regfio_rootkey(regfile))) { - regfio_close(regfile); - return WERR_REG_FILE_INVALID; - } - - result = reg_load_tree(regfile, krecord->name, rootkey); - - /* cleanup */ - - regfio_close(regfile); - - return result; -} - -WERROR reg_restorekey(struct registry_key *key, const char *fname) -{ - return restore_registry_key(key->key, fname); -} - -/******************************************************************** -********************************************************************/ - -static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, - REGF_NK_REC *parent) -{ - REGF_NK_REC *key; - struct regval_ctr *values; - struct regsubkey_ctr *subkeys; - int i, num_subkeys; - char *key_tmp = NULL; - char *keyname, *parentpath; - char *subkeypath = NULL; - char *subkeyname; - struct registry_key_handle registry_key; - WERROR result = WERR_OK; - struct security_descriptor *sec_desc = NULL; - - if (!regfile) { - return WERR_GENERAL_FAILURE; - } - - if (!keypath) { - return WERR_OBJECT_PATH_INVALID; - } - - /* split up the registry key path */ - - key_tmp = talloc_strdup(regfile->mem_ctx, keypath); - if (!key_tmp) { - return WERR_NOMEM; - } - if (!reg_split_key(key_tmp, &parentpath, &keyname)) { - return WERR_OBJECT_PATH_INVALID; - } - - if (!keyname) { - keyname = parentpath; - } - - /* we need a registry_key_handle object here to enumerate subkeys and values */ - - ZERO_STRUCT(registry_key); - - registry_key.name = talloc_strdup(regfile->mem_ctx, keypath); - if (registry_key.name == NULL) { - return WERR_NOMEM; - } - - registry_key.ops = reghook_cache_find(registry_key.name); - if (registry_key.ops == NULL) { - return WERR_BADFILE; - } - - /* lookup the values and subkeys */ - - result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); - W_ERROR_NOT_OK_RETURN(result); - - result = regval_ctr_init(subkeys, &values); - W_ERROR_NOT_OK_RETURN(result); - - fetch_reg_keys(®istry_key, subkeys); - fetch_reg_values(®istry_key, values); - - result = regkey_get_secdesc(regfile->mem_ctx, ®istry_key, &sec_desc); - if (!W_ERROR_IS_OK(result)) { - goto done; - } - - /* write out this key */ - - key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc, - parent); - if (key == NULL) { - result = WERR_CAN_NOT_COMPLETE; - goto done; - } - - /* write each one of the subkeys out */ - - num_subkeys = regsubkey_ctr_numkeys(subkeys); - for (i=0; i<num_subkeys; i++) { - subkeyname = regsubkey_ctr_specific_key(subkeys, i); - subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s", - keypath, subkeyname); - if (subkeypath == NULL) { - result = WERR_NOMEM; - goto done; - } - result = reg_write_tree(regfile, subkeypath, key); - if (!W_ERROR_IS_OK(result)) - goto done; - } - - DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath)); - -done: - TALLOC_FREE(subkeys); - TALLOC_FREE(registry_key.name); - - return result; -} - -static WERROR backup_registry_key(struct registry_key_handle *krecord, - const char *fname) -{ - REGF_FILE *regfile; - WERROR result; - - /* open the registry file....fail if the file already exists */ - - regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL), - (S_IREAD|S_IWRITE)); - if (regfile == NULL) { - DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", - fname, strerror(errno) )); - return ntstatus_to_werror(map_nt_error_from_unix(errno)); - } - - /* write the registry tree to the file */ - - result = reg_write_tree(regfile, krecord->name, NULL); - - /* cleanup */ - - regfio_close(regfile); - - return result; -} - -WERROR reg_savekey(struct registry_key *key, const char *fname) -{ - return backup_registry_key(key->key, fname); -} - /********************************************************************** * Higher level utility functions **********************************************************************/ @@ -1051,62 +779,6 @@ WERROR reg_deleteallvalues(struct registry_key *key) } /* - * Utility function to open a complete registry path including the hive prefix. - */ - -WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, - uint32 desired_access, const struct security_token *token, - struct registry_key **pkey) -{ - struct registry_key *hive, *key; - char *path, *p; - WERROR err; - - if (!(path = SMB_STRDUP(orig_path))) { - return WERR_NOMEM; - } - - p = strchr(path, '\\'); - - if ((p == NULL) || (p[1] == '\0')) { - /* - * No key behind the hive, just return the hive - */ - - err = reg_openhive(mem_ctx, path, desired_access, token, - &hive); - if (!W_ERROR_IS_OK(err)) { - SAFE_FREE(path); - return err; - } - SAFE_FREE(path); - *pkey = hive; - return WERR_OK; - } - - *p = '\0'; - - err = reg_openhive(mem_ctx, path, KEY_ENUMERATE_SUB_KEYS, token, - &hive); - if (!W_ERROR_IS_OK(err)) { - SAFE_FREE(path); - return err; - } - - err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key); - - TALLOC_FREE(hive); - SAFE_FREE(path); - - if (!W_ERROR_IS_OK(err)) { - return err; - } - - *pkey = key; - return WERR_OK; -} - -/* * Utility function to delete a registry key with all its subkeys. * Note that reg_deletekey returns ACCESS_DENIED when called on a * key that has subkeys. @@ -1212,101 +884,3 @@ WERROR reg_deletesubkeys_recursive(TALLOC_CTX *ctx, return reg_deletekey_recursive_trans(ctx, parent, path, false); } -#if 0 -/* these two functions are unused. */ - -/** - * Utility function to create a registry key without opening the hive - * before. Assumes the hive already exists. - */ - -WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path, - uint32 desired_access, - const struct security_token *token, - enum winreg_CreateAction *paction, - struct registry_key **pkey) -{ - struct registry_key *hive; - char *path, *p; - WERROR err; - - if (!(path = SMB_STRDUP(orig_path))) { - return WERR_NOMEM; - } - - p = strchr(path, '\\'); - - if ((p == NULL) || (p[1] == '\0')) { - /* - * No key behind the hive, just return the hive - */ - - err = reg_openhive(mem_ctx, path, desired_access, token, - &hive); - if (!W_ERROR_IS_OK(err)) { - SAFE_FREE(path); - return err; - } - SAFE_FREE(path); - *pkey = hive; - *paction = REG_OPENED_EXISTING_KEY; - return WERR_OK; - } - - *p = '\0'; - - err = reg_openhive(mem_ctx, path, - (strchr(p+1, '\\') != NULL) ? - KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY, - token, &hive); - if (!W_ERROR_IS_OK(err)) { - SAFE_FREE(path); - return err; - } - - err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction); - SAFE_FREE(path); - TALLOC_FREE(hive); - return err; -} - -/* - * Utility function to create a registry key without opening the hive - * before. Will not delete a hive. - */ - -WERROR reg_delete_path(const struct security_token *token, - const char *orig_path) -{ - struct registry_key *hive; - char *path, *p; - WERROR err; - - if (!(path = SMB_STRDUP(orig_path))) { - return WERR_NOMEM; - } - - p = strchr(path, '\\'); - - if ((p == NULL) || (p[1] == '\0')) { - SAFE_FREE(path); - return WERR_INVALID_PARAM; - } - - *p = '\0'; - - err = reg_openhive(NULL, path, - (strchr(p+1, '\\') != NULL) ? - KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY, - token, &hive); - if (!W_ERROR_IS_OK(err)) { - SAFE_FREE(path); - return err; - } - - err = reg_deletekey(hive, p+1); - SAFE_FREE(path); - TALLOC_FREE(hive); - return err; -} -#endif /* #if 0 */ diff --git a/source3/registry/reg_api_regf.c b/source3/registry/reg_api_regf.c new file mode 100644 index 0000000000..8f249b5aa7 --- /dev/null +++ b/source3/registry/reg_api_regf.c @@ -0,0 +1,301 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Volker Lendecke 2006 + * Copyright (C) Michael Adam 2007-2008 + * + * 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 "registry.h" +#include "reg_cachehook.h" +#include "regfio.h" +#include "reg_util_internal.h" +#include "reg_dispatcher.h" +#include "reg_objects.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_REGISTRY + +/******************************************************************* + Note: topkeypat is the *full* path that this *key will be + loaded into (including the name of the key) + ********************************************************************/ + +static WERROR reg_load_tree(REGF_FILE *regfile, const char *topkeypath, + REGF_NK_REC *key) +{ + REGF_NK_REC *subkey; + struct registry_key_handle registry_key; + struct regval_ctr *values; + struct regsubkey_ctr *subkeys; + int i; + char *path = NULL; + WERROR result = WERR_OK; + + /* initialize the struct registry_key_handle structure */ + + registry_key.ops = reghook_cache_find(topkeypath); + if (!registry_key.ops) { + DEBUG(0, ("reg_load_tree: Failed to assign registry_ops " + "to [%s]\n", topkeypath)); + return WERR_BADFILE; + } + + registry_key.name = talloc_strdup(regfile->mem_ctx, topkeypath); + if (!registry_key.name) { + DEBUG(0, ("reg_load_tree: Talloc failed for reg_key.name!\n")); + return WERR_NOMEM; + } + + /* now start parsing the values and subkeys */ + + result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); + W_ERROR_NOT_OK_RETURN(result); + + result = regval_ctr_init(subkeys, &values); + W_ERROR_NOT_OK_RETURN(result); + + /* copy values into the struct regval_ctr */ + + for (i=0; i<key->num_values; i++) { + regval_ctr_addvalue(values, key->values[i].valuename, + key->values[i].type, + key->values[i].data, + (key->values[i].data_size & ~VK_DATA_IN_OFFSET)); + } + + /* copy subkeys into the struct regsubkey_ctr */ + + key->subkey_index = 0; + while ((subkey = regfio_fetch_subkey( regfile, key ))) { + result = regsubkey_ctr_addkey(subkeys, subkey->keyname); + if (!W_ERROR_IS_OK(result)) { + TALLOC_FREE(subkeys); + return result; + } + } + + /* write this key and values out */ + + if (!store_reg_values(®istry_key, values) + || !store_reg_keys(®istry_key, subkeys)) + { + DEBUG(0,("reg_load_tree: Failed to load %s!\n", topkeypath)); + result = WERR_REG_IO_FAILURE; + } + + TALLOC_FREE(subkeys); + + if (!W_ERROR_IS_OK(result)) { + return result; + } + + /* now continue to load each subkey registry tree */ + + key->subkey_index = 0; + while ((subkey = regfio_fetch_subkey(regfile, key))) { + path = talloc_asprintf(regfile->mem_ctx, + "%s\\%s", + topkeypath, + subkey->keyname); + if (path == NULL) { + return WERR_NOMEM; + } + result = reg_load_tree(regfile, path, subkey); + if (!W_ERROR_IS_OK(result)) { + break; + } + } + + return result; +} + +/******************************************************************* + ********************************************************************/ + +static WERROR restore_registry_key(struct registry_key_handle *krecord, + const char *fname) +{ + REGF_FILE *regfile; + REGF_NK_REC *rootkey; + WERROR result; + + /* open the registry file....fail if the file already exists */ + + regfile = regfio_open(fname, (O_RDONLY), 0); + if (regfile == NULL) { + DEBUG(0, ("restore_registry_key: failed to open \"%s\" (%s)\n", + fname, strerror(errno))); + return ntstatus_to_werror(map_nt_error_from_unix(errno)); + } + + /* get the rootkey from the regf file and then load the tree + via recursive calls */ + + if (!(rootkey = regfio_rootkey(regfile))) { + regfio_close(regfile); + return WERR_REG_FILE_INVALID; + } + + result = reg_load_tree(regfile, krecord->name, rootkey); + + /* cleanup */ + + regfio_close(regfile); + + return result; +} + +WERROR reg_restorekey(struct registry_key *key, const char *fname) +{ + return restore_registry_key(key->key, fname); +} + +/******************************************************************** +********************************************************************/ + +static WERROR reg_write_tree(REGF_FILE *regfile, const char *keypath, + REGF_NK_REC *parent) +{ + REGF_NK_REC *key; + struct regval_ctr *values; + struct regsubkey_ctr *subkeys; + int i, num_subkeys; + char *key_tmp = NULL; + char *keyname, *parentpath; + char *subkeypath = NULL; + char *subkeyname; + struct registry_key_handle registry_key; + WERROR result = WERR_OK; + struct security_descriptor *sec_desc = NULL; + + if (!regfile) { + return WERR_GENERAL_FAILURE; + } + + if (!keypath) { + return WERR_OBJECT_PATH_INVALID; + } + + /* split up the registry key path */ + + key_tmp = talloc_strdup(regfile->mem_ctx, keypath); + if (!key_tmp) { + return WERR_NOMEM; + } + if (!reg_split_key(key_tmp, &parentpath, &keyname)) { + return WERR_OBJECT_PATH_INVALID; + } + + if (!keyname) { + keyname = parentpath; + } + + /* we need a registry_key_handle object here to enumerate subkeys and values */ + + ZERO_STRUCT(registry_key); + + registry_key.name = talloc_strdup(regfile->mem_ctx, keypath); + if (registry_key.name == NULL) { + return WERR_NOMEM; + } + + registry_key.ops = reghook_cache_find(registry_key.name); + if (registry_key.ops == NULL) { + return WERR_BADFILE; + } + + /* lookup the values and subkeys */ + + result = regsubkey_ctr_init(regfile->mem_ctx, &subkeys); + W_ERROR_NOT_OK_RETURN(result); + + result = regval_ctr_init(subkeys, &values); + W_ERROR_NOT_OK_RETURN(result); + + fetch_reg_keys(®istry_key, subkeys); + fetch_reg_values(®istry_key, values); + + result = regkey_get_secdesc(regfile->mem_ctx, ®istry_key, &sec_desc); + if (!W_ERROR_IS_OK(result)) { + goto done; + } + + /* write out this key */ + + key = regfio_write_key(regfile, keyname, values, subkeys, sec_desc, + parent); + if (key == NULL) { + result = WERR_CAN_NOT_COMPLETE; + goto done; + } + + /* write each one of the subkeys out */ + + num_subkeys = regsubkey_ctr_numkeys(subkeys); + for (i=0; i<num_subkeys; i++) { + subkeyname = regsubkey_ctr_specific_key(subkeys, i); + subkeypath = talloc_asprintf(regfile->mem_ctx, "%s\\%s", + keypath, subkeyname); + if (subkeypath == NULL) { + result = WERR_NOMEM; + goto done; + } + result = reg_write_tree(regfile, subkeypath, key); + if (!W_ERROR_IS_OK(result)) + goto done; + } + + DEBUG(6, ("reg_write_tree: wrote key [%s]\n", keypath)); + +done: + TALLOC_FREE(subkeys); + TALLOC_FREE(registry_key.name); + + return result; +} + +static WERROR backup_registry_key(struct registry_key_handle *krecord, + const char *fname) +{ + REGF_FILE *regfile; + WERROR result; + + /* open the registry file....fail if the file already exists */ + + regfile = regfio_open(fname, (O_RDWR|O_CREAT|O_EXCL), + (S_IREAD|S_IWRITE)); + if (regfile == NULL) { + DEBUG(0,("backup_registry_key: failed to open \"%s\" (%s)\n", + fname, strerror(errno) )); + return ntstatus_to_werror(map_nt_error_from_unix(errno)); + } + + /* write the registry tree to the file */ + + result = reg_write_tree(regfile, krecord->name, NULL); + + /* cleanup */ + + regfio_close(regfile); + + return result; +} + +WERROR reg_savekey(struct registry_key *key, const char *fname) +{ + return backup_registry_key(key->key, fname); +} diff --git a/source3/registry/reg_api_util.c b/source3/registry/reg_api_util.c new file mode 100644 index 0000000000..592b370d3b --- /dev/null +++ b/source3/registry/reg_api_util.c @@ -0,0 +1,181 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Volker Lendecke 2006 + * Copyright (C) Michael Adam 2007-2010 + * + * 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/>. + */ + +/* + * Higher level utility functions on top of reg_api.c + */ + +#include "includes.h" +#include "registry.h" +#include "reg_api_util.h" + +/** + * Utility function to open a complete registry path including the hive prefix. + */ +WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, + uint32 desired_access, const struct security_token *token, + struct registry_key **pkey) +{ + struct registry_key *hive, *key; + char *path, *p; + WERROR err; + + if (!(path = SMB_STRDUP(orig_path))) { + return WERR_NOMEM; + } + + p = strchr(path, '\\'); + + if ((p == NULL) || (p[1] == '\0')) { + /* + * No key behind the hive, just return the hive + */ + + err = reg_openhive(mem_ctx, path, desired_access, token, + &hive); + if (!W_ERROR_IS_OK(err)) { + SAFE_FREE(path); + return err; + } + SAFE_FREE(path); + *pkey = hive; + return WERR_OK; + } + + *p = '\0'; + + err = reg_openhive(mem_ctx, path, KEY_ENUMERATE_SUB_KEYS, token, + &hive); + if (!W_ERROR_IS_OK(err)) { + SAFE_FREE(path); + return err; + } + + err = reg_openkey(mem_ctx, hive, p+1, desired_access, &key); + + TALLOC_FREE(hive); + SAFE_FREE(path); + + if (!W_ERROR_IS_OK(err)) { + return err; + } + + *pkey = key; + return WERR_OK; +} + +#if 0 +/* these two functions are unused. */ + +/** + * Utility function to create a registry key without opening the hive + * before. Assumes the hive already exists. + */ + +WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path, + uint32 desired_access, + const struct security_token *token, + enum winreg_CreateAction *paction, + struct registry_key **pkey) +{ + struct registry_key *hive; + char *path, *p; + WERROR err; + + if (!(path = SMB_STRDUP(orig_path))) { + return WERR_NOMEM; + } + + p = strchr(path, '\\'); + + if ((p == NULL) || (p[1] == '\0')) { + /* + * No key behind the hive, just return the hive + */ + + err = reg_openhive(mem_ctx, path, desired_access, token, + &hive); + if (!W_ERROR_IS_OK(err)) { + SAFE_FREE(path); + return err; + } + SAFE_FREE(path); + *pkey = hive; + *paction = REG_OPENED_EXISTING_KEY; + return WERR_OK; + } + + *p = '\0'; + + err = reg_openhive(mem_ctx, path, + (strchr(p+1, '\\') != NULL) ? + KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY, + token, &hive); + if (!W_ERROR_IS_OK(err)) { + SAFE_FREE(path); + return err; + } + + err = reg_createkey(mem_ctx, hive, p+1, desired_access, pkey, paction); + SAFE_FREE(path); + TALLOC_FREE(hive); + return err; +} + +/* + * Utility function to create a registry key without opening the hive + * before. Will not delete a hive. + */ + +WERROR reg_delete_path(const struct security_token *token, + const char *orig_path) +{ + struct registry_key *hive; + char *path, *p; + WERROR err; + + if (!(path = SMB_STRDUP(orig_path))) { + return WERR_NOMEM; + } + + p = strchr(path, '\\'); + + if ((p == NULL) || (p[1] == '\0')) { + SAFE_FREE(path); + return WERR_INVALID_PARAM; + } + + *p = '\0'; + + err = reg_openhive(NULL, path, + (strchr(p+1, '\\') != NULL) ? + KEY_ENUMERATE_SUB_KEYS : KEY_CREATE_SUB_KEY, + token, &hive); + if (!W_ERROR_IS_OK(err)) { + SAFE_FREE(path); + return err; + } + + err = reg_deletekey(hive, p+1); + SAFE_FREE(path); + TALLOC_FREE(hive); + return err; +} +#endif /* #if 0 */ diff --git a/source3/registry/reg_api_util.h b/source3/registry/reg_api_util.h new file mode 100644 index 0000000000..d2d7894d78 --- /dev/null +++ b/source3/registry/reg_api_util.h @@ -0,0 +1,46 @@ +/* + * Unix SMB/CIFS implementation. + * Virtual Windows Registry Layer + * Copyright (C) Volker Lendecke 2006 + * Copyright (C) Michael Adam 2007-2010 + * + * 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/>. + */ + +/* + * Higher level utility functions on top of reg_api.c + */ + +#ifndef _REG_API_UTIL_H +#define _REG_API_UTIL_H + +/** + * Utility function to open a complete registry path including the hive prefix. + */ +WERROR reg_open_path(TALLOC_CTX *mem_ctx, const char *orig_path, + uint32 desired_access, const struct security_token *token, + struct registry_key **pkey); + +#if 0 +/* currently unused */ +WERROR reg_create_path(TALLOC_CTX *mem_ctx, const char *orig_path, + uint32 desired_access, + const struct security_token *token, + enum winreg_CreateAction *paction, + struct registry_key **pkey); +WERROR reg_delete_path(const struct security_token *token, + const char *orig_path); +#endif + +#endif /* _REG_API_UTIL_H */ diff --git a/source3/registry/reg_util_legacy.c b/source3/registry/reg_util_legacy.c index 3a3f0207e2..29b0889402 100644 --- a/source3/registry/reg_util_legacy.c +++ b/source3/registry/reg_util_legacy.c @@ -22,6 +22,7 @@ #include "includes.h" #include "registry.h" #include "reg_util_legacy.h" +#include "reg_api_util.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_REGISTRY diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c index 823bdfac6a..52fd6037e0 100644 --- a/source3/rpc_client/cli_lsarpc.c +++ b/source3/rpc_client/cli_lsarpc.c @@ -26,6 +26,7 @@ #include "../librpc/gen_ndr/cli_lsa.h" #include "rpc_client/cli_lsarpc.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" /** @defgroup lsa LSA - Local Security Architecture * @ingroup rpc_client @@ -145,7 +146,7 @@ static NTSTATUS rpccli_lsa_lookup_sids_noalloc(struct rpc_pipe_client *cli, } for (i = 0; i<num_sids; i++) { - sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]); + sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]); if (!sid_array.sids[i].sid) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1975d73e70..d8bed84e2d 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -704,6 +704,7 @@ struct rpc_api_pipe_state { static void rpc_api_pipe_trans_done(struct tevent_req *subreq); static void rpc_api_pipe_got_pdu(struct tevent_req *subreq); +static void rpc_api_pipe_auth3_done(struct tevent_req *subreq); static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, struct event_context *ev, @@ -738,6 +739,16 @@ static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, DEBUG(5,("rpc_api_pipe: %s\n", rpccli_pipe_txt(talloc_tos(), cli))); + if (state->expected_pkt_type == DCERPC_PKT_AUTH3) { + subreq = rpc_write_send(state, ev, cli->transport, + data->data, data->length); + if (subreq == NULL) { + goto fail; + } + tevent_req_set_callback(subreq, rpc_api_pipe_auth3_done, req); + return req; + } + /* get the header first, then fetch the rest once we have * the frag_length available */ max_recv_frag = RPC_HEADER_LEN; @@ -758,6 +769,23 @@ static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, return NULL; } +static void rpc_api_pipe_auth3_done(struct tevent_req *subreq) +{ + struct tevent_req *req = + tevent_req_callback_data(subreq, + struct tevent_req); + NTSTATUS status; + + status = rpc_write_recv(subreq); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + + tevent_req_done(req); +} + static void rpc_api_pipe_trans_done(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data( @@ -1446,53 +1474,6 @@ NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -#if 0 -/**************************************************************************** - Set the handle state. -****************************************************************************/ - -static bool rpc_pipe_set_hnd_state(struct rpc_pipe_client *cli, - const char *pipe_name, uint16 device_state) -{ - bool state_set = False; - char param[2]; - uint16 setup[2]; /* only need 2 uint16 setup parameters */ - char *rparam = NULL; - char *rdata = NULL; - uint32 rparam_len, rdata_len; - - if (pipe_name == NULL) - return False; - - DEBUG(5,("Set Handle state Pipe[%x]: %s - device state:%x\n", - cli->fnum, pipe_name, device_state)); - - /* create parameters: device state */ - SSVAL(param, 0, device_state); - - /* create setup parameters. */ - setup[0] = 0x0001; - setup[1] = cli->fnum; /* pipe file handle. got this from an SMBOpenX. */ - - /* send the data on \PIPE\ */ - if (cli_api_pipe(cli->cli, "\\PIPE\\", - setup, 2, 0, /* setup, length, max */ - param, 2, 0, /* param, length, max */ - NULL, 0, 1024, /* data, length, max */ - &rparam, &rparam_len, /* return param, length */ - &rdata, &rdata_len)) /* return data, length */ - { - DEBUG(5, ("Set Handle state: return OK\n")); - state_set = True; - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return state_set; -} -#endif - /**************************************************************************** Check the rpc bind acknowledge response. ****************************************************************************/ @@ -1623,11 +1604,11 @@ struct rpc_pipe_bind_state { struct event_context *ev; struct rpc_pipe_client *cli; DATA_BLOB rpc_out; + bool auth3; uint32_t rpc_call_id; }; static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq); -static void rpc_bind_auth3_write_done(struct tevent_req *subreq); static NTSTATUS rpc_bind_next_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, DATA_BLOB *credentials); @@ -1658,7 +1639,6 @@ struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, state->ev = ev; state->cli = cli; state->rpc_call_id = get_rpc_call_id(); - state->rpc_out = data_blob_null; cli->auth = talloc_move(cli, &auth); @@ -1697,13 +1677,12 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) struct rpc_pipe_bind_state *state = tevent_req_data( req, struct rpc_pipe_bind_state); struct pipe_auth_data *pauth = state->cli->auth; - DATA_BLOB reply_pdu; struct ncacn_packet *pkt; struct dcerpc_auth auth; DATA_BLOB auth_token = data_blob_null; NTSTATUS status; - status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, &reply_pdu); + status = rpc_api_pipe_recv(subreq, talloc_tos(), &pkt, NULL); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n", @@ -1713,6 +1692,11 @@ static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) return; } + if (state->auth3) { + tevent_req_done(req); + return; + } + if (!check_bind_response(&pkt->u.bind_ack, &state->cli->transfer_syntax)) { DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n")); tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); @@ -1835,21 +1819,6 @@ err_out: tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); } -static void rpc_bind_auth3_write_done(struct tevent_req *subreq) -{ - struct tevent_req *req = tevent_req_callback_data( - subreq, struct tevent_req); - NTSTATUS status; - - status = rpc_write_recv(subreq); - TALLOC_FREE(subreq); - if (!NT_STATUS_IS_OK(status)) { - tevent_req_nterror(req, status); - return; - } - tevent_req_done(req); -} - static NTSTATUS rpc_bind_next_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, DATA_BLOB *auth_token) @@ -1890,6 +1859,8 @@ static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, struct tevent_req *subreq; NTSTATUS status; + state->auth3 = true; + /* Now prepare the auth3 context pdu. */ data_blob_free(&state->rpc_out); @@ -1903,12 +1874,12 @@ static NTSTATUS rpc_bind_finish_send(struct tevent_req *req, return status; } - subreq = rpc_write_send(state, state->ev, state->cli->transport, - state->rpc_out.data, state->rpc_out.length); + subreq = rpc_api_pipe_send(state, state->ev, state->cli, + &state->rpc_out, DCERPC_PKT_AUTH3); if (subreq == NULL) { return NT_STATUS_NO_MEMORY; } - tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req); + tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req); return NT_STATUS_OK; } diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index b7bb7d70d5..359ec478cc 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -18,6 +18,7 @@ */ #include "includes.h" +#include "../lib/async_req/async_sock.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_CLI diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index 96787a374f..de3439eb93 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -24,6 +24,7 @@ #include "../librpc/gen_ndr/srv_eventlog.h" #include "lib/eventlog/eventlog.h" #include "registry.h" +#include "registry/reg_api_util.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index 49bdca7b7f..191cdfeb66 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -34,6 +34,7 @@ #include "secrets.h" #include "../librpc/gen_ndr/netlogon.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -91,7 +92,7 @@ static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx, if (dom_name != NULL) { for (num = 0; num < ref->count; num++) { - if (sid_equal(dom_sid, ref->domains[num].sid)) { + if (dom_sid_equal(dom_sid, ref->domains[num].sid)) { return num; } } @@ -116,7 +117,7 @@ static int init_lsa_ref_domain_list(TALLOC_CTX *mem_ctx, ZERO_STRUCT(ref->domains[num]); init_lsa_StringLarge(&ref->domains[num].name, dom_name); - ref->domains[num].sid = sid_dup_talloc(mem_ctx, dom_sid); + ref->domains[num].sid = dom_sid_dup(mem_ctx, dom_sid); if (!ref->domains[num].sid) { return -1; } @@ -306,7 +307,7 @@ static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx, /* Initialize the lsa_TranslatedSid3 return. */ trans_sids[i].sid_type = type; - trans_sids[i].sid = sid_dup_talloc(mem_ctx, &sid); + trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid); trans_sids[i].sid_index = dom_idx; } @@ -653,7 +654,7 @@ NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p, case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: name = get_global_sam_name(); - sid = sid_dup_talloc(p->mem_ctx, get_global_sam_sid()); + sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid()); if (!sid) { return NT_STATUS_NO_MEMORY; } @@ -662,7 +663,7 @@ NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p, name = lp_workgroup(); /* We need to return the Domain SID here. */ if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { - sid = sid_dup_talloc(p->mem_ctx, &domain_sid); + sid = dom_sid_dup(p->mem_ctx, &domain_sid); if (!sid) { return NT_STATUS_NO_MEMORY; } @@ -1605,7 +1606,7 @@ NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p, } for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) { - sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]); + sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]); if (!sids[j].sid) { talloc_free(sid_list); return NT_STATUS_NO_MEMORY; @@ -2427,7 +2428,7 @@ NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p, r->out.sids->num_sids); for (i=0; i < r->out.sids->num_sids; i++) { - r->out.sids->sids[i].sid = sid_dup_talloc(r->out.sids->sids, + r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids, &sids[i]); if (!r->out.sids->sids[i].sid) { TALLOC_FREE(r->out.sids->sids); diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 4b692b36fc..76da1d00d6 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -36,6 +36,7 @@ #include "../lib/crypto/md4.h" #include "rpc_client/init_lsa.h" #include "rpc_server/rpc_ncacn_np.h" +#include "../libcli/security/dom_sid.h" extern userdom_struct current_user_info; @@ -909,7 +910,7 @@ NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p, goto out; } - creds->sid = sid_dup_talloc(creds, &sid); + creds->sid = dom_sid_dup(creds, &sid); if (!creds->sid) { status = NT_STATUS_NO_MEMORY; goto out; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index bc71146f38..994fc7934b 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -39,6 +39,7 @@ #include "../lib/crypto/arcfour.h" #include "secrets.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -712,7 +713,7 @@ NTSTATUS _samr_SetSecurity(struct pipes_struct *p, dacl = r->in.sdbuf->sd->dacl; for (i=0; i < dacl->num_aces; i++) { - if (sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) { + if (dom_sid_equal(&uinfo->sid, &dacl->aces[i].trustee)) { ret = pdb_set_pass_can_change(sampass, (dacl->aces[i].access_mask & SAMR_USER_ACCESS_CHANGE_PASSWORD) ? @@ -5472,7 +5473,7 @@ NTSTATUS _samr_GetMembersInAlias(struct pipes_struct *p, } for (i = 0; i < num_sids; i++) { - sids[i].sid = sid_dup_talloc(p->mem_ctx, &pdb_sids[i]); + sids[i].sid = dom_sid_dup(p->mem_ctx, &pdb_sids[i]); if (!sids[i].sid) { TALLOC_FREE(pdb_sids); return NT_STATUS_NO_MEMORY; @@ -6735,7 +6736,7 @@ NTSTATUS _samr_RidToSid(struct pipes_struct *p, return NT_STATUS_NO_MEMORY; } - *r->out.sid = sid_dup_talloc(p->mem_ctx, &sid); + *r->out.sid = dom_sid_dup(p->mem_ctx, &sid); if (!*r->out.sid) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/rpc_server/srv_spoolss_util.c b/source3/rpc_server/srv_spoolss_util.c index 2ebce91c52..cd5ffe245f 100644 --- a/source3/rpc_server/srv_spoolss_util.c +++ b/source3/rpc_server/srv_spoolss_util.c @@ -28,6 +28,7 @@ #include "../librpc/gen_ndr/ndr_security.h" #include "secrets.h" #include "rpc_server/rpc_ncacn_np.h" +#include "../libcli/security/dom_sid.h" #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print" #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers" @@ -2387,7 +2388,7 @@ create_default: /* If security descriptor is owned by S-1-1-0 and winbindd is up, this security descriptor has been created when winbindd was down. Take ownership of security descriptor. */ - if (sid_equal(secdesc->owner_sid, &global_sid_World)) { + if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) { struct dom_sid owner_sid; /* Change sd owner to workgroup administrator */ diff --git a/source3/rpcclient/cmd_samr.c b/source3/rpcclient/cmd_samr.c index cba555ac3a..17314d23e9 100644 --- a/source3/rpcclient/cmd_samr.c +++ b/source3/rpcclient/cmd_samr.c @@ -30,6 +30,7 @@ #include "rpc_client/cli_samr.h" #include "rpc_client/init_samr.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" extern struct dom_sid domain_sid; @@ -668,7 +669,7 @@ static NTSTATUS cmd_samr_query_useraliases(struct rpc_pipe_client *cli, } for (i=0; i<num_sids; i++) { - sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[i]); + sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[i]); if (!sid_array.sids[i].sid) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/rpcclient/cmd_winreg.c b/source3/rpcclient/cmd_winreg.c new file mode 100644 index 0000000000..6fcb528467 --- /dev/null +++ b/source3/rpcclient/cmd_winreg.c @@ -0,0 +1,321 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Guenther Deschner 2009 + + 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 "rpcclient.h" +#include "../librpc/gen_ndr/cli_winreg.h" +#include "../librpc/gen_ndr/ndr_misc.h" + +static WERROR cmd_winreg_enumkeys(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status; + WERROR werr; + struct policy_handle handle; + uint32_t enum_index = 0; + struct winreg_StringBuf name; + + if (argc < 2) { + printf("usage: %s [name]\n", argv[0]); + return WERR_OK; + } + + status = rpccli_winreg_OpenHKLM(cli, mem_ctx, + NULL, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + ZERO_STRUCT(name); + + name.name = argv[1]; + name.length = strlen_m_term_null(name.name)*2; + name.size = name.length; + + status = rpccli_winreg_EnumKey(cli, mem_ctx, + &handle, + enum_index, + &name, + NULL, + NULL, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + return WERR_OK; +} + +/**************************************************************************** +****************************************************************************/ + +static WERROR pull_winreg_Data(TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, + union winreg_Data *data, + enum winreg_Type type) +{ + enum ndr_err_code ndr_err; + ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type, + (ndr_pull_flags_fn_t)ndr_pull_winreg_Data); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_GENERAL_FAILURE; + } + return WERR_OK; +} + +/**************************************************************************** +****************************************************************************/ + +static void display_winreg_data(const char *v, + enum winreg_Type type, + uint8_t *data, + uint32_t length) +{ + int i; + union winreg_Data r; + DATA_BLOB blob = data_blob_const(data, length); + WERROR result; + + result = pull_winreg_Data(talloc_tos(), &blob, &r, type); + if (!W_ERROR_IS_OK(result)) { + return; + } + + switch (type) { + case REG_DWORD: + printf("%s: REG_DWORD: 0x%08x\n", v, r.value); + break; + case REG_SZ: + printf("%s: REG_SZ: %s\n", v, r.string); + break; + case REG_BINARY: { + char *hex = hex_encode_talloc(NULL, + r.binary.data, r.binary.length); + size_t len; + printf("%s: REG_BINARY:", v); + len = strlen(hex); + for (i=0; i<len; i++) { + if (hex[i] == '\0') { + break; + } + if (i%40 == 0) { + putchar('\n'); + } + putchar(hex[i]); + } + TALLOC_FREE(hex); + putchar('\n'); + break; + } + case REG_MULTI_SZ: + printf("%s: REG_MULTI_SZ: ", v); + for (i=0; r.string_array[i] != NULL; i++) { + printf("%s ", r.string_array[i]); + } + printf("\n"); + break; + default: + printf("%s: unknown type 0x%02x:\n", v, type); + break; + } +} + + +static WERROR cmd_winreg_querymultiplevalues_ex(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv, bool multiplevalues2) +{ + NTSTATUS status; + WERROR werr; + struct policy_handle handle, key_handle; + struct winreg_String key_name; + + struct QueryMultipleValue *values_in, *values_out; + uint32_t num_values; + uint8_t *buffer = NULL; + int i; + + + if (argc < 2) { + printf("usage: %s [key] [value1] [value2] ...\n", argv[0]); + return WERR_OK; + } + + status = rpccli_winreg_OpenHKLM(cli, mem_ctx, + NULL, + SEC_FLAG_MAXIMUM_ALLOWED, + &handle, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + key_name.name = argv[1]; + + status = rpccli_winreg_OpenKey(cli, mem_ctx, + &handle, + key_name, + 0, /* options */ + SEC_FLAG_MAXIMUM_ALLOWED, + &key_handle, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + + num_values = argc-2; + + values_in = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values); + if (values_in == NULL) { + return WERR_NOMEM; + } + + values_out = talloc_zero_array(mem_ctx, struct QueryMultipleValue, num_values); + if (values_out == NULL) { + return WERR_NOMEM; + } + + for (i=0; i < num_values; i++) { + + values_in[i].ve_valuename = talloc_zero(values_in, struct winreg_ValNameBuf); + if (values_in[i].ve_valuename == NULL) { + return WERR_NOMEM; + } + + values_in[i].ve_valuename->name = talloc_strdup(values_in[i].ve_valuename, argv[i+2]); + values_in[i].ve_valuename->length = strlen_m_term_null(values_in[i].ve_valuename->name)*2; + values_in[i].ve_valuename->size = values_in[i].ve_valuename->length; + } + + if (multiplevalues2) { + + uint32_t offered = 0, needed = 0; + + status = rpccli_winreg_QueryMultipleValues2(cli, mem_ctx, + &key_handle, + values_in, + values_out, + num_values, + buffer, + &offered, + &needed, + &werr); + if (W_ERROR_EQUAL(werr, WERR_MORE_DATA)) { + offered = needed; + + buffer = talloc_zero_array(mem_ctx, uint8_t, needed); + if (buffer == NULL) { + return WERR_NOMEM; + } + + status = rpccli_winreg_QueryMultipleValues2(cli, mem_ctx, + &key_handle, + values_in, + values_out, + num_values, + buffer, + &offered, + &needed, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + } + + } else { + + uint32_t buffer_size = 0xff; + + buffer = talloc_zero_array(mem_ctx, uint8_t, buffer_size); + if (buffer == NULL) { + return WERR_NOMEM; + } + + status = rpccli_winreg_QueryMultipleValues(cli, mem_ctx, + &key_handle, + values_in, + values_out, + num_values, + buffer, + &buffer_size, + &werr); + if (!NT_STATUS_IS_OK(status)) { + return ntstatus_to_werror(status); + } + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + } + + for (i=0; i < num_values; i++) { + if (buffer) { + display_winreg_data(values_in[i].ve_valuename->name, + values_out[i].ve_type, + buffer + values_out[i].ve_valueptr, + values_out[i].ve_valuelen); + } + } + + return WERR_OK; +} + +static WERROR cmd_winreg_querymultiplevalues(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, false); +} + +static WERROR cmd_winreg_querymultiplevalues2(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + return cmd_winreg_querymultiplevalues_ex(cli, mem_ctx, argc, argv, true); +} + +/* List of commands exported by this module */ + +struct cmd_set winreg_commands[] = { + + { "WINREG" }, + { "enumkey", RPC_RTYPE_WERROR, NULL, cmd_winreg_enumkeys, &ndr_table_winreg.syntax_id, NULL, "Enumerate Keys", "" }, + { "querymultiplevalues", RPC_RTYPE_WERROR, NULL, cmd_winreg_querymultiplevalues, &ndr_table_winreg.syntax_id, NULL, "Query multiple values", "" }, + { "querymultiplevalues2", RPC_RTYPE_WERROR, NULL, cmd_winreg_querymultiplevalues2, &ndr_table_winreg.syntax_id, NULL, "Query multiple values", "" }, + { NULL } +}; diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index 9529212dd7..5fa8132db8 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -9,12 +9,12 @@ 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/>. */ @@ -54,7 +54,7 @@ handle completion of commands for readline ****************************************************************************/ static char **completion_fn(const char *text, int start, int end) { -#define MAX_COMPLETIONS 100 +#define MAX_COMPLETIONS 1000 char **matches; int i, count=0; struct cmd_list *commands = cmd_list; @@ -87,7 +87,7 @@ static char **completion_fn(const char *text, int start, int end) if (!commands->cmd_set) { break; } - + for (i=0; commands->cmd_set[i].name; i++) { if ((strncmp(text, commands->cmd_set[i].name, strlen(text)) == 0) && (( commands->cmd_set[i].returntype == RPC_RTYPE_NTSTATUS && @@ -106,7 +106,6 @@ static char **completion_fn(const char *text, int start, int end) } } commands = commands->next; - } if (count == 2) { @@ -121,10 +120,10 @@ static char *next_command (char **cmdstr) { char *command; char *p; - + if (!cmdstr || !(*cmdstr)) return NULL; - + p = strchr_m(*cmdstr, ';'); if (p) *p = '\0'; @@ -133,7 +132,7 @@ static char *next_command (char **cmdstr) *cmdstr = p + 1; else *cmdstr = NULL; - + return command; } @@ -161,7 +160,7 @@ static void fetch_machine_sid(struct cli_state *cli) fprintf(stderr, "could not initialise lsa pipe. Error was %s\n", nt_errstr(result) ); goto error; } - + result = rpccli_lsa_open_policy(lsapipe, mem_ctx, True, SEC_FLAG_MAXIMUM_ALLOWED, &pol); @@ -222,7 +221,7 @@ static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct for (tmp = cmd_list; tmp; tmp = tmp->next) { tmp_set = tmp->cmd_set; - + if (!StrCaseCmp(argv[1], tmp_set->name)) { printf("Available commands on the %s pipe:\n\n", tmp_set->name); @@ -236,7 +235,7 @@ static NTSTATUS cmd_listcommands(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ct if (i%3 == 0) printf("\n"); } - + /* drop out of the loop */ break; } @@ -265,7 +264,7 @@ static NTSTATUS cmd_help(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, if (argc == 2) { for (tmp = cmd_list; tmp; tmp = tmp->next) { - + tmp_set = tmp->cmd_set; while(tmp_set->name) { @@ -475,7 +474,7 @@ static NTSTATUS cmd_timeout(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, timeout = atoi(argv[1]); for (tmp = cmd_list; tmp; tmp = tmp->next) { - + struct cmd_set *tmp_set; for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) { @@ -600,6 +599,7 @@ extern struct cmd_set wkssvc_commands[]; extern struct cmd_set ntsvcs_commands[]; extern struct cmd_set drsuapi_commands[]; extern struct cmd_set eventlog_commands[]; +extern struct cmd_set winreg_commands[]; static struct cmd_set *rpcclient_command_list[] = { rpcclient_commands, @@ -618,6 +618,7 @@ static struct cmd_set *rpcclient_command_list[] = { ntsvcs_commands, drsuapi_commands, eventlog_commands, + winreg_commands, NULL }; @@ -650,7 +651,7 @@ static NTSTATUS do_cmd(struct cli_state *cli, { NTSTATUS ntresult; WERROR wresult; - + TALLOC_CTX *mem_ctx; /* Create mem_ctx */ diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 9470447f53..dc3585d81b 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "../libcli/security/dom_sid.h" extern const struct generic_mapping file_generic_mapping; @@ -944,10 +945,10 @@ static void merge_aces( canon_ace **pp_list_head, bool dir_acl) * ensure the POSIX ACL types are the same. */ if (!dir_acl) { - can_merge = (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) && + can_merge = (dom_sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) && (curr_ace->attr == curr_ace_outer->attr)); } else { - can_merge = (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) && + can_merge = (dom_sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) && (curr_ace->type == curr_ace_outer->type) && (curr_ace->attr == curr_ace_outer->attr)); } @@ -996,7 +997,7 @@ static void merge_aces( canon_ace **pp_list_head, bool dir_acl) * we've put on the ACL, we know the deny must be the first one. */ - if (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) && + if (dom_sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) && (curr_ace_outer->attr == DENY_ACE) && (curr_ace->attr == ALLOW_ACE)) { if( DEBUGLVL( 10 )) { @@ -1297,7 +1298,7 @@ static bool uid_entry_in_group(connection_struct *conn, canon_ace *uid_ace, cano /* "Everyone" always matches every uid. */ - if (sid_equal(&group_ace->trustee, &global_sid_World)) + if (dom_sid_equal(&group_ace->trustee, &global_sid_World)) return True; /* @@ -1513,12 +1514,12 @@ static void check_owning_objs(canon_ace *ace, struct dom_sid *pfile_owner_sid, s for (i=0, current_ace = ace; i < entries; i++, current_ace = current_ace->next) { if (!got_user_obj && current_ace->owner_type == UID_ACE && - sid_equal(¤t_ace->trustee, pfile_owner_sid)) { + dom_sid_equal(¤t_ace->trustee, pfile_owner_sid)) { current_ace->type = SMB_ACL_USER_OBJ; got_user_obj = True; } if (!got_group_obj && current_ace->owner_type == GID_ACE && - sid_equal(¤t_ace->trustee, pfile_grp_sid)) { + dom_sid_equal(¤t_ace->trustee, pfile_grp_sid)) { current_ace->type = SMB_ACL_GROUP_OBJ; got_group_obj = True; } @@ -1549,7 +1550,7 @@ static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace) */ if (ace->type == SMB_ACL_USER_OBJ && - !(sid_equal(&ace->trustee, &global_sid_Creator_Owner))) { + !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Owner))) { canon_ace *dup_ace = dup_canon_ace(ace); if (dup_ace == NULL) { @@ -1560,7 +1561,7 @@ static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace) } if (ace->type == SMB_ACL_GROUP_OBJ && - !(sid_equal(&ace->trustee, &global_sid_Creator_Group))) { + !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Group))) { canon_ace *dup_ace = dup_canon_ace(ace); if (dup_ace == NULL) { @@ -1646,7 +1647,7 @@ static bool create_canon_ace_lists(files_struct *fsp, if (psa1->access_mask != psa2->access_mask) continue; - if (!sid_equal(&psa1->trustee, &psa2->trustee)) + if (!dom_sid_equal(&psa1->trustee, &psa2->trustee)) continue; /* @@ -1692,11 +1693,11 @@ static bool create_canon_ace_lists(files_struct *fsp, * Note what kind of a POSIX ACL this should map to. */ - if( sid_equal(¤t_ace->trustee, &global_sid_World)) { + if( dom_sid_equal(¤t_ace->trustee, &global_sid_World)) { current_ace->owner_type = WORLD_ACE; current_ace->unix_ug.world = -1; current_ace->type = SMB_ACL_OTHER; - } else if (sid_equal(¤t_ace->trustee, &global_sid_Creator_Owner)) { + } else if (dom_sid_equal(¤t_ace->trustee, &global_sid_Creator_Owner)) { current_ace->owner_type = UID_ACE; current_ace->unix_ug.uid = pst->st_ex_uid; current_ace->type = SMB_ACL_USER_OBJ; @@ -1709,7 +1710,7 @@ static bool create_canon_ace_lists(files_struct *fsp, psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY; - } else if (sid_equal(¤t_ace->trustee, &global_sid_Creator_Group)) { + } else if (dom_sid_equal(¤t_ace->trustee, &global_sid_Creator_Group)) { current_ace->owner_type = GID_ACE; current_ace->unix_ug.gid = pst->st_ex_gid; current_ace->type = SMB_ACL_GROUP_OBJ; @@ -2085,7 +2086,7 @@ static void process_deny_list(connection_struct *conn, canon_ace **pp_ace_list ) continue; } - if (!sid_equal(&curr_ace->trustee, &global_sid_World)) + if (!dom_sid_equal(&curr_ace->trustee, &global_sid_World)) continue; /* JRATEST - assert. */ @@ -3080,7 +3081,7 @@ static size_t merge_default_aces( struct security_ace *nt_ace_list, size_t num_a if ((nt_ace_list[i].type == nt_ace_list[j].type) && (nt_ace_list[i].size == nt_ace_list[j].size) && (nt_ace_list[i].access_mask == nt_ace_list[j].access_mask) && - sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) && + dom_sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) && (i_inh == j_inh) && (i_flags_ni == 0) && (j_flags_ni == (SEC_ACE_FLAG_OBJECT_INHERIT| @@ -3144,7 +3145,7 @@ static void add_or_replace_ace(struct security_ace *nt_ace_list, size_t *num_ace /* first search for a duplicate */ for (i = 0; i < *num_aces; i++) { - if (sid_equal(&nt_ace_list[i].trustee, sid) && + if (dom_sid_equal(&nt_ace_list[i].trustee, sid) && (nt_ace_list[i].flags == flags)) break; } @@ -3367,7 +3368,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn, if (lp_profile_acls(SNUM(conn))) { for (i = 0; i < num_aces; i++) { - if (sid_equal(&nt_ace_list[i].trustee, &owner_sid)) { + if (dom_sid_equal(&nt_ace_list[i].trustee, &owner_sid)) { add_or_replace_ace(nt_ace_list, &num_aces, &orig_owner_sid, nt_ace_list[i].type, @@ -3756,7 +3757,7 @@ NTSTATUS append_parent_acl(files_struct *fsp, * same SID. This is order N^2. Ouch :-(. JRA. */ unsigned int k; for (k = 0; k < psd->dacl->num_aces; k++) { - if (sid_equal(&psd->dacl->aces[k].trustee, + if (dom_sid_equal(&psd->dacl->aces[k].trustee, &se->trustee)) { break; } diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 40009c8a3c..b890687425 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -22,6 +22,8 @@ #include "smbd/globals.h" #include "librpc/gen_ndr/netlogon.h" #include "librpc/gen_ndr/messaging.h" +#include "../lib/async_req/async_sock.h" +#include "ctdbd_conn.h" extern bool global_machine_password_needs_changing; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 247cbb84d5..e2edaf3a3c 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -29,6 +29,7 @@ #include "libcli/auth/schannel.h" #include "secrets.h" #include "memcache.h" +#include "ctdbd_conn.h" #include "../librpc/gen_ndr/srv_dfs.h" #include "../librpc/gen_ndr/srv_dssetup.h" diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 06ed264deb..588ed14675 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -29,6 +29,7 @@ #include "nsswitch/winbind_client.h" #include "dbwrap.h" #include "talloc_dict.h" +#include "async_smb.h" extern char *optarg; extern int optind; @@ -6851,7 +6852,7 @@ static bool run_local_string_to_sid(int dummy) { printf("could not parse S-1-5-32-545\n"); return false; } - if (!sid_equal(&sid, &global_sid_Builtin_Users)) { + if (!dom_sid_equal(&sid, &global_sid_Builtin_Users)) { printf("mis-parsed S-1-5-32-545 as %s\n", sid_string_tos(&sid)); return false; diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 671f7e81e9..96b3626391 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -36,6 +36,7 @@ #include "secrets.h" #include "lib/netapi/netapi.h" #include "rpc_client/init_lsa.h" +#include "../libcli/security/dom_sid.h" static int net_mode_share; static bool sync_files(struct copy_clistate *cp_clistate, const char *mask); @@ -4171,7 +4172,7 @@ static bool is_alias_member(struct dom_sid *sid, struct full_alias *alias) int i; for (i=0; i<alias->num_members; i++) { - if (sid_compare(sid, &alias->members[i]) == 0) + if (dom_sid_compare(sid, &alias->members[i]) == 0) return true; } diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index 8b5a90838e..59c52bc270 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -29,6 +29,7 @@ #include "../librpc/gen_ndr/ndr_drsuapi.h" #include "libnet/libnet_samsync.h" #include "libnet/libnet_dssync.h" +#include "../libcli/security/dom_sid.h" static void parse_samsync_partial_replication_objects(TALLOC_CTX *mem_ctx, int argc, @@ -187,7 +188,7 @@ NTSTATUS rpc_vampire_internals(struct net_context *c, NTSTATUS result; struct samsync_context *ctx = NULL; - if (!sid_equal(domain_sid, get_global_sam_sid())) { + if (!dom_sid_equal(domain_sid, get_global_sam_sid())) { d_printf(_("Cannot import users from %s at this time, " "as the current domain:\n\t%s: %s\nconflicts " "with the remote domain\n\t%s: %s\n" @@ -235,7 +236,7 @@ NTSTATUS rpc_vampire_internals(struct net_context *c, } /* fetch builtin */ - ctx->domain_sid = sid_dup_talloc(mem_ctx, &global_sid_Builtin); + ctx->domain_sid = dom_sid_dup(mem_ctx, &global_sid_Builtin); ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid); result = libnet_samsync(SAM_DATABASE_BUILTIN, ctx); @@ -318,7 +319,7 @@ NTSTATUS rpc_vampire_ldif_internals(struct net_context *c, } /* fetch builtin */ - ctx->domain_sid = sid_dup_talloc(mem_ctx, &global_sid_Builtin); + ctx->domain_sid = dom_sid_dup(mem_ctx, &global_sid_Builtin); ctx->domain_sid_str = sid_string_talloc(mem_ctx, ctx->domain_sid); status = libnet_samsync(SAM_DATABASE_BUILTIN, ctx); diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index a5be714631..ff2a8db9fd 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -21,6 +21,7 @@ #include "includes.h" #include "utils/net.h" #include "../librpc/gen_ndr/samr.h" +#include "smbldap.h" /* * Set a user's data diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 38ed9f7c9b..f8145b4a6d 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -34,6 +34,7 @@ #include "../lib/crypto/arcfour.h" #include "libads/kerberos_proto.h" #include "nsswitch/winbind_client.h" +#include "librpc/gen_ndr/krb5pac.h" #ifndef PAM_WINBIND_CONFIG_FILE #define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf" @@ -812,15 +813,17 @@ static NTSTATUS do_ccache_ntlm_auth(DATA_BLOB initial_msg, DATA_BLOB challenge_m return NT_STATUS_MORE_PROCESSING_REQUIRED; } -static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, - char *buf, int length) +static void manage_squid_ntlmssp_request_int(struct ntlm_auth_state *state, + char *buf, int length, + TALLOC_CTX *mem_ctx, + char **response) { DATA_BLOB request, reply; NTSTATUS nt_status; if (strlen(buf) < 2) { DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); + *response = talloc_strdup(mem_ctx, "BH NTLMSSP query invalid"); return; } @@ -830,7 +833,7 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, TALLOC_FREE(state->want_feature_list); state->want_feature_list = talloc_strdup(state->mem_ctx, buf+3); - x_fprintf(x_stdout, "OK\n"); + *response = talloc_strdup(mem_ctx, "OK"); return; } request = base64_decode_data_blob(buf + 3); @@ -847,12 +850,12 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, if (opt_password == NULL) { DEBUG(1, ("Out of memory\n")); - x_fprintf(x_stdout, "BH Out of memory\n"); + *response = talloc_strdup(mem_ctx, "BH Out of memory"); data_blob_free(&request); return; } - x_fprintf(x_stdout, "OK\n"); + *response = talloc_strdup(mem_ctx, "OK"); data_blob_free(&request); return; } @@ -866,10 +869,11 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, DEBUG(10, ("Requested negotiated NTLMSSP flags\n")); if (state->svr_state == SERVER_FINISHED) { - x_fprintf(x_stdout, "GF 0x%08x\n", state->neg_flags); + *response = talloc_asprintf(mem_ctx, "GF 0x%08x", + state->neg_flags); } else { - x_fprintf(x_stdout, "BH\n"); + *response = talloc_strdup(mem_ctx, "BH\n"); } data_blob_free(&request); return; @@ -878,17 +882,18 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, if(state->have_session_key) { char *key64 = base64_encode_data_blob(state->mem_ctx, state->session_key); - x_fprintf(x_stdout, "GK %s\n", key64?key64:"<NULL>"); + *response = talloc_asprintf(mem_ctx, "GK %s", + key64 ? key64 : "<NULL>"); TALLOC_FREE(key64); } else { - x_fprintf(x_stdout, "BH\n"); + *response = talloc_strdup(mem_ctx, "BH"); } data_blob_free(&request); return; } else { DEBUG(1, ("NTLMSSP query [%s] invalid\n", buf)); - x_fprintf(x_stdout, "BH NTLMSSP query invalid\n"); + *response = talloc_strdup(mem_ctx, "BH NTLMSSP query invalid"); return; } @@ -896,7 +901,8 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, nt_status = ntlm_auth_start_ntlmssp_server( &state->ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); + *response = talloc_asprintf( + mem_ctx, "BH %s", nt_errstr(nt_status)); return; } ntlmssp_want_feature_list(state->ntlmssp_state, @@ -911,22 +917,25 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { char *reply_base64 = base64_encode_data_blob(state->mem_ctx, reply); - x_fprintf(x_stdout, "TT %s\n", reply_base64); + *response = talloc_asprintf(mem_ctx, "TT %s", reply_base64); TALLOC_FREE(reply_base64); data_blob_free(&reply); state->svr_state = SERVER_CHALLENGE; DEBUG(10, ("NTLMSSP challenge\n")); } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED)) { - x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status)); + *response = talloc_asprintf(mem_ctx, "BH %s", + nt_errstr(nt_status)); DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status))); TALLOC_FREE(state->ntlmssp_state); } else if (!NT_STATUS_IS_OK(nt_status)) { - x_fprintf(x_stdout, "NA %s\n", nt_errstr(nt_status)); + *response = talloc_asprintf(mem_ctx, "NA %s", + nt_errstr(nt_status)); DEBUG(10, ("NTLMSSP %s\n", nt_errstr(nt_status))); } else { - x_fprintf(x_stdout, "AF %s\n", - (char *)state->ntlmssp_state->callback_private); + *response = talloc_asprintf( + mem_ctx, "AF %s", + (char *)state->ntlmssp_state->callback_private); DEBUG(10, ("NTLMSSP OK!\n")); if(state->have_session_key) @@ -942,6 +951,22 @@ static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, data_blob_free(&request); } +static void manage_squid_ntlmssp_request(struct ntlm_auth_state *state, + char *buf, int length) +{ + char *response; + + manage_squid_ntlmssp_request_int(state, buf, length, + talloc_tos(), &response); + + if (response == NULL) { + x_fprintf(x_stdout, "BH Out of memory\n"); + return; + } + x_fprintf(x_stdout, "%s\n", response); + TALLOC_FREE(response); +} + static void manage_client_ntlmssp_request(struct ntlm_auth_state *state, char *buf, int length) { @@ -1199,6 +1224,45 @@ static void offer_gss_spnego_mechs(void) { return; } +bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) +{ + bool ret; + ASN1_DATA *data; + int data_remaining; + + data = asn1_init(talloc_tos()); + if (data == NULL) { + return false; + } + + asn1_load(data, blob); + asn1_start_tag(data, ASN1_APPLICATION(0)); + asn1_check_OID(data, OID_KERBEROS5); + + data_remaining = asn1_tag_remaining(data); + + if (data_remaining < 3) { + data->has_error = True; + } else { + asn1_read(data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob_talloc(ctx, NULL, data_remaining); + asn1_read(data, ticket->data, ticket->length); + } + + asn1_end_tag(data); + + ret = !data->has_error; + + if (data->has_error) { + data_blob_free(ticket); + } + + asn1_free(data); + + return ret; +} + static void manage_gss_spnego_request(struct ntlm_auth_state *state, char *buf, int length) { @@ -1250,6 +1314,31 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, } token = base64_decode_data_blob(buf + 3); + + if ((token.length >= 7) + && (strncmp((char *)token.data, "NTLMSSP", 7) == 0)) { + char *reply; + + DEBUG(10, ("Could not parse GSS-SPNEGO, trying raw " + "ntlmssp\n")); + + manage_squid_ntlmssp_request_int(state, buf, length, + talloc_tos(), &reply); + if (reply == NULL) { + x_fprintf(x_stdout, "BH Out of memory\n"); + return; + } + + if (strncmp(reply, "AF ", 3) == 0) { + x_fprintf(x_stdout, "AF * %s\n", reply+3); + } else { + x_fprintf(x_stdout, "%s *\n", reply); + } + + TALLOC_FREE(reply); + return; + } + len = spnego_read_data(ctx, token, &request); data_blob_free(&token); @@ -1318,6 +1407,8 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, DATA_BLOB ap_rep; DATA_BLOB session_key; struct PAC_LOGON_INFO *logon_info = NULL; + DATA_BLOB ticket; + uint8_t tok_id[2]; if ( request.negTokenInit.mechToken.data == NULL ) { DEBUG(1, ("Client did not provide Kerberos data\n")); @@ -1326,13 +1417,23 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, return; } + dump_data(10, request.negTokenInit.mechToken.data, + request.negTokenInit.mechToken.length); + + if (!spnego_parse_krb5_wrap(ctx, request.negTokenInit.mechToken, + &ticket, tok_id)) { + DEBUG(1, ("spnego_parse_krb5_wrap failed\n")); + x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n"); + return; + } + response.type = SPNEGO_NEG_TOKEN_TARG; response.negTokenTarg.supportedMech = talloc_strdup(ctx, OID_KERBEROS5_OLD); response.negTokenTarg.mechListMIC = data_blob_talloc(ctx, NULL, 0); response.negTokenTarg.responseToken = data_blob_talloc(ctx, NULL, 0); status = ads_verify_ticket(mem_ctx, lp_realm(), 0, - &request.negTokenInit.mechToken, + &ticket, &principal, &logon_info, &ap_rep, &session_key, True); @@ -1356,6 +1457,9 @@ static void manage_gss_spnego_request(struct ntlm_auth_state *state, domain = SMB_STRDUP(domain); user = SMB_STRDUP(principal); + netsamlogon_cache_store( + user, &logon_info->info3); + data_blob_free(&ap_rep); } @@ -2319,7 +2423,9 @@ static void squid_stream(enum stdio_helper_mode stdio_mode, stdio_helper_functio state->helper_mode = stdio_mode; while(1) { + TALLOC_CTX *frame = talloc_stackframe(); manage_squid_request(state, fn); + TALLOC_FREE(frame); } } diff --git a/source3/utils/profiles.c b/source3/utils/profiles.c index f6f500a2aa..faec8e2c3b 100644 --- a/source3/utils/profiles.c +++ b/source3/utils/profiles.c @@ -23,6 +23,7 @@ #include "popt_common.h" #include "registry/reg_objects.h" #include "regfio.h" +#include "../libcli/security/dom_sid.h" /* GLOBAL VARIABLES */ @@ -64,7 +65,7 @@ static bool swap_sid_in_acl( struct security_descriptor *sd, struct dom_sid *s1, bool update = False; verbose_output(" Owner SID: %s\n", sid_string_tos(sd->owner_sid)); - if ( sid_equal( sd->owner_sid, s1 ) ) { + if ( dom_sid_equal( sd->owner_sid, s1 ) ) { sid_copy( sd->owner_sid, s2 ); update = True; verbose_output(" New Owner SID: %s\n", @@ -73,7 +74,7 @@ static bool swap_sid_in_acl( struct security_descriptor *sd, struct dom_sid *s1, } verbose_output(" Group SID: %s\n", sid_string_tos(sd->group_sid)); - if ( sid_equal( sd->group_sid, s1 ) ) { + if ( dom_sid_equal( sd->group_sid, s1 ) ) { sid_copy( sd->group_sid, s2 ); update = True; verbose_output(" New Group SID: %s\n", @@ -85,7 +86,7 @@ static bool swap_sid_in_acl( struct security_descriptor *sd, struct dom_sid *s1, for ( i=0; i<theacl->num_aces; i++ ) { verbose_output(" Trustee SID: %s\n", sid_string_tos(&theacl->aces[i].trustee)); - if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) { + if ( dom_sid_equal( &theacl->aces[i].trustee, s1 ) ) { sid_copy( &theacl->aces[i].trustee, s2 ); update = True; verbose_output(" New Trustee SID: %s\n", @@ -99,7 +100,7 @@ static bool swap_sid_in_acl( struct security_descriptor *sd, struct dom_sid *s1, for ( i=0; i<theacl->num_aces; i++ ) { verbose_output(" Trustee SID: %s\n", sid_string_tos(&theacl->aces[i].trustee)); - if ( sid_equal( &theacl->aces[i].trustee, s1 ) ) { + if ( dom_sid_equal( &theacl->aces[i].trustee, s1 ) ) { sid_copy( &theacl->aces[i].trustee, s2 ); update = True; verbose_output(" New Trustee SID: %s\n", diff --git a/source3/utils/sharesec.c b/source3/utils/sharesec.c index 79078b234a..decd063913 100644 --- a/source3/utils/sharesec.c +++ b/source3/utils/sharesec.c @@ -24,6 +24,7 @@ #include "includes.h" #include "popt_common.h" +#include "../libcli/security/dom_sid.h" static TALLOC_CTX *ctx; @@ -370,8 +371,8 @@ static int ace_compare(struct security_ace *ace1, struct security_ace *ace2) if (ace1->type != ace2->type) return ace2->type - ace1->type; - if (sid_compare(&ace1->trustee, &ace2->trustee)) - return sid_compare(&ace1->trustee, &ace2->trustee); + if (dom_sid_compare(&ace1->trustee, &ace2->trustee)) + return dom_sid_compare(&ace1->trustee, &ace2->trustee); if (ace1->flags != ace2->flags) return ace1->flags - ace2->flags; @@ -459,7 +460,7 @@ static int change_share_sec(TALLOC_CTX *mem_ctx, const char *sharename, char *th bool found = False; for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sid_equal(&sd->dacl->aces[i].trustee, + if (dom_sid_equal(&sd->dacl->aces[i].trustee, &old->dacl->aces[j].trustee)) { old->dacl->aces[j] = sd->dacl->aces[i]; found = True; diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c index 65fec1041b..fa039f639f 100644 --- a/source3/utils/smbcacls.c +++ b/source3/utils/smbcacls.c @@ -25,6 +25,7 @@ #include "popt_common.h" #include "../librpc/gen_ndr/ndr_lsa.h" #include "rpc_client/cli_lsarpc.h" +#include "../libcli/security/dom_sid.h" extern bool AllowDebugChange; @@ -835,8 +836,8 @@ static int ace_compare(struct security_ace *ace1, struct security_ace *ace2) if (ace1->type != ace2->type) return ace2->type - ace1->type; - if (sid_compare(&ace1->trustee, &ace2->trustee)) - return sid_compare(&ace1->trustee, &ace2->trustee); + if (dom_sid_compare(&ace1->trustee, &ace2->trustee)) + return dom_sid_compare(&ace1->trustee, &ace2->trustee); if (ace1->flags != ace2->flags) return ace1->flags - ace2->flags; @@ -929,7 +930,7 @@ static int cacl_set(struct cli_state *cli, const char *filename, bool found = False; for (j=0;old->dacl && j<old->dacl->num_aces;j++) { - if (sid_equal(&sd->dacl->aces[i].trustee, + if (dom_sid_equal(&sd->dacl->aces[i].trustee, &old->dacl->aces[j].trustee)) { old->dacl->aces[j] = sd->dacl->aces[i]; found = True; diff --git a/source3/winbindd/idmap_ad.c b/source3/winbindd/idmap_ad.c index 3d47baadc9..f2e47a7042 100644 --- a/source3/winbindd/idmap_ad.c +++ b/source3/winbindd/idmap_ad.c @@ -33,6 +33,7 @@ #include "nss_info.h" #include "secrets.h" #include "idmap.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_IDMAP @@ -266,7 +267,7 @@ static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid) int i; for (i = 0; maps[i] && i<IDMAP_AD_MAX_IDS; i++) { - if (sid_equal(maps[i]->sid, sid)) { + if (dom_sid_equal(maps[i]->sid, sid)) { return maps[i]; } } diff --git a/source3/winbindd/idmap_ldap.c b/source3/winbindd/idmap_ldap.c index 39df489be7..dcdc14f277 100644 --- a/source3/winbindd/idmap_ldap.c +++ b/source3/winbindd/idmap_ldap.c @@ -28,6 +28,7 @@ #include "secrets.h" #include "idmap.h" #include "idmap_rw.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_IDMAP @@ -1030,7 +1031,7 @@ static struct id_map *find_map_by_sid(struct id_map **maps, struct dom_sid *sid) if (maps[i] == NULL) { /* end of the run */ return NULL; } - if (sid_equal(maps[i]->sid, sid)) { + if (dom_sid_equal(maps[i]->sid, sid)) { return maps[i]; } } diff --git a/source3/winbindd/wb_getgrsid.c b/source3/winbindd/wb_getgrsid.c index bb93be2174..8accc639af 100644 --- a/source3/winbindd/wb_getgrsid.c +++ b/source3/winbindd/wb_getgrsid.c @@ -20,6 +20,7 @@ #include "includes.h" #include "winbindd.h" #include "librpc/gen_ndr/cli_wbint.h" +#include "../libcli/security/dom_sid.h" struct wb_getgrsid_state { struct tevent_context *ev; @@ -55,7 +56,7 @@ struct tevent_req *wb_getgrsid_send(TALLOC_CTX *mem_ctx, if (lp_winbind_trusted_domains_only()) { struct winbindd_domain *our_domain = find_our_domain(); - if (sid_compare_domain(group_sid, &our_domain->sid) == 0) { + if (dom_sid_compare_domain(group_sid, &our_domain->sid) == 0) { DEBUG(7, ("winbindd_getgrsid: My domain -- rejecting " "getgrsid() for %s\n", sid_string_tos(group_sid))); tevent_req_nterror(req, NT_STATUS_NO_SUCH_GROUP); diff --git a/source3/winbindd/winbindd_cache.c b/source3/winbindd/winbindd_cache.c index 9c48c71aa2..c2ce0a2713 100644 --- a/source3/winbindd/winbindd_cache.c +++ b/source3/winbindd/winbindd_cache.c @@ -30,6 +30,7 @@ #include "../librpc/gen_ndr/ndr_wbint.h" #include "ads.h" #include "nss_info.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -105,35 +106,6 @@ void (*smb_panic_fn)(const char *const why) = smb_panic; static struct winbind_cache *wcache; -void winbindd_check_cache_size(time_t t) -{ - static time_t last_check_time; - struct stat st; - - if (last_check_time == (time_t)0) - last_check_time = t; - - if (t - last_check_time < 60 && t - last_check_time > 0) - return; - - if (wcache == NULL || wcache->tdb == NULL) { - DEBUG(0, ("Unable to check size of tdb cache - cache not open !\n")); - return; - } - - if (fstat(tdb_fd(wcache->tdb), &st) == -1) { - DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) )); - return; - } - - if (st.st_size > WINBINDD_MAX_CACHE_SIZE) { - DEBUG(10,("flushing cache due to size (%lu) > (%lu)\n", - (unsigned long)st.st_size, - (unsigned long)WINBINDD_MAX_CACHE_SIZE)); - wcache_flush_cache(); - } -} - /* get the winbind_cache structure */ static struct winbind_cache *get_cache(struct winbindd_domain *domain) { @@ -147,7 +119,7 @@ static struct winbind_cache *get_cache(struct winbindd_domain *domain) } if (strequal(domain->name, get_global_sam_name()) && - sid_equal(&domain->sid, get_global_sam_sid())) { + dom_sid_equal(&domain->sid, get_global_sam_sid())) { domain->backend = &sam_passdb_methods; domain->initialized = True; } @@ -673,7 +645,7 @@ static struct cache_entry *wcache_fetch_raw(char *kstr) static bool is_my_own_sam_domain(struct winbindd_domain *domain) { if (strequal(domain->name, get_global_sam_name()) && - sid_equal(&domain->sid, get_global_sam_sid())) { + dom_sid_equal(&domain->sid, get_global_sam_sid())) { return true; } @@ -683,7 +655,7 @@ static bool is_my_own_sam_domain(struct winbindd_domain *domain) static bool is_builtin_domain(struct winbindd_domain *domain) { if (strequal(domain->name, "BUILTIN") && - sid_equal(&domain->sid, &global_sid_Builtin)) { + dom_sid_equal(&domain->sid, &global_sid_Builtin)) { return true; } diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index ae6401379a..f43c08f417 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -81,7 +81,6 @@ bool parse_sidlist(TALLOC_CTX *mem_ctx, const char *sidstr, /* The following definitions come from winbindd/winbindd_cache.c */ -void winbindd_check_cache_size(time_t t); struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status); NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid); NTSTATUS wcache_get_creds(struct winbindd_domain *domain, diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index 80f7bb69bf..3ceaa67b7e 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -33,6 +33,7 @@ #include "librpc/gen_ndr/srv_lsa.h" #include "rpc_client/cli_samr.h" #include "rpc_client/cli_lsarpc.h" +#include "../libcli/security/dom_sid.h" /* Query display info for a domain */ NTSTATUS rpc_query_user_list(TALLOC_CTX *mem_ctx, @@ -612,7 +613,7 @@ NTSTATUS rpc_lookup_useraliases(TALLOC_CTX *mem_ctx, } for (i = 0; i < num_query_sids; i++) { - sid_array.sids[i].sid = sid_dup_talloc(mem_ctx, &sids[total_sids++]); + sid_array.sids[i].sid = dom_sid_dup(mem_ctx, &sids[total_sids++]); if (sid_array.sids[i].sid == NULL) { return NT_STATUS_NO_MEMORY; } @@ -739,7 +740,7 @@ NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx, struct lsa_SidPtr sid_ptr; struct samr_Ids rids_query; - sid_ptr.sid = sid_dup_talloc(mem_ctx, group_sid); + sid_ptr.sid = dom_sid_dup(mem_ctx, group_sid); if (sid_ptr.sid == NULL) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index 671c868273..14be0e26fa 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -23,6 +23,7 @@ #include "includes.h" #include "winbindd.h" #include "secrets.h" +#include "../libcli/security/dom_sid.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_WINBIND @@ -135,7 +136,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const continue; } - if (sid_equal(sid, &domain->sid)) { + if (dom_sid_equal(sid, &domain->sid)) { break; } } @@ -146,7 +147,7 @@ static struct winbindd_domain *add_trusted_domain(const char *domain_name, const * We found a match. Possibly update the SID */ if ((sid != NULL) - && sid_equal(&domain->sid, &global_sid_NULL)) { + && dom_sid_equal(&domain->sid, &global_sid_NULL)) { sid_copy( &domain->sid, sid ); } return domain; @@ -740,7 +741,7 @@ struct winbindd_domain *find_domain_from_sid_noinit(const struct dom_sid *sid) /* Search through list */ for (domain = domain_list(); domain != NULL; domain = domain->next) { - if (sid_compare_domain(sid, &domain->sid) == 0) + if (dom_sid_compare_domain(sid, &domain->sid) == 0) return domain; } diff --git a/source3/wscript_build b/source3/wscript_build index e0e0e5fb50..e5ad33bab4 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -66,78 +66,81 @@ LIBNDR_SCHANNEL_SRC = '''../librpc/gen_ndr/ndr_schannel.c LIBNDR_SPOOLSS_SRC = '''../librpc/gen_ndr/ndr_spoolss.c ../librpc/ndr/ndr_spoolss_buf.c''' +LIBNDR_PREG_SRC = '''librpc/gen_ndr/ndr_preg.c + librpc/ndr/ndr_preg.c''' + LIBNDR_XATTR_SRC = '''../librpc/gen_ndr/ndr_xattr.c ../librpc/ndr/ndr_xattr.c''' LIBCLI_SPOOLSS_SRC = ''' - librpc/gen_ndr/cli_spoolss.c - librpc/gen_ndr/ndr_spoolss_c.c + ../librpc/gen_ndr/cli_spoolss.c + ../librpc/gen_ndr/ndr_spoolss_c.c rpc_client/cli_spoolss.c rpc_client/init_spoolss.c''' LIBCLI_EVENTLOG_SRC = ''' - librpc/gen_ndr/cli_eventlog.c - librpc/gen_ndr/ndr_eventlog_c.c''' + ../librpc/gen_ndr/cli_eventlog.c + ../librpc/gen_ndr/ndr_eventlog_c.c''' LIBCLI_WINREG_SRC = ''' - librpc/gen_ndr/cli_winreg.c - librpc/gen_ndr/ndr_winreg_c.c''' + ../librpc/gen_ndr/cli_winreg.c + ../librpc/gen_ndr/ndr_winreg_c.c''' LIBCLI_NTSVCS_SRC = ''' - librpc/gen_ndr/cli_ntsvcs.c - librpc/gen_ndr/ndr_ntsvcs_c.c''' + ../librpc/gen_ndr/cli_ntsvcs.c + ../librpc/gen_ndr/ndr_ntsvcs_c.c''' LIBCLI_DRSUAPI_SRC = ''' - librpc/gen_ndr/cli_drsuapi.c - librpc/gen_ndr/ndr_drsuapi_c.c''' + ../librpc/gen_ndr/cli_drsuapi.c + ../librpc/gen_ndr/ndr_drsuapi_c.c''' LIBCLI_DFS_SRC = ''' - librpc/gen_ndr/cli_dfs.c - librpc/gen_ndr/ndr_dfs_c.c''' + ../librpc/gen_ndr/cli_dfs.c + ../librpc/gen_ndr/ndr_dfs_c.c''' LIBCLI_ECHO_SRC = ''' - librpc/gen_ndr/cli_echo.c - librpc/gen_ndr/ndr_echo_c.c''' + ../librpc/gen_ndr/cli_echo.c + ../librpc/gen_ndr/ndr_echo_c.c''' LIBCLI_INITSHUTDOWN_SRC = ''' - librpc/gen_ndr/cli_initshutdown.c - librpc/gen_ndr/ndr_initshutdown_c.c''' + ../librpc/gen_ndr/cli_initshutdown.c + ../librpc/gen_ndr/ndr_initshutdown_c.c''' LIBCLI_DSSETUP_SRC = ''' - librpc/gen_ndr/cli_dssetup.c - librpc/gen_ndr/ndr_dssetup_c.c''' + ../librpc/gen_ndr/cli_dssetup.c + ../librpc/gen_ndr/ndr_dssetup_c.c''' LIBCLI_SVCCTL_SRC = ''' - librpc/gen_ndr/cli_svcctl.c - librpc/gen_ndr/ndr_svcctl_c.c''' + ../librpc/gen_ndr/cli_svcctl.c + ../librpc/gen_ndr/ndr_svcctl_c.c''' LIBCLI_WKSSVC_SRC = ''' - librpc/gen_ndr/cli_wkssvc.c - librpc/gen_ndr/ndr_wkssvc_c.c''' + ../librpc/gen_ndr/cli_wkssvc.c + ../librpc/gen_ndr/ndr_wkssvc_c.c''' LIBCLI_SRVSVC_SRC = ''' - librpc/gen_ndr/cli_srvsvc.c - librpc/gen_ndr/ndr_srvsvc_c.c''' + ../librpc/gen_ndr/cli_srvsvc.c + ../librpc/gen_ndr/ndr_srvsvc_c.c''' LIBCLI_LSA_SRC = ''' - librpc/gen_ndr/cli_lsa.c - librpc/gen_ndr/ndr_lsa_c.c + ../librpc/gen_ndr/cli_lsa.c + ../librpc/gen_ndr/ndr_lsa_c.c rpc_client/cli_lsarpc.c rpc_client/init_lsa.c''' LIBCLI_SAMR_SRC = ''' - librpc/gen_ndr/cli_samr.c - librpc/gen_ndr/ndr_samr_c.c + ../librpc/gen_ndr/cli_samr.c + ../librpc/gen_ndr/ndr_samr_c.c rpc_client/cli_samr.c''' LIBCLI_NETLOGON_SRC = ''' - librpc/gen_ndr/cli_netlogon.c - librpc/gen_ndr/ndr_netlogon_c.c + ../librpc/gen_ndr/cli_netlogon.c + ../librpc/gen_ndr/ndr_netlogon_c.c rpc_client/cli_netlogon.c''' LIBCLI_EPMAPPER_SRC = ''' - librpc/gen_ndr/cli_epmapper.c - librpc/gen_ndr/ndr_epmapper_c.c''' + ../librpc/gen_ndr/cli_epmapper.c + ../librpc/gen_ndr/ndr_epmapper_c.c''' LIBNDR_GEN_SRC = '''../librpc/gen_ndr/ndr_wkssvc.c ${LIBNDR_GEN_SRC0} @@ -376,6 +379,8 @@ REG_INIT_FULL_SRC = '''registry/reg_init_full.c''' REGFIO_SRC = '''registry/regfio.c ${REG_PARSE_PRS_SRC}''' +REG_API_REGF_SRC = '''registry/reg_api_regf.c''' + REGSRCS_SRC = '''registry/reg_objects.c''' REG_BACKENDS_BASE_SRC = '''registry/reg_backend_db.c''' @@ -394,7 +399,6 @@ REG_BACKENDS_EXTRA_SRC = '''registry/reg_backend_printing.c REG_BASE_SRC = '''registry/reg_api.c registry/reg_dispatcher.c registry/reg_cachehook.c - ${REGFIO_SRC} ${REGSRCS_SRC} registry/reg_util_internal.c lib/util_nttoken.c @@ -404,7 +408,8 @@ REG_BASE_SRC = '''registry/reg_api.c REG_SMBCONF_SRC = '''${REG_BASE_SRC} ${REG_BACKENDS_SMBCONF_SRC} ${REG_INIT_SMBCONF_SRC} - registry/reg_util_token.c''' + registry/reg_util_token.c + registry/reg_api_util.c''' REG_FULL_SRC = '''${REG_SMBCONF_SRC} ${REG_BACKENDS_EXTRA_SRC} @@ -808,6 +813,8 @@ SMBD_SRC_BASE = '''${SMBD_SRC_SRV} rpc_client/init_samr.c ${AUTH_SRC} ${PRIVILEGES_BASIC_SRC} + ${REGFIO_SRC} + ${REG_API_REGF_SRC} ${LIBNDR_XATTR_SRC}''' PRINTING_SRC = '''printing/pcap.c printing/print_svid.c printing/print_aix.c @@ -874,6 +881,99 @@ CLIENT_SRC = '''${CLIENT_SRC1} ${LIBMSRPC_GEN_SRC} ${LIBCLI_SRVSVC_SRC} rpc_client/init_lsa.c''' +RPCCLIENT_SRC1 = '''rpcclient/rpcclient.c rpcclient/cmd_lsarpc.c + rpcclient/cmd_samr.c rpcclient/cmd_spoolss.c + rpcclient/cmd_netlogon.c rpcclient/cmd_srvsvc.c + rpcclient/cmd_dfs.c rpcclient/cmd_epmapper.c + rpcclient/cmd_dssetup.c rpcclient/cmd_echo.c + rpcclient/cmd_shutdown.c rpcclient/cmd_test.c + rpcclient/cmd_wkssvc.c rpcclient/cmd_ntsvcs.c + rpcclient/cmd_drsuapi.c rpcclient/cmd_eventlog.c + rpcclient/cmd_winreg.c + ${DISPLAY_SEC_SRC}''' + +RPCCLIENT_SRC = '''${RPCCLIENT_SRC1} + ${LIBMSRPC_GEN_SRC} + ${LIBMSRPC_SRC} + ${READLINE_SRC} + ${LIBADS_SRC} + ${DCUTIL_SRC} + ${LIBCLI_SPOOLSS_SRC} + ${LIBCLI_EVENTLOG_SRC} + ${LIBCLI_NTSVCS_SRC} + ${LIBCLI_DRSUAPI_SRC} + ${LIBCLI_DFS_SRC} + ${LIBCLI_ECHO_SRC} + ${LIBCLI_DSSETUP_SRC} + ${LIBCLI_WKSSVC_SRC} + ${LIBCLI_SRVSVC_SRC} + ${LIBCLI_LSA_SRC} + ${LIBCLI_SAMR_SRC} + ${LIBCLI_WINREG_SRC} + ${LIBCLI_NETLOGON_SRC} + ${RPC_CLIENT_SCHANNEL_SRC} + rpc_client/init_netlogon.c + rpc_client/init_samr.c''' + +LIBNET_DSSYNC_SRC = '''libnet/libnet_dssync.c + libnet/libnet_dssync_keytab.c + ../libcli/drsuapi/repl_decrypt.c''' + +LIBNET_SAMSYNC_SRC = '''libnet/libnet_samsync.c + libnet/libnet_samsync_ldif.c + libnet/libnet_samsync_passdb.c + libnet/libnet_samsync_display.c + libnet/libnet_samsync_keytab.c + ../libcli/samsync/decrypt.c''' + +PASSWD_UTIL_SRC = 'utils/passwd_util.c' + +NET_SRC1 = '''utils/net.c utils/net_ads.c utils/net_help.c + utils/net_rap.c utils/net_rpc.c utils/net_rpc_samsync.c + utils/net_rpc_join.c utils/net_time.c utils/net_lookup.c + utils/net_cache.c utils/net_groupmap.c utils/net_idmap.c + utils/net_status.c utils/net_rpc_printer.c utils/net_rpc_rights.c + utils/net_rpc_service.c utils/net_rpc_registry.c utils/net_usershare.c + utils/netlookup.c utils/net_sam.c utils/net_rpc_shell.c + utils/net_util.c utils/net_rpc_sh_acct.c utils/net_rpc_audit.c + ${PASSWD_UTIL_SRC} utils/net_dns.c utils/net_ads_gpo.c + utils/net_conf.c utils/net_join.c utils/net_user.c + utils/net_group.c utils/net_file.c utils/net_registry.c + auth/token_util.c utils/net_dom.c utils/net_share.c + utils/net_g_lock.c + utils/net_serverid.c + utils/net_eventlog.c + utils/net_printing.c + ${LIBNDR_NTPRINTING_SRC} + ${LIBNDR_PREG_SRC} + ${LIBCLI_SPOOLSS_SRC} + ${LIBCLI_WINREG_SRC} + ${LIBCLI_DRSUAPI_SRC} + ${LIBCLI_INITSHUTDOWN_SRC} + ${LIBCLI_DSSETUP_SRC} + ${LIBCLI_SVCCTL_SRC} + ${LIBCLI_WKSSVC_SRC} + ${LIBCLI_SRVSVC_SRC} + ${LIBCLI_LSA_SRC} + ${LIBCLI_SAMR_SRC} + ${LIBCLI_NETLOGON_SRC} + ${RPC_CLIENT_SCHANNEL_SRC} + rpc_client/init_netlogon.c + rpc_client/init_samr.c''' + + +NET_SRC2 = 'utils/net_registry_util.c utils/net_help_common.c' + +NET_SRC = '''${NET_SRC1} + ${NET_SRC2} + ${LIBADDNS_SRC0} + ${LIBMSRPC_SRC} ${LIBMSRPC_GEN_SRC} + ${LIBADS_SRC} ${LIBADS_SERVER_SRC} ${LIBADS_PRINTER_SRC} + ${DCUTIL_SRC} + ${AFS_SRC} ${AFS_SETTOKEN_SRC} ${READLINE_SRC} + ${LIBGPO_SRC} ${DISPLAY_SEC_SRC} + ${LIBNET_SRC} ${LIBNET_DSSYNC_SRC} ${LIBNET_SAMSYNC_SRC} + ${LIB_EVENTLOG_SRC} ${REGFIO_SRC}''' LIBS='ICONV' @@ -925,7 +1025,7 @@ for prefix in bld.env.MODULE_PREFIXES: bld.SAMBA_SUBSYSTEM('WBCOMMON', source=WBCOMMON_SRC) -bld.SAMBA_SUBSYSTEM('LIBWBCLIENT', +bld.SAMBA_LIBRARY('libwbclient', source='''../nsswitch/libwbclient/wbc_guid.c ../nsswitch/libwbclient/wbc_idmap.c ../nsswitch/libwbclient/wbclient.c @@ -935,6 +1035,24 @@ bld.SAMBA_SUBSYSTEM('LIBWBCLIENT', ../nsswitch/libwbclient/wbc_util.c''', public_deps='talloc WBCOMMON') +bld.SAMBA_LIBRARY('libnetapi', + source='''lib/netapi/netapi.c + lib/netapi/cm.c + librpc/gen_ndr/ndr_libnetapi.c + lib/netapi/libnetapi.c + lib/netapi/joindomain.c + lib/netapi/serverinfo.c + lib/netapi/getdc.c + lib/netapi/user.c + lib/netapi/group.c + lib/netapi/localgroup.c + lib/netapi/samr.c + lib/netapi/sid.c + lib/netapi/share.c + lib/netapi/file.c + lib/netapi/shutdown.c + lib/netapi/netlogon.c''', + public_deps='''talloc tdb''') bld.SAMBA_SUBSYSTEM('ASN1_UTIL', source='../lib/util/asn1.c', @@ -1014,14 +1132,14 @@ bld.SAMBA_SUBSYSTEM('SMBLDAP', bld.SAMBA_BINARY('smbd/smbd', source=SMBD_SRC, deps='''tdb DYNCONFIG tevent dl krb5 ldap gssapi gssapi_krb5 - NSS_WRAPPER LIBWBCLIENT crypt nsl cups cap resolv ZLIB PASSDB + NSS_WRAPPER libwbclient crypt nsl cups cap resolv ZLIB PASSDB PARAM_WITHOUT_REG LIBS LIBSMB POPT_SAMBA KRBCLIENT AVAHI''', install_path='${SBINDIR}', vars=locals()) bld.SAMBA_BINARY('nmbd/nmbd', source=NMBD_SRC, - deps='''talloc tdb tevent ZLIB cap resolv LIBWBCLIENT dl + deps='''talloc tdb tevent ZLIB cap resolv libwbclient dl NSS_WRAPPER DYNCONFIG PASSDB PARAM ldap LIB_NONSMBD LIBSMB POPT_SAMBA KRBCLIENT''', install_path='${SBINDIR}', @@ -1030,7 +1148,7 @@ bld.SAMBA_BINARY('nmbd/nmbd', bld.SAMBA_BINARY('winbindd/winbindd', source=WINBINDD_SRC, deps='''talloc tdb tevent cap dl DYNCONFIG ZLIB NSS_WRAPPER - LIBWBCLIENT PASSDB ldap resolv PARAM LIB_NONSMBD LIBSMB + libwbclient PASSDB ldap resolv PARAM LIB_NONSMBD LIBSMB POPT_SAMBA KRBCLIENT''', enabled=bld.env.build_winbind, install_path='${SBINDIR}', @@ -1038,7 +1156,7 @@ bld.SAMBA_BINARY('winbindd/winbindd', bld.SAMBA_BINARY('web/swat', source=SWAT_SRC, - deps='''talloc tevent cap DYNCONFIG LIBS LIBSMB LIBWBCLIENT PARAM + deps='''talloc tevent cap DYNCONFIG LIBS LIBSMB libwbclient PARAM LIB_NONSMBD resolv PASSDB POPT_SAMBA KRBCLIENT cups''', enabled=bld.env.build_swat, install_path='${SBINDIR}', @@ -1047,12 +1165,18 @@ bld.SAMBA_BINARY('web/swat', bld.SAMBA_BINARY('smbclient', source=CLIENT_SRC, deps='''talloc tdb cap resolv POPT_SAMBA PASSDB LIBSMB LIB_NONSMBD - PARAM_WITHOUT_REG LIBWBCLIENT DYNCONFIG PARAM KRBCLIENT''', + PARAM_WITHOUT_REG libwbclient DYNCONFIG PARAM KRBCLIENT''', + vars=locals()) + +bld.SAMBA_BINARY('rpcclient/rpcclient', + source=RPCCLIENT_SRC, + deps='''talloc tdb cap resolv POPT_SAMBA PASSDB LIBSMB LIB_NONSMBD + PARAM_WITHOUT_REG libwbclient DYNCONFIG PARAM KRBCLIENT''', vars=locals()) bld.SAMBA_BINARY('wbinfo', source=WBINFO_SRC, - deps='''talloc LIBWBCLIENT DYNCONFIG tevent cap + deps='''talloc libwbclient DYNCONFIG tevent cap NSS_WRAPPER ASN1_UTIL LIBTSOCKET PASSDB ldap PARAM LIB_NONSMBD LIBSAMBA POPT_SAMBA''', vars=locals()) @@ -1060,14 +1184,21 @@ bld.SAMBA_BINARY('wbinfo', bld.SAMBA_BINARY('testparm', source=TESTPARM_SRC, deps='''talloc tevent DYNCONFIG ldap cap NSS_WRAPPER - LIBWBCLIENT ASN1_UTIL LIBTSOCKET PASSDB PARAM LIB_NONSMBD + libwbclient ASN1_UTIL LIBTSOCKET PASSDB PARAM LIB_NONSMBD LIBSMB_ERR POPT_SAMBA''', vars=locals()) bld.SAMBA_BINARY('eventlogadm', source=EVTLOGADM_SRC, deps='''talloc tevent cap POPT_SAMBA DYNCONFIG LIBS PARAM - LIB_NONSMBD LIBSMB_ERR PASSDB LIBWBCLIENT''', + LIB_NONSMBD LIBSMB_ERR PASSDB libwbclient''', + vars=locals()) + +bld.SAMBA_BINARY('net', + source=NET_SRC, + deps='''talloc tdb libnetapi cap resolv POPT_SAMBA PASSDB LIBSMB LIB_NONSMBD + PARAM_WITHOUT_REG libwbclient DYNCONFIG PARAM KRBCLIENT + LOCALE_DIR''', vars=locals()) swat_files=recursive_dirlist('../swat', '../swat', '*') diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 0e371082be..a5d7caeefe 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -43,6 +43,7 @@ #include "dsdb/common/util.h" #include "lib/socket/socket.h" #include "dsdb/samdb/ldb_modules/util.h" +#include "librpc/gen_ndr/irpc.h" /* search the sam for the specified attributes in a specific domain, filter on @@ -3982,3 +3983,95 @@ bool dsdb_attr_in_rodc_fas(const struct dsdb_attribute *sa) /* other attributes are denied */ return false; } + +/* return fsmo role dn and role owner dn for a particular role*/ +WERROR dsdb_get_fsmo_role_info(TALLOC_CTX *tmp_ctx, + struct ldb_context *ldb, + uint32_t role, + struct ldb_dn **fsmo_role_dn, + struct ldb_dn **role_owner_dn) +{ + int ret; + switch (role) { + case DREPL_NAMING_MASTER: + *fsmo_role_dn = samdb_partitions_dn(ldb, tmp_ctx); + ret = samdb_reference_dn(ldb, tmp_ctx, *fsmo_role_dn, "fSMORoleOwner", role_owner_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Naming Master object - %s", + ldb_errstring(ldb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + break; + case DREPL_INFRASTRUCTURE_MASTER: + *fsmo_role_dn = samdb_infrastructure_dn(ldb, tmp_ctx); + ret = samdb_reference_dn(ldb, tmp_ctx, *fsmo_role_dn, "fSMORoleOwner", role_owner_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Schema Master object - %s", + ldb_errstring(ldb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + break; + case DREPL_RID_MASTER: + ret = samdb_rid_manager_dn(ldb, tmp_ctx, fsmo_role_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0, (__location__ ": Failed to find RID Manager object - %s", ldb_errstring(ldb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + + ret = samdb_reference_dn(ldb, tmp_ctx, *fsmo_role_dn, "fSMORoleOwner", role_owner_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in RID Manager object - %s", + ldb_errstring(ldb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + break; + case DREPL_SCHEMA_MASTER: + *fsmo_role_dn = ldb_get_schema_basedn(ldb); + ret = samdb_reference_dn(ldb, tmp_ctx, *fsmo_role_dn, "fSMORoleOwner", role_owner_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Schema Master object - %s", + ldb_errstring(ldb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + break; + case DREPL_PDC_MASTER: + *fsmo_role_dn = ldb_get_default_basedn(ldb); + ret = samdb_reference_dn(ldb, tmp_ctx, *fsmo_role_dn, "fSMORoleOwner", role_owner_dn); + if (ret != LDB_SUCCESS) { + DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Pd Master object - %s", + ldb_errstring(ldb))); + talloc_free(tmp_ctx); + return WERR_DS_DRA_INTERNAL_ERROR; + } + break; + default: + return WERR_DS_DRA_INTERNAL_ERROR; + } + return WERR_OK; +} + +const char *samdb_dn_to_dnshostname(struct ldb_context *ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *server_dn) +{ + int ldb_ret; + struct ldb_result *res = NULL; + const char * const attrs[] = { "dNSHostName", NULL}; + + ldb_ret = ldb_search(ldb, mem_ctx, &res, + server_dn, + LDB_SCOPE_BASE, + attrs, NULL); + if (ldb_ret != LDB_SUCCESS) { + DEBUG(4, ("Failed to find dNSHostName for dn %s, ldb error: %s", + ldb_dn_get_linearized(server_dn), ldb_errstring(ldb))); + return NULL; + } + + return samdb_result_string(res->msgs[0], "dNSHostName", NULL); +} diff --git a/source4/dsdb/pydsdb.c b/source4/dsdb/pydsdb.c index 5ba69d7388..7f2e71550c 100644 --- a/source4/dsdb/pydsdb.c +++ b/source4/dsdb/pydsdb.c @@ -534,6 +534,30 @@ static PyObject *py_dsdb_get_partitions_dn(PyObject *self, PyObject *args) } +/* + call into samdb_rodc() + */ +static PyObject *py_dsdb_am_rodc(PyObject *self, PyObject *args) +{ + PyObject *py_ldb; + struct ldb_context *ldb; + int ret; + bool am_rodc; + + if (!PyArg_ParseTuple(args, "O", &py_ldb)) + return NULL; + + PyErr_LDB_OR_RAISE(py_ldb, ldb); + + ret = samdb_rodc(ldb, &am_rodc); + if (samdb_rodc(ldb, &am_rodc) != LDB_SUCCESS) { + PyErr_SetString(PyExc_RuntimeError, ldb_errstring(ldb)); + return NULL; + } + + return PyBool_FromLong(am_rodc); +} + static PyMethodDef py_dsdb_methods[] = { { "_samdb_server_site_name", (PyCFunction)py_samdb_server_site_name, @@ -573,6 +597,9 @@ static PyMethodDef py_dsdb_methods[] = { { "_dsdb_set_am_rodc", (PyCFunction)py_dsdb_set_am_rodc, METH_VARARGS, NULL }, + { "_am_rodc", + (PyCFunction)py_dsdb_am_rodc, METH_VARARGS, + NULL }, { "_dsdb_set_schema_from_ldif", (PyCFunction)py_dsdb_set_schema_from_ldif, METH_VARARGS, NULL }, { "_dsdb_set_schema_from_ldb", (PyCFunction)py_dsdb_set_schema_from_ldb, METH_VARARGS, diff --git a/source4/dsdb/repl/drepl_fsmo.c b/source4/dsdb/repl/drepl_fsmo.c index 375e37b517..ad655f77b9 100644 --- a/source4/dsdb/repl/drepl_fsmo.c +++ b/source4/dsdb/repl/drepl_fsmo.c @@ -6,6 +6,7 @@ Copyright (C) Nadezhda Ivanova 2010 Copyright (C) Andrew Tridgell 2010 Copyright (C) Andrew Bartlett 2010 + Copyright (C) Anatoliy Atanasov 2010 based on drepl_ridalloc.c @@ -62,76 +63,31 @@ WERROR dreplsrv_fsmo_role_check(struct dreplsrv_service *service, { struct ldb_dn *role_owner_dn, *fsmo_role_dn, *ntds_dn; TALLOC_CTX *tmp_ctx = talloc_new(service); - struct ldb_context *ldb = service->samdb; - int ret; uint64_t fsmo_info = 0; enum drsuapi_DsExtendedOperation extended_op = DRSUAPI_EXOP_NONE; WERROR werr; - ntds_dn = samdb_ntds_settings_dn(ldb); + ntds_dn = samdb_ntds_settings_dn(service->samdb); if (!ntds_dn) { return WERR_DS_DRA_INTERNAL_ERROR; } + werr = dsdb_get_fsmo_role_info(tmp_ctx, service->samdb, role, + &fsmo_role_dn, &role_owner_dn); + if (!W_ERROR_IS_OK(werr)) { + return werr; + } + switch (role) { case DREPL_NAMING_MASTER: - fsmo_role_dn = samdb_partitions_dn(ldb, tmp_ctx), - ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); - if (ret != LDB_SUCCESS) { - DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Naming Master object - %s", - ldb_errstring(ldb))); - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } - break; case DREPL_INFRASTRUCTURE_MASTER: - fsmo_role_dn = samdb_infrastructure_dn(ldb, tmp_ctx); - ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); - if (ret != LDB_SUCCESS) { - DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Schema Master object - %s", - ldb_errstring(ldb))); - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } + case DREPL_SCHEMA_MASTER: extended_op = DRSUAPI_EXOP_FSMO_REQ_ROLE; break; case DREPL_RID_MASTER: - ret = samdb_rid_manager_dn(ldb, tmp_ctx, &fsmo_role_dn); - if (ret != LDB_SUCCESS) { - DEBUG(0, (__location__ ": Failed to find RID Manager object - %s", ldb_errstring(ldb))); - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } - - ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); - if (ret != LDB_SUCCESS) { - DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in RID Manager object - %s", - ldb_errstring(ldb))); - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } extended_op = DRSUAPI_EXOP_FSMO_RID_REQ_ROLE; break; - case DREPL_SCHEMA_MASTER: - fsmo_role_dn = ldb_get_schema_basedn(ldb); - ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); - if (ret != LDB_SUCCESS) { - DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Schema Master object - %s", - ldb_errstring(ldb))); - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } - extended_op = DRSUAPI_EXOP_FSMO_REQ_ROLE; - break; case DREPL_PDC_MASTER: - fsmo_role_dn = ldb_get_default_basedn(ldb); - ret = samdb_reference_dn(ldb, tmp_ctx, fsmo_role_dn, "fSMORoleOwner", &role_owner_dn); - if (ret != LDB_SUCCESS) { - DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in Pd Master object - %s", - ldb_errstring(ldb))); - talloc_free(tmp_ctx); - return WERR_DS_DRA_INTERNAL_ERROR; - } extended_op = DRSUAPI_EXOP_FSMO_REQ_PDC; break; default: diff --git a/source4/dsdb/repl/replicated_objects.c b/source4/dsdb/repl/replicated_objects.c index 838dc84655..0beb53c2f3 100644 --- a/source4/dsdb/repl/replicated_objects.c +++ b/source4/dsdb/repl/replicated_objects.c @@ -197,7 +197,7 @@ WERROR dsdb_convert_object_ex(struct ldb_context *ldb, } WERROR dsdb_extended_replicated_objects_convert(struct ldb_context *ldb, - const char *partition_dn, + const char *partition_dn_str, const struct drsuapi_DsReplicaOIDMapping_Ctr *mapping_ctr, uint32_t object_count, const struct drsuapi_DsReplicaObjectListItemEx *first_object, @@ -210,6 +210,7 @@ WERROR dsdb_extended_replicated_objects_convert(struct ldb_context *ldb, struct dsdb_extended_replicated_objects **objects) { WERROR status; + struct ldb_dn *partition_dn; const struct dsdb_schema *schema; struct dsdb_extended_replicated_objects *out; const struct drsuapi_DsReplicaObjectListItemEx *cur; @@ -226,14 +227,24 @@ WERROR dsdb_extended_replicated_objects_convert(struct ldb_context *ldb, return WERR_DS_SCHEMA_NOT_LOADED; } - status = dsdb_schema_pfm_contains_drsuapi_pfm(schema->prefixmap, mapping_ctr); - if (!W_ERROR_IS_OK(status)) { - talloc_free(out); - return status; + partition_dn = ldb_dn_new(out, ldb, partition_dn_str); + W_ERROR_HAVE_NO_MEMORY_AND_FREE(partition_dn, out); + + if (ldb_dn_compare(partition_dn, ldb_get_schema_basedn(ldb)) != 0) { + /* + * check for schema changes in case + * we are not replicating Schema NC + */ + status = dsdb_schema_info_cmp(schema, mapping_ctr); + if (!W_ERROR_IS_OK(status)) { + DEBUG(1,("Remote schema has changed while replicating %s\n", + partition_dn_str)); + talloc_free(out); + return status; + } } - out->partition_dn = ldb_dn_new(out, ldb, partition_dn); - W_ERROR_HAVE_NO_MEMORY(out->partition_dn); + out->partition_dn = partition_dn; out->source_dsa = source_dsa; out->uptodateness_vector= uptodateness_vector; @@ -242,7 +253,7 @@ WERROR dsdb_extended_replicated_objects_convert(struct ldb_context *ldb, out->objects = talloc_array(out, struct dsdb_extended_replicated_object, out->num_objects); - W_ERROR_HAVE_NO_MEMORY(out->objects); + W_ERROR_HAVE_NO_MEMORY_AND_FREE(out->objects, out); /* pass the linked attributes down to the repl_meta_data module */ diff --git a/source4/dsdb/samdb/cracknames.c b/source4/dsdb/samdb/cracknames.c index 63fe34552d..e642984171 100644 --- a/source4/dsdb/samdb/cracknames.c +++ b/source4/dsdb/samdb/cracknames.c @@ -39,12 +39,14 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, - uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, + uint32_t format_flags, enum drsuapi_DsNameFormat format_offered, + enum drsuapi_DsNameFormat format_desired, struct ldb_dn *name_dn, const char *name, const char *domain_filter, const char *result_filter, struct drsuapi_DsNameInfo1 *info1); static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, - uint32_t format_offered, uint32_t format_desired, + enum drsuapi_DsNameFormat format_offered, + enum drsuapi_DsNameFormat format_desired, struct ldb_dn *name_dn, const char *name, struct drsuapi_DsNameInfo1 *info1); @@ -177,7 +179,8 @@ static enum drsuapi_DsNameStatus LDB_lookup_spn_alias(krb5_context context, stru static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, - uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, + uint32_t format_flags, enum drsuapi_DsNameFormat format_offered, + enum drsuapi_DsNameFormat format_desired, const char *name, struct drsuapi_DsNameInfo1 *info1) { WERROR wret; @@ -262,7 +265,8 @@ static WERROR DsCrackNameSPNAlias(struct ldb_context *sam_ctx, TALLOC_CTX *mem_c static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, - uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, + uint32_t format_flags, enum drsuapi_DsNameFormat format_offered, + enum drsuapi_DsNameFormat format_desired, const char *name, struct drsuapi_DsNameInfo1 *info1) { int ldb_ret; @@ -348,7 +352,8 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, /* Crack a single 'name', from format_offered into format_desired, returning the result in info1 */ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, - uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, + uint32_t format_flags, enum drsuapi_DsNameFormat format_offered, + enum drsuapi_DsNameFormat format_desired, const char *name, struct drsuapi_DsNameInfo1 *info1) { krb5_error_code ret; @@ -678,7 +683,8 @@ WERROR DsCrackNameOneName(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, * database */ static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, - uint32_t format_offered, uint32_t format_desired, + enum drsuapi_DsNameFormat format_offered, + enum drsuapi_DsNameFormat format_desired, struct ldb_dn *name_dn, const char *name, struct drsuapi_DsNameInfo1 *info1) { @@ -717,7 +723,8 @@ static WERROR DsCrackNameOneSyntactical(TALLOC_CTX *mem_ctx, static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, - uint32_t format_flags, uint32_t format_offered, uint32_t format_desired, + uint32_t format_flags, enum drsuapi_DsNameFormat format_offered, + enum drsuapi_DsNameFormat format_desired, struct ldb_dn *name_dn, const char *name, const char *domain_filter, const char *result_filter, struct drsuapi_DsNameInfo1 *info1) @@ -872,6 +879,8 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ return DsCrackNameUPN(sam_ctx, mem_ctx, smb_krb5_context, format_flags, format_offered, format_desired, name, info1); + default: + break; } info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND; return WERR_OK; @@ -894,6 +903,8 @@ static WERROR DsCrackNameOneFilter(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ case DRSUAPI_DS_NAME_FORMAT_CANONICAL_EX: canonical_name = ldb_dn_canonical_ex_string(mem_ctx, result_res[i]->dn); break; + default: + break; } if (strcasecmp_m(canonical_name, name) == 0) { result = result_res[i]; @@ -1208,7 +1219,7 @@ NTSTATUS crack_service_principal_name(struct ldb_context *sam_ctx, NTSTATUS crack_name_to_nt4_name(TALLOC_CTX *mem_ctx, struct tevent_context *ev_ctx, struct loadparm_context *lp_ctx, - uint32_t format_offered, + enum drsuapi_DsNameFormat format_offered, const char *name, const char **nt4_domain, const char **nt4_account) { @@ -1275,7 +1286,7 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx, const char **nt4_domain, const char **nt4_account) { - uint32_t format_offered = DRSUAPI_DS_NAME_FORMAT_UNKNOWN; + enum drsuapi_DsNameFormat format_offered = DRSUAPI_DS_NAME_FORMAT_UNKNOWN; /* Handle anonymous bind */ if (!name || !*name) { @@ -1298,3 +1309,76 @@ NTSTATUS crack_auto_name_to_nt4_name(TALLOC_CTX *mem_ctx, return crack_name_to_nt4_name(mem_ctx, ev_ctx, lp_ctx, format_offered, name, nt4_domain, nt4_account); } + + +WERROR dcesrv_drsuapi_ListRoles(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, + const struct drsuapi_DsNameRequest1 *req1, + struct drsuapi_DsNameCtr1 **ctr1) +{ + struct drsuapi_DsNameInfo1 *names; + uint32_t i; + uint32_t count = 5;/*number of fsmo role owners we are going to return*/ + + *ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1); + W_ERROR_HAVE_NO_MEMORY(*ctr1); + names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count); + W_ERROR_HAVE_NO_MEMORY(names); + + for (i = 0; i < count; i++) { + WERROR werr; + struct ldb_dn *role_owner_dn, *fsmo_role_dn, *server_dn; + werr = dsdb_get_fsmo_role_info(mem_ctx, sam_ctx, i, + &fsmo_role_dn, &role_owner_dn); + if(!W_ERROR_IS_OK(werr)) { + return werr; + } + server_dn = ldb_dn_copy(mem_ctx, role_owner_dn); + ldb_dn_remove_child_components(server_dn, 1); + names[i].status = DRSUAPI_DS_NAME_STATUS_OK; + names[i].dns_domain_name = samdb_dn_to_dnshostname(sam_ctx, mem_ctx, + server_dn); + if(!names[i].dns_domain_name) { + DEBUG(4, ("list_roles: Failed to find dNSHostName for server %s", + ldb_dn_get_linearized(server_dn))); + } + names[i].result_name = talloc_strdup(mem_ctx, ldb_dn_get_linearized(role_owner_dn)); + } + + (*ctr1)->count = count; + (*ctr1)->array = names; + + return WERR_OK; +} + +WERROR dcesrv_drsuapi_CrackNamesByNameFormat(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx, + const struct drsuapi_DsNameRequest1 *req1, + struct drsuapi_DsNameCtr1 **ctr1) +{ + struct drsuapi_DsNameInfo1 *names; + uint32_t i, count; + WERROR status; + + *ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1); + W_ERROR_HAVE_NO_MEMORY(*ctr1); + + count = req1->count; + names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count); + W_ERROR_HAVE_NO_MEMORY(names); + + for (i=0; i < count; i++) { + status = DsCrackNameOneName(sam_ctx, mem_ctx, + req1->format_flags, + req1->format_offered, + req1->format_desired, + req1->names[i].str, + &names[i]); + if (!W_ERROR_IS_OK(status)) { + return status; + } + } + + (*ctr1)->count = count; + (*ctr1)->array = names; + + return WERR_OK; +} diff --git a/source4/dsdb/samdb/ldb_modules/rootdse.c b/source4/dsdb/samdb/ldb_modules/rootdse.c index 2e7c97af38..b84621f9ee 100644 --- a/source4/dsdb/samdb/ldb_modules/rootdse.c +++ b/source4/dsdb/samdb/ldb_modules/rootdse.c @@ -492,6 +492,35 @@ static int rootdse_callback(struct ldb_request *req, struct ldb_reply *ares) return LDB_SUCCESS; } +/* + mark our registered controls as non-critical in the request + + This is needed as clients may mark controls as critical even if they + are not needed at all in a request. For example, the centrify client + sets the SD_FLAGS control as critical on ldap modify requests which + are setting the dNSHostName attribute on the machine account. That + request doesn't need SD_FLAGS at all, but centrify adds it on all + ldap requests. + */ +static void rootdse_mark_noncritical(struct ldb_module *module, struct ldb_control **controls) +{ + int i, j; + struct private_data *priv = talloc_get_type(ldb_module_get_private(module), struct private_data); + + if (!controls) return; + + for (i=0; controls[i]; i++) { + if (controls[i]->critical == 0) { + continue; + } + for (j=0; j<priv->num_controls; j++) { + if (strcasecmp(priv->controls[j], controls[i]->oid) == 0) { + controls[i]->critical = 0; + } + } + } +} + static int rootdse_search(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb; @@ -499,6 +528,8 @@ static int rootdse_search(struct ldb_module *module, struct ldb_request *req) struct ldb_request *down_req; int ret; + rootdse_mark_noncritical(module, req->controls); + ldb = ldb_module_get_ctx(module); /* see if its for the rootDSE - only a base search on the "" DN qualifies */ @@ -963,6 +994,8 @@ static int rootdse_add(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); + rootdse_mark_noncritical(module, req->controls); + /* If dn is not "" we should let it pass through */ @@ -1013,6 +1046,8 @@ static int rootdse_modify(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); + rootdse_mark_noncritical(module, req->controls); + /* If dn is not "" we should let it pass through */ @@ -1054,6 +1089,8 @@ static int rootdse_delete(struct ldb_module *module, struct ldb_request *req) { struct ldb_context *ldb = ldb_module_get_ctx(module); + rootdse_mark_noncritical(module, req->controls); + /* If dn is not "" we should let it pass through */ diff --git a/source4/dsdb/schema/schema_info_attr.c b/source4/dsdb/schema/schema_info_attr.c index a9c5e932a1..0b5d50b529 100644 --- a/source4/dsdb/schema/schema_info_attr.c +++ b/source4/dsdb/schema/schema_info_attr.c @@ -70,6 +70,28 @@ WERROR dsdb_schema_info_blob_new(TALLOC_CTX *mem_ctx, DATA_BLOB *_schema_info_bl /** + * Verify the 'blob' is a valid schemaInfo blob + */ +bool dsdb_schema_info_blob_is_valid(const DATA_BLOB *blob) +{ + if (!blob || !blob->data) { + return false; + } + + /* schemaInfo blob must be 21 bytes long */ + if (blob->length != 21) { + return false; + } + + /* schemaInfo blob should start with 0xFF */ + if (blob->data[0] != 0xFF) { + return false; + } + + return true; +} + +/** * Parse schemaInfo structure from a data_blob * (DATA_BLOB or ldb_val). * Suitable for parsing blobs that comes from @@ -83,16 +105,8 @@ WERROR dsdb_schema_info_from_blob(const DATA_BLOB *blob, struct dsdb_schema_info *schema_info; struct schemaInfoBlob schema_info_blob; - if (!blob || !blob->data) { - return WERR_INVALID_PARAMETER; - } - - if (blob->length != 21) { - return WERR_INVALID_PARAMETER; - } - - /* schemaInfo blob should start with 0xFF */ - if (blob->data[0] != 0xFF) { + /* verify schemaInfo blob is valid */ + if (!dsdb_schema_info_blob_is_valid(blob)) { return WERR_INVALID_PARAMETER; } @@ -150,6 +164,47 @@ WERROR dsdb_blob_from_schema_info(const struct dsdb_schema_info *schema_info, return WERR_OK; } +/** + * Compares schemaInfo signatures in dsdb_schema and prefixMap. + * NOTE: At present function compares schemaInfo values + * as string without taking into account schemVersion field + * + * @return WERR_OK if schemaInfos are equal + * WERR_DS_DRA_SCHEMA_MISMATCH if schemaInfos are different + */ +WERROR dsdb_schema_info_cmp(const struct dsdb_schema *schema, + const struct drsuapi_DsReplicaOIDMapping_Ctr *ctr) +{ + bool bres; + DATA_BLOB blob; + char *schema_info_str; + struct drsuapi_DsReplicaOIDMapping *mapping; + + /* we should have at least schemaInfo element */ + if (ctr->num_mappings < 1) { + return WERR_INVALID_PARAMETER; + } + + /* verify schemaInfo element is valid */ + mapping = &ctr->mappings[ctr->num_mappings - 1]; + if (mapping->id_prefix != 0) { + return WERR_INVALID_PARAMETER; + } + + blob = data_blob_const(mapping->oid.binary_oid, mapping->oid.length); + if (!dsdb_schema_info_blob_is_valid(&blob)) { + return WERR_INVALID_PARAMETER; + } + + schema_info_str = hex_encode_talloc(NULL, blob.data, blob.length); + W_ERROR_HAVE_NO_MEMORY(schema_info_str); + + bres = strequal(schema->schema_info, schema_info_str); + talloc_free(schema_info_str); + + return bres ? WERR_OK : WERR_DS_DRA_SCHEMA_MISMATCH; +} + /** * Reads schema_info structure from schemaInfo diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c index a95e7ec2af..ba12f523e8 100644 --- a/source4/dsdb/schema/schema_init.c +++ b/source4/dsdb/schema/schema_init.c @@ -113,20 +113,17 @@ WERROR dsdb_load_oid_mappings_ldb(struct dsdb_schema *schema, WERROR werr; const char *schema_info; struct dsdb_schema_prefixmap *pfm; - struct dsdb_schema_info *schi; TALLOC_CTX *mem_ctx; + /* verify schemaInfo blob is valid one */ + if (!dsdb_schema_info_blob_is_valid(schemaInfo)) { + DEBUG(0,(__location__": dsdb_schema_info_blob_is_valid() failed.\n")); + return WERR_INVALID_PARAMETER; + } + mem_ctx = talloc_new(schema); W_ERROR_HAVE_NO_MEMORY(mem_ctx); - /* parse schemaInfo blob to verify it is valid */ - werr = dsdb_schema_info_from_blob(schemaInfo, mem_ctx, &schi); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(0, (__location__ " dsdb_schema_info_from_blob failed: %s\n", win_errstr(werr))); - talloc_free(mem_ctx); - return werr; - } - /* fetch prefixMap */ werr = _dsdb_prefixmap_from_ldb_val(prefixMap, mem_ctx, &pfm); diff --git a/source4/dsdb/schema/schema_prefixmap.c b/source4/dsdb/schema/schema_prefixmap.c index 50f74b7161..79894fe272 100644 --- a/source4/dsdb/schema/schema_prefixmap.c +++ b/source4/dsdb/schema/schema_prefixmap.c @@ -188,6 +188,7 @@ static WERROR _dsdb_pfm_make_binary_oid(const char *full_oid, TALLOC_CTX *mem_ct /* encode oid in BER format */ if (!ber_write_OID_String(mem_ctx, _bin_oid, full_oid)) { + DEBUG(0,("ber_write_OID_String() failed for %s\n", full_oid)); return WERR_INTERNAL_ERROR; } @@ -341,7 +342,9 @@ WERROR dsdb_schema_pfm_oid_from_attid(struct dsdb_schema_prefixmap *pfm, uint32_ } if (!pfm_entry) { - return WERR_INTERNAL_ERROR; + DEBUG(1,("Failed to find prefixMap entry for ATTID = 0x%08X (%d)\n", + attid, attid)); + return WERR_DS_NO_ATTRIBUTE_OR_VALUE; } /* copy oid prefix making enough room */ @@ -363,6 +366,8 @@ WERROR dsdb_schema_pfm_oid_from_attid(struct dsdb_schema_prefixmap *pfm, uint32_ } if (!ber_read_OID_String(mem_ctx, bin_oid, _oid)) { + DEBUG(0,("ber_read_OID_String() failed for %s\n", + hex_encode_talloc(bin_oid.data, bin_oid.data, bin_oid.length))); werr = WERR_INTERNAL_ERROR; } @@ -394,7 +399,6 @@ static WERROR _dsdb_drsuapi_pfm_verify(const struct drsuapi_DsReplicaOIDMapping_ if (have_schema_info) { DATA_BLOB blob; - struct dsdb_schema_info *schi = NULL; if (ctr->num_mappings < 2) { return WERR_INVALID_PARAMETER; @@ -406,10 +410,9 @@ static WERROR _dsdb_drsuapi_pfm_verify(const struct drsuapi_DsReplicaOIDMapping_ return WERR_INVALID_PARAMETER; } - /* parse schemaInfo blob to verify it is valid */ + /* verify schemaInfo blob is valid one */ blob = data_blob_const(mapping->oid.binary_oid, mapping->oid.length); - if (!W_ERROR_IS_OK(dsdb_schema_info_from_blob(&blob, talloc_autofree_context(), &schi))) { - talloc_free(schi); + if (!dsdb_schema_info_blob_is_valid(&blob)) { return WERR_INVALID_PARAMETER; } diff --git a/source4/lib/registry/pyregistry.c b/source4/lib/registry/pyregistry.c index 7f4f8333c6..1373ed87ca 100644 --- a/source4/lib/registry/pyregistry.c +++ b/source4/lib/registry/pyregistry.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 + Copyright (C) Wilco Baan Hofman <wilco@baanhofman.nl> 2010 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 @@ -238,16 +239,53 @@ static PyMethodDef hive_key_methods[] = { { NULL } }; -static PyObject *hive_open(PyTypeObject *type, PyObject *args, PyObject *kwargs) -{ - /* reg_open_hive */ +static PyObject *hive_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) { Py_RETURN_NONE; } +static PyObject *py_open_hive(PyTypeObject *type, PyObject *args, PyObject *kwargs) +{ + const char *kwnames[] = { "location", "lp_ctx", "session_info", "credentials", NULL }; + WERROR result; + struct loadparm_context *lp_ctx; + PyObject *py_lp_ctx, *py_session_info, *py_credentials; + struct auth_session_info *session_info; + struct cli_credentials *credentials; + char *location; + struct hive_key *hive_key; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|OOO", + discard_const_p(char *, kwnames), + &location, + &py_lp_ctx, &py_session_info, + &py_credentials)) + return NULL; + + lp_ctx = lpcfg_from_py_object(NULL, py_lp_ctx); /* FIXME: leaky */ + if (lp_ctx == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected loadparm context"); + return NULL; + } + + credentials = cli_credentials_from_py_object(py_credentials); + if (credentials == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected credentials"); + return NULL; + } + session_info = NULL; + + result = reg_open_hive(NULL, location, session_info, credentials, + tevent_context_init(NULL), + lp_ctx, &hive_key); + PyErr_WERROR_IS_ERR_RAISE(result); + + return py_talloc_steal(&PyHiveKey, hive_key); +} + PyTypeObject PyHiveKey = { .tp_name = "HiveKey", .tp_methods = hive_key_methods, - .tp_new = hive_open, + .tp_new = hive_new, .tp_basicsize = sizeof(py_talloc_Object), .tp_dealloc = py_talloc_dealloc, .tp_flags = Py_TPFLAGS_DEFAULT, @@ -396,6 +434,7 @@ static PyMethodDef py_registry_methods[] = { { "open_directory", py_open_directory, METH_VARARGS, "open_dir(location) -> key" }, { "create_directory", py_create_directory, METH_VARARGS, "create_dir(location) -> key" }, { "open_ldb", (PyCFunction)py_open_ldb_file, METH_VARARGS|METH_KEYWORDS, "open_ldb(location, session_info=None, credentials=None, loadparm_context=None) -> key" }, + { "open_hive", (PyCFunction)py_open_hive, METH_VARARGS|METH_KEYWORDS, "open_hive(location, session_info=None, credentials=None, loadparm_context=None) -> key" }, { "str_regtype", py_str_regtype, METH_VARARGS, "str_regtype(int) -> str" }, { "get_predef_name", py_get_predef_name, METH_VARARGS, "get_predef_name(hkey) -> str" }, { NULL } diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index cfbaaddf54..b62109ed57 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -110,7 +110,7 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) hbin = hbin_by_offset(data, offset, &rel_offset); if (hbin == NULL) { - DEBUG(1, ("Can't find HBIN containing 0x%04x\n", offset)); + DEBUG(1, ("Can't find HBIN at 0x%04x\n", offset)); return ret; } @@ -216,6 +216,8 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, if (data->hbins[i] == NULL) { DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", size)); + + /* Add extra hbin block */ data->hbins = talloc_realloc(data, data->hbins, struct hbin_block *, i+2); hbin = talloc(data->hbins, struct hbin_block); @@ -224,17 +226,22 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, data->hbins[i] = hbin; data->hbins[i+1] = NULL; + /* Set hbin data */ hbin->HBIN_ID = talloc_strdup(hbin, "hbin"); hbin->offset_from_first = (i == 0?0:data->hbins[i-1]->offset_from_first+data->hbins[i-1]->offset_to_next); hbin->offset_to_next = 0x1000; hbin->unknown[0] = 0; - hbin->unknown[0] = 0; + hbin->unknown[1] = 0; unix_to_nt_time(&hbin->last_change, time(NULL)); hbin->block_size = hbin->offset_to_next; hbin->data = talloc_zero_array(hbin, uint8_t, hbin->block_size - 0x20); + /* Update the regf header */ + data->header->last_block += hbin->offset_to_next; - rel_offset = 0x0; + /* Set the next block to it's proper size and set the + * rel_offset for this block */ SIVAL(hbin->data, size, hbin->block_size - size - 0x20); + rel_offset = 0x0; } /* Set size and mark as used */ @@ -314,7 +321,7 @@ static void hbin_free (struct regf_data *data, uint32_t offset) size = -size; /* If the next block is free, merge into big free block */ - if (rel_offset + size < hbin->offset_to_next) { + if (rel_offset + size < hbin->offset_to_next - 0x20) { next_size = IVALS(hbin->data, rel_offset+size); if (next_size > 0) { size += next_size; @@ -489,7 +496,7 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { - DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); + DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n", offset)); return NULL; } @@ -519,7 +526,8 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key, tmp = hbin_get(regf, private_data->nk->values_offset); if (!tmp.data) { - DEBUG(0, ("Unable to find value list\n")); + DEBUG(0, ("Unable to find value list at 0x%x\n", + private_data->nk->values_offset)); return WERR_GENERAL_FAILURE; } @@ -534,7 +542,7 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, struct hive_key *key, if (!hbin_get_tdr(regf, vk_offset, vk, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { - DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); + DEBUG(0, ("Unable to get VK block at 0x%x\n", vk_offset)); talloc_free(vk); return WERR_GENERAL_FAILURE; } @@ -606,9 +614,15 @@ static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, if (idx >= nk->num_subkeys) return WERR_NO_MORE_ITEMS; + /* Make sure that we don't crash if the key is empty */ + if (nk->subkeys_offset == -1) { + return WERR_NO_MORE_ITEMS; + } + data = hbin_get(private_data->hive, nk->subkeys_offset); if (!data.data) { - DEBUG(0, ("Unable to find subkey list\n")); + DEBUG(0, ("Unable to find subkey list at 0x%x\n", + nk->subkeys_offset)); return WERR_GENERAL_FAILURE; } @@ -845,6 +859,11 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, struct nk_block *nk = private_data->nk; uint32_t key_off = 0; + /* Make sure that we don't crash if the key is empty */ + if (nk->subkeys_offset == -1) { + return WERR_BADFILE; + } + data = hbin_get(private_data->hive, nk->subkeys_offset); if (!data.data) { DEBUG(0, ("Unable to find subkey list\n")); @@ -1739,7 +1758,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, if (!hbin_get_tdr(regf, regf->header->data_offset, root, (tdr_pull_fn_t)tdr_pull_nk_block, root)) { - DEBUG(0, ("Unable to find HBIN data for offset %d\n", + DEBUG(0, ("Unable to find HBIN data for offset 0x%x\n", regf->header->data_offset)); return WERR_GENERAL_FAILURE; } @@ -1764,6 +1783,7 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, *ret = (struct hive_key *)regf_get_key(ctx, regf, offset); + DEBUG(9, ("Storing key %s\n", name)); return regf_save_hbin(private_data->hive); } @@ -1789,7 +1809,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, if (!hbin_get_tdr(regf, tmp_vk_offset, private_data, (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { - DEBUG(0, ("Unable to get VK block at %d\n", + DEBUG(0, ("Unable to get VK block at 0x%x\n", tmp_vk_offset)); return WERR_GENERAL_FAILURE; } diff --git a/source4/lib/registry/regf.idl b/source4/lib/registry/regf.idl index fd58ad2d61..064aaf09ce 100644 --- a/source4/lib/registry/regf.idl +++ b/source4/lib/registry/regf.idl @@ -74,8 +74,8 @@ interface regf }; [noprint] enum reg_key_type { - REG_ROOT_KEY = 0x20, - REG_SUB_KEY = 0x2C, + REG_ROOT_KEY = 0x2C, + REG_SUB_KEY = 0x20, REG_SYM_LINK = 0x10 }; diff --git a/source4/libcli/finddcs_cldap.c b/source4/libcli/finddcs_cldap.c index 33e31a9cf7..b7a8324c0f 100644 --- a/source4/libcli/finddcs_cldap.c +++ b/source4/libcli/finddcs_cldap.c @@ -36,6 +36,7 @@ struct finddcs_cldap_state { struct tevent_req *req; const char *domain_name; struct dom_sid *domain_sid; + const char *srv_name; const char **srv_addresses; uint32_t minimum_dc_flags; uint32_t srv_address_index; @@ -112,18 +113,17 @@ static bool finddcs_cldap_srv_lookup(struct finddcs_cldap_state *state, struct resolve_context *resolve_ctx, struct tevent_context *event_ctx) { - const char *srv_name; struct composite_context *creq; struct nbt_name name; if (io->in.site_name) { - srv_name = talloc_asprintf(state, "_ldap._tcp.%s._sites.%s", + state->srv_name = talloc_asprintf(state, "_ldap._tcp.%s._sites.%s", io->in.site_name, io->in.domain_name); } else { - srv_name = talloc_asprintf(state, "_ldap._tcp.%s", io->in.domain_name); + state->srv_name = talloc_asprintf(state, "_ldap._tcp.%s", io->in.domain_name); } - make_nbt_name(&name, srv_name, 0); + make_nbt_name(&name, state->srv_name, 0); creq = resolve_name_ex_send(resolve_ctx, state, RESOLVE_NAME_FLAG_FORCE_DNS | RESOLVE_NAME_FLAG_DNS_SRV, @@ -167,6 +167,7 @@ static void finddcs_cldap_next_server(struct finddcs_cldap_state *state) if (state->srv_addresses[state->srv_address_index] == NULL) { tevent_req_nterror(state->req, NT_STATUS_OBJECT_NAME_NOT_FOUND); + DEBUG(2,("finddcs: No matching CLDAP server found\n")); return; } @@ -247,9 +248,12 @@ static void finddcs_cldap_name_resolved(struct composite_context *ctx) status = resolve_name_recv(ctx, state, &address); if (tevent_req_nterror(state->req, status)) { + DEBUG(2,("finddcs: No matching NBT <1c> server found\n")); return; } + DEBUG(4,("finddcs: Found NBT <1c> server at %s\n", address)); + state->srv_addresses = talloc_array(state, const char *, 2); if (tevent_req_nomem(state->srv_addresses, state->req)) { return; @@ -279,6 +283,7 @@ static void finddcs_cldap_srv_resolved(struct composite_context *ctx) status = resolve_name_multiple_recv(ctx, state, &state->srv_addresses); if (tevent_req_nterror(state->req, status)) { + DEBUG(2,("finddcs: Failed to find SRV record for %s\n", state->srv_name)); return; } diff --git a/source4/libnet/libnet_lookup.c b/source4/libnet/libnet_lookup.c index 3677c2a31e..6b8ab6edd4 100644 --- a/source4/libnet/libnet_lookup.c +++ b/source4/libnet/libnet_lookup.c @@ -195,10 +195,7 @@ struct tevent_req *libnet_LookupDCs_send(struct libnet_context *ctx, struct finddcs finddcs_io; ZERO_STRUCT(finddcs_io); - finddcs_io.in.domain_name = lpcfg_realm(ctx->lp_ctx); - if (strcmp(finddcs_io.in.domain_name, "") == 0) { - finddcs_io.in.domain_name = lpcfg_workgroup(ctx->lp_ctx); - } + finddcs_io.in.domain_name = io->in.domain_name; finddcs_io.in.minimum_dc_flags = NBT_SERVER_LDAP | NBT_SERVER_DS | NBT_SERVER_WRITABLE; diff --git a/source4/librpc/idl/winbind.idl b/source4/librpc/idl/winbind.idl index 849b8166a7..f9bccb87c5 100644 --- a/source4/librpc/idl/winbind.idl +++ b/source4/librpc/idl/winbind.idl @@ -47,4 +47,9 @@ interface winbind [in,out] [size_is(count)] id_map ids[] ); + NTSTATUS winbind_DsrUpdateReadOnlyServerDnsRecords( + [in,unique] [string,charset(UTF16)] uint16 *site_name, + [in] uint32 dns_ttl, + [in,out,ref] NL_DNS_NAME_INFO_ARRAY *dns_names + ); } diff --git a/source4/librpc/rpc/pyrpc.h b/source4/librpc/rpc/pyrpc.h index fb5f35fcf1..c3bc83877c 100644 --- a/source4/librpc/rpc/pyrpc.h +++ b/source4/librpc/rpc/pyrpc.h @@ -24,7 +24,7 @@ #define PY_CHECK_TYPE(type, var, fail) \ if (!PyObject_TypeCheck(var, type)) {\ - PyErr_Format(PyExc_TypeError, "Expected type %s for %s", (type)->tp_name, #var); \ + PyErr_Format(PyExc_TypeError, __location__ ": Expected type '%s' for '%s' of type '%s'", (type)->tp_name, #var, Py_TYPE(var)->tp_name); \ fail; \ } @@ -42,4 +42,14 @@ typedef struct { struct dcerpc_binding_handle *binding_handle; } dcerpc_InterfaceObject; + +/* + these prototypes should be generated by the python pidl backend, but + aren't yet. They are needed when one module that has python access + is accessed by another module + */ +union netr_LogonLevel *py_export_netr_LogonLevel(TALLOC_CTX *mem_ctx, int level, PyObject *in); +union netr_Validation; +PyObject *py_import_netr_Validation(TALLOC_CTX *mem_ctx, int level, union netr_Validation *in); + #endif /* _PYRPC_H_ */ diff --git a/source4/librpc/rpc/pyrpc_util.c b/source4/librpc/rpc/pyrpc_util.c index f3911eeb9a..ba42c08154 100644 --- a/source4/librpc/rpc/pyrpc_util.c +++ b/source4/librpc/rpc/pyrpc_util.c @@ -28,6 +28,8 @@ #include "param/pyparam.h" #include "auth/credentials/pycredentials.h" #include "lib/events/events.h" +#include "lib/messaging/messaging.h" +#include "lib/messaging/irpc.h" #ifndef Py_TYPE /* Py_TYPE is only available on Python > 2.6 */ #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) @@ -65,7 +67,31 @@ bool py_check_dcerpc_type(PyObject *obj, const char *module, const char *typenam return ret; } -PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, const struct ndr_interface_table *table) +/* + connect to a IRPC pipe from python + */ +static NTSTATUS pyrpc_irpc_connect(TALLOC_CTX *mem_ctx, const char *irpc_server, + const struct ndr_interface_table *table, + struct tevent_context *event_ctx, + struct loadparm_context *lp_ctx, + struct dcerpc_binding_handle **binding_handle) +{ + struct messaging_context *msg; + + msg = messaging_client_init(mem_ctx, lpcfg_messaging_path(mem_ctx, lp_ctx), event_ctx); + NT_STATUS_HAVE_NO_MEMORY(msg); + + *binding_handle = irpc_binding_handle_by_name(mem_ctx, msg, irpc_server, table); + if (*binding_handle == NULL) { + talloc_free(msg); + return NT_STATUS_INVALID_PIPE_STATE; + } + + return NT_STATUS_OK; +} + +PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, PyObject *kwargs, + const struct ndr_interface_table *table) { dcerpc_InterfaceObject *ret; const char *binding_string; @@ -103,18 +129,17 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py talloc_free(mem_ctx); return NULL; } - credentials = cli_credentials_from_py_object(py_credentials); - if (credentials == NULL) { - PyErr_SetString(PyExc_TypeError, "Expected credentials"); - talloc_free(mem_ctx); - return NULL; - } + ret = PyObject_New(dcerpc_InterfaceObject, type); ret->mem_ctx = mem_ctx; event_ctx = s4_event_context_init(ret->mem_ctx); - if (py_basis != Py_None) { + if (strncmp(binding_string, "irpc:", 5) == 0) { + ret->pipe = NULL; + status = pyrpc_irpc_connect(ret->mem_ctx, binding_string+5, table, + event_ctx, lp_ctx, &ret->binding_handle); + } else if (py_basis != Py_None) { struct dcerpc_pipe *base_pipe; PyObject *py_base; PyTypeObject *ClientConnection_Type; @@ -144,6 +169,12 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py ret->pipe = talloc_steal(ret->mem_ctx, ret->pipe); } else { + credentials = cli_credentials_from_py_object(py_credentials); + if (credentials == NULL) { + PyErr_SetString(PyExc_TypeError, "Expected credentials"); + talloc_free(mem_ctx); + return NULL; + } status = dcerpc_pipe_connect(event_ctx, &ret->pipe, binding_string, table, credentials, event_ctx, lp_ctx); } @@ -153,8 +184,10 @@ PyObject *py_dcerpc_interface_init_helper(PyTypeObject *type, PyObject *args, Py return NULL; } - ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC; - ret->binding_handle = ret->pipe->binding_handle; + if (ret->pipe) { + ret->pipe->conn->flags |= DCERPC_NDR_REF_ALLOC; + ret->binding_handle = ret->pipe->binding_handle; + } return (PyObject *)ret; } diff --git a/source4/librpc/wscript_build b/source4/librpc/wscript_build index 06bd8a7794..65e8260ab4 100755 --- a/source4/librpc/wscript_build +++ b/source4/librpc/wscript_build @@ -764,6 +764,18 @@ bld.SAMBA_PYTHON('python_irpc', realname='samba/dcerpc/irpc.so' ) +bld.SAMBA_PYTHON('python_winbind', + source='gen_ndr/py_winbind.c', + deps='RPC_NDR_WINBIND PYTALLOC pyrpc_util python_netlogon', + realname='samba/dcerpc/winbind.so' + ) + +bld.SAMBA_PYTHON('python_idmap', + source='../../librpc/gen_ndr/py_idmap.c', + deps='NDR_IDMAP PYTALLOC pyrpc_util', + realname='samba/dcerpc/idmap.so' + ) + bld.SAMBA_PYTHON('python_drsuapi', source='../../librpc/gen_ndr/py_drsuapi.c', diff --git a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c index 16c19cdd3e..2299714c2d 100644 --- a/source4/rpc_server/drsuapi/dcesrv_drsuapi.c +++ b/source4/rpc_server/drsuapi/dcesrv_drsuapi.c @@ -406,14 +406,12 @@ static WERROR dcesrv_drsuapi_DsGetNT4ChangeLog(struct dcesrv_call_state *dce_cal DRSUAPI_UNSUPPORTED(drsuapi_DsGetNT4ChangeLog); } - /* drsuapi_DsCrackNames */ static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct drsuapi_DsCrackNames *r) { - WERROR status; struct drsuapi_bind_state *b_state; struct dcesrv_handle *h; @@ -427,37 +425,36 @@ static WERROR dcesrv_drsuapi_DsCrackNames(struct dcesrv_call_state *dce_call, TA switch (r->in.level) { case 1: { - struct drsuapi_DsNameCtr1 *ctr1; - struct drsuapi_DsNameInfo1 *names; - uint32_t i, count; - - ctr1 = talloc(mem_ctx, struct drsuapi_DsNameCtr1); - W_ERROR_HAVE_NO_MEMORY(ctr1); - - count = r->in.req->req1.count; - names = talloc_array(mem_ctx, struct drsuapi_DsNameInfo1, count); - W_ERROR_HAVE_NO_MEMORY(names); - - for (i=0; i < count; i++) { - status = DsCrackNameOneName(b_state->sam_ctx, mem_ctx, - r->in.req->req1.format_flags, - r->in.req->req1.format_offered, - r->in.req->req1.format_desired, - r->in.req->req1.names[i].str, - &names[i]); - if (!W_ERROR_IS_OK(status)) { - return status; - } + switch(r->in.req->req1.format_offered){ + case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID: + case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX: + case DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS: + case DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON: + case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE: + case DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME: + case DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME: + case DRSUAPI_DS_NAME_FORMAT_LIST_NCS: + case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS: + case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID: + case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN: + case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER: + case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE: + case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE: + case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE: + case DRSUAPI_DS_NAME_FORMAT_LIST_SITES: + DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X", + r->in.req->req1.format_offered)); + return WERR_OK; + case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES: + return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx, + &r->in.req->req1, &r->out.ctr->ctr1); + default:/* format_offered is in the enum drsuapi_DsNameFormat*/ + return dcesrv_drsuapi_CrackNamesByNameFormat(b_state->sam_ctx, mem_ctx, + &r->in.req->req1, &r->out.ctr->ctr1); } - - ctr1->count = count; - ctr1->array = names; - r->out.ctr->ctr1 = ctr1; - return WERR_OK; } } - return WERR_UNKNOWN_LEVEL; } diff --git a/source4/scripting/bin/samba_dnsupdate b/source4/scripting/bin/samba_dnsupdate index b295224ddc..d3abcb1052 100755 --- a/source4/scripting/bin/samba_dnsupdate +++ b/source4/scripting/bin/samba_dnsupdate @@ -36,17 +36,20 @@ from samba import getopt as options from ldb import SCOPE_BASE from samba.auth import system_session from samba.samdb import SamDB +from samba.dcerpc import netlogon, winbind samba.ensure_external_module("dns", "dnspython") import dns.resolver as resolver default_ttl = 900 +am_rodc = False parser = optparse.OptionParser("samba_dnsupdate") sambaopts = options.SambaOptions(parser) parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) parser.add_option("--verbose", action="store_true") +parser.add_option("--all-names", action="store_true") parser.add_option("--all-interfaces", action="store_true") parser.add_option("--use-file", type="string", help="Use a file, rather than real DNS calls") @@ -75,7 +78,8 @@ if len(IPs) == 0: print "No IP interfaces - skipping DNS updates" sys.exit(0) - +if opts.verbose: + print "IPs: %s" % IPs ######################################################## # get credentials if we haven't got them already @@ -189,19 +193,22 @@ def check_dns_name(d): ########################################### # get the list of substitution vars def get_subst_vars(): - global lp + global lp, am_rodc vars = {} samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), lp=lp) vars['DNSDOMAIN'] = lp.get('realm').lower() + vars['DNSFOREST'] = lp.get('realm').lower() vars['HOSTNAME'] = lp.get('netbios name').lower() + "." + vars['DNSDOMAIN'] vars['NTDSGUID'] = samdb.get_ntds_GUID() vars['SITE'] = samdb.server_site_name() res = samdb.search(base=None, scope=SCOPE_BASE, attrs=["objectGUID"]) guid = samdb.schema_format_value("objectGUID", res[0]['objectGUID'][0]) vars['DOMAINGUID'] = guid + am_rodc = samdb.am_rodc() + return vars @@ -241,6 +248,75 @@ def call_nsupdate(d): os.unlink(tmpfile) + +def rodc_dns_update(d, t): + '''a single DNS update via the RODC netlogon call''' + global sub_vars + + if opts.verbose: + print "Calling netlogon RODC update for %s" % d + + typemap = { + netlogon.NlDnsLdapAtSite : netlogon.NlDnsInfoTypeNone, + netlogon.NlDnsGcAtSite : netlogon.NlDnsDomainNameAlias, + netlogon.NlDnsDsaCname : netlogon.NlDnsDomainNameAlias, + netlogon.NlDnsKdcAtSite : netlogon.NlDnsInfoTypeNone, + netlogon.NlDnsDcAtSite : netlogon.NlDnsInfoTypeNone, + netlogon.NlDnsRfc1510KdcAtSite : netlogon.NlDnsInfoTypeNone, + netlogon.NlDnsGenericGcAtSite : netlogon.NlDnsDomainNameAlias + } + + w = winbind.winbind("irpc:winbind_server", lp) + dns_names = netlogon.NL_DNS_NAME_INFO_ARRAY() + dns_names.count = 1 + name = netlogon.NL_DNS_NAME_INFO() + name.type = t + name.dns_domain_info_type = typemap[t] + name.priority = 0 + name.weight = 0 + if d.port is not None: + name.port = int(d.port) + name.dns_register = True + dns_names.names = [ name ] + site_name = sub_vars['SITE'].decode('utf-8') + + try: + ret_names = w.DsrUpdateReadOnlyServerDnsRecords(site_name, default_ttl, dns_names) + if ret_names.names[0].status != 0: + print("Failed to set DNS entry: %s (status %u)" % (d, ret_names.names[0].status)) + except RuntimeError, reason: + print("Error setting DNS entry of type %u: %s: %s" % (t, d, reason)) + + +def call_rodc_update(d): + '''RODCs need to use the netlogon API for nsupdate''' + global lp, sub_vars + + # we expect failure for 3268 if we aren't a GC + if d.port is not None and int(d.port) == 3268: + return + + # map the DNS request to a netlogon update type + map = { + netlogon.NlDnsLdapAtSite : '_ldap._tcp.${SITE}._sites.${DNSDOMAIN}', + netlogon.NlDnsGcAtSite : '_ldap._tcp.${SITE}._sites.gc._msdcs.${DNSDOMAIN}', + netlogon.NlDnsDsaCname : '${NTDSGUID}._msdcs.${DNSFOREST}', + netlogon.NlDnsKdcAtSite : '_kerberos._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN}', + netlogon.NlDnsDcAtSite : '_ldap._tcp.${SITE}._sites.dc._msdcs.${DNSDOMAIN}', + netlogon.NlDnsRfc1510KdcAtSite : '_kerberos._tcp.${SITE}._sites.${DNSDOMAIN}', + netlogon.NlDnsGenericGcAtSite : '_gc._tcp.${SITE}._sites.${DNSFOREST}' + } + + for t in map: + subname = samba.substitute_var(map[t], sub_vars) + if subname.lower() == d.name.lower(): + # found a match - do the update + rodc_dns_update(d, t) + return + if opts.verbose: + print("Unable to map to netlogon DNS update: %s" % d) + + # get the list of DNS entries we should have dns_update_list = lp.private_path('dns_update_list') @@ -273,7 +349,7 @@ for d in dns_list: # now check if the entries already exist on the DNS server for d in dns_list: - if not check_dns_name(d): + if opts.all_names or not check_dns_name(d): update_list.append(d) if len(update_list) == 0: @@ -286,7 +362,10 @@ get_credentials(lp) # ask nsupdate to add entries as needed for d in update_list: - call_nsupdate(d) + if am_rodc: + call_rodc_update(d) + else: + call_nsupdate(d) # delete the ccache if we created it if ccachename is not None: diff --git a/source4/scripting/devel/getncchanges b/source4/scripting/devel/getncchanges index 7656c22ea4..99f14eafe9 100755 --- a/source4/scripting/devel/getncchanges +++ b/source4/scripting/devel/getncchanges @@ -54,6 +54,7 @@ def do_DsBind(drs): if __name__ == "__main__": parser = OptionParser("getncchanges [options] server") sambaopts = options.SambaOptions(parser) + parser.add_option_group(sambaopts) credopts = options.CredentialsOptionsDouble(parser) parser.add_option_group(credopts) diff --git a/source4/scripting/devel/ldapcmp b/source4/scripting/devel/ldapcmp index 76b4e8eec6..edf37d36d0 100755 --- a/source4/scripting/devel/ldapcmp +++ b/source4/scripting/devel/ldapcmp @@ -518,13 +518,10 @@ class LDAPBundel(object): if __name__ == "__main__": parser = OptionParser("ldapcmp [options] domain|configuration|schema") sambaopts = options.SambaOptions(parser) + parser.add_option_group(sambaopts) credopts = options.CredentialsOptionsDouble(parser) parser.add_option_group(credopts) - lp = sambaopts.get_loadparm() - creds = credopts.get_credentials(lp) - creds2 = credopts.get_credentials2(lp) - parser.add_option("", "--host", dest="host", help="IP of the first LDAP server",) parser.add_option("", "--host2", dest="host2", @@ -537,6 +534,15 @@ if __name__ == "__main__": help="Print all DN pairs that have been compared",) (opts, args) = parser.parse_args() + lp = sambaopts.get_loadparm() + creds = credopts.get_credentials(lp) + creds2 = credopts.get_credentials2(lp) + if creds2.is_anonymous(): + creds2 = creds + + if creds.is_anonymous(): + parser.error("You must supply at least one username/password pair") + if not (len(args) == 1 and args[0].upper() in ["DOMAIN", "CONFIGURATION", "SCHEMA"]): parser.error("Incorrect arguments") diff --git a/source4/scripting/devel/rodcdns b/source4/scripting/devel/rodcdns new file mode 100755 index 0000000000..bd24342ab8 --- /dev/null +++ b/source4/scripting/devel/rodcdns @@ -0,0 +1,43 @@ +#!/usr/bin/env python + +# script to call a netlogon RODC DNS update + +import sys +from optparse import OptionParser + +sys.path.insert(0, "bin/python") + +import samba +import samba.getopt as options +from samba.dcerpc import netlogon, winbind + +########### main code ########### +if __name__ == "__main__": + parser = OptionParser("rodcdns [options]") + sambaopts = options.SambaOptions(parser) + + parser.add_option("", "--weight", dest="weight", help="record weight", default=0, type='int') + parser.add_option("", "--priority", dest="priority", help="record priority", default=100, type='int') + parser.add_option("", "--port", dest="port", help="port number", default=389, type='int') + parser.add_option("", "--type", dest="type", help="record type", default=netlogon.NlDnsLdapAtSite, type='int') + parser.add_option("", "--site", dest="site", help="site name", default="Default-First-Site-Name") + + (opts, args) = parser.parse_args() + + lp = sambaopts.get_loadparm() + + w = winbind.winbind("irpc:winbind_server", lp) + + dns_names = netlogon.NL_DNS_NAME_INFO_ARRAY() + dns_names.count = 1 + name = netlogon.NL_DNS_NAME_INFO() + name.type = opts.type + name.priority = opts.priority + name.weight = opts.weight + name.port = opts.port + name.dns_register = True + dns_names.names = [ name ] + site_name = opts.site.decode('utf-8') + + ret_names = w.DsrUpdateReadOnlyServerDnsRecords(site_name, 600, dns_names) + print("Status: %u" % ret_names.names[0].status) diff --git a/source4/scripting/python/samba/join.py b/source4/scripting/python/samba/join.py index 2cb1e3da0b..679dc5bf99 100644 --- a/source4/scripting/python/samba/join.py +++ b/source4/scripting/python/samba/join.py @@ -69,6 +69,8 @@ def join_rodc(server=None, creds=None, lp=None, site=None, netbios_name=None, def find_dc(ctx, domain): '''find a writeable DC for the given domain''' ctx.cldap_ret = ctx.net.finddc(domain, nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS | nbt.NBT_SERVER_WRITABLE) + if ctx.cldap_ret.client_site is not None and ctx.cldap_ret.client_site != "": + ctx.site = ctx.cldap_ret.client_site return ctx.cldap_ret.pdc_dns_name; diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index e2ac37a240..bbc52a9ebd 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -40,7 +40,7 @@ class SamDB(samba.Ldb): def __init__(self, url=None, lp=None, modules_dir=None, session_info=None, credentials=None, flags=0, options=None, global_schema=True, - auto_connect=True, am_rodc=False): + auto_connect=True, am_rodc=None): self.lp = lp if not auto_connect: url = None @@ -54,7 +54,8 @@ class SamDB(samba.Ldb): if global_schema: dsdb._dsdb_set_global_schema(self) - dsdb._dsdb_set_am_rodc(self, am_rodc) + if am_rodc is not None: + dsdb._dsdb_set_am_rodc(self, am_rodc) def connect(self, url=None, flags=0, options=None): if self.lp is not None: @@ -63,6 +64,9 @@ class SamDB(samba.Ldb): super(SamDB, self).connect(url=url, flags=flags, options=options) + def am_rodc(self): + return dsdb._am_rodc(self) + def domain_dn(self): # find the DNs for the domain res = self.search(base="", diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c index c9148d1915..7b96e1c093 100644 --- a/source4/torture/basic/base.c +++ b/source4/torture/basic/base.c @@ -680,13 +680,13 @@ static bool run_deferopen(struct torture_context *tctx, struct smbcli_state *cli torture_comment(tctx, "pid %u open %d\n", (unsigned)getpid(), i); - msleep(10 * msec); + smb_msleep(10 * msec); i++; if (NT_STATUS_IS_ERR(smbcli_close(cli->tree, fnum))) { torture_comment(tctx,"Failed to close %s, error=%s\n", fname, smbcli_errstr(cli->tree)); return false; } - msleep(2 * msec); + smb_msleep(2 * msec); } if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fname))) { diff --git a/source4/torture/basic/delaywrite.c b/source4/torture/basic/delaywrite.c index 0c43c29cad..f82b32fe8d 100644 --- a/source4/torture/basic/delaywrite.c +++ b/source4/torture/basic/delaywrite.c @@ -111,7 +111,7 @@ static bool test_delayed_write_update(struct torture_context *tctx, struct smbcl break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) { @@ -162,7 +162,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc /* 3 second delay to ensure we get past any 2 second time granularity (older systems may have that) */ - msleep(3 * msec); + smb_msleep(3 * msec); finfo1.all_info.level = RAW_FILEINFO_ALL_INFO; finfo1.all_info.in.file.fnum = fnum1; @@ -180,7 +180,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc /* 3 second delay to ensure we get past any 2 second time granularity (older systems may have that) */ - msleep(3 * msec); + smb_msleep(3 * msec); /* Do a zero length SMBwrite call to truncate. */ written = smbcli_smbwrite(cli->tree, fnum1, "x", 1024, 0); @@ -231,7 +231,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) { @@ -241,7 +241,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc } fflush(stdout); - msleep(2 * msec); + smb_msleep(2 * msec); /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */ written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1); @@ -282,7 +282,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) { @@ -292,7 +292,7 @@ static bool test_delayed_write_update1(struct torture_context *tctx, struct smbc } fflush(stdout); - msleep(2 * msec); + smb_msleep(2 * msec); /* the close should trigger an write time update */ smbcli_close(cli->tree, fnum1); @@ -353,7 +353,7 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb /* 3 second delay to ensure we get past any 2 second time granularity (older systems may have that) */ - msleep(3 * msec); + smb_msleep(3 * msec); finfo1.all_info.level = RAW_FILEINFO_ALL_INFO; finfo1.all_info.in.file.fnum = fnum1; @@ -418,7 +418,7 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) { @@ -428,7 +428,7 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb } fflush(stdout); - msleep(2 * msec); + smb_msleep(2 * msec); /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */ written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1); @@ -467,7 +467,7 @@ static bool test_delayed_write_update1a(struct torture_context *tctx, struct smb break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) { @@ -535,7 +535,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb /* 3 second delay to ensure we get past any 2 second time granularity (older systems may have that) */ - msleep(3 * msec); + smb_msleep(3 * msec); finfo1.all_info.level = RAW_FILEINFO_ALL_INFO; finfo1.all_info.in.file.fnum = fnum1; @@ -596,7 +596,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) { @@ -606,7 +606,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb } fflush(stdout); - msleep(2 * msec); + smb_msleep(2 * msec); /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */ written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1); @@ -644,7 +644,7 @@ static bool test_delayed_write_update1b(struct torture_context *tctx, struct smb break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) { @@ -710,7 +710,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb /* 3 second delay to ensure we get past any 2 second time granularity (older systems may have that) */ - msleep(3 * msec); + smb_msleep(3 * msec); finfo1.all_info.level = RAW_FILEINFO_ALL_INFO; finfo1.all_info.in.file.fnum = fnum1; @@ -776,7 +776,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo1.all_info.out.write_time == finfo2.all_info.out.write_time) { @@ -786,7 +786,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb } fflush(stdout); - msleep(2 * msec); + smb_msleep(2 * msec); /* Do a non-zero length SMBwrite and make sure it doesn't update the write time. */ written = smbcli_smbwrite(cli->tree, fnum1, "x", 0, 1); @@ -822,7 +822,7 @@ static bool test_delayed_write_update1c(struct torture_context *tctx, struct smb break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo2.all_info.out.write_time != finfo3.all_info.out.write_time) { @@ -900,7 +900,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc /* 3 second delay to ensure we get past any 2 second time granularity (older systems may have that) */ - msleep(3 * msec); + smb_msleep(3 * msec); { /* Try using setfileinfo instead of write to update write time. */ @@ -1007,7 +1007,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) { @@ -1015,7 +1015,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc } fflush(stdout); - msleep(2 * msec); + smb_msleep(2 * msec); fnum2 = smbcli_open(cli->tree, fname, O_RDWR, DENY_NONE); if (fnum2 == -1) { @@ -1099,7 +1099,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc break; } fflush(stdout); - msleep(1 * msec); + smb_msleep(1 * msec); } if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) { @@ -1131,7 +1131,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc torture_comment(tctx, "Second open initial write time %s\n", nt_time_string(tctx, finfo1.basic_info.out.write_time)); - msleep(10 * msec); + smb_msleep(10 * msec); torture_comment(tctx, "Doing a 10 byte write to extend the file to see if this changes the last write time.\n"); written = smbcli_write(cli->tree, fnum1, 0, "0123456789", 31, 10); @@ -1187,7 +1187,7 @@ static bool test_delayed_write_update2(struct torture_context *tctx, struct smbc break; } fflush(stdout); - msleep(1*msec); + smb_msleep(1*msec); } if (finfo1.basic_info.out.write_time == finfo2.basic_info.out.write_time) { @@ -1258,7 +1258,7 @@ static bool test_finfo_after_write(struct torture_context *tctx, struct smbcli_s goto done; } - msleep(1 * msec); + smb_msleep(1 * msec); written = smbcli_write(cli->tree, fnum1, 0, "x", 0, 1); @@ -1573,7 +1573,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx, diff, sec); break; } - msleep(0.5 * msec); + smb_msleep(0.5 * msec); } GET_INFO_BOTH(finfo1,pinfo1); @@ -1602,7 +1602,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo2,pinfo2); @@ -1612,7 +1612,7 @@ static bool test_delayed_write_update3(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo3,pinfo3); COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); @@ -1699,7 +1699,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, * sleep some time, to demonstrate the handling of write times * doesn't depend on the time since the open */ - msleep(5 * msec); + smb_msleep(5 * msec); /* get the initial times */ GET_INFO_BOTH(finfo1,pinfo1); @@ -1739,20 +1739,20 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, diff, sec); break; } - msleep(0.5 * msec); + smb_msleep(0.5 * msec); } GET_INFO_BOTH(finfo1,pinfo1); COMPARE_WRITE_TIME_GREATER(pinfo1, pinfo0); - msleep(3 * msec); + smb_msleep(3 * msec); /* * demonstrate that a truncate write always * updates the write time immediately */ for (i=0; i < 3; i++) { - msleep(2 * msec); + smb_msleep(2 * msec); /* do a write */ torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); written = smbcli_smbwrite(cli->tree, fnum1, "x", 10240, 0); @@ -1767,7 +1767,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, finfo1 = finfo2; } - msleep(3 * msec); + smb_msleep(3 * msec); /* sure any further write doesn't update the write time */ start = timeval_current(); @@ -1792,7 +1792,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo2,pinfo2); @@ -1802,7 +1802,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, } /* sleep */ - msleep(3 * msec); + smb_msleep(3 * msec); /* get the initial times */ GET_INFO_BOTH(finfo1,pinfo1); @@ -1813,7 +1813,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, * updates the write time immediately */ for (i=0; i < 3; i++) { - msleep(2 * msec); + smb_msleep(2 * msec); /* do a write */ torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); @@ -1829,7 +1829,7 @@ static bool test_delayed_write_update3a(struct torture_context *tctx, } /* sleep */ - msleep(3 * msec); + smb_msleep(3 * msec); GET_INFO_BOTH(finfo3,pinfo3); COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); @@ -1914,7 +1914,7 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, * sleep some time, to demonstrate the handling of write times * doesn't depend on the time since the open */ - msleep(5 * msec); + smb_msleep(5 * msec); /* get the initial times */ GET_INFO_BOTH(finfo1,pinfo1); @@ -1954,7 +1954,7 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, diff, sec); break; } - msleep(0.5 * msec); + smb_msleep(0.5 * msec); } GET_INFO_BOTH(finfo1,pinfo1); @@ -1983,7 +1983,7 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo2,pinfo2); @@ -1993,7 +1993,7 @@ static bool test_delayed_write_update3b(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo3,pinfo3); COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); @@ -2082,7 +2082,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, * sleep some time, to demonstrate the handling of write times * doesn't depend on the time since the open */ - msleep(5 * msec); + smb_msleep(5 * msec); /* get the initial times */ GET_INFO_BOTH(finfo1,pinfo1); @@ -2093,7 +2093,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, * updates the write time immediately */ for (i=0; i < 3; i++) { - msleep(2 * msec); + smb_msleep(2 * msec); /* do a write */ torture_comment(tctx, "Do a truncate SMBwrite [%d] on the file handle\n", i); written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); @@ -2130,7 +2130,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo2,pinfo2); @@ -2140,7 +2140,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); /* get the initial times */ GET_INFO_BOTH(finfo1,pinfo1); @@ -2151,7 +2151,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, * updates the write time immediately */ for (i=0; i < 3; i++) { - msleep(2 * msec); + smb_msleep(2 * msec); /* do a write */ torture_comment(tctx, "Do a truncate write [%d] on the file handle\n", i); written = smbcli_smbwrite(cli->tree, fnum1, "x", 512, 0); @@ -2167,7 +2167,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo2,pinfo2); COMPARE_WRITE_TIME_EQUAL(finfo2, finfo1); @@ -2195,7 +2195,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo2,pinfo2); @@ -2205,7 +2205,7 @@ static bool test_delayed_write_update3c(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo3,pinfo3); COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); @@ -2289,7 +2289,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, GET_INFO_BOTH(finfo0,pinfo0); /* sleep a bit */ - msleep(5 * msec); + smb_msleep(5 * msec); /* do a write */ torture_comment(tctx, "Do a write on the file handle\n"); @@ -2329,7 +2329,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, diff, sec); break; } - msleep(0.5 * msec); + smb_msleep(0.5 * msec); } GET_INFO_BOTH(finfo1,pinfo1); @@ -2358,7 +2358,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo2,pinfo2); @@ -2368,7 +2368,7 @@ static bool test_delayed_write_update4(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo3,pinfo3); COMPARE_WRITE_TIME_EQUAL(finfo3, finfo2); @@ -2489,7 +2489,7 @@ static bool test_delayed_write_update5(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo3,pinfo3); @@ -2521,7 +2521,7 @@ static bool test_delayed_write_update5(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo4,pinfo4); @@ -2531,7 +2531,7 @@ static bool test_delayed_write_update5(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo5,pinfo5); COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4); @@ -2651,7 +2651,7 @@ static bool test_delayed_write_update5b(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo3,pinfo3); @@ -2683,7 +2683,7 @@ static bool test_delayed_write_update5b(struct torture_context *tctx, ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo4,pinfo4); @@ -2693,7 +2693,7 @@ static bool test_delayed_write_update5b(struct torture_context *tctx, } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo5,pinfo5); COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4); @@ -2830,7 +2830,7 @@ again: ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo3,pinfo3); @@ -2862,7 +2862,7 @@ again: ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } GET_INFO_BOTH(finfo4,pinfo4); @@ -2872,7 +2872,7 @@ again: } /* sleep */ - msleep(5 * msec); + smb_msleep(5 * msec); GET_INFO_BOTH(finfo5,pinfo5); COMPARE_WRITE_TIME_EQUAL(finfo5, finfo4); @@ -2898,7 +2898,7 @@ again: COMPARE_WRITE_TIME_EQUAL(finfo5, pinfo6); /* See if we have lost the sticky write time on handle2 */ - msleep(3 * msec); + smb_msleep(3 * msec); torture_comment(tctx, "Have we lost the sticky write time ?\n"); /* Make sure any further normal write doesn't update the write time */ @@ -2925,7 +2925,7 @@ again: ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } /* What about a truncate write ? */ @@ -2952,7 +2952,7 @@ again: ret = false; break; } - msleep(1 * msec); + smb_msleep(1 * msec); } diff --git a/source4/torture/basic/delete.c b/source4/torture/basic/delete.c index 22d92193b9..2b26b1e64a 100644 --- a/source4/torture/basic/delete.c +++ b/source4/torture/basic/delete.c @@ -1422,7 +1422,7 @@ static bool deltest21(struct torture_context *tctx) /* On slow build farm machines it might happen that they are not fast * enogh to delete the file for this test */ - msleep(200); + smb_msleep(200); /* File should not be there. */ fnum1 = smbcli_nt_create_full(cli1->tree, fname, 0, diff --git a/source4/torture/basic/disconnect.c b/source4/torture/basic/disconnect.c index 7f071178f4..2cfa72048e 100644 --- a/source4/torture/basic/disconnect.c +++ b/source4/torture/basic/disconnect.c @@ -162,7 +162,7 @@ bool torture_disconnect(struct torture_context *torture) * new process comes in. Try to get rid of the random * failures in the build farm. */ - msleep(200); + smb_msleep(200); } } diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 9ee2edfdd0..4e5c852df7 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -95,7 +95,7 @@ mkinclude libsmbclient/config.mk [SUBSYSTEM::TORTURE_NDR] PRIVATE_DEPENDENCIES = torture SERVICE_SMB -TORTURE_NDR_OBJ_FILES = $(addprefix $(torturesrcdir)/ndr/, ndr.o winreg.o atsvc.o lsa.o epmap.o dfs.o netlogon.o drsuapi.o spoolss.o samr.o dfsblob.o drsblobs.o nbt.o) +TORTURE_NDR_OBJ_FILES = $(addprefix $(torturesrcdir)/ndr/, ndr.o winreg.o atsvc.o lsa.o epmap.o dfs.o netlogon.o drsuapi.o spoolss.o samr.o dfsblob.o drsblobs.o nbt.o ntlmssp.o) $(eval $(call proto_header_template,$(torturesrcdir)/ndr/proto.h,$(TORTURE_NDR_OBJ_FILES:.o=.c))) diff --git a/source4/torture/drs/python/fsmo.py b/source4/torture/drs/python/fsmo.py index c64a0b2987..9b13275e18 100644 --- a/source4/torture/drs/python/fsmo.py +++ b/source4/torture/drs/python/fsmo.py @@ -148,6 +148,10 @@ class DrsFsmoTestCase(samba.tests.TestCase): self._role_transfer(role="rid", role_dn=self.rid_dn) pass + def test_NamingMasterTransfer(self): + self._role_transfer(role="naming", role_dn=self.naming_dn) + pass + ######################################################################################## def get_env_var(var_name): diff --git a/source4/torture/drs/unit/prefixmap_tests.c b/source4/torture/drs/unit/prefixmap_tests.c index a4521eb675..a954399771 100644 --- a/source4/torture/drs/unit/prefixmap_tests.c +++ b/source4/torture/drs/unit/prefixmap_tests.c @@ -394,8 +394,13 @@ static bool torture_drs_unit_pfm_oid_from_attid_check_attid(struct torture_conte const char *oid; /* Test with valid prefixMap attid */ - werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0x00000000, tctx, &oid); - torture_assert_werr_ok(tctx, werr, "Testing prefixMap type attid = 0x0000000"); + werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0x00010001, tctx, &oid); + torture_assert_werr_ok(tctx, werr, "Testing prefixMap type attid = 0x00010001"); + + /* Test with valid attid but invalid index */ + werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0x01110001, tctx, &oid); + torture_assert_werr_equal(tctx, werr, WERR_DS_NO_ATTRIBUTE_OR_VALUE, + "Testing invalid-index attid = 0x01110001"); /* Test with attid in msDS-IntId range */ werr = dsdb_schema_pfm_oid_from_attid(priv->pfm_full, 0x80000000, tctx, &oid); diff --git a/source4/torture/drs/unit/schemainfo_tests.c b/source4/torture/drs/unit/schemainfo_tests.c index 3958eb365b..e419ab0c49 100644 --- a/source4/torture/drs/unit/schemainfo_tests.c +++ b/source4/torture/drs/unit/schemainfo_tests.c @@ -297,6 +297,82 @@ static bool test_dsdb_blob_from_schema_info(struct torture_context *tctx, return true; } +static bool test_dsdb_schema_info_cmp(struct torture_context *tctx, + struct drsut_schemainfo_data *priv) +{ + DATA_BLOB blob; + struct drsuapi_DsReplicaOIDMapping_Ctr *ctr; + + ctr = talloc_zero(priv, struct drsuapi_DsReplicaOIDMapping_Ctr); + torture_assert(tctx, ctr, "Not enough memory!"); + + /* not enough elements */ + torture_assert_werr_equal(tctx, + dsdb_schema_info_cmp(priv->schema, ctr), + WERR_INVALID_PARAMETER, + "dsdb_schema_info_cmp(): unexpected result"); + + /* an empty element for schemaInfo */ + ctr->num_mappings = 1; + ctr->mappings = talloc_zero_array(ctr, struct drsuapi_DsReplicaOIDMapping, 1); + torture_assert(tctx, ctr->mappings, "Not enough memory!"); + torture_assert_werr_equal(tctx, + dsdb_schema_info_cmp(priv->schema, ctr), + WERR_INVALID_PARAMETER, + "dsdb_schema_info_cmp(): unexpected result"); + + /* test with invalid schemaInfo - length != 21 */ + blob = strhex_to_data_blob(ctr, "FF00000001FD821C07C7455143A3DB51F75A630A7F00"); + torture_assert(tctx, blob.data, "Not enough memory!"); + ctr->mappings[0].oid.length = blob.length; + ctr->mappings[0].oid.binary_oid = blob.data; + torture_assert_werr_equal(tctx, + dsdb_schema_info_cmp(priv->schema, ctr), + WERR_INVALID_PARAMETER, + "dsdb_schema_info_cmp(): unexpected result"); + + /* test with invalid schemaInfo - marker != 0xFF */ + blob = strhex_to_data_blob(ctr, "AA00000001FD821C07C7455143A3DB51F75A630A7F"); + torture_assert(tctx, blob.data, "Not enough memory!"); + ctr->mappings[0].oid.length = blob.length; + ctr->mappings[0].oid.binary_oid = blob.data; + torture_assert_werr_equal(tctx, + dsdb_schema_info_cmp(priv->schema, ctr), + WERR_INVALID_PARAMETER, + "dsdb_schema_info_cmp(): unexpected result"); + + /* test with valid schemaInfo, but not correct one */ + blob = strhex_to_data_blob(ctr, "FF0000000000000000000000000000000000000000"); + torture_assert(tctx, blob.data, "Not enough memory!"); + ctr->mappings[0].oid.length = blob.length; + ctr->mappings[0].oid.binary_oid = blob.data; + torture_assert_werr_equal(tctx, + dsdb_schema_info_cmp(priv->schema, ctr), + WERR_DS_DRA_SCHEMA_MISMATCH, + "dsdb_schema_info_cmp(): unexpected result"); + + /* test with correct schemaInfo, but invalid ATTID */ + blob = strhex_to_data_blob(ctr, priv->schema->schema_info); + torture_assert(tctx, blob.data, "Not enough memory!"); + ctr->mappings[0].id_prefix = 1; + ctr->mappings[0].oid.length = blob.length; + ctr->mappings[0].oid.binary_oid = blob.data; + torture_assert_werr_equal(tctx, + dsdb_schema_info_cmp(priv->schema, ctr), + WERR_INVALID_PARAMETER, + "dsdb_schema_info_cmp(): unexpected result"); + + /* test with valid schemaInfo */ + blob = strhex_to_data_blob(ctr, priv->schema->schema_info); + ctr->mappings[0].id_prefix = 0; + torture_assert_werr_ok(tctx, + dsdb_schema_info_cmp(priv->schema, ctr), + "dsdb_schema_info_cmp(): unexpected result"); + + talloc_free(ctr); + return true; +} + /* * Tests dsdb_module_schema_info_blob_read() * and dsdb_module_schema_info_blob_write() @@ -515,6 +591,9 @@ static bool torture_drs_unit_schemainfo_setup(struct torture_context *tctx, /* create schema mockup object */ priv->schema = dsdb_new_schema(priv); + /* set schema_info in dsdb_schema for testing */ + priv->schema->schema_info = talloc_strdup(priv->schema, SCHEMA_INFO_DEFAULT_STR); + /* pre-cache invocationId for samdb_ntds_invocation_id() * to work with our mock ldb */ ldb_err = ldb_set_opaque(priv->ldb, "cache.invocation_id", @@ -575,6 +654,8 @@ struct torture_tcase * torture_drs_unit_schemainfo(struct torture_suite *suite) (pfn_run)test_dsdb_schema_info_from_blob); torture_tcase_add_simple_test(tc, "dsdb_blob_from_schema_info", (pfn_run)test_dsdb_blob_from_schema_info); + torture_tcase_add_simple_test(tc, "dsdb_schema_info_cmp", + (pfn_run)test_dsdb_schema_info_cmp); torture_tcase_add_simple_test(tc, "dsdb_module_schema_info_blob read|write", (pfn_run)test_dsdb_module_schema_info_blob_rw); torture_tcase_add_simple_test(tc, "dsdb_module_schema_info_update", diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index 4fc05df3f4..6f69460dc8 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -1211,7 +1211,7 @@ static void check_pending(void) { int i, j; - msleep(20); + smb_msleep(20); for (j=0;j<NINSTANCES;j++) { for (i=0;i<NSERVERS;i++) { diff --git a/source4/torture/libnetapi/config.mk b/source4/torture/libnetapi/config.mk index 2ac506e1b2..0cd485e44a 100644 --- a/source4/torture/libnetapi/config.mk +++ b/source4/torture/libnetapi/config.mk @@ -12,6 +12,7 @@ PRIVATE_DEPENDENCIES = \ TORTURE_LIBNETAPI_OBJ_FILES = $(addprefix $(torturesrcdir)/libnetapi/, libnetapi.o \ libnetapi_user.o \ - libnetapi_group.o) + libnetapi_group.o + libnetapi_server.o) $(eval $(call proto_header_template,$(torturesrcdir)/libnetapi/proto.h,$(TORTURE_LIBNETAPI_OBJ_FILES:.o=.c))) diff --git a/source4/torture/libnetapi/libnetapi.c b/source4/torture/libnetapi/libnetapi.c index c3a27eba0c..6854bf8444 100644 --- a/source4/torture/libnetapi/libnetapi.c +++ b/source4/torture/libnetapi/libnetapi.c @@ -68,6 +68,7 @@ NTSTATUS torture_libnetapi_init(void) suite = torture_suite_create(talloc_autofree_context(), "NETAPI"); + torture_suite_add_simple_test(suite, "SERVER", torture_libnetapi_server); torture_suite_add_simple_test(suite, "GROUP", torture_libnetapi_group); torture_suite_add_simple_test(suite, "USER", torture_libnetapi_user); torture_suite_add_simple_test(suite, "INITIALIZE", torture_libnetapi_initialize); diff --git a/source4/torture/libnetapi/libnetapi_server.c b/source4/torture/libnetapi/libnetapi_server.c new file mode 100644 index 0000000000..1888009402 --- /dev/null +++ b/source4/torture/libnetapi/libnetapi_server.c @@ -0,0 +1,76 @@ +/* + Unix SMB/CIFS implementation. + SMB torture tester + Copyright (C) Guenther Deschner 2010 + + 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 "torture/smbtorture.h" +#include <netapi.h> +#include "torture/libnetapi/proto.h" + +#define NETAPI_STATUS(tctx, x,y,fn) \ + torture_warning(tctx, "FAILURE: line %d: %s failed with status: %s (%d)\n", \ + __LINE__, fn, libnetapi_get_error_string(x,y), y); + +bool torture_libnetapi_server(struct torture_context *tctx) +{ + NET_API_STATUS status = 0; + uint8_t *buffer = NULL; + int i; + + const char *hostname = torture_setting_string(tctx, "host", NULL); + struct libnetapi_ctx *ctx; + + torture_assert(tctx, torture_libnetapi_init_context(tctx, &ctx), + "failed to initialize libnetapi"); + + torture_comment(tctx, "NetServer tests\n"); + + torture_comment(tctx, "Testing NetRemoteTOD\n"); + + status = NetRemoteTOD(hostname, &buffer); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetRemoteTOD"); + goto out; + } + NetApiBufferFree(buffer); + + torture_comment(tctx, "Testing NetRemoteTOD 10 times\n"); + + for (i=0; i<10; i++) { + status = NetRemoteTOD(hostname, &buffer); + if (status) { + NETAPI_STATUS(tctx, ctx, status, "NetRemoteTOD"); + goto out; + } + NetApiBufferFree(buffer); + } + + status = 0; + + torture_comment(tctx, "NetServer tests succeeded\n"); + out: + if (status != 0) { + torture_comment(tctx, "NetServer testsuite failed with: %s\n", + libnetapi_get_error_string(ctx, status)); + libnetapi_free(ctx); + return false; + } + + libnetapi_free(ctx); + return true; +} diff --git a/source4/torture/libnetapi/wscript_build b/source4/torture/libnetapi/wscript_build index ddcc602f88..a087c96662 100644 --- a/source4/torture/libnetapi/wscript_build +++ b/source4/torture/libnetapi/wscript_build @@ -1,7 +1,7 @@ #!/usr/bin/env python bld.SAMBA_MODULE('TORTURE_LIBNETAPI', - source='libnetapi.c libnetapi_user.c libnetapi_group.c', + source='libnetapi.c libnetapi_user.c libnetapi_group.c libnetapi_server.c', autoproto='proto.h', subsystem='smbtorture', init_function='torture_libnetapi_init', diff --git a/source4/torture/nbench/nbio.c b/source4/torture/nbench/nbio.c index fa8155e2c3..ca186d007b 100644 --- a/source4/torture/nbench/nbio.c +++ b/source4/torture/nbench/nbio.c @@ -192,7 +192,7 @@ void nbio_target_rate(double rate) tdelay = (children[nbio_id].bytes - last_bytes)/(1.0e6*rate) - timeval_elapsed(&last_time); if (tdelay > 0) { - msleep(tdelay*1000); + smb_msleep(tdelay*1000); } else { children[nbio_id].max_latency = MAX(children[nbio_id].max_latency, -tdelay); } @@ -210,7 +210,7 @@ void nbio_time_delay(double targett) { double elapsed = timeval_elapsed(&children[nbio_id].starttime); if (targett > elapsed) { - msleep(1000*(targett - elapsed)); + smb_msleep(1000*(targett - elapsed)); } else if (elapsed - targett > children[nbio_id].max_latency) { children[nbio_id].max_latency = MAX(elapsed - targett, children[nbio_id].max_latency); } diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c index a0d4c23ae7..caa2d33ede 100644 --- a/source4/torture/nbt/winsreplication.c +++ b/source4/torture/nbt/winsreplication.c @@ -9599,7 +9599,7 @@ static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_ while (nbtsock->send_queue) { event_loop_once(nbtsock->event_ctx); } - msleep(1000); + smb_msleep(1000); rec->defend.timeout = 0; rec->defend.ret = true; @@ -9656,7 +9656,7 @@ static void test_conflict_owned_active_vs_replica_handler_release( while (nbtsock->send_queue) { event_loop_once(nbtsock->event_ctx); } - msleep(1000); + smb_msleep(1000); rec->defend.timeout = 0; rec->defend.ret = true; diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c index e13cb94bbd..8c2e7f8e45 100644 --- a/source4/torture/ndr/ndr.c +++ b/source4/torture/ndr/ndr.c @@ -353,6 +353,7 @@ struct torture_suite *torture_local_ndr(TALLOC_CTX *mem_ctx) torture_suite_add_suite(suite, ndr_samr_suite(suite)); torture_suite_add_suite(suite, ndr_drsblobs_suite(suite)); torture_suite_add_suite(suite, ndr_nbt_suite(suite)); + torture_suite_add_suite(suite, ndr_ntlmssp_suite(suite)); torture_suite_add_simple_test(suite, "string terminator", test_check_string_terminator); diff --git a/source4/torture/ndr/ntlmssp.c b/source4/torture/ndr/ntlmssp.c new file mode 100644 index 0000000000..b139fdf232 --- /dev/null +++ b/source4/torture/ndr/ntlmssp.c @@ -0,0 +1,119 @@ +/* + Unix SMB/CIFS implementation. + test suite for ntlmssp ndr operations + + Copyright (C) Guenther Deschner 2010 + + 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 "torture/ndr/ndr.h" +#include "librpc/gen_ndr/ndr_ntlmssp.h" + +static const uint8_t ntlmssp_NEGOTIATE_MESSAGE_data[] = { + 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x97, 0x82, 0x08, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x01, 0xb0, 0x1d, + 0x00, 0x00, 0x00, 0x0f +}; + +static bool ntlmssp_NEGOTIATE_MESSAGE_check(struct torture_context *tctx, + struct NEGOTIATE_MESSAGE *r) +{ + return true; +} + +static const uint8_t ntlmssp_CHALLENGE_MESSAGE_data[] = { + 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x0a, 0x00, 0x0a, 0x00, 0x38, 0x00, 0x00, 0x00, 0x95, 0x82, 0x89, 0xe2, + 0xed, 0xc8, 0x2b, 0x7d, 0x2e, 0xd7, 0xd0, 0xd9, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x78, 0x00, 0x42, 0x00, 0x00, 0x00, + 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x53, 0x00, 0x41, 0x00, + 0x4d, 0x00, 0x42, 0x00, 0x41, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x53, 0x00, + 0x41, 0x00, 0x4d, 0x00, 0x42, 0x00, 0x41, 0x00, 0x01, 0x00, 0x10, 0x00, + 0x4d, 0x00, 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x4c, 0x00, 0x45, 0x00, + 0x4e, 0x00, 0x41, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x62, 0x00, 0x65, 0x00, + 0x72, 0x00, 0x2e, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x68, 0x00, + 0x61, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, + 0x03, 0x00, 0x2e, 0x00, 0x6d, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, + 0x6c, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x2e, 0x00, 0x62, 0x00, + 0x65, 0x00, 0x72, 0x00, 0x2e, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, + 0x68, 0x00, 0x61, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, + 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static bool ntlmssp_CHALLENGE_MESSAGE_check(struct torture_context *tctx, + struct CHALLENGE_MESSAGE *r) +{ + return true; +} + +static const uint8_t ntlmssp_AUTHENTICATE_MESSAGE_data[] = { + 0x4e, 0x54, 0x4c, 0x4d, 0x53, 0x53, 0x50, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x18, 0x00, 0x18, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x0e, 0x01, + 0xa4, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x0e, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x1a, 0x00, 0x1a, 0x00, 0x66, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x0c, 0x00, + 0x80, 0x00, 0x00, 0x00, 0x10, 0x00, 0x10, 0x00, 0xb2, 0x01, 0x00, 0x00, + 0x15, 0x82, 0x88, 0xe2, 0x06, 0x01, 0xb0, 0x1d, 0x00, 0x00, 0x00, 0x0f, + 0x50, 0xe2, 0xb2, 0xa7, 0xf5, 0x83, 0x3e, 0xda, 0x71, 0xa7, 0xe8, 0x6e, + 0x95, 0x1e, 0x3a, 0x57, 0x57, 0x00, 0x32, 0x00, 0x4b, 0x00, 0x38, 0x00, + 0x44, 0x00, 0x4f, 0x00, 0x4d, 0x00, 0x41, 0x00, 0x64, 0x00, 0x6d, 0x00, + 0x69, 0x00, 0x6e, 0x00, 0x69, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, + 0x61, 0x00, 0x74, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x57, 0x00, 0x32, 0x00, + 0x4b, 0x00, 0x38, 0x00, 0x52, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0xcf, 0xfb, 0x39, + 0x5a, 0xb3, 0x4c, 0x58, 0x86, 0x35, 0xa3, 0xe7, 0x1e, 0x00, 0x98, 0x43, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96, 0x79, 0x02, 0x77, + 0x1e, 0x54, 0xcb, 0x01, 0x3c, 0x21, 0x0a, 0xe9, 0xde, 0x61, 0xc0, 0x7e, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x0a, 0x00, 0x53, 0x00, 0x41, 0x00, + 0x4d, 0x00, 0x42, 0x00, 0x41, 0x00, 0x01, 0x00, 0x10, 0x00, 0x4d, 0x00, + 0x54, 0x00, 0x48, 0x00, 0x45, 0x00, 0x4c, 0x00, 0x45, 0x00, 0x4e, 0x00, + 0x41, 0x00, 0x04, 0x00, 0x1c, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, + 0x2e, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x68, 0x00, 0x61, 0x00, + 0x74, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x03, 0x00, + 0x2e, 0x00, 0x6d, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, + 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x65, 0x00, + 0x72, 0x00, 0x2e, 0x00, 0x72, 0x00, 0x65, 0x00, 0x64, 0x00, 0x68, 0x00, + 0x61, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, + 0x08, 0x00, 0x30, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0a, 0xfd, 0x3b, 0x2c, + 0xad, 0x43, 0x46, 0x8b, 0x49, 0x01, 0x6c, 0xa5, 0xf3, 0xbc, 0xd2, 0x13, + 0xbb, 0x70, 0xe2, 0x65, 0x96, 0xba, 0x0d, 0x8d, 0x5d, 0x31, 0xe6, 0x47, + 0x94, 0x61, 0xed, 0x28, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x1a, 0x00, 0x63, 0x00, 0x69, 0x00, 0x66, 0x00, 0x73, 0x00, + 0x2f, 0x00, 0x6d, 0x00, 0x74, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6c, 0x00, + 0x65, 0x00, 0x6e, 0x00, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xa4, 0x23, 0xd4, 0x5c, 0x16, 0x52, 0x8d, 0x56, 0x34, 0x2d, + 0x1c, 0xff, 0x86, 0x17, 0xc9, 0x4f +}; + +static bool ntlmssp_AUTHENTICATE_MESSAGE_check(struct torture_context *tctx, + struct AUTHENTICATE_MESSAGE *r) +{ + return true; +} + +struct torture_suite *ndr_ntlmssp_suite(TALLOC_CTX *ctx) +{ + struct torture_suite *suite = torture_suite_create(ctx, "ntlmssp"); + + torture_suite_add_ndr_pull_fn_test(suite, NEGOTIATE_MESSAGE, ntlmssp_NEGOTIATE_MESSAGE_data, NDR_IN, ntlmssp_NEGOTIATE_MESSAGE_check); + /* torture_suite_add_ndr_pull_fn_test(suite, CHALLENGE_MESSAGE, ntlmssp_CHALLENGE_MESSAGE_data, NDR_IN, ntlmssp_CHALLENGE_MESSAGE_check); + torture_suite_add_ndr_pull_fn_test(suite, AUTHENTICATE_MESSAGE, ntlmssp_AUTHENTICATE_MESSAGE_data, NDR_IN, ntlmssp_AUTHENTICATE_MESSAGE_check); */ + + return suite; +} diff --git a/source4/torture/ndr/winreg.c b/source4/torture/ndr/winreg.c index ca3a71ed7d..b6da7bccd2 100644 --- a/source4/torture/ndr/winreg.c +++ b/source4/torture/ndr/winreg.c @@ -247,7 +247,7 @@ static bool querymultiplevalues_in_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->in.values_in[0].ve_valuename->length, 18, "name len"); torture_assert_int_equal(tctx, r->in.values_in[0].ve_valuename->size, 18, "name size"); torture_assert_int_equal(tctx, r->in.values_in[0].ve_valuelen, 0, "length"); - torture_assert(tctx, (r->in.values_in[0].ve_valueptr == NULL), "ve_valueptr"); + torture_assert_int_equal(tctx, r->in.values_in[0].ve_valueptr, 0, "ve_valueptr"); torture_assert_int_equal(tctx, r->in.values_in[0].ve_type, 0, "type"); torture_assert_int_equal(tctx, *r->in.buffer_size, 32, "buffer size"); @@ -303,7 +303,7 @@ static bool querymultiplevalues2_in_check(struct torture_context *tctx, torture_assert_int_equal(tctx, r->in.values_in[0].ve_valuename->length, 10, "name len"); torture_assert_int_equal(tctx, r->in.values_in[0].ve_valuename->size, 10, "name size"); torture_assert_int_equal(tctx, r->in.values_in[0].ve_valuelen, 0, "length"); - torture_assert(tctx, (r->in.values_in[0].ve_valueptr == NULL), "ve_valueptr"); + torture_assert_int_equal(tctx, r->in.values_in[0].ve_valueptr, 0, "ve_valueptr"); torture_assert_int_equal(tctx, r->in.values_in[0].ve_type, 0, "type"); torture_assert_int_equal(tctx, *r->in.offered, 0, "buffer size"); diff --git a/source4/torture/raw/notify.c b/source4/torture/raw/notify.c index 6fc005929c..7ccdbd7c76 100644 --- a/source4/torture/raw/notify.c +++ b/source4/torture/raw/notify.c @@ -144,7 +144,7 @@ static bool test_notify_dir(struct smbcli_state *cli, struct smbcli_state *cli2, smbcli_rmdir(cli2->tree, BASEDIR "\\subdir-name"); smbcli_mkdir(cli2->tree, BASEDIR "\\subdir-name"); smbcli_rmdir(cli2->tree, BASEDIR "\\subdir-name"); - msleep(200); + smb_msleep(200); req = smb_raw_changenotify_send(cli->tree, ¬ify); status = smb_raw_changenotify_recv(req, mem_ctx, ¬ify); CHECK_STATUS(status, NT_STATUS_OK); @@ -365,7 +365,7 @@ static bool test_notify_recursive(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) notify.nttrans.in.completion_filter = 0; notify.nttrans.in.recursive = true; - msleep(200); + smb_msleep(200); req1 = smb_raw_changenotify_send(cli->tree, ¬ify); smbcli_rmdir(cli->tree, BASEDIR "\\subdir-name\\subname1-r"); @@ -602,7 +602,7 @@ static bool test_notify_mask(struct smbcli_state *cli, struct torture_context *t notify.nttrans.in.completion_filter = (1<<i); \ req = smb_raw_changenotify_send(cli->tree, ¬ify); \ op \ - msleep(200); smb_raw_ntcancel(req); \ + smb_msleep(200); smb_raw_ntcancel(req); \ status = smb_raw_changenotify_recv(req, tctx, ¬ify); \ cleanup \ smbcli_close(cli->tree, fnum); \ @@ -1420,7 +1420,7 @@ static bool test_notify_basedir(struct smbcli_state *cli, TALLOC_CTX *mem_ctx) /* set attribute on a file to assure we receive a notification */ smbcli_setatr(cli->tree, BASEDIR "\\tname1", FILE_ATTRIBUTE_HIDDEN, 0); - msleep(200); + smb_msleep(200); /* check how many responses were given, expect only 1 for the file */ status = smb_raw_changenotify_recv(req1, mem_ctx, ¬ify); diff --git a/source4/torture/rpc/handles.c b/source4/torture/rpc/handles.c index f47789ae60..13357ac947 100644 --- a/source4/torture/rpc/handles.c +++ b/source4/torture/rpc/handles.c @@ -287,7 +287,7 @@ static bool test_handles_lsa_shared(struct torture_context *torture) /* close first connection */ torture_comment(torture, "disconnect p1\n"); talloc_free(p1); - msleep(5); + smb_msleep(5); /* * and it's still available on p2,p3 @@ -327,7 +327,7 @@ static bool test_handles_lsa_shared(struct torture_context *torture) talloc_free(p2); talloc_free(p3); talloc_free(p4); - msleep(10); + smb_msleep(10); /* * now open p5 @@ -455,7 +455,7 @@ static bool test_handles_mixed_shared(struct torture_context *torture) talloc_free(p1); talloc_free(p2); - msleep(10); + smb_msleep(10); torture_comment(torture, "connect samr pipe3 - should fail\n"); status = torture_rpc_connection_transport(torture, &p3, &ndr_table_samr, diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index 9283fc3e31..a1ad9fde1d 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -1435,7 +1435,7 @@ static bool test_CreateSecret(struct dcerpc_pipe *p, r5.in.new_val->size = enc_key.length; - msleep(200); + smb_msleep(200); torture_comment(tctx, "Testing SetSecret (existing value should move to old)\n"); torture_assert_ntstatus_ok(tctx, dcerpc_lsa_SetSecret_r(b, tctx, &r5), diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index b83b050fb2..c2eb872462 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -2911,7 +2911,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed"); torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); - msleep(250); + smb_msleep(250); if (sam_ctx) { /* AD workstation infos entry check */ @@ -3000,7 +3000,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); - msleep(250); + smb_msleep(250); if (sam_ctx) { /* AD workstation infos entry check */ @@ -3076,7 +3076,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed"); torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); - msleep(250); + smb_msleep(250); if (sam_ctx) { /* AD workstation infos entry check */ @@ -3147,7 +3147,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed"); torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); - msleep(250); + smb_msleep(250); /* Now the in/out DNS hostnames should be the same */ torture_assert_str_equal(tctx, @@ -3181,7 +3181,7 @@ static bool test_GetDomainInfo(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, r.out.result, "LogonGetDomainInfo failed"); torture_assert(tctx, netlogon_creds_client_check(creds, &a.cred), "Credential chaining failed"); - msleep(250); + smb_msleep(250); /* Checks "workstation flags" */ torture_assert(tctx, diff --git a/source4/torture/rpc/svcctl.c b/source4/torture/rpc/svcctl.c index 8f9ec1aed8..5ad678fe0e 100644 --- a/source4/torture/rpc/svcctl.c +++ b/source4/torture/rpc/svcctl.c @@ -1,6 +1,6 @@ /* Unix SMB/CIFS implementation. - test suite for srvsvc rpc operations + test suite for svcctl rpc operations Copyright (C) Jelmer Vernooij 2004 Copyright (C) Guenther Deschner 2008,2009 @@ -324,6 +324,65 @@ static bool test_QueryServiceObjectSecurity(struct torture_context *tctx, return true; } +static bool test_SetServiceObjectSecurity(struct torture_context *tctx, + struct dcerpc_pipe *p) +{ + struct svcctl_QueryServiceObjectSecurity q; + struct svcctl_SetServiceObjectSecurity r; + struct policy_handle h, s; + struct dcerpc_binding_handle *b = p->binding_handle; + + uint8_t *buffer; + uint32_t needed; + + if (!test_OpenSCManager(b, tctx, &h)) + return false; + + if (!test_OpenService(b, tctx, &h, TORTURE_DEFAULT_SERVICE, &s)) + return false; + + q.in.handle = &s; + q.in.security_flags = SECINFO_DACL; + q.in.offered = 0; + q.out.buffer = NULL; + q.out.needed = &needed; + + torture_assert_ntstatus_ok(tctx, + dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &q), + "QueryServiceObjectSecurity failed!"); + + if (W_ERROR_EQUAL(q.out.result, WERR_INSUFFICIENT_BUFFER)) { + q.in.offered = needed; + buffer = talloc_array(tctx, uint8_t, needed); + q.out.buffer = buffer; + torture_assert_ntstatus_ok(tctx, + dcerpc_svcctl_QueryServiceObjectSecurity_r(b, tctx, &q), + "QueryServiceObjectSecurity failed!"); + } + + torture_assert_werr_ok(tctx, q.out.result, + "QueryServiceObjectSecurity failed!"); + + r.in.handle = &s; + r.in.security_flags = SECINFO_DACL; + r.in.buffer = q.out.buffer; + r.in.offered = *q.out.needed; + + torture_assert_ntstatus_ok(tctx, + dcerpc_svcctl_SetServiceObjectSecurity_r(b, tctx, &r), + "SetServiceObjectSecurity failed!"); + torture_assert_werr_ok(tctx, r.out.result, + "SetServiceObjectSecurity failed!"); + + if (!test_CloseServiceHandle(b, tctx, &s)) + return false; + + if (!test_CloseServiceHandle(b, tctx, &h)) + return false; + + return true; +} + static bool test_StartServiceW(struct torture_context *tctx, struct dcerpc_pipe *p) { @@ -570,6 +629,8 @@ struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx) test_QueryServiceConfig2W); torture_rpc_tcase_add_test(tcase, "QueryServiceObjectSecurity", test_QueryServiceObjectSecurity); + torture_rpc_tcase_add_test(tcase, "SetServiceObjectSecurity", + test_SetServiceObjectSecurity); torture_rpc_tcase_add_test(tcase, "StartServiceW", test_StartServiceW); torture_rpc_tcase_add_test(tcase, "ControlService", diff --git a/source4/torture/smb2/lease.c b/source4/torture/smb2/lease.c index 63285d40e0..eda3b97eea 100644 --- a/source4/torture/smb2/lease.c +++ b/source4/torture/smb2/lease.c @@ -803,7 +803,7 @@ static bool test_lease_multibreak(struct torture_context *tctx, break_info.held_oplock_level = io.out.oplock_level; /* Sleep, use a write to clear the recv queue. */ - msleep(250); + smb_msleep(250); ZERO_STRUCT(w); w.in.file.handle = h3; w.in.offset = 0; diff --git a/source4/torture/smb2/notify.c b/source4/torture/smb2/notify.c index 313ef6848f..0115cd0478 100644 --- a/source4/torture/smb2/notify.c +++ b/source4/torture/smb2/notify.c @@ -308,7 +308,7 @@ static bool torture_smb2_notify_dir(struct torture_context *torture, smb2_util_rmdir(tree2, fname); smb2_util_mkdir(tree2, fname); smb2_util_rmdir(tree2, fname); - msleep(200); + smb_msleep(200); req = smb2_notify_send(tree1, &(notify.smb2)); status = smb2_notify_recv(req, torture, &(notify.smb2)); CHECK_STATUS(status, NT_STATUS_OK); @@ -603,7 +603,7 @@ static bool torture_smb2_notify_recursive(struct torture_context *torture, notify.smb2.in.completion_filter = 0; notify.smb2.in.recursive = true; - msleep(200); + smb_msleep(200); req1 = smb2_notify_send(tree1, &(notify.smb2)); status = smb2_util_rmdir(tree2, BASEDIR "\\subdir-name\\subname1-r"); @@ -898,7 +898,7 @@ static bool torture_smb2_notify_mask(struct torture_context *torture, /* send the change notify request */ \ req = smb2_notify_send(tree1, &(notify.smb2)); \ op \ - msleep(200); smb2_cancel(req); \ + smb_msleep(200); smb2_cancel(req); \ status = smb2_notify_recv(req, torture, &(notify.smb2)); \ cleanup \ smb2_util_close(tree1, h1); \ @@ -1775,7 +1775,7 @@ static bool torture_smb2_notify_basedir(struct torture_context *torture, /* set attribute on a file to assure we receive a notification */ smb2_util_setatr(tree2, BASEDIR "\\tname1", FILE_ATTRIBUTE_HIDDEN); - msleep(200); + smb_msleep(200); /* check how many responses were given, expect only 1 for the file */ status = smb2_notify_recv(req1, torture, &(notify.smb2)); diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c index 8d5accd2dc..df2716f316 100644 --- a/source4/torture/util_smb.c +++ b/source4/torture/util_smb.c @@ -699,7 +699,7 @@ double torture_create_procs(struct torture_context *tctx, printf("pid %d failed to start\n", (int)getpid()); _exit(1); } - msleep(100); + smb_msleep(100); } child_status[i] = getpid(); @@ -723,7 +723,7 @@ double torture_create_procs(struct torture_context *tctx, if (child_status[i]) synccount++; } if (synccount == torture_nprocs) break; - msleep(100); + smb_msleep(100); } while (timeval_elapsed(&tv) < start_time_limit); if (synccount != torture_nprocs) { diff --git a/source4/torture/wscript_build b/source4/torture/wscript_build index 715bec502f..b576a5c95e 100644 --- a/source4/torture/wscript_build +++ b/source4/torture/wscript_build @@ -33,7 +33,7 @@ bld.RECURSE('libnetapi') bld.RECURSE('libsmbclient') bld.SAMBA_SUBSYSTEM('TORTURE_NDR', - source='ndr/ndr.c ndr/winreg.c ndr/atsvc.c ndr/lsa.c ndr/epmap.c ndr/dfs.c ndr/netlogon.c ndr/drsuapi.c ndr/spoolss.c ndr/samr.c ndr/dfsblob.c ndr/drsblobs.c ndr/nbt.c', + source='ndr/ndr.c ndr/winreg.c ndr/atsvc.c ndr/lsa.c ndr/epmap.c ndr/dfs.c ndr/netlogon.c ndr/drsuapi.c ndr/spoolss.c ndr/samr.c ndr/dfsblob.c ndr/drsblobs.c ndr/nbt.c ndr/ntlmssp.c', autoproto='ndr/proto.h', deps='torture SERVICE_SMB' ) diff --git a/source4/winbind/wb_irpc.c b/source4/winbind/wb_irpc.c index bfb31e66a7..1eed89fd41 100644 --- a/source4/winbind/wb_irpc.c +++ b/source4/winbind/wb_irpc.c @@ -71,6 +71,52 @@ static void wb_irpc_SamLogon_callback(struct composite_context *ctx) irpc_send_reply(s->msg, status); } +struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state { + struct irpc_message *msg; + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req; +}; + +static void wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback(struct composite_context *ctx); + +static NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg, + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req) +{ + struct wbsrv_service *service = talloc_get_type(msg->private_data, + struct wbsrv_service); + struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state *s; + struct composite_context *ctx; + + DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n")); + + s = talloc(msg, struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state); + NT_STATUS_HAVE_NO_MEMORY(s); + + s->msg = msg; + s->req = req; + + ctx = wb_update_rodc_dns_send(msg, service, req); + NT_STATUS_HAVE_NO_MEMORY(ctx); + + ctx->async.fn = wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback; + ctx->async.private_data = s; + + msg->defer_reply = true; + return NT_STATUS_OK; +} + +static void wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback(struct composite_context *ctx) +{ + struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state *s = talloc_get_type(ctx->async.private_data, + struct wb_irpc_DsrUpdateReadOnlyServerDnsRecords_state); + NTSTATUS status; + + DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords_callback called\n")); + + status = wb_update_rodc_dns_recv(ctx, s, s->req); + + irpc_send_reply(s->msg, status); +} + struct wb_irpc_get_idmap_state { struct irpc_message *msg; struct winbind_get_idmap *req; @@ -149,6 +195,10 @@ NTSTATUS wbsrv_init_irpc(struct wbsrv_service *service) wb_irpc_SamLogon, service); NT_STATUS_NOT_OK_RETURN(status); + status = IRPC_REGISTER(service->task->msg_ctx, winbind, WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS, + wb_irpc_DsrUpdateReadOnlyServerDnsRecords, service); + NT_STATUS_NOT_OK_RETURN(status); + status = IRPC_REGISTER(service->task->msg_ctx, winbind, WINBIND_GET_IDMAP, wb_irpc_get_idmap, service); NT_STATUS_NOT_OK_RETURN(status); diff --git a/source4/winbind/wb_server.h b/source4/winbind/wb_server.h index ddb77d05f6..f20bc0aa51 100644 --- a/source4/winbind/wb_server.h +++ b/source4/winbind/wb_server.h @@ -176,6 +176,7 @@ struct wbsrv_samba3_call { struct netr_LMSessionKey; struct netr_UserSessionKey; struct winbind_SamLogon; +struct winbind_DsrUpdateReadOnlyServerDnsRecords; #include "winbind/wb_async_helpers.h" #include "winbind/wb_proto.h" diff --git a/source4/winbind/wb_update_rodc_dns.c b/source4/winbind/wb_update_rodc_dns.c new file mode 100644 index 0000000000..5ad2d0cbb0 --- /dev/null +++ b/source4/winbind/wb_update_rodc_dns.c @@ -0,0 +1,167 @@ +/* + Unix SMB/CIFS implementation. + + Do a netr_DsrUpdateReadOnlyServerDnsRecords to a remote DC + + Copyright (C) Andrew Bartlett 2010 + Copyright (C) Andrew Tridgell 2010 + + based heavily on wb_sam_logon.c which is copyright: + + Copyright (C) Volker Lendecke 2005 + Copyright (C) Andrew Bartlett 2005 + Copyright (C) Stefan Metzmacher 2006 + + 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 "libcli/composite/composite.h" +#include "winbind/wb_server.h" +#include "smbd/service_task.h" +#include "auth/credentials/credentials.h" +#include "libcli/auth/libcli_auth.h" +#include "librpc/gen_ndr/ndr_netlogon_c.h" +#include "librpc/gen_ndr/winbind.h" + +struct wb_update_rodc_dns_state { + struct composite_context *ctx; + + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req; + + struct netlogon_creds_CredentialState *creds_state; + struct netr_Authenticator auth1, auth2; + + TALLOC_CTX *r_mem_ctx; + struct netr_DsrUpdateReadOnlyServerDnsRecords r; +}; + +static void wb_update_rodc_dns_recv_domain(struct composite_context *ctx); +static void wb_update_rodc_dns_recv_response(struct tevent_req *subreq); + +/* + Find the connection to the DC (or find an existing connection) +*/ +struct composite_context *wb_update_rodc_dns_send(TALLOC_CTX *mem_ctx, + struct wbsrv_service *service, + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req) +{ + struct composite_context *c, *creq; + struct wb_update_rodc_dns_state *s; + + c = composite_create(mem_ctx, service->task->event_ctx); + if (!c) return NULL; + + s = talloc_zero(c, struct wb_update_rodc_dns_state); + if (composite_nomem(s, c)) return c; + s->ctx = c; + s->req = req; + + c->private_data = s; + + creq = wb_sid2domain_send(s, service, service->primary_sid); + composite_continue(c, creq, wb_update_rodc_dns_recv_domain, s); + return c; +} + +/* + Having finished making the connection to the DC + Send of a DsrUpdateReadOnlyServerDnsRecords request to authenticate a user. +*/ +static void wb_update_rodc_dns_recv_domain(struct composite_context *creq) +{ + struct wb_update_rodc_dns_state *s = talloc_get_type(creq->async.private_data, + struct wb_update_rodc_dns_state); + struct wbsrv_domain *domain; + struct tevent_req *subreq; + + s->ctx->status = wb_sid2domain_recv(creq, &domain); + if (!composite_is_ok(s->ctx)) return; + + s->creds_state = cli_credentials_get_netlogon_creds(domain->libnet_ctx->cred); + netlogon_creds_client_authenticator(s->creds_state, &s->auth1); + + s->r.in.server_name = talloc_asprintf(s, "\\\\%s", + dcerpc_server_name(domain->netlogon_pipe)); + if (composite_nomem(s->r.in.server_name, s->ctx)) return; + + s->r.in.computer_name = cli_credentials_get_workstation(domain->libnet_ctx->cred); + s->r.in.credential = &s->auth1; + s->r.out.return_authenticator = &s->auth2; + s->r.in.site_name = s->req->in.site_name; + s->r.in.dns_ttl = s->req->in.dns_ttl; + s->r.in.dns_names = s->req->in.dns_names; + s->r.out.dns_names = s->req->in.dns_names; + + /* + * use a new talloc context for the DsrUpdateReadOnlyServerDnsRecords call + * because then we can just to a talloc_steal on this context + * in the final _recv() function to give the caller all the content of + * the s->r.out.dns_names + */ + s->r_mem_ctx = talloc_new(s); + if (composite_nomem(s->r_mem_ctx, s->ctx)) return; + + subreq = dcerpc_netr_DsrUpdateReadOnlyServerDnsRecords_r_send(s, + s->ctx->event_ctx, + domain->netlogon_pipe->binding_handle, + &s->r); + if (composite_nomem(subreq, s->ctx)) return; + tevent_req_set_callback(subreq, wb_update_rodc_dns_recv_response, s); +} + +/* + NTLM Authentication + + Check the DsrUpdateReadOnlyServerDnsRecords reply and decrypt the session keys +*/ +static void wb_update_rodc_dns_recv_response(struct tevent_req *subreq) +{ + struct wb_update_rodc_dns_state *s = tevent_req_callback_data(subreq, + struct wb_update_rodc_dns_state); + + s->ctx->status = dcerpc_netr_DsrUpdateReadOnlyServerDnsRecords_r_recv(subreq, s->r_mem_ctx); + TALLOC_FREE(subreq); + if (!composite_is_ok(s->ctx)) return; + + s->ctx->status = s->r.out.result; + if (!composite_is_ok(s->ctx)) return; + + if ((s->r.out.return_authenticator == NULL) || + (!netlogon_creds_client_check(s->creds_state, + &s->r.out.return_authenticator->cred))) { + DEBUG(0, ("Credentials check failed!\n")); + composite_error(s->ctx, NT_STATUS_ACCESS_DENIED); + return; + } + + composite_done(s->ctx); +} + +NTSTATUS wb_update_rodc_dns_recv(struct composite_context *c, + TALLOC_CTX *mem_ctx, + struct winbind_DsrUpdateReadOnlyServerDnsRecords *req) +{ + struct wb_update_rodc_dns_state *s = talloc_get_type(c->private_data, + struct wb_update_rodc_dns_state); + NTSTATUS status = composite_wait(c); + + if (NT_STATUS_IS_OK(status)) { + talloc_steal(mem_ctx, s->r_mem_ctx); + req->out.dns_names = s->r.out.dns_names; + } + + talloc_free(s); + return status; +} diff --git a/source4/winbind/wscript_build b/source4/winbind/wscript_build index c9682f3eec..2c8a6f8317 100644 --- a/source4/winbind/wscript_build +++ b/source4/winbind/wscript_build @@ -2,7 +2,7 @@ bld.SAMBA_MODULE('WINBIND', - source='wb_server.c wb_irpc.c wb_samba3_protocol.c wb_samba3_cmd.c wb_init_domain.c wb_dom_info.c wb_dom_info_trusted.c wb_sid2domain.c wb_name2domain.c wb_sids2xids.c wb_xids2sids.c wb_gid2sid.c wb_sid2uid.c wb_sid2gid.c wb_uid2sid.c wb_connect_lsa.c wb_connect_sam.c wb_cmd_lookupname.c wb_cmd_lookupsid.c wb_cmd_getdcname.c wb_cmd_getgrnam.c wb_cmd_getgrgid.c wb_cmd_getpwnam.c wb_cmd_getpwuid.c wb_cmd_userdomgroups.c wb_cmd_usersids.c wb_cmd_list_groups.c wb_cmd_list_trustdom.c wb_cmd_list_users.c wb_cmd_setpwent.c wb_cmd_getpwent.c wb_cmd_getgrent.c wb_cmd_setgrent.c wb_cmd_getgroups.c wb_pam_auth.c wb_sam_logon.c', + source='wb_server.c wb_irpc.c wb_samba3_protocol.c wb_samba3_cmd.c wb_init_domain.c wb_dom_info.c wb_dom_info_trusted.c wb_sid2domain.c wb_name2domain.c wb_sids2xids.c wb_xids2sids.c wb_gid2sid.c wb_sid2uid.c wb_sid2gid.c wb_uid2sid.c wb_connect_lsa.c wb_connect_sam.c wb_cmd_lookupname.c wb_cmd_lookupsid.c wb_cmd_getdcname.c wb_cmd_getgrnam.c wb_cmd_getgrgid.c wb_cmd_getpwnam.c wb_cmd_getpwuid.c wb_cmd_userdomgroups.c wb_cmd_usersids.c wb_cmd_list_groups.c wb_cmd_list_trustdom.c wb_cmd_list_users.c wb_cmd_setpwent.c wb_cmd_getpwent.c wb_cmd_getgrent.c wb_cmd_setgrent.c wb_cmd_getgroups.c wb_pam_auth.c wb_sam_logon.c wb_update_rodc_dns.c', autoproto='wb_proto.h', subsystem='service', init_function='server_service_winbind_init', diff --git a/testprogs/win32/spoolss/testspoolss.c b/testprogs/win32/spoolss/testspoolss.c index 7aa3703f89..d0129ef7fe 100644 --- a/testprogs/win32/spoolss/testspoolss.c +++ b/testprogs/win32/spoolss/testspoolss.c @@ -1052,8 +1052,12 @@ static BOOL test_OnePrinter(struct torture_context *tctx, ret &= test_EnumPrinterData(tctx, printername, handle); ret &= test_EnumPrinterDataEx(tctx, printername, "PrinterDriverData", handle, NULL, NULL); ret &= test_DeviceModes(tctx, printername, handle); +#if 0 + /* dont run these at the moment, behaviour is PrinterData API calls (not + * dcerpc calls) is almost unpredictable - gd */ ret &= test_PrinterData(tctx, printername, handle); ret &= test_PrinterDataW(tctx, printername, handle); +#endif ret &= test_ClosePrinter(tctx, handle); return ret; |