summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-03-31 11:58:37 +1100
committerAndrew Tridgell <tridge@samba.org>2009-03-31 11:58:37 +1100
commit631e688c821b78d09d77f5940074800525c554aa (patch)
tree74473f1727ea0afa27d9c15e50e4638c4d8faf28 /source4
parent13be4d7ff42bd2b8bf5702a499c482404e5cd164 (diff)
parent4b8e4ea7286f045effb6feb4c7bf8c5ef4ed2f9b (diff)
downloadsamba-631e688c821b78d09d77f5940074800525c554aa.tar.gz
samba-631e688c821b78d09d77f5940074800525c554aa.tar.bz2
samba-631e688c821b78d09d77f5940074800525c554aa.zip
Merge branch 'master' into wspp-schema
Diffstat (limited to 'source4')
-rw-r--r--source4/auth/config.m42
-rw-r--r--source4/auth/credentials/credentials_krb5.h1
-rw-r--r--source4/auth/kerberos/clikrb5.c6
-rw-r--r--source4/build/m4/public.m44
-rw-r--r--source4/build/make/rules.mk5
-rw-r--r--source4/configure.ac6
-rwxr-xr-xsource4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py246
-rw-r--r--source4/headermap.txt2
-rw-r--r--source4/heimdal_build/replace.c4
-rw-r--r--source4/heimdal_build/roken.h19
-rw-r--r--source4/kdc/kdc.c2
-rw-r--r--source4/lib/ldb/modules/paged_searches.c115
-rw-r--r--source4/lib/ldb/pyldb.c63
-rwxr-xr-xsource4/lib/ldb/tests/python/api.py13
-rw-r--r--source4/lib/smbreadline/smbreadline.c1
-rw-r--r--source4/libcli/raw/interfaces.h12
-rw-r--r--source4/libcli/security/config.mk2
-rw-r--r--source4/libcli/smb2/create.c30
-rw-r--r--source4/libcli/smb2/smb2.h8
-rw-r--r--source4/librpc/config.mk4
-rw-r--r--source4/librpc/idl/dcerpc.idl306
-rw-r--r--source4/main.mk1
-rw-r--r--source4/min_versions.m48
-rwxr-xr-xsource4/script/uninstallman.sh2
-rw-r--r--source4/scripting/bin/fullschema179
-rwxr-xr-xsource4/scripting/bin/minschema49
-rw-r--r--source4/scripting/python/samba/__init__.py6
-rw-r--r--source4/scripting/python/samba/provision.py2
-rw-r--r--source4/selftest/config.mk12
-rw-r--r--source4/smbd/server.c2
-rw-r--r--source4/torture/ldap/cldap.c4
-rw-r--r--source4/torture/smb2/config.mk3
-rw-r--r--source4/torture/smb2/durable_open.c (renamed from source4/torture/smb2/persistent_handles.c)133
-rw-r--r--source4/torture/smb2/lease.c296
-rw-r--r--source4/torture/smb2/smb2.c13
35 files changed, 1099 insertions, 462 deletions
diff --git a/source4/auth/config.m4 b/source4/auth/config.m4
index fb9ee58c60..9735b17cac 100644
--- a/source4/auth/config.m4
+++ b/source4/auth/config.m4
@@ -28,6 +28,8 @@ if test x"$ac_cv_header_sasl_sasl_h" = x"yes" -a x"$ac_cv_lib_ext_sasl2_sasl_cli
SASL_CPPFLAGS="$CPPFLAGS"
SASL_LDFLAGS="$LDFLAGS"
LIB_REMOVE_USR_LIB(SASL_LDFLAGS)
+ CFLAGS_REMOVE_USR_INCLUDE(SASL_CPPFLAGS)
+ CFLAGS_REMOVE_USR_INCLUDE(SASL_CFLAGS)
else
SMB_ENABLE(cyrus_sasl,NO)
fi
diff --git a/source4/auth/credentials/credentials_krb5.h b/source4/auth/credentials/credentials_krb5.h
index 0d0e9f330f..5e56752eb4 100644
--- a/source4/auth/credentials/credentials_krb5.h
+++ b/source4/auth/credentials/credentials_krb5.h
@@ -24,6 +24,7 @@
#define __CREDENTIALS_KRB5_H__
#include <gssapi/gssapi.h>
+#include <gssapi/gssapi_krb5.h>
#include <krb5.h>
struct gssapi_creds_container {
diff --git a/source4/auth/kerberos/clikrb5.c b/source4/auth/kerberos/clikrb5.c
index cf87d13cf2..68e7eb90cc 100644
--- a/source4/auth/kerberos/clikrb5.c
+++ b/source4/auth/kerberos/clikrb5.c
@@ -74,13 +74,9 @@
void kerberos_free_data_contents(krb5_context context, krb5_data *pdata)
{
-#if defined(HAVE_KRB5_FREE_DATA_CONTENTS)
if (pdata->data) {
- krb5_free_data_contents(context, pdata);
+ krb5_data_free(pdata);
}
-#else
- SAFE_FREE(pdata->data);
-#endif
}
krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry)
diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4
index bd98a400be..2bf63f0ca6 100644
--- a/source4/build/m4/public.m4
+++ b/source4/build/m4/public.m4
@@ -102,10 +102,12 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG],
ac_cv_$1_libs_only_other="`$PKG_CONFIG --libs-only-other '$2'` `$PKG_CONFIG --libs-only-L '$2'`"
LIB_REMOVE_USR_LIB(ac_cv_$1_libs_only_other)
+ ac_cv_$1_includedir_only="`$PKG_CONFIG --cflags-only-I '$2'`"
+ CFLAGS_REMOVE_USR_INCLUDE(ac_cv_$1_includedir_only)
SMB_EXT_LIB($1,
[`$PKG_CONFIG --libs-only-l '$2'`],
[`$PKG_CONFIG --cflags-only-other '$2'`],
- [`$PKG_CONFIG --cflags-only-I '$2'`],
+ [$ac_cv_$1_includedir_only],
[$ac_cv_$1_libs_only_other])
ac_cv_$1_found=yes
diff --git a/source4/build/make/rules.mk b/source4/build/make/rules.mk
index 55ecf8968b..e9f4786d34 100644
--- a/source4/build/make/rules.mk
+++ b/source4/build/make/rules.mk
@@ -185,7 +185,8 @@ showflags::
base_srcdirs = $(srcdir) ../librpc/ ../lib/ ../libcli
etags:
- etags `find $(base_srcdirs) -name "*.[ch]"`
+ etags $(ETAGS_OPTIONS) `find $(base_srcdirs) -name "*.[ch]"`
ctags:
- ctags `find $(base_srcdirs) -name "*.[ch]"`
+ ctags $(CTAGS_OPTIONS) `find $(base_srcdirs) -name "*.[ch]"`
+
diff --git a/source4/configure.ac b/source4/configure.ac
index 065a3300ca..3c23f27d68 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -44,14 +44,14 @@ AC_CONFIG_FILES(librpc/dcerpc_atsvc.pc)
m4_include(min_versions.m4)
-SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION, [],
+SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= TALLOC_MIN_VERSION, [],
[
m4_include(../lib/talloc/libtalloc.m4)
SMB_INCLUDE_MK(../lib/talloc/config.mk)
]
)
-SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION,
+SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= TDB_MIN_VERSION,
[],
[
m4_include(../lib/tdb/libtdb.m4)
@@ -67,7 +67,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBTEVENT, tevent = TEVENT_REQUIRED_VERSION,
SMB_INCLUDE_MK(../lib/tevent/python.mk)
-SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION,
+SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION,
[
SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk)
SMB_INCLUDE_MK(lib/ldb/tools/config.mk)
diff --git a/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py
new file mode 100755
index 0000000000..aab93e59a3
--- /dev/null
+++ b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py
@@ -0,0 +1,246 @@
+#!/usr/bin/python
+
+# Unix SMB/CIFS implementation.
+# Copyright (C) Andrew Tridgell 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/>.
+#
+
+"""Tests the possibleInferiors generation in the schema_fsmo ldb module"""
+
+import optparse
+import sys
+
+
+# Find right directory when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba
+from samba import getopt as options, Ldb
+import ldb
+
+parser = optparse.OptionParser("possibleinferiors.py <URL> [<CLASS>]")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--wspp", action="store_true")
+
+opts, args = parser.parse_args()
+
+if len(args) < 1:
+ parser.print_usage()
+ sys.exit(1)
+
+url = args[0]
+if (len(args) > 1):
+ objectclass = args[1]
+else:
+ objectclass = None
+
+def uniq_list(alist):
+ """return a unique list"""
+ set = {}
+ return [set.setdefault(e,e) for e in alist if e not in set]
+
+
+lp_ctx = sambaopts.get_loadparm()
+
+creds = credopts.get_credentials(lp_ctx)
+db = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"])
+
+# get the rootDSE
+res = db.search(base="", expression="",
+ scope=ldb.SCOPE_BASE,
+ attrs=["schemaNamingContext"])
+rootDse = res[0]
+
+schema_base = rootDse["schemaNamingContext"][0]
+
+def possible_inferiors_search(db, oc):
+ """return the possible inferiors via a search for the possibleInferiors attribute"""
+ res = db.search(base=schema_base,
+ expression=("ldapDisplayName=%s" % oc),
+ attrs=["possibleInferiors"])
+
+ poss=[]
+ if len(res) == 0 or res[0].get("possibleInferiors") is None:
+ return poss
+ for item in res[0]["possibleInferiors"]:
+ poss.append(str(item))
+ poss = uniq_list(poss)
+ poss.sort()
+ return poss;
+
+
+
+# see [MS-ADTS] section 3.1.1.4.5.21
+# and section 3.1.1.4.2 for this algorithm
+
+# !systemOnly=TRUE
+# !objectClassCategory=2
+# !objectClassCategory=3
+
+def SUPCLASSES(classinfo, oc):
+ list = []
+ if oc == "top":
+ return list
+ if classinfo[oc].get("SUPCLASSES") is not None:
+ return classinfo[oc]["SUPCLASSES"]
+ res = classinfo[oc]["subClassOf"];
+ for r in res:
+ list.append(r)
+ list.extend(SUPCLASSES(classinfo,r))
+ classinfo[oc]["SUPCLASSES"] = list
+ return list
+
+def AUXCLASSES(classinfo, oclist):
+ list = []
+ if oclist == []:
+ return list
+ for oc in oclist:
+ if classinfo[oc].get("AUXCLASSES") is not None:
+ list.extend(classinfo[oc]["AUXCLASSES"])
+ else:
+ list2 = []
+ list2.extend(classinfo[oc]["systemAuxiliaryClass"])
+ list2.extend(AUXCLASSES(classinfo, classinfo[oc]["systemAuxiliaryClass"]))
+ list2.extend(classinfo[oc]["auxiliaryClass"])
+ list2.extend(AUXCLASSES(classinfo, classinfo[oc]["auxiliaryClass"]))
+ list2.extend(AUXCLASSES(classinfo, SUPCLASSES(classinfo, oc)))
+ classinfo[oc]["AUXCLASSES"] = list2
+ list.extend(list2)
+ return list
+
+def SUBCLASSES(classinfo, oclist):
+ list = []
+ for oc in oclist:
+ list.extend(classinfo[oc]["SUBCLASSES"])
+ return list
+
+def POSSSUPERIORS(classinfo, oclist):
+ list = []
+ for oc in oclist:
+ if classinfo[oc].get("POSSSUPERIORS") is not None:
+ list.extend(classinfo[oc]["POSSSUPERIORS"])
+ else:
+ list2 = []
+ list2.extend(classinfo[oc]["systemPossSuperiors"])
+ list2.extend(classinfo[oc]["possSuperiors"])
+ list2.extend(POSSSUPERIORS(classinfo, SUPCLASSES(classinfo, oc)))
+ if opts.wspp:
+ # the WSPP docs suggest we should do this:
+ list2.extend(POSSSUPERIORS(classinfo, AUXCLASSES(classinfo, [oc])))
+ else:
+ # but testing against w2k3 and w2k8 shows that we need to do this instead
+ list2.extend(SUBCLASSES(classinfo, list2))
+ classinfo[oc]["POSSSUPERIORS"] = list2
+ list.extend(list2)
+ return list
+
+def pull_classinfo(db):
+ """At startup we build a classinfo[] dictionary that holds all the information needed to construct the possible inferiors"""
+ classinfo = {}
+ res = db.search(base=schema_base,
+ expression="objectclass=classSchema",
+ attrs=["ldapDisplayName", "systemOnly", "objectClassCategory",
+ "possSuperiors", "systemPossSuperiors",
+ "auxiliaryClass", "systemAuxiliaryClass", "subClassOf"])
+ for r in res:
+ name = str(r["ldapDisplayName"][0])
+ classinfo[name] = {}
+ if str(r["systemOnly"]) == "TRUE":
+ classinfo[name]["systemOnly"] = True
+ else:
+ classinfo[name]["systemOnly"] = False
+ if r.get("objectClassCategory"):
+ classinfo[name]["objectClassCategory"] = int(r["objectClassCategory"][0])
+ else:
+ classinfo[name]["objectClassCategory"] = 0
+ for a in [ "possSuperiors", "systemPossSuperiors",
+ "auxiliaryClass", "systemAuxiliaryClass",
+ "subClassOf" ]:
+ classinfo[name][a] = []
+ if r.get(a):
+ for i in r[a]:
+ classinfo[name][a].append(str(i))
+
+ # build a list of subclasses for each class
+ def subclasses_recurse(subclasses, oc):
+ list = subclasses[oc]
+ for c in list:
+ list.extend(subclasses_recurse(subclasses, c))
+ return list
+
+ subclasses = {}
+ for oc in classinfo:
+ subclasses[oc] = []
+ for oc in classinfo:
+ for c in classinfo[oc]["subClassOf"]:
+ if not c == oc:
+ subclasses[c].append(oc)
+ for oc in classinfo:
+ classinfo[oc]["SUBCLASSES"] = uniq_list(subclasses_recurse(subclasses, oc))
+
+ return classinfo
+
+def is_in_list(list, c):
+ for a in list:
+ if c == a:
+ return True
+ return False
+
+def possible_inferiors_constructed(db, classinfo, c):
+ list = []
+ for oc in classinfo:
+ superiors = POSSSUPERIORS(classinfo, [oc])
+ if (is_in_list(superiors, c) and
+ classinfo[oc]["systemOnly"] == False and
+ classinfo[oc]["objectClassCategory"] != 2 and
+ classinfo[oc]["objectClassCategory"] != 3):
+ list.append(oc)
+ list = uniq_list(list)
+ list.sort()
+ return list
+
+def test_class(db, classinfo, oc):
+ """test to see if one objectclass returns the correct possibleInferiors"""
+ print "testing objectClass %s" % oc
+ poss1 = possible_inferiors_search(db, oc)
+ poss2 = possible_inferiors_constructed(db, classinfo, oc)
+ if poss1 != poss2:
+ print "Returned incorrect list for objectclass %s" % oc
+ print poss1
+ print poss2
+ for i in range(0,min(len(poss1),len(poss2))):
+ print "%30s %30s" % (poss1[i], poss2[i])
+ exit(1)
+
+def get_object_classes(db):
+ """return a list of all object classes"""
+ list=[]
+ for item in classinfo:
+ list.append(item)
+ return list
+
+classinfo = pull_classinfo(db)
+
+if objectclass is None:
+ for oc in get_object_classes(db):
+ test_class(db,classinfo,oc)
+else:
+ test_class(db,classinfo,objectclass)
+
+print "Lists match OK"
diff --git a/source4/headermap.txt b/source4/headermap.txt
index 280d60beb2..1c86f9e934 100644
--- a/source4/headermap.txt
+++ b/source4/headermap.txt
@@ -86,6 +86,8 @@ librpc/gen_ndr/nbt.h: gen_ndr/nbt.h
librpc/gen_ndr/svcctl.h: gen_ndr/svcctl.h
librpc/gen_ndr/ndr_svcctl.h: gen_ndr/ndr_svcctl.h
librpc/gen_ndr/ndr_svcctl_c.h: gen_ndr/ndr_svcctl_c.h
+../librpc/gen_ndr/dcerpc.h: gen_ndr/dcerpc.h
+../librpc/gen_ndr/ndr_dcerpc.h: gen_ndr/ndr_dcerpc.h
../librpc/gen_ndr/netlogon.h: gen_ndr/netlogon.h
../librpc/gen_ndr/ndr_misc.h: gen_ndr/ndr_misc.h
../librpc/gen_ndr/mgmt.h: gen_ndr/mgmt.h
diff --git a/source4/heimdal_build/replace.c b/source4/heimdal_build/replace.c
index 41309fea6e..ba43dd9495 100644
--- a/source4/heimdal_build/replace.c
+++ b/source4/heimdal_build/replace.c
@@ -84,3 +84,7 @@
return -1;
}
#endif
+
+const char *heimdal_version = "samba-internal-heimdal";
+const char *heimdal_long_version = "samba-interal-heimdal";
+
diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h
index 3edeb2fb2e..e3edd53872 100644
--- a/source4/heimdal_build/roken.h
+++ b/source4/heimdal_build/roken.h
@@ -41,6 +41,22 @@
#define HAVE_STRNDUP
#endif
+#ifndef HAVE_STRLCPY
+#define HAVE_STRLCPY
+#endif
+
+#ifndef HAVE_STRLCAT
+#define HAVE_STRLCAT
+#endif
+
+#ifndef HAVE_STRCASECMP
+#define HAVE_STRCASECMP
+#endif
+
+#ifndef HAVE_MKSTEMP
+#define HAVE_MKSTEMP
+#endif
+
#ifndef HAVE_SETENV
#define HAVE_SETENV
#endif
@@ -84,4 +100,7 @@
#undef SOCKET_WRAPPER_REPLACE
#include "heimdal/lib/roken/roken.h.in"
+extern const char *heimdal_version;
+extern const char *heimdal_long_version;
+
#endif
diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c
index 1cfe9852f0..3d11441062 100644
--- a/source4/kdc/kdc.c
+++ b/source4/kdc/kdc.c
@@ -345,7 +345,7 @@ static bool kdc_process(struct kdc_server *kdc,
}
if (k5_reply.length) {
*reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
- krb5_free_data_contents(kdc->smb_krb5_context->krb5_context, &k5_reply);
+ krb5_data_free(&k5_reply);
} else {
*reply = data_blob(NULL, 0);
}
diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c
index 01e77cb22c..c5430eb9bf 100644
--- a/source4/lib/ldb/modules/paged_searches.c
+++ b/source4/lib/ldb/modules/paged_searches.c
@@ -2,6 +2,7 @@
ldb database library
Copyright (C) Simo Sorce 2005-2008
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
@@ -52,23 +53,40 @@ struct ps_context {
char **saved_referrals;
int num_referrals;
+
+ struct ldb_request *down_req;
};
-static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares)
+static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares)
{
- struct ps_context *ac;
- struct ldb_paged_control *rep_control, *req_control;
+ struct ldb_context *ldb;
+ struct ldb_control *rep_control, *req_control;
+ struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL;
+ ldb = ldb_module_get_ctx(ac->module);
- ac = talloc_get_type(req->context, struct ps_context);
+ rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID);
+ if (rep_control) {
+ paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control);
+ }
- /* look up our paged control */
- if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) {
- /* something wrong here */
- return LDB_ERR_OPERATIONS_ERROR;
+ req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID);
+ paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control);
+
+ if (!rep_control || !paged_rep_control) {
+ if (paged_req_control->cookie) {
+ /* something wrong here - why give us a control back befre, but not one now? */
+ ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!");
+ return LDB_ERR_OPERATIONS_ERROR;
+ } else {
+ /* No cookie recived yet, valid to just return the full data set */
+
+ /* we are done */
+ ac->pending = false;
+ return LDB_SUCCESS;
+ }
}
- rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control);
- if (rep_control->cookie_len == 0) {
+ if (paged_rep_control->cookie_len == 0) {
/* we are done */
ac->pending = false;
return LDB_SUCCESS;
@@ -79,21 +97,14 @@ static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares
/* if there's a reply control we must find a request
* control matching it */
- if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, req->controls[0]->oid) != 0) {
- /* something wrong here */
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- req_control = talloc_get_type(req->controls[0]->data, struct ldb_paged_control);
-
- if (req_control->cookie) {
- talloc_free(req_control->cookie);
+ if (paged_req_control->cookie) {
+ talloc_free(paged_req_control->cookie);
}
- req_control->cookie = talloc_memdup(req_control,
- rep_control->cookie,
- rep_control->cookie_len);
- req_control->cookie_len = rep_control->cookie_len;
+ paged_req_control->cookie = talloc_memdup(req_control,
+ paged_rep_control->cookie,
+ paged_rep_control->cookie_len);
+ paged_req_control->cookie_len = paged_rep_control->cookie_len;
ac->pending = true;
return LDB_SUCCESS;
@@ -141,8 +152,6 @@ static int send_referrals(struct ps_context *ac)
return LDB_SUCCESS;
}
-static int ps_next_request(struct ps_context *ac);
-
static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct ps_context *ac;
@@ -176,14 +185,15 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares)
case LDB_REPLY_DONE:
- ret = check_ps_continuation(req, ares);
+ ret = check_ps_continuation(ac, req, ares);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
if (ac->pending) {
- ret = ps_next_request(ac);
+ ret = ldb_next_request(ac->module, ac->down_req);
+
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req,
NULL, NULL, ret);
@@ -214,14 +224,16 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
struct ldb_context *ldb;
struct private_data *private_data;
struct ps_context *ac;
+ struct ldb_paged_control *control;
+ int ret;
private_data = talloc_get_type(ldb_module_get_private(module), struct private_data);
ldb = ldb_module_get_ctx(module);
- /* check if paging is supported and if there is a any control */
- if (!private_data || !private_data->paged_supported || req->controls) {
+ /* check if paging is supported */
+ if (!private_data || !private_data->paged_supported) {
/* do not touch this request paged controls not
- * supported or explicit controls have been set or we
+ * supported or we
* are just not setup yet */
return ldb_next_request(module, req);
}
@@ -238,30 +250,9 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req)
ac->saved_referrals = NULL;
ac->num_referrals = 0;
- return ps_next_request(ac);
-}
-
-static int ps_next_request(struct ps_context *ac) {
-
- struct ldb_context *ldb;
- struct ldb_paged_control *control;
- struct ldb_control **controls;
- struct ldb_request *new_req;
- int ret;
-
ldb = ldb_module_get_ctx(ac->module);
- controls = talloc_array(ac, struct ldb_control *, 2);
- if (!controls) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- controls[0] = talloc(controls, struct ldb_control);
- if (!controls[0]) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- control = talloc(controls[0], struct ldb_paged_control);
+ control = talloc(ac, struct ldb_paged_control);
if (!control) {
return LDB_ERR_OPERATIONS_ERROR;
}
@@ -270,26 +261,28 @@ static int ps_next_request(struct ps_context *ac) {
control->cookie = NULL;
control->cookie_len = 0;
- controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID;
- controls[0]->critical = 1;
- controls[0]->data = control;
- controls[1] = NULL;
-
- ret = ldb_build_search_req_ex(&new_req, ldb, ac,
+ ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac,
ac->req->op.search.base,
ac->req->op.search.scope,
ac->req->op.search.tree,
ac->req->op.search.attrs,
- controls,
+ ac->req->controls,
ac,
ps_callback,
ac->req);
if (ret != LDB_SUCCESS) {
return ret;
}
- talloc_steal(new_req, controls);
- return ldb_next_request(ac->module, new_req);
+ ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID,
+ true, control);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+
+ talloc_steal(ac->down_req, control);
+
+ return ldb_next_request(ac->module, ac->down_req);
}
static int check_supported_paged(struct ldb_request *req,
diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c
index 7ff4bf4aad..bceda05e4f 100644
--- a/source4/lib/ldb/pyldb.c
+++ b/source4/lib/ldb/pyldb.c
@@ -5,7 +5,7 @@
Copyright (C) 2005,2006 Tim Potter <tpot@samba.org>
Copyright (C) 2006 Simo Sorce <idra@samba.org>
- Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org>
+ Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
** NOTE! The following LGPL license applies to the ldb
** library. This does NOT imply that all of Samba is released
@@ -65,18 +65,7 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
PyObject *ret;
new_val = *val;
-
- if (ldb_ctx != NULL) {
- a = ldb_schema_attribute_by_name(ldb_ctx, el->name);
-
- if (a != NULL) {
- if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) {
- talloc_free(mem_ctx);
- return NULL;
- }
- }
- }
-
+
ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length);
talloc_free(mem_ctx);
@@ -84,6 +73,14 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx,
return ret;
}
+/**
+ * Obtain a ldb DN from a Python object.
+ *
+ * @param mem_ctx Memory context
+ * @param object Python object
+ * @param ldb_ctx LDB context
+ * @return Whether or not the conversion succeeded
+ */
bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
struct ldb_context *ldb_ctx, struct ldb_dn **dn)
{
@@ -104,6 +101,12 @@ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object,
return false;
}
+/**
+ * Create a Python object from a ldb_result.
+ *
+ * @param result LDB result to convert
+ * @return Python object with converted result (a list object)
+ */
static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
{
PyObject *ret;
@@ -119,7 +122,16 @@ static PyObject *PyLdbResult_FromResult(struct ldb_result *result)
return ret;
}
-static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, PyObject *obj)
+/**
+ * Create a LDB Result from a Python object.
+ * If conversion fails, NULL will be returned and a Python exception set.
+ *
+ * @param mem_ctx Memory context in which to allocate the LDB Result
+ * @param obj Python object to convert
+ * @return a ldb_result, or NULL if the conversion failed
+ */
+static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx,
+ PyObject *obj)
{
struct ldb_result *res;
int i;
@@ -451,7 +463,6 @@ static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self)
return PyLdbDn_FromDn(dn);
}
-
static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
{
struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self));
@@ -460,7 +471,6 @@ static PyObject *py_ldb_get_config_basedn(PyLdbObject *self)
return PyLdbDn_FromDn(dn);
}
-
static PyObject *py_ldb_get_default_basedn(PyLdbObject *self)
{
struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self));
@@ -652,8 +662,6 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args)
Py_RETURN_NONE;
}
-
-
static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args)
{
PyObject *py_dn;
@@ -1257,6 +1265,21 @@ PyTypeObject PyLdbModule = {
.tp_flags = Py_TPFLAGS_DEFAULT,
};
+
+/**
+ * Create a ldb_message_element from a Python object.
+ *
+ * This will accept any sequence objects that contains strings, or
+ * a string object.
+ *
+ * A reference to set_obj will be borrowed.
+ *
+ * @param mem_ctx Memory context
+ * @param set_obj Python object to convert
+ * @param flags ldb_message_element flags to set
+ * @param attr_name Name of the attribute
+ * @return New ldb_message_element, allocated as child of mem_ctx
+ */
struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
PyObject *set_obj, int flags,
const char *attr_name)
@@ -1274,9 +1297,7 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx,
me->num_values = 1;
me->values = talloc_array(me, struct ldb_val, me->num_values);
me->values[0].length = PyString_Size(set_obj);
- me->values[0].data = (uint8_t *)talloc_strndup(me->values,
- PyString_AsString(set_obj),
- me->values[0].length);
+ me->values[0].data = (uint8_t *)PyString_AsString(set_obj);
} else if (PySequence_Check(set_obj)) {
int i;
me->num_values = PySequence_Size(set_obj);
diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py
index c372b8fa71..07500e2372 100755
--- a/source4/lib/ldb/tests/python/api.py
+++ b/source4/lib/ldb/tests/python/api.py
@@ -258,6 +258,19 @@ class SimpleLdb(unittest.TestCase):
l = ldb.Ldb(filename())
l.set_debug(my_report_fn)
+ def test_zero_byte_string(self):
+ """Testing we do not get trapped in the \0 byte in a property string."""
+ l = ldb.Ldb(filename())
+ l.add({
+ "dn" : "dc=somedn",
+ "objectclass" : "user",
+ "cN" : "LDAPtestUSER",
+ "givenname" : "ldap",
+ "displayname" : "foo\0bar",
+ })
+ res = l.search(expression="(dn=dc=somedn)")
+ self.assertEquals("foo\0bar", res[0]["displayname"][0])
+
class DnTests(unittest.TestCase):
def setUp(self):
diff --git a/source4/lib/smbreadline/smbreadline.c b/source4/lib/smbreadline/smbreadline.c
index 5fb3bf4fae..b07417357f 100644
--- a/source4/lib/smbreadline/smbreadline.c
+++ b/source4/lib/smbreadline/smbreadline.c
@@ -83,6 +83,7 @@ static char *smb_readline_replacement(const char *prompt, void (*callback)(void)
char *ret;
printf("%s", prompt);
+ fflush(stdout);
line = (char *)malloc(BUFSIZ);
if (!line) {
diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h
index a0584c0aa4..bd93fa1695 100644
--- a/source4/libcli/raw/interfaces.h
+++ b/source4/libcli/raw/interfaces.h
@@ -53,6 +53,16 @@ struct smb2_handle {
uint64_t data[2];
};
+/*
+ SMB2 lease structure (per MS-SMB2 2.2.13)
+*/
+struct smb2_lease {
+ uint64_t lease_key[2];
+ uint32_t lease_state;
+ uint32_t lease_flags; /* should be 0 */
+ uint64_t lease_duration; /* should be 0 */
+};
+
struct ntvfs_handle;
/*
@@ -1633,6 +1643,7 @@ union smb_open {
bool query_maximal_access;
NTTIME timewarp;
bool query_on_disk_id;
+ struct smb2_lease *lease_request;
/* and any additional blobs the caller wants */
struct smb2_create_blobs {
@@ -1666,6 +1677,7 @@ union smb_open {
/* optional return values matching tagged values in the call */
uint32_t maximal_access;
uint8_t on_disk_id[32];
+ struct smb2_lease lease_response;
/* tagged blobs in the reply */
struct smb2_create_blobs blobs;
diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk
index d6d9ad5545..9d23fe9588 100644
--- a/source4/libcli/security/config.mk
+++ b/source4/libcli/security/config.mk
@@ -4,7 +4,5 @@ PUBLIC_DEPENDENCIES = LIBNDR LIBSECURITY_COMMON
LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \
security_token.o security_descriptor.o \
access_check.o privilege.o sddl.o) \
- ../libcli/security/secace.o \
- ../libcli/security/secacl.o
$(eval $(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c)))
diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c
index 8a40e56a00..344be60f6e 100644
--- a/source4/libcli/smb2/create.c
+++ b/source4/libcli/smb2/create.c
@@ -312,6 +312,23 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create
}
}
+ if (io->in.lease_request) {
+ uint8_t data[32];
+
+ memcpy(&data[0], io->in.lease_request->lease_key, 16);
+ SIVAL(data, 16, io->in.lease_request->lease_state);
+ SIVAL(data, 20, io->in.lease_request->lease_flags);
+ SBVAL(data, 24, io->in.lease_request->lease_duration);
+
+ status = smb2_create_blob_add(req, &blobs,
+ SMB2_CREATE_TAG_RQLS,
+ data_blob_const(data, 32));
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(req);
+ return NULL;
+ }
+ }
+
/* and any custom blobs */
for (i=0;i<io->in.blobs.num_blobs;i++) {
status = smb2_create_blob_add(req, &blobs,
@@ -402,6 +419,19 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct
}
memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32);
}
+ if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_RQLS) == 0) {
+ uint8_t *data;
+ if (io->out.blobs.blobs[i].data.length != 32) {
+ smb2_request_destroy(req);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ data = io->out.blobs.blobs[i].data.data;
+ memcpy(io->out.lease_response.lease_key, data, 16);
+ io->out.lease_response.lease_state = IVAL(data, 16);
+ io->out.lease_response.lease_flags = IVAL(data, 20);
+ io->out.lease_response.lease_duration = BVAL(data, 24);
+ }
}
data_blob_free(&blob);
diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h
index 7c07c84740..fd961ce5f3 100644
--- a/source4/libcli/smb2/smb2.h
+++ b/source4/libcli/smb2/smb2.h
@@ -263,6 +263,13 @@ struct smb2_request {
#define SMB2_OPLOCK_LEVEL_II 0x01
#define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08
#define SMB2_OPLOCK_LEVEL_BATCH 0x09
+#define SMB2_OPLOCK_LEVEL_LEASE 0xFF
+
+/* SMB2 lease bits */
+#define SMB2_LEASE_NONE 0x00
+#define SMB2_LEASE_READ 0x01
+#define SMB2_LEASE_HANDLE 0x02
+#define SMB2_LEASE_WRITE 0x04
/* SMB2 impersonation levels */
#define SMB2_IMPERSONATION_ANONYMOUS 0x00
@@ -279,6 +286,7 @@ struct smb2_request {
#define SMB2_CREATE_TAG_ALSI "AlSi"
#define SMB2_CREATE_TAG_TWRP "TWrp"
#define SMB2_CREATE_TAG_QFID "QFid"
+#define SMB2_CREATE_TAG_RQLS "RqLs"
/* SMB2 Create ignore some more create_options */
#define SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK (NTCREATEX_OPTIONS_TREE_CONNECTION | \
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index 2f1b14dc37..64a4750ab7 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -595,9 +595,9 @@ RPC_NDR_KEYSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_keysvc_c.o
[SUBSYSTEM::NDR_DCERPC]
PUBLIC_DEPENDENCIES = LIBNDR
-NDR_DCERPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dcerpc.o
+NDR_DCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_dcerpc.o
-PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/dcerpc.h gen_ndr/ndr_dcerpc.h)
+PUBLIC_HEADERS += ../librpc/gen_ndr/dcerpc.h ../librpc/gen_ndr/ndr_dcerpc.h
################################################
# Start SUBSYSTEM dcerpc
diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl
deleted file mode 100644
index 7c0abe6ab8..0000000000
--- a/source4/librpc/idl/dcerpc.idl
+++ /dev/null
@@ -1,306 +0,0 @@
-#include "idl_types.h"
-
-/*
- the base dcerpc packet definitions - not traditionally coded as IDL,
- but given that pidl can handle it nicely it simplifies things a lot
- to do it this way
-
- see http://www.opengroup.org/onlinepubs/9629399/chap12.htm for packet
- layouts
-*/
-import "misc.idl";
-
-interface dcerpc
-{
- typedef struct {
- uint16 context_id;
- uint8 num_transfer_syntaxes;
- ndr_syntax_id abstract_syntax;
- ndr_syntax_id transfer_syntaxes[num_transfer_syntaxes];
- } dcerpc_ctx_list;
-
- typedef struct {
- uint16 max_xmit_frag;
- uint16 max_recv_frag;
- uint32 assoc_group_id;
- uint8 num_contexts;
- dcerpc_ctx_list ctx_list[num_contexts];
- [flag(NDR_ALIGN4)] DATA_BLOB _pad;
- [flag(NDR_REMAINING)] DATA_BLOB auth_info;
- } dcerpc_bind;
-
- const uint8 DCERPC_REQUEST_LENGTH = 24;
-
- typedef struct {
- } dcerpc_empty;
-
- typedef [nodiscriminant] union {
- [default] dcerpc_empty empty;
- [case(LIBNDR_FLAG_OBJECT_PRESENT)] GUID object;
- } dcerpc_object;
-
- typedef struct {
- uint32 alloc_hint;
- uint16 context_id;
- uint16 opnum;
- [switch_is(ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)] dcerpc_object object;
- [flag(NDR_ALIGN8)] DATA_BLOB _pad;
- [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier;
- } dcerpc_request;
-
- const int DCERPC_BIND_REASON_ASYNTAX = 1;
- const int DCERPC_BIND_PROVIDER_REJECT = 2;
- const int DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED = 4;
- const int DCERPC_BIND_REASON_INVALID_AUTH_TYPE = 8;
-
- typedef struct {
- uint16 result;
- uint16 reason;
- ndr_syntax_id syntax;
- } dcerpc_ack_ctx;
-
- typedef struct {
- uint16 max_xmit_frag;
- uint16 max_recv_frag;
- uint32 assoc_group_id;
- [value(strlen(secondary_address)+1)] uint16 secondary_address_size;
- [charset(DOS)] uint8 secondary_address[secondary_address_size];
- [flag(NDR_ALIGN4)] DATA_BLOB _pad1;
- uint8 num_results;
- dcerpc_ack_ctx ctx_list[num_results];
- [flag(NDR_REMAINING)] DATA_BLOB auth_info;
- } dcerpc_bind_ack;
-
- typedef struct {
- uint32 num_versions;
- uint32 versions[num_versions];
- } dcerpc_bind_nak_versions;
-
- typedef [nodiscriminant] union {
- [case(DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED)] dcerpc_bind_nak_versions v;
- [default] ;
- } dcerpc_bind_nak_versions_ctr;
-
- typedef struct {
- uint16 reject_reason;
- [switch_is(reject_reason)] dcerpc_bind_nak_versions_ctr versions;
- } dcerpc_bind_nak;
-
- const uint8 DCERPC_RESPONSE_LENGTH = 24;
-
- typedef struct {
- uint32 alloc_hint;
- uint16 context_id;
- uint8 cancel_count;
- [flag(NDR_ALIGN8)] DATA_BLOB _pad;
- [flag(NDR_REMAINING)] DATA_BLOB stub_and_verifier;
- } dcerpc_response;
-
-
- const int DCERPC_FAULT_OP_RNG_ERROR = 0x1c010002;
- const int DCERPC_FAULT_UNK_IF = 0x1c010003;
- const int DCERPC_FAULT_NDR = 0x000006f7;
- const int DCERPC_FAULT_INVALID_TAG = 0x1c000006;
- const int DCERPC_FAULT_CONTEXT_MISMATCH = 0x1c00001a;
- const int DCERPC_FAULT_OTHER = 0x00000001;
- const int DCERPC_FAULT_ACCESS_DENIED = 0x00000005;
- const int DCERPC_FAULT_CANT_PERFORM = 0x000006d8;
-
- /* we return this fault when we haven't yet run the test
- to see what fault w2k3 returns in this case */
- const int DCERPC_FAULT_TODO = 0x00000042;
-
- typedef struct {
- uint32 alloc_hint;
- uint16 context_id;
- uint8 cancel_count;
- uint32 status;
- [flag(NDR_REMAINING)] DATA_BLOB _pad;
- } dcerpc_fault;
-
- /* the auth types we know about */
- typedef [enum8bit] enum {
- DCERPC_AUTH_TYPE_NONE = 0,
- /* this seems to be not krb5! */
- DCERPC_AUTH_TYPE_KRB5_1 = 1,
- DCERPC_AUTH_TYPE_SPNEGO = 9,
- DCERPC_AUTH_TYPE_NTLMSSP = 10,
- DCERPC_AUTH_TYPE_KRB5 = 16,
- DCERPC_AUTH_TYPE_DPA = 17,
- DCERPC_AUTH_TYPE_MSN = 18,
- DCERPC_AUTH_TYPE_DIGEST = 21,
- DCERPC_AUTH_TYPE_SCHANNEL = 68,
- DCERPC_AUTH_TYPE_MSMQ = 100
- } dcerpc_AuthType;
-
- typedef [enum8bit] enum {
- DCERPC_AUTH_LEVEL_NONE = 1,
- DCERPC_AUTH_LEVEL_CONNECT = 2,
- DCERPC_AUTH_LEVEL_CALL = 3,
- DCERPC_AUTH_LEVEL_PACKET = 4,
- DCERPC_AUTH_LEVEL_INTEGRITY = 5,
- DCERPC_AUTH_LEVEL_PRIVACY = 6
- } dcerpc_AuthLevel;
-
- const uint8 DCERPC_AUTH_LEVEL_DEFAULT = DCERPC_AUTH_LEVEL_CONNECT;
-
- typedef [public] struct {
- dcerpc_AuthType auth_type;
- dcerpc_AuthLevel auth_level;
- uint8 auth_pad_length;
- uint8 auth_reserved;
- uint32 auth_context_id;
- [flag(NDR_REMAINING)] DATA_BLOB credentials;
- } dcerpc_auth;
-
- const uint8 DCERPC_AUTH_TRAILER_LENGTH = 8;
-
- typedef [public] struct {
- uint32 _pad;
- [flag(NDR_REMAINING)] DATA_BLOB auth_info;
- } dcerpc_auth3;
-
- typedef [public] struct {
- uint32 _pad;
- [flag(NDR_REMAINING)] DATA_BLOB auth_info;
- } dcerpc_orphaned;
-
- typedef [public] struct {
- uint32 _pad;
- [flag(NDR_REMAINING)] DATA_BLOB auth_info;
- } dcerpc_co_cancel;
-
- typedef [public] struct {
- uint32 version;
- uint32 id;
- } dcerpc_cl_cancel;
-
- typedef [public] struct {
- uint32 version;
- uint32 id;
- boolean32 server_is_accepting;
- } dcerpc_cancel_ack;
-
- typedef [public] struct {
- uint32 version;
- uint8 _pad1;
- uint16 window_size;
- uint32 max_tdsu;
- uint32 max_frag_size;
- uint16 serial_no;
- uint16 selack_size;
- uint32 selack[selack_size];
- } dcerpc_fack;
-
- typedef [public] struct {
- } dcerpc_ack;
-
- typedef [public] struct {
- } dcerpc_ping;
-
- typedef [public] struct {
- } dcerpc_shutdown;
-
- typedef [public] struct {
- } dcerpc_working;
-
- typedef [enum8bit] enum {
- DCERPC_PKT_REQUEST = 0, /* Ordinary request. */
- DCERPC_PKT_PING = 1, /* Connectionless is server alive ? */
- DCERPC_PKT_RESPONSE = 2, /* Ordinary reply. */
- DCERPC_PKT_FAULT = 3, /* Fault in processing of call. */
- DCERPC_PKT_WORKING = 4, /* Connectionless reply to a ping when server busy. */
- DCERPC_PKT_NOCALL = 5, /* Connectionless reply to a ping when server has lost part of clients call. */
- DCERPC_PKT_REJECT = 6, /* Refuse a request with a code. */
- DCERPC_PKT_ACK = 7, /* Connectionless client to server code. */
- DCERPC_PKT_CL_CANCEL = 8, /* Connectionless cancel. */
- DCERPC_PKT_FACK = 9, /* Connectionless fragment ack. Both client and server send. */
- DCERPC_PKT_CANCEL_ACK = 10, /* Server ACK to client cancel request. */
- DCERPC_PKT_BIND = 11, /* Bind to interface. */
- DCERPC_PKT_BIND_ACK = 12, /* Server ack of bind. */
- DCERPC_PKT_BIND_NAK = 13, /* Server nack of bind. */
- DCERPC_PKT_ALTER = 14, /* Alter auth. */
- DCERPC_PKT_ALTER_RESP = 15, /* Reply to alter auth. */
- DCERPC_PKT_AUTH3 = 16, /* not the real name! this is undocumented! */
- DCERPC_PKT_SHUTDOWN = 17, /* Server to client request to shutdown. */
- DCERPC_PKT_CO_CANCEL = 18, /* Connection-oriented cancel request. */
- DCERPC_PKT_ORPHANED = 19 /* Client telling server it's aborting a partially sent request or telling server to stop sending replies. */
- } dcerpc_pkt_type;
-
- typedef [nodiscriminant] union {
- [case(DCERPC_PKT_REQUEST)] dcerpc_request request;
- [case(DCERPC_PKT_PING)] dcerpc_ping ping;
- [case(DCERPC_PKT_RESPONSE)] dcerpc_response response;
- [case(DCERPC_PKT_FAULT)] dcerpc_fault fault;
- [case(DCERPC_PKT_WORKING)] dcerpc_working working;
- [case(DCERPC_PKT_NOCALL)] dcerpc_fack nocall;
- [case(DCERPC_PKT_REJECT)] dcerpc_fault reject;
- [case(DCERPC_PKT_ACK)] dcerpc_ack ack;
- [case(DCERPC_PKT_CL_CANCEL)] dcerpc_cl_cancel cl_cancel;
- [case(DCERPC_PKT_FACK)] dcerpc_fack fack;
- [case(DCERPC_PKT_CANCEL_ACK)] dcerpc_cancel_ack cancel_ack;
- [case(DCERPC_PKT_BIND)] dcerpc_bind bind;
- [case(DCERPC_PKT_BIND_ACK)] dcerpc_bind_ack bind_ack;
- [case(DCERPC_PKT_BIND_NAK)] dcerpc_bind_nak bind_nak;
- [case(DCERPC_PKT_ALTER)] dcerpc_bind alter;
- [case(DCERPC_PKT_ALTER_RESP)] dcerpc_bind_ack alter_resp;
- [case(DCERPC_PKT_SHUTDOWN)] dcerpc_shutdown shutdown;
- [case(DCERPC_PKT_CO_CANCEL)] dcerpc_co_cancel co_cancel;
- [case(DCERPC_PKT_ORPHANED)] dcerpc_orphaned orphaned;
- [case(DCERPC_PKT_AUTH3)] dcerpc_auth3 auth3;
- } dcerpc_payload;
-
- /* pfc_flags values */
- const uint8 DCERPC_PFC_FLAG_FIRST = 0x01; /* First fragment */
- const uint8 DCERPC_PFC_FLAG_LAST = 0x02; /* Last fragment */
- const uint8 DCERPC_PFC_FLAG_PENDING_CANCEL = 0x04; /* Cancel was pending at sender */
- const uint8 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN = DCERPC_PFC_FLAG_PENDING_CANCEL; /* depends on the pdu type */
- const uint8 DCERPC_PFC_FLAG_CONC_MPX = 0x10; /* supports concurrent multiplexing of a single connection. */
- const uint8 DCERPC_PFC_FLAG_DID_NOT_EXECUTE = 0x20; /* on a fault it means the server hasn't done anything */
- const uint8 DCERPC_PFC_FLAG_MAYBE = 0x40; /* `maybe' call semantics requested */
- const uint8 DCERPC_PFC_FLAG_OBJECT_UUID = 0x80; /* on valid guid is in the optional object field */
-
- /* these offsets are needed by the signing code */
- const uint8 DCERPC_PFC_OFFSET = 3;
- const uint8 DCERPC_DREP_OFFSET = 4;
- const uint8 DCERPC_FRAG_LEN_OFFSET = 8;
- const uint8 DCERPC_AUTH_LEN_OFFSET = 10;
-
- /* little-endian flag */
- const uint8 DCERPC_DREP_LE = 0x10;
-
- typedef [public] struct {
- uint8 rpc_vers; /* RPC version */
- uint8 rpc_vers_minor; /* Minor version */
- dcerpc_pkt_type ptype; /* Packet type */
- uint8 pfc_flags; /* Fragmentation flags */
- uint8 drep[4]; /* NDR data representation */
- uint16 frag_length; /* Total length of fragment */
- uint16 auth_length; /* authenticator length */
- uint32 call_id; /* Call identifier */
- [switch_is(ptype)] dcerpc_payload u;
- } ncacn_packet;
-
- typedef [public] struct {
- uint8 rpc_vers; /* RPC version (4) */
- uint8 ptype;
- uint8 pfc_flags;
- uint8 ncadg_flags;
- uint8 drep[3];
- uint8 serial_high;
- GUID object;
- GUID iface;
- GUID activity;
- uint32 server_boot; /* Server boot time */
- uint32 iface_version;
- uint32 seq_num;
- uint16 opnum;
- uint16 ihint;
- uint16 ahint;
- uint16 len;
- uint16 fragnum;
- uint8 auth_proto;
- uint8 serial_low;
- [switch_is(ptype)] dcerpc_payload u;
- } ncadg_packet;
-}
diff --git a/source4/main.mk b/source4/main.mk
index a143604f33..d7db0580e9 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -46,6 +46,7 @@ mkinclude torture/config.mk
mkinclude librpc/config.mk
mkinclude client/config.mk
mkinclude libcli/config.mk
+mkinclude ../libcli/cldap/config.mk
mkinclude scripting/python/config.mk
mkinclude kdc/config.mk
mkinclude ../lib/smbconf/config.mk
diff --git a/source4/min_versions.m4 b/source4/min_versions.m4
index eaefbd5148..1dd3501b99 100644
--- a/source4/min_versions.m4
+++ b/source4/min_versions.m4
@@ -1,6 +1,6 @@
# Minimum and exact required versions for various libraries
# if we use the ones installed in the system.
-TDB_MIN_VERSION=1.1.3
-TALLOC_MIN_VERSION=1.3.0
-LDB_REQUIRED_VERSION=0.9.3
-TEVENT_REQUIRED_VERSION=0.9.5
+define(TDB_MIN_VERSION,1.1.3)
+define(TALLOC_MIN_VERSION,1.3.0)
+define(LDB_REQUIRED_VERSION,0.9.3)
+define(TEVENT_REQUIRED_VERSION,0.9.5)
diff --git a/source4/script/uninstallman.sh b/source4/script/uninstallman.sh
index 9b087c68bb..edc1c47e4d 100755
--- a/source4/script/uninstallman.sh
+++ b/source4/script/uninstallman.sh
@@ -8,7 +8,7 @@ MANPAGES=$*
for I in $MANPAGES
do
- SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"
+ SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"`
FNAME=$MANDIR/man$SECTION/$I
if test -f $FNAME; then
echo Deleting $FNAME
diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema
new file mode 100644
index 0000000000..41c45f30c8
--- /dev/null
+++ b/source4/scripting/bin/fullschema
@@ -0,0 +1,179 @@
+#!/usr/bin/python
+#
+# work out the minimal schema for a set of objectclasses
+#
+
+import base64
+import optparse
+import os
+import sys
+
+# Find right directory when running from source tree
+sys.path.insert(0, "bin/python")
+
+import samba
+from samba import getopt as options, Ldb
+from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError
+import sys
+
+parser = optparse.OptionParser("fullschema <URL>")
+sambaopts = options.SambaOptions(parser)
+parser.add_option_group(sambaopts)
+credopts = options.CredentialsOptions(parser)
+parser.add_option_group(credopts)
+parser.add_option_group(options.VersionOptions(parser))
+parser.add_option("--dump-classes", action="store_true")
+parser.add_option("--dump-attributes", action="store_true")
+
+opts, args = parser.parse_args()
+opts.dump_all = True
+
+if opts.dump_classes:
+ opts.dump_all = False
+if opts.dump_attributes:
+ opts.dump_all = False
+if opts.dump_all:
+ opts.dump_classes = True
+ opts.dump_attributes = True
+
+if len(args) != 1:
+ parser.print_usage()
+ sys.exit(1)
+
+url = args[0]
+
+lp_ctx = sambaopts.get_loadparm()
+
+creds = credopts.get_credentials(lp_ctx)
+ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"])
+
+# the attributes we need for objectclasses
+class_attrs = ["objectClass",
+ "cn",
+ "subClassOf",
+ "governsID",
+ "possSuperiors",
+ "possibleInferiors",
+ "mayContain",
+ "mustContain",
+ "auxiliaryClass",
+ "rDNAttID",
+ "adminDisplayName",
+ "adminDescription",
+ "objectClassCategory",
+ "lDAPDisplayName",
+ "schemaIDGUID",
+ "systemOnly",
+ "systemPossSuperiors",
+ "systemMayContain",
+ "systemMustContain",
+ "systemAuxiliaryClass",
+ "defaultSecurityDescriptor",
+ "systemFlags",
+ "defaultHidingValue",
+ "defaultObjectCategory",
+
+ # this attributes are not used by w2k3
+ "schemaFlagsEx",
+ "msDs-IntId",
+ "msDs-Schema-Extensions",
+ "classDisplayName",
+ "isDefunct"]
+
+attrib_attrs = ["objectClass",
+ "cn",
+ "attributeID",
+ "attributeSyntax",
+ "isSingleValued",
+ "rangeLower",
+ "rangeUpper",
+ "mAPIID",
+ "linkID",
+ "adminDisplayName",
+ "oMObjectClass",
+ "adminDescription",
+ "oMSyntax",
+ "searchFlags",
+ "extendedCharsAllowed",
+ "lDAPDisplayName",
+ "schemaIDGUID",
+ "attributeSecurityGUID",
+ "systemOnly",
+ "systemFlags",
+ "isMemberOfPartialAttributeSet",
+
+ # this attributes are not used by w2k3
+ "schemaFlagsEx",
+ "msDs-IntId",
+ "msDs-Schema-Extensions",
+ "classDisplayName",
+ "isEphemeral",
+ "isDefunct"]
+
+class Objectclass(dict):
+
+ def __init__(self, ldb, name):
+ """create an objectclass object"""
+ self.name = name
+
+
+class Attribute(dict):
+
+ def __init__(self, ldb, name):
+ """create an attribute object"""
+ self.name = name
+ self["cn"] = get_object_cn(ldb, name)
+
+
+
+def fix_dn(dn):
+ """fix a string DN to use ${SCHEMADN}"""
+ return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}")
+
+
+def write_ldif_one(o, attrs):
+ """dump an object as ldif"""
+ print "dn: CN=%s,${SCHEMADN}" % o["cn"]
+ for a in attrs:
+ if not o.has_key(a):
+ continue
+ # special case for oMObjectClass, which is a binary object
+ v = o[a]
+ for j in v:
+ value = fix_dn(j)
+ if a != "cn":
+ if a == "oMObjectClass":
+ print "%s:: %s" % (a, base64.b64encode(value))
+ elif a.endswith("GUID"):
+ print "%s: %s" % (a, ldb.schema_format_value(a, value))
+ else:
+ print "%s: %s" % (a, value)
+ print ""
+
+
+# get the rootDSE
+res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"])
+rootDse = res[0]
+
+if opts.dump_attributes:
+ res = ldb.search(expression="objectClass=attributeSchema",
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs,
+ controls=["server_sort:1:0:cn"])
+
+ for msg in res:
+ o = Objectclass(ldb, msg["ldapDisplayName"])
+ for a in msg:
+ o[a] = msg[a]
+ write_ldif_one(o, attrib_attrs)
+
+if opts.dump_classes:
+ res = ldb.search(expression="objectClass=classSchema",
+ base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs,
+ controls=["server_sort:1:0:cn"])
+
+ for msg in res:
+ o = Objectclass(ldb, msg["ldapDisplayName"])
+ for a in msg:
+ o[a] = msg[a]
+ write_ldif_one(o, class_attrs)
+
diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema
index f2dfdcb564..c860495e96 100755
--- a/source4/scripting/bin/minschema
+++ b/source4/scripting/bin/minschema
@@ -72,7 +72,6 @@ class_attrs = ["objectClass",
"mustContain",
"auxiliaryClass",
"rDNAttID",
- "showInAdvancedViewOnly",
"adminDisplayName",
"adminDescription",
"objectClassCategory",
@@ -104,7 +103,6 @@ attrib_attrs = ["objectClass",
"rangeUpper",
"mAPIID",
"linkID",
- "showInAdvancedViewOnly",
"adminDisplayName",
"oMObjectClass",
"adminDescription",
@@ -405,40 +403,40 @@ def attribute_list(objectclass, attr1, attr2):
def aggregate_list(name, list):
"""write out a list in aggregate form"""
- if list is None:
- return
- print "%s ( %s )" % (name, "$ ".join(list))
+ if list == []:
+ return ""
+ return " %s ( %s )" % (name, " $ ".join(list))
def write_aggregate_objectclass(objectclass):
"""write the aggregate record for an objectclass"""
- print "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name),
+ line = "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name)
if not objectclass.has_key('subClassOf'):
- print "SUP %s " % objectclass['subClassOf'],
+ line += "SUP %s" % objectclass['subClassOf']
if objectclass["objectClassCategory"] == 1:
- print "STRUCTURAL ",
+ line += "STRUCTURAL"
elif objectclass["objectClassCategory"] == 2:
- print "ABSTRACT ",
+ line += "ABSTRACT"
elif objectclass["objectClassCategory"] == 3:
- print "AUXILIARY ",
+ line += "AUXILIARY"
list = attribute_list(objectclass, "systemMustContain", "mustContain")
- aggregate_list("MUST", list)
+ line += aggregate_list("MUST", list)
list = attribute_list(objectclass, "systemMayContain", "mayContain")
- aggregate_list("MAY", list)
+ line += aggregate_list("MAY", list)
- print ")"
+ print line + " )"
def write_aggregate_ditcontentrule(objectclass):
"""write the aggregate record for an ditcontentrule"""
list = attribute_list(objectclass, "auxiliaryClass", "systemAuxiliaryClass")
- if list is None:
+ if list == []:
return
- print "dITContentRules: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name)
+ line = "dITContentRules: ( %s NAME '%s'" % (objectclass["governsID"], objectclass.name)
- aggregate_list("AUX", list)
+ line += aggregate_list("AUX", list)
may_list = []
must_list = []
@@ -451,31 +449,30 @@ def write_aggregate_ditcontentrule(objectclass):
"mustContain", "systemMustContain")
must_list = must_list + list2
- aggregate_list("MUST", must_list)
- aggregate_list("MAY", may_list)
+ line += aggregate_list("MUST", must_list)
+ line += aggregate_list("MAY", may_list)
- print ")\n"
+ print line + " )"
def write_aggregate_attribute(attrib):
"""write the aggregate record for an attribute"""
- print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
+ line = "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % (
attrib["attributeID"], attrib.name,
map_attribute_syntax(attrib["attributeSyntax"]))
if attrib.get('isSingleValued') == "TRUE":
- print "SINGLE-VALUE "
+ line += "SINGLE-VALUE "
if attrib.get('systemOnly') == "TRUE":
- print "NO-USER-MODIFICATION "
+ line += "NO-USER-MODIFICATION "
- print ")\n"
+ print line + ")"
def write_aggregate():
"""write the aggregate record"""
- print "dn: CN=Aggregate,${SCHEMADN}\n"
+ print "dn: CN=Aggregate,${SCHEMADN}"
print """objectClass: top
objectClass: subSchema
-objectCategory: CN=SubSchema,${SCHEMADN}
-"""
+objectCategory: CN=SubSchema,${SCHEMADN}"""
if not opts.dump_subschema_auto:
return
diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py
index a49e6e1ead..c5827b96e0 100644
--- a/source4/scripting/python/samba/__init__.py
+++ b/source4/scripting/python/samba/__init__.py
@@ -54,7 +54,7 @@ class Ldb(ldb.Ldb):
functions see samdb.py.
"""
def __init__(self, url=None, session_info=None, credentials=None,
- modules_dir=None, lp=None):
+ modules_dir=None, lp=None, options=None):
"""Open a Samba Ldb file.
:param url: Optional LDB URL to open
@@ -67,7 +67,7 @@ class Ldb(ldb.Ldb):
modules-dir is used by default and that credentials and session_info
can be passed through (required by some modules).
"""
- super(Ldb, self).__init__()
+ super(Ldb, self).__init__(options=options)
if modules_dir is not None:
self.set_modules_dir(modules_dir)
@@ -90,7 +90,7 @@ class Ldb(ldb.Ldb):
#self.set_debug(msg)
if url is not None:
- self.connect(url)
+ self.connect(url, options=options)
def set_credentials(self, credentials):
glue.ldb_set_credentials(self, credentials)
diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py
index 1e34b11d0a..64908ccb4d 100644
--- a/source4/scripting/python/samba/provision.py
+++ b/source4/scripting/python/samba/provision.py
@@ -1051,7 +1051,7 @@ def provision(setup_dir, message, session_info,
serverrole=serverrole, ldap_backend=ldap_backend,
ldap_backend_type=ldap_backend_type)
- if lp.get("server role") == "domain controller":
+ if serverrole == "domain controller":
if paths.netlogon is None:
message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.")
message("Please either remove %s or see the template at %s" %
diff --git a/source4/selftest/config.mk b/source4/selftest/config.mk
index 324532c22a..1838a0bb38 100644
--- a/source4/selftest/config.mk
+++ b/source4/selftest/config.mk
@@ -59,31 +59,31 @@ test-%::
valgrindtest:: valgrindtest-all
valgrindtest-quick:: all
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS)
valgrindtest-all:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS)
valgrindtest-env:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \
VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv
gdbtest:: gdbtest-all
gdbtest-quick:: all
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS)
gdbtest-all:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS)
gdbtest-env:: everything
- SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
+ SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \
$(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv
diff --git a/source4/smbd/server.c b/source4/smbd/server.c
index d576782ab1..635e84fafe 100644
--- a/source4/smbd/server.c
+++ b/source4/smbd/server.c
@@ -365,5 +365,5 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[
int main(int argc, const char *argv[])
{
- return binary_smbd_main("smbd", argc, argv);
+ return binary_smbd_main("samba", argc, argv);
}
diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c
index 98669288a8..814c9ac86d 100644
--- a/source4/torture/ldap/cldap.c
+++ b/source4/torture/ldap/cldap.c
@@ -59,8 +59,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
CHECK_STATUS(status, NT_STATUS_OK);
ZERO_STRUCT(search);
- search.in.dest_address = NULL;//dest;
- search.in.dest_port = 0;//lp_cldap_port(tctx->lp_ctx);
+ search.in.dest_address = NULL;
+ search.in.dest_port = 0;
search.in.acct_control = -1;
search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
search.in.map_response = true;
diff --git a/source4/torture/smb2/config.mk b/source4/torture/smb2/config.mk
index e0fc29f278..70b1743929 100644
--- a/source4/torture/smb2/config.mk
+++ b/source4/torture/smb2/config.mk
@@ -20,8 +20,9 @@ TORTURE_SMB2_OBJ_FILES = $(addprefix $(torturesrcdir)/smb2/, \
lock.o \
notify.o \
smb2.o \
- persistent_handles.o \
+ durable_open.o \
oplocks.o \
+ lease.o \
create.o \
read.o)
diff --git a/source4/torture/smb2/persistent_handles.c b/source4/torture/smb2/durable_open.c
index 05c5dbbe85..9cc25e3408 100644
--- a/source4/torture/smb2/persistent_handles.c
+++ b/source4/torture/smb2/durable_open.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
- test suite for SMB2 persistent file handles
+ test suite for SMB2 durable opens
Copyright (C) Stefan Metzmacher 2008
@@ -41,19 +41,19 @@
goto done; \
}} while (0)
-/*
- basic testing of SMB2 persistent file handles
+/*
+ basic testing of SMB2 durable opens
regarding the position information on the handle
*/
-bool torture_smb2_persistent_handles1(struct torture_context *tctx,
- struct smb2_tree *tree1,
- struct smb2_tree *tree2)
+bool test_durable_open_file_position(struct torture_context *tctx,
+ struct smb2_tree *tree1,
+ struct smb2_tree *tree2)
{
TALLOC_CTX *mem_ctx = talloc_new(tctx);
struct smb2_handle h1, h2;
struct smb2_create io1, io2;
NTSTATUS status;
- const char *fname = "persistent_handles.dat";
+ const char *fname = "durable_open_position.dat";
DATA_BLOB b;
union smb_fileinfo qfinfo;
union smb_setfileinfo sfinfo;
@@ -181,3 +181,122 @@ bool torture_smb2_persistent_handles1(struct torture_context *tctx,
done:
return ret;
}
+
+/*
+ Open, disconnect, oplock break, reconnect.
+*/
+bool test_durable_open_oplock(struct torture_context *tctx,
+ struct smb2_tree *tree1,
+ struct smb2_tree *tree2)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_create io1, io2;
+ struct smb2_handle h1;
+ NTSTATUS status;
+ const char *fname = "durable_open_oplock.dat";
+ DATA_BLOB b;
+ bool ret = true;
+
+ /* Clean slate */
+ smb2_util_unlink(tree1, fname);
+
+ /* Create with batch oplock */
+ ZERO_STRUCT(io1);
+ io1.in.security_flags = 0x00;
+ io1.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH;
+ io1.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
+ io1.in.create_flags = 0x00000000;
+ io1.in.reserved = 0x00000000;
+ io1.in.desired_access = SEC_RIGHTS_FILE_ALL;
+ io1.in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ io1.in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ io1.in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+ io1.in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
+ NTCREATEX_OPTIONS_ASYNC_ALERT |
+ NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
+ 0x00200000;
+ io1.in.fname = fname;
+
+ io2 = io1;
+ io2.in.create_disposition = NTCREATEX_DISP_OPEN;
+
+ b = data_blob_talloc(mem_ctx, NULL, 16);
+ SBVAL(b.data, 0, 0);
+ SBVAL(b.data, 8, 0);
+
+ status = smb2_create_blob_add(tree1, &io1.in.blobs,
+ SMB2_CREATE_TAG_DHNQ,
+ b);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ status = smb2_create(tree1, mem_ctx, &io1);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
+ CHECK_VAL(io1.out.create_action, NTCREATEX_ACTION_CREATED);
+ CHECK_VAL(io1.out.alloc_size, 0);
+ CHECK_VAL(io1.out.size, 0);
+ CHECK_VAL(io1.out.file_attr, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_VAL(io1.out.reserved2, 0);
+
+ h1 = io1.out.file.handle;
+
+ /* Disconnect after getting the batch */
+ talloc_free(tree1);
+ tree1 = NULL;
+
+ /*
+ * Windows7 (build 7000) will break a batch oplock immediately if the
+ * original client is gone. (ZML: This seems like a bug. It should give
+ * some time for the client to reconnect!)
+ */
+ status = smb2_create(tree2, mem_ctx, &io2);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_VAL(io2.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH);
+ CHECK_VAL(io2.out.create_action, NTCREATEX_ACTION_EXISTED);
+ CHECK_VAL(io2.out.alloc_size, 0);
+ CHECK_VAL(io2.out.size, 0);
+ CHECK_VAL(io2.out.file_attr, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_VAL(io2.out.reserved2, 0);
+
+ /* What if tree1 tries to come back and reclaim? */
+ if (!torture_smb2_connection(tctx, &tree1)) {
+ torture_warning(tctx, "couldn't reconnect, bailing\n");
+ ret = false;
+ goto done;
+ }
+
+ ZERO_STRUCT(io2);
+ io2.in.fname = fname;
+
+ b = data_blob_talloc(tctx, NULL, 16);
+ SBVAL(b.data, 0, h1.data[0]);
+ SBVAL(b.data, 8, h1.data[1]);
+
+ status = smb2_create_blob_add(tree2, &io2.in.blobs,
+ SMB2_CREATE_TAG_DHNC,
+ b);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ status = smb2_create(tree2, mem_ctx, &io2);
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+
+done:
+ return ret;
+
+}
+
+struct torture_suite *torture_smb2_durable_open_init(void)
+{
+ struct torture_suite *suite =
+ torture_suite_create(talloc_autofree_context(), "DURABLE-OPEN");
+
+ torture_suite_add_2smb2_test(suite, "FILE-POSITION",
+ test_durable_open_file_position);
+ torture_suite_add_2smb2_test(suite, "OPLOCK", test_durable_open_oplock);
+
+ suite->description = talloc_strdup(suite, "SMB2-DURABLE-OPEN tests");
+
+ return suite;
+}
diff --git a/source4/torture/smb2/lease.c b/source4/torture/smb2/lease.c
new file mode 100644
index 0000000000..e67517324b
--- /dev/null
+++ b/source4/torture/smb2/lease.c
@@ -0,0 +1,296 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ test suite for SMB2 leases
+
+ Copyright (C) Zachary Loafman 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 "librpc/gen_ndr/security.h"
+#include "libcli/smb2/smb2.h"
+#include "libcli/smb2/smb2_calls.h"
+#include "torture/torture.h"
+#include "torture/smb2/proto.h"
+
+#define CHECK_VAL(v, correct) do { \
+ if ((v) != (correct)) { \
+ torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \
+ __location__, #v, (int)v, (int)correct); \
+ ret = false; \
+ }} while (0)
+
+#define CHECK_STATUS(status, correct) do { \
+ if (!NT_STATUS_EQUAL(status, correct)) { \
+ torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \
+ nt_errstr(status), nt_errstr(correct)); \
+ ret = false; \
+ goto done; \
+ }} while (0)
+
+static void smb2_lease_create(struct smb2_create *io, struct smb2_lease *ls,
+ bool dir, const char *name, uint64_t leasekey,
+ uint32_t leasestate)
+{
+ ZERO_STRUCT(*io);
+ io->in.security_flags = 0x00;
+ io->in.oplock_level = SMB2_OPLOCK_LEVEL_LEASE;
+ io->in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION;
+ io->in.create_flags = 0x00000000;
+ io->in.reserved = 0x00000000;
+ io->in.desired_access = SEC_RIGHTS_FILE_ALL;
+ io->in.file_attributes = FILE_ATTRIBUTE_NORMAL;
+ io->in.share_access = NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE |
+ NTCREATEX_SHARE_ACCESS_DELETE;
+ io->in.create_disposition = NTCREATEX_DISP_OPEN_IF;
+ io->in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY |
+ NTCREATEX_OPTIONS_ASYNC_ALERT |
+ NTCREATEX_OPTIONS_NON_DIRECTORY_FILE |
+ 0x00200000;
+ io->in.fname = name;
+
+ if (dir) {
+ io->in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
+ io->in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE;
+ io->in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
+ io->in.create_disposition = NTCREATEX_DISP_CREATE;
+ }
+
+ ZERO_STRUCT(*ls);
+ ls->lease_key[0] = leasekey;
+ ls->lease_key[1] = ~leasekey;
+ ls->lease_state = leasestate;
+ io->in.lease_request = ls;
+}
+
+#define CHECK_CREATED(__io, __created, __attribute) \
+ do { \
+ if (__created) { \
+ CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_CREATED); \
+ } else { \
+ CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_EXISTED); \
+ } \
+ CHECK_VAL((__io)->out.alloc_size, 0); \
+ CHECK_VAL((__io)->out.size, 0); \
+ CHECK_VAL((__io)->out.file_attr, (__attribute)); \
+ CHECK_VAL((__io)->out.reserved2, 0); \
+ } while(0)
+
+#define CHECK_LEASE(__io, __state, __oplevel, __key) \
+ do { \
+ if (__oplevel) { \
+ CHECK_VAL((__io)->out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE); \
+ CHECK_VAL((__io)->out.lease_response.lease_key[0], (__key)); \
+ CHECK_VAL((__io)->out.lease_response.lease_key[1], ~(__key)); \
+ CHECK_VAL((__io)->out.lease_response.lease_state, (__state)); \
+ } else { \
+ CHECK_VAL((__io)->out.oplock_level, SMB2_OPLOCK_LEVEL_NONE); \
+ CHECK_VAL((__io)->out.lease_response.lease_key[0], 0); \
+ CHECK_VAL((__io)->out.lease_response.lease_key[1], 0); \
+ CHECK_VAL((__io)->out.lease_response.lease_state, 0); \
+ } \
+ \
+ CHECK_VAL((__io)->out.lease_response.lease_flags, 0); \
+ CHECK_VAL((__io)->out.lease_response.lease_duration, 0); \
+ } while(0) \
+
+static const uint64_t LEASE1 = 0xBADC0FFEE0DDF00Dull;
+static const uint64_t LEASE2 = 0xDEADBEEFFEEDBEADull;
+static const uint64_t LEASE3 = 0xDAD0FFEDD00DF00Dull;
+
+#define NRESULTS 8
+static const int request_results[NRESULTS][2] = {
+ { SMB2_LEASE_NONE, SMB2_LEASE_NONE },
+ { SMB2_LEASE_READ, SMB2_LEASE_READ },
+ { SMB2_LEASE_HANDLE, SMB2_LEASE_NONE, },
+ { SMB2_LEASE_WRITE, SMB2_LEASE_NONE },
+ { SMB2_LEASE_READ|SMB2_LEASE_HANDLE,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE },
+ { SMB2_LEASE_READ|SMB2_LEASE_WRITE,
+ SMB2_LEASE_READ|SMB2_LEASE_WRITE },
+ { SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE, SMB2_LEASE_NONE },
+ { SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE },
+};
+
+static bool test_lease_request(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_create io;
+ struct smb2_lease ls;
+ struct smb2_handle h1, h2;
+ NTSTATUS status;
+ const char *fname = "lease.dat";
+ const char *fname2 = "lease2.dat";
+ const char *sname = "lease.dat:stream";
+ const char *dname = "lease.dir";
+ bool ret = true;
+ int i;
+
+ smb2_util_unlink(tree, fname);
+ smb2_util_unlink(tree, fname2);
+ smb2_util_rmdir(tree, dname);
+
+ /* Win7 is happy to grant RHW leases on files. */
+ smb2_lease_create(&io, &ls, false, fname, LEASE1,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ h1 = io.out.file.handle;
+ CHECK_CREATED(&io, true, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE,
+ true, LEASE1);
+
+ /* But will reject leases on directories. */
+ smb2_lease_create(&io, &ls, true, dname, LEASE2,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_CREATED(&io, true, FILE_ATTRIBUTE_DIRECTORY);
+ CHECK_LEASE(&io, SMB2_LEASE_NONE, false, 0);
+ smb2_util_close(tree, io.out.file.handle);
+
+ /* Also rejects multiple files leased under the same key. */
+ smb2_lease_create(&io, &ls, true, fname2, LEASE1,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+ /* And grants leases on streams (with separate leasekey). */
+ smb2_lease_create(&io, &ls, false, sname, LEASE2,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
+ status = smb2_create(tree, mem_ctx, &io);
+ h2 = io.out.file.handle;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_CREATED(&io, true, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE,
+ true, LEASE2);
+ smb2_util_close(tree, h2);
+
+ smb2_util_close(tree, h1);
+
+ /* Now see what combos are actually granted. */
+ for (i = 0; i < NRESULTS; i++) {
+ torture_comment(tctx, "Testing lease type %x, expecting %x\n",
+ request_results[i][0], request_results[i][1]);
+ smb2_lease_create(&io, &ls, false, fname, LEASE1,
+ request_results[i][0]);
+ status = smb2_create(tree, mem_ctx, &io);
+ h2 = io.out.file.handle;
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io, request_results[i][1], true, LEASE1);
+ smb2_util_close(tree, io.out.file.handle);
+ }
+
+ done:
+ smb2_util_close(tree, h1);
+ smb2_util_close(tree, h2);
+
+ smb2_util_unlink(tree, fname);
+ smb2_util_unlink(tree, fname2);
+ smb2_util_rmdir(tree, dname);
+
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+static bool test_lease_upgrade(struct torture_context *tctx,
+ struct smb2_tree *tree)
+{
+ TALLOC_CTX *mem_ctx = talloc_new(tctx);
+ struct smb2_create io;
+ struct smb2_lease ls;
+ struct smb2_handle h, hnew;
+ NTSTATUS status;
+ const char *fname = "lease.dat";
+ bool ret = true;
+
+ smb2_util_unlink(tree, fname);
+
+ /* Grab a RH lease. */
+ smb2_lease_create(&io, &ls, false, fname, LEASE1,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE);
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_CREATED(&io, true, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE, true, LEASE1);
+ h = io.out.file.handle;
+
+ /* Upgrades (sidegrades?) to RW leave us with an RH. */
+ smb2_lease_create(&io, &ls, false, fname, LEASE1,
+ SMB2_LEASE_READ|SMB2_LEASE_WRITE);
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE, true, LEASE1);
+ hnew = io.out.file.handle;
+
+ smb2_util_close(tree, hnew);
+
+ /* Upgrade to RHW lease. */
+ smb2_lease_create(&io, &ls, false, fname, LEASE1,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE,
+ true, LEASE1);
+ hnew = io.out.file.handle;
+
+ smb2_util_close(tree, h);
+ h = hnew;
+
+ /* Attempt to downgrade - original lease state is maintained. */
+ smb2_lease_create(&io, &ls, false, fname, LEASE1,
+ SMB2_LEASE_READ|SMB2_LEASE_HANDLE);
+ status = smb2_create(tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE);
+ CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE,
+ true, LEASE1);
+ hnew = io.out.file.handle;
+
+ smb2_util_close(tree, hnew);
+
+ done:
+ smb2_util_close(tree, h);
+ smb2_util_close(tree, hnew);
+
+ smb2_util_unlink(tree, fname);
+
+ talloc_free(mem_ctx);
+
+ return ret;
+}
+
+struct torture_suite *torture_smb2_lease_init(void)
+{
+ struct torture_suite *suite =
+ torture_suite_create(talloc_autofree_context(), "LEASE");
+
+ torture_suite_add_1smb2_test(suite, "REQUEST", test_lease_request);
+ torture_suite_add_1smb2_test(suite, "UPGRADE", test_lease_upgrade);
+
+ suite->description = talloc_strdup(suite, "SMB2-LEASE tests");
+
+ return suite;
+}
diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c
index 9418650de4..64456aaed5 100644
--- a/source4/torture/smb2/smb2.c
+++ b/source4/torture/smb2/smb2.c
@@ -100,11 +100,11 @@ static bool wrap_simple_2smb2_test(struct torture_context *torture_ctx,
}
-_PUBLIC_ struct torture_test *torture_suite_add_2smb2_test(struct torture_suite *suite,
- const char *name,
- bool (*run)(struct torture_context *,
- struct smb2_tree *,
- struct smb2_tree *))
+struct torture_test *torture_suite_add_2smb2_test(struct torture_suite *suite,
+ const char *name,
+ bool (*run)(struct torture_context *,
+ struct smb2_tree *,
+ struct smb2_tree *))
{
struct torture_test *test;
struct torture_tcase *tcase;
@@ -139,8 +139,9 @@ NTSTATUS torture_smb2_init(void)
torture_suite_add_suite(suite, torture_smb2_read_init());
torture_suite_add_suite(suite, torture_smb2_create_init());
torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify);
- torture_suite_add_2smb2_test(suite, "PERSISTENT-HANDLES1", torture_smb2_persistent_handles1);
+ torture_suite_add_suite(suite, torture_smb2_durable_open_init());
torture_suite_add_1smb2_test(suite, "OPLOCK-BATCH1", torture_smb2_oplock_batch1);
+ torture_suite_add_suite(suite, torture_smb2_lease_init());
suite->description = talloc_strdup(suite, "SMB2-specific tests");