summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2008-12-03 17:47:39 +1100
committerAndrew Tridgell <tridge@samba.org>2008-12-03 17:47:39 +1100
commita226d86dcec393b2cd657d5441c3041dfdf5cd8f (patch)
tree03ef7f3207607a4e5351bf50892b0a39dcf6f219 /source4
parent30eff4f31b497ac94d8ee02ee2ec24bc8865ce0d (diff)
parent85b8cccab072bab263061654b677bc84826646c9 (diff)
downloadsamba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.gz
samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.bz2
samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.zip
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source4')
-rw-r--r--source4/Makefile4
-rw-r--r--source4/auth/config.m46
-rw-r--r--source4/build/m4/check_python.m415
-rw-r--r--source4/build/m4/public.m413
-rw-r--r--source4/build/make/python.mk2
-rw-r--r--source4/configure.ac2
-rw-r--r--source4/dsdb/common/util.c33
-rw-r--r--source4/dsdb/config.mk2
-rw-r--r--source4/dsdb/samdb/ldb_modules/config.mk8
-rw-r--r--source4/dsdb/samdb/ldb_modules/linked_attributes.c41
-rw-r--r--source4/dsdb/samdb/ldb_modules/objectclass.c4
-rw-r--r--source4/dsdb/samdb/ldb_modules/schema_fsmo.c56
-rw-r--r--source4/dsdb/samdb/ldb_modules/tests/samba3sam.py6
-rw-r--r--source4/dsdb/schema/schema.h4
-rw-r--r--source4/dsdb/schema/schema_description.c142
-rw-r--r--source4/dsdb/schema/schema_init.c43
-rw-r--r--source4/dsdb/schema/schema_syntax.c9
-rw-r--r--source4/headermap.txt3
-rw-r--r--source4/ldap_server/ldap_backend.c22
-rw-r--r--source4/lib/ldb-samba/config.mk2
-rw-r--r--source4/lib/ldb/common/ldb_ldif.c6
-rw-r--r--source4/lib/ldb/ldb.i3
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.c9
-rw-r--r--source4/lib/ldb/ldb_tdb/ldb_tdb.h1
-rw-r--r--source4/lib/ldb/ldb_wrap.c1
-rw-r--r--source4/lib/registry/config.mk2
-rw-r--r--source4/lib/torture/config.mk14
-rw-r--r--source4/lib/torture/subunit.c96
-rw-r--r--source4/lib/torture/torture.c627
-rw-r--r--source4/lib/torture/torture.h425
-rw-r--r--source4/lib/torture/torture.pc.in12
-rw-r--r--source4/lib/wmi/config.mk2
-rw-r--r--source4/libcli/clideltree.c3
-rw-r--r--source4/libcli/ldap/ldap_bind.c2
-rw-r--r--source4/libcli/resolve/host.c22
-rw-r--r--source4/libcli/security/config.mk2
-rw-r--r--source4/libcli/util/nterr.c1
-rw-r--r--source4/libnet/groupinfo.c18
-rw-r--r--source4/libnet/groupman.c10
-rw-r--r--source4/libnet/libnet_domain.c21
-rw-r--r--source4/libnet/libnet_group.c16
-rw-r--r--source4/libnet/libnet_join.c25
-rw-r--r--source4/libnet/libnet_passwd.c22
-rw-r--r--source4/libnet/libnet_samsync_ldb.c6
-rw-r--r--source4/libnet/libnet_user.c16
-rw-r--r--source4/libnet/userinfo.c16
-rw-r--r--source4/libnet/userman.c33
-rw-r--r--source4/librpc/config.mk69
-rw-r--r--source4/librpc/idl/dom_sid.idl42
-rw-r--r--source4/librpc/idl/samr.idl1424
-rw-r--r--source4/librpc/idl/security.cnf1
-rw-r--r--source4/librpc/idl/security.idl410
-rw-r--r--source4/librpc/ndr/ndr_dom_sid.c (renamed from source4/librpc/ndr/ndr_sec_helper.c)63
-rw-r--r--source4/main.mk2
-rw-r--r--source4/ntvfs/posix/pvfs_resolve.c65
-rw-r--r--source4/rpc_server/dcerpc_server.c4
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c363
-rw-r--r--source4/rpc_server/samr/samr_password.c11
-rw-r--r--source4/rpc_server/service_rpc.c41
-rw-r--r--source4/selftest/knownfail1
-rw-r--r--source4/selftest/skip2
-rw-r--r--source4/setup/schema-map-fedora-ds-1.04
-rw-r--r--source4/setup/schema-map-openldap-2.34
-rw-r--r--source4/smbd/config.mk3
-rw-r--r--source4/smbd/service_named_pipe.c366
-rw-r--r--source4/torture/config.mk11
-rw-r--r--source4/torture/libnet/libnet_domain.c6
-rw-r--r--source4/torture/libnet/libnet_group.c9
-rw-r--r--source4/torture/libnet/libnet_user.c9
-rw-r--r--source4/torture/libnet/utils.c18
-rw-r--r--source4/torture/raw/acls.c16
-rw-r--r--source4/torture/raw/chkpath.c81
-rw-r--r--source4/torture/raw/streams.c429
-rw-r--r--source4/torture/rpc/eventlog.c8
-rw-r--r--source4/torture/rpc/netlogon.c535
-rw-r--r--source4/torture/rpc/ntsvcs.c169
-rw-r--r--source4/torture/rpc/rpc.c2
-rw-r--r--source4/torture/rpc/rpc.h3
-rw-r--r--source4/torture/rpc/samba3rpc.c61
-rw-r--r--source4/torture/rpc/samr.c1214
-rw-r--r--source4/torture/rpc/samr_accessmask.c29
-rw-r--r--source4/torture/rpc/samsync.c149
-rw-r--r--source4/torture/rpc/schannel.c2
-rw-r--r--source4/torture/rpc/svcctl.c178
-rw-r--r--source4/torture/rpc/testjoin.c19
-rw-r--r--source4/torture/smb2/config.mk2
-rw-r--r--source4/torture/smbtorture.h2
-rw-r--r--source4/torture/util.h2
-rw-r--r--source4/torture/winbind/config.mk2
-rw-r--r--source4/utils/ad2oLschema.c17
-rw-r--r--source4/utils/net/config.mk1
-rw-r--r--source4/utils/net/net.c2
-rw-r--r--source4/utils/net/net_machinepw.c91
-rw-r--r--source4/winbind/wb_async_helpers.c7
94 files changed, 3945 insertions, 3832 deletions
diff --git a/source4/Makefile b/source4/Makefile
index be41d02a38..38eb0706c9 100644
--- a/source4/Makefile
+++ b/source4/Makefile
@@ -11,7 +11,7 @@ include mkconfig.mk
pidldir := $(srcdir)/../pidl
basedir = $(prefix)
-torturedir = $(libdir)/torture
+torturedir = ../lib/torture
swatdir = $(datadir)/swat
setupdir = $(datadir)/setup
ncalrpcdir = $(localstatedir)/ncalrpc
@@ -78,7 +78,7 @@ libutilsrcdir := ../lib/util
libtdrsrcdir := lib/tdr
libdbwrapsrcdir := lib/dbwrap
libcryptosrcdir := ../lib/crypto
-libtorturesrcdir := lib/torture
+libtorturesrcdir := ../lib/torture
smb_serversrcdir := smb_server
libcompressionsrcdir := ../lib/compression
libgencachesrcdir := lib
diff --git a/source4/auth/config.m4 b/source4/auth/config.m4
index 1338b775ec..a271a9f6fe 100644
--- a/source4/auth/config.m4
+++ b/source4/auth/config.m4
@@ -20,11 +20,15 @@ AC_CHECK_FUNCS(crypt16 getauthuid getpwanam)
AC_CHECK_HEADERS(sasl/sasl.h)
AC_CHECK_LIB_EXT(sasl2, SASL_LIBS, sasl_client_init)
-SMB_EXT_LIB(SASL, $SASL_LIBS)
if test x"$ac_cv_header_sasl_sasl_h" = x"yes" -a x"$ac_cv_lib_ext_sasl2_sasl_client_init" = x"yes";then
SMB_ENABLE(SASL,YES)
SMB_ENABLE(cyrus_sasl,YES)
+ SASL_CFLAGS="$CFLAGS"
+ SASL_CPPFLAGS="$CPPFLAGS"
+ SASL_LDFLAGS="$LDFLAGS"
else
SMB_ENABLE(cyrus_sasl,NO)
fi
+
+SMB_EXT_LIB(SASL, $SASL_LIBS, [${SASL_CFLAGS}], [${SASL_CPPFLAGS}], [${SASL_LDFLAGS}])
diff --git a/source4/build/m4/check_python.m4 b/source4/build/m4/check_python.m4
index 96f93a3d75..7e56af76f7 100644
--- a/source4/build/m4/check_python.m4
+++ b/source4/build/m4/check_python.m4
@@ -71,8 +71,19 @@ AC_DEFUN([AC_SAMBA_PYTHON_DEVEL],
if test x$PYTHON != x
then
- DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; print '-I%s -I%s %s' % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=1), sysconfig.get_config_var('CFLAGS'))"`
- DISTUTILS_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; print '%s %s -lpython%s -L%s' % (sysconfig.get_config_var('LIBS'), sysconfig.get_config_var('SYSLIBS'), sysconfig.get_config_var('VERSION'), sysconfig.get_config_var('LIBPL'))"`
+ DISTUTILS_CFLAGS=`$PYTHON -c "from distutils import sysconfig; \
+ print '-I%s -I%s %s' % ( \
+ sysconfig.get_python_inc(), \
+ sysconfig.get_python_inc(plat_specific=1), \
+ sysconfig.get_config_var('CFLAGS'))"`
+ DISTUTILS_LDFLAGS=`$PYTHON -c "from distutils import sysconfig; \
+ print '%s %s -lpython%s -L%s %s -L%s' % ( \
+ sysconfig.get_config_var('LIBS'), \
+ sysconfig.get_config_var('SYSLIBS'), \
+ sysconfig.get_config_var('VERSION'), \
+ sysconfig.get_config_var('LIBDIR'), \
+ sysconfig.get_config_var('LDFLAGS'), \
+ sysconfig.get_config_var('LIBPL'))"`
TRY_LINK_PYTHON($DISTUTILS_LDFLAGS, $DISTUTILS_CFLAGS)
fi
diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4
index d61e00b22e..5be4189e06 100644
--- a/source4/build/m4/public.m4
+++ b/source4/build/m4/public.m4
@@ -188,10 +188,17 @@ use strict;
use vars qw(%enabled %config);
-%config = (AC_FOREACH([AC_Var], m4_defn([_AC_SUBST_VARS]), [
- AC_Var => '$AC_Var',])
-);
+%config = (
+CEOF
+
+for ac_var in $ac_subst_vars
+do
+ eval ac_val=\$$ac_var
+ echo "$ac_var => '$ac_val'," >> $1
+done
+cat >>$1<<CEOF
+);
$SMB_INFO_ENABLES
1;
CEOF
diff --git a/source4/build/make/python.mk b/source4/build/make/python.mk
index e307ba74bb..67a3e86215 100644
--- a/source4/build/make/python.mk
+++ b/source4/build/make/python.mk
@@ -46,7 +46,7 @@ swig:: pythonmods
.SUFFIXES: _wrap.c .i .py
%_wrap.c %.py: %.i
- [ "$(SWIG)" == "no" ] || $(SWIG) -O -Wall -python -keyword -I../source4 $<
+ [ "$(SWIG)" = "no" ] || $(SWIG) -O -Wall -python -keyword -I../source4 $<
realdistclean::
@echo "Removing SWIG output files"
diff --git a/source4/configure.ac b/source4/configure.ac
index cf85b13225..a90ac9e668 100644
--- a/source4/configure.ac
+++ b/source4/configure.ac
@@ -37,7 +37,7 @@ AC_CONFIG_FILES(lib/registry/registry.pc)
AC_CONFIG_FILES(lib/events/events.pc)
AC_CONFIG_FILES(librpc/dcerpc.pc)
AC_CONFIG_FILES(../librpc/ndr.pc)
-AC_CONFIG_FILES(lib/torture/torture.pc)
+AC_CONFIG_FILES(../lib/torture/torture.pc)
AC_CONFIG_FILES(auth/gensec/gensec.pc)
AC_CONFIG_FILES(param/samba-hostconfig.pc)
AC_CONFIG_FILES(librpc/dcerpc_samr.pc)
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 69e456274c..2161286e08 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -657,6 +657,28 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
return acct_flags;
}
+struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg,
+ const char *attr)
+{
+ struct lsa_BinaryString s;
+ const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
+
+ ZERO_STRUCT(s);
+
+ if (!val) {
+ return s;
+ }
+
+ s.array = talloc_array(mem_ctx, uint16_t, val->length/2);
+ if (!s.array) {
+ return s;
+ }
+ s.length = s.size = val->length/2;
+ memcpy(s.array, val->data, val->length);
+
+ return s;
+}
/* Find an attribute, with a particular value */
@@ -897,6 +919,17 @@ int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx,
}
/*
+ add a parameters element to a message
+*/
+int samdb_msg_add_parameters(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+ const char *attr_name, struct lsa_BinaryString *parameters)
+{
+ struct ldb_val val;
+ val.length = parameters->length * 2;
+ val.data = (uint8_t *)parameters->array;
+ return ldb_msg_add_value(msg, attr_name, &val, NULL);
+}
+/*
add a general value element to a message
*/
int samdb_msg_add_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg,
diff --git a/source4/dsdb/config.mk b/source4/dsdb/config.mk
index 8bc8b6e000..bd188192a0 100644
--- a/source4/dsdb/config.mk
+++ b/source4/dsdb/config.mk
@@ -6,7 +6,7 @@ mkinclude samdb/ldb_modules/config.mk
# Start SUBSYSTEM SAMDB
[SUBSYSTEM::SAMDB]
PUBLIC_DEPENDENCIES = HEIMDAL_KRB5
-PRIVATE_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI NDR_DRSBLOBS NSS_WRAPPER \
+PRIVATE_DEPENDENCIES = LIBNDR NDR_DRSUAPI NDR_DRSBLOBS NSS_WRAPPER \
auth_system_session LDAP_ENCODE LIBCLI_AUTH LIBNDR \
SAMDB_SCHEMA LDB_WRAP SAMDB_COMMON
diff --git a/source4/dsdb/samdb/ldb_modules/config.mk b/source4/dsdb/samdb/ldb_modules/config.mk
index 00e4f1af92..1387066256 100644
--- a/source4/dsdb/samdb/ldb_modules/config.mk
+++ b/source4/dsdb/samdb/ldb_modules/config.mk
@@ -2,7 +2,7 @@
# Start MODULE ldb_objectguid
[MODULE::ldb_objectguid]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR NDR_MISC
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR
INIT_FUNCTION = LDB_MODULE(objectguid)
# End MODULE ldb_objectguid
################################################
@@ -14,7 +14,7 @@ ldb_objectguid_OBJ_FILES = $(dsdbsrcdir)/samdb/ldb_modules/objectguid.o
[MODULE::ldb_repl_meta_data]
SUBSYSTEM = LIBLDB
PRIVATE_DEPENDENCIES = SAMDB LIBTALLOC LIBEVENTS \
- LIBNDR NDR_MISC NDR_DRSUAPI \
+ LIBNDR NDR_DRSUAPI \
NDR_DRSBLOBS LIBNDR
INIT_FUNCTION = LDB_MODULE(repl_meta_data)
# End MODULE ldb_repl_meta_data
@@ -75,7 +75,7 @@ ldb_pdc_fsmo_OBJ_FILES = \
# Start MODULE ldb_samldb
[MODULE::ldb_samldb]
SUBSYSTEM = LIBLDB
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE NDR_MISC SAMDB
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LDAP_ENCODE SAMDB
INIT_FUNCTION = LDB_MODULE(samldb)
#
# End MODULE ldb_samldb
@@ -102,7 +102,7 @@ ldb_samba3sam_OBJ_FILES = \
[MODULE::ldb_simple_ldap_map]
SUBSYSTEM = LIBLDB
INIT_FUNCTION = LDB_MODULE(entryuuid),LDB_MODULE(nsuniqueid)
-PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR NDR_MISC
+PRIVATE_DEPENDENCIES = LIBTALLOC LIBEVENTS LIBNDR
ENABLE = YES
ALIASES = entryuuid nsuniqueid
# End MODULE ldb_entryuuid
diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
index dd199c0137..f16eb215a6 100644
--- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c
+++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c
@@ -249,10 +249,14 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request *
return ldb_next_request(module, req);
}
- /* start with the first one */
- return la_do_mod_request(ac);
+ /* start with the original request */
+ return la_down_req(ac);
}
+/* For a delete or rename, we need to find out what linked attributes
+ * are currently on this DN, and then deal with them. This is the
+ * callback to the base search */
+
static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *ares)
{
const struct dsdb_attribute *schema_attr;
@@ -349,8 +353,8 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are
talloc_free(ares);
- /* All mods set up, start with the first one */
- ret = la_do_mod_request(ac);
+ /* Start with the original request */
+ ret = la_down_req(ac);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
@@ -539,8 +543,8 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques
} else {
if (ac->ops) {
- /* Jump directly to handling the modifies */
- ret = la_do_mod_request(ac);
+ /* Start with the original request */
+ ret = la_down_req(ac);
} else {
/* nothing to do for this module, proceed */
talloc_free(ac);
@@ -732,12 +736,8 @@ static int la_op_search_callback(struct ldb_request *req,
talloc_free(ares);
- if (ac->ops) {
- /* start the mod requests chain */
- ret = la_do_mod_request(ac);
- } else {
- ret = la_down_req(ac);
- }
+ /* start the mod requests chain */
+ ret = la_down_req(ac);
if (ret != LDB_SUCCESS) {
return ldb_module_done(ac->req, NULL, NULL, ret);
}
@@ -840,11 +840,13 @@ static int la_mod_callback(struct ldb_request *req, struct ldb_reply *ares)
talloc_free(os);
}
- /* as last op run the original request */
+ /* If we still have modifies in the queue, then run them */
if (ac->ops) {
ret = la_do_mod_request(ac);
} else {
- ret = la_down_req(ac);
+ /* Otherwise, we are done! */
+ ret = ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
}
if (ret != LDB_SUCCESS) {
@@ -898,6 +900,7 @@ static int la_down_req(struct la_context *ac)
return ldb_next_request(ac->module, down_req);
}
+/* Having done the original operation, then try to fix up all the linked attributes */
static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares)
{
struct la_context *ac;
@@ -920,9 +923,13 @@ static int la_down_callback(struct ldb_request *req, struct ldb_reply *ares)
return ldb_module_done(ac->req, NULL, NULL,
LDB_ERR_OPERATIONS_ERROR);
}
-
- return ldb_module_done(ac->req, ares->controls,
- ares->response, ares->error);
+ /* If we have modfies to make, then run them */
+ if (ac->ops) {
+ return la_do_mod_request(ac);
+ } else {
+ return ldb_module_done(ac->req, ares->controls,
+ ares->response, ares->error);
+ }
}
_PUBLIC_ const struct ldb_module_ops ldb_linked_attributes_module_ops = {
diff --git a/source4/dsdb/samdb/ldb_modules/objectclass.c b/source4/dsdb/samdb/ldb_modules/objectclass.c
index 7d00851792..1d240a33fe 100644
--- a/source4/dsdb/samdb/ldb_modules/objectclass.c
+++ b/source4/dsdb/samdb/ldb_modules/objectclass.c
@@ -414,10 +414,10 @@ static int objectclass_add(struct ldb_module *module, struct ldb_request *req)
return ldb_next_request(module, req);
}
- /* Need to object to this, but cn=rootdse doesn't have an objectClass... */
+ /* the objectClass must be specified on add */
if (ldb_msg_find_element(req->op.add.message,
"objectClass") == NULL) {
- return ldb_next_request(module, req);
+ return LDB_ERR_OBJECT_CLASS_VIOLATION;
}
ac = oc_init_context(module, req);
diff --git a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
index 0266654811..df409a8ae3 100644
--- a/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
+++ b/source4/dsdb/samdb/ldb_modules/schema_fsmo.c
@@ -38,6 +38,10 @@ static int generate_attributeTypes(struct ldb_context *ldb, struct ldb_message *
const struct dsdb_schema *schema);
static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message *msg,
const struct dsdb_schema *schema);
+static int generate_extendedAttributeInfo(struct ldb_context *ldb, struct ldb_message *msg,
+ const struct dsdb_schema *schema);
+static int generate_extendedClassInfo(struct ldb_context *ldb, struct ldb_message *msg,
+ const struct dsdb_schema *schema);
static const struct {
const char *attr;
@@ -54,6 +58,14 @@ static const struct {
{
.attr = "dITContentRules",
.fn = generate_dITContentRules
+ },
+ {
+ .attr = "extendedAttributeInfo",
+ .fn = generate_extendedAttributeInfo
+ },
+ {
+ .attr = "extendedClassInfo",
+ .fn = generate_extendedClassInfo
}
};
@@ -322,7 +334,51 @@ static int generate_dITContentRules(struct ldb_context *ldb, struct ldb_message
return LDB_SUCCESS;
}
+static int generate_extendedAttributeInfo(struct ldb_context *ldb,
+ struct ldb_message *msg,
+ const struct dsdb_schema *schema)
+{
+ const struct dsdb_attribute *attribute;
+ int ret;
+
+ for (attribute = schema->attributes; attribute; attribute = attribute->next) {
+ char *val = schema_attribute_to_extendedInfo(msg, attribute);
+ if (!val) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ ret = ldb_msg_add_string(msg, "extendedAttributeInfo", val);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ return LDB_SUCCESS;
+}
+
+static int generate_extendedClassInfo(struct ldb_context *ldb,
+ struct ldb_message *msg,
+ const struct dsdb_schema *schema)
+{
+ const struct dsdb_class *sclass;
+ int ret;
+
+ for (sclass = schema->classes; sclass; sclass = sclass->next) {
+ char *val = schema_class_to_extendedInfo(msg, sclass);
+ if (!val) {
+ ldb_oom(ldb);
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+ ret = ldb_msg_add_string(msg, "extendedClassInfo", val);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
+ return LDB_SUCCESS;
+}
/* Add objectClasses, attributeTypes and dITContentRules from the
schema object (they are not stored in the database)
diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
index 1fc531902d..fa1af2ad61 100644
--- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
+++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py
@@ -27,7 +27,7 @@ import ldb
from ldb import SCOPE_DEFAULT, SCOPE_BASE, SCOPE_SUBTREE
from samba import Ldb, substitute_var
from samba.tests import LdbTestCase, TestCaseInTempDir, cmdline_loadparm
-import samba.dcerpc.security
+import samba.dcerpc.dom_sid
import samba.security
import samba.ndr
@@ -50,7 +50,7 @@ class MapBaseTestCase(TestCaseInTempDir):
"@TO": "sambaDomainName=TESTS," + s3.basedn})
ldb.add({"dn": "@MODULES",
- "@LIST": "rootdse,paged_results,server_sort,extended_dn,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"})
+ "@LIST": "rootdse,paged_results,server_sort,asq,samldb,password_hash,operational,objectguid,rdn_name,samba3sam,partition"})
ldb.add({"dn": "@PARTITION",
"partition": ["%s:%s" % (s4.basedn, s4.url),
@@ -116,7 +116,7 @@ class MapBaseTestCase(TestCaseInTempDir):
super(MapBaseTestCase, self).tearDown()
def assertSidEquals(self, text, ndr_sid):
- sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.security.dom_sid,
+ sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.dom_sid.dom_sid,
str(ndr_sid[0]))
sid_obj2 = samba.security.Sid(text)
# For now, this is the only way we can compare these since the
diff --git a/source4/dsdb/schema/schema.h b/source4/dsdb/schema/schema.h
index 68dc8197cb..e8fefb5246 100644
--- a/source4/dsdb/schema/schema.h
+++ b/source4/dsdb/schema/schema.h
@@ -72,8 +72,8 @@ struct dsdb_attribute {
struct ldb_val oMObjectClass;
bool isSingleValued;
- uint32_t rangeLower;
- uint32_t rangeUpper;
+ uint32_t *rangeLower;
+ uint32_t *rangeUpper;
bool extendedCharsAllowed;
uint32_t schemaFlagsEx;
diff --git a/source4/dsdb/schema/schema_description.c b/source4/dsdb/schema/schema_description.c
index c3c37b4653..9443c04bb0 100644
--- a/source4/dsdb/schema/schema_description.c
+++ b/source4/dsdb/schema/schema_description.c
@@ -20,6 +20,7 @@
*/
#include "includes.h"
#include "dsdb/samdb/samdb.h"
+#include "librpc/ndr/libndr.h"
#define IF_NULL_FAIL_RET(x) do { \
if (!x) { \
@@ -36,7 +37,12 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
const char *equality,
const char *substring,
const char *syntax,
- bool single_value, bool operational)
+ bool single_value, bool operational,
+ uint32_t *range_lower,
+ uint32_t *range_upper,
+ const char *property_guid,
+ const char *property_set_guid,
+ bool indexed, bool system_only)
{
char *schema_entry = talloc_asprintf(mem_ctx,
"(%s%s%s", seperator, oid, seperator);
@@ -55,11 +61,13 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
"SUBSTR %s%s", substring, seperator);
IF_NULL_FAIL_RET(schema_entry);
}
-
- schema_entry = talloc_asprintf_append(schema_entry,
- "SYNTAX %s%s", syntax, seperator);
- IF_NULL_FAIL_RET(schema_entry);
-
+
+ if (syntax) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "SYNTAX %s%s", syntax, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
if (single_value) {
schema_entry = talloc_asprintf_append(schema_entry,
"SINGLE-VALUE%s", seperator);
@@ -71,7 +79,47 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
"NO-USER-MODIFICATION%s", seperator);
IF_NULL_FAIL_RET(schema_entry);
}
-
+
+ if (range_lower) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "RANGE-LOWER '%u'%s",
+ *range_lower, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (range_upper) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "RANGE-UPPER '%u'%s",
+ *range_upper, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (property_guid) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "PROPERTY-GUID '%s'%s",
+ property_guid, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (property_set_guid) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "PROPERTY-SET-GUID '%s'%s",
+ property_set_guid, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (indexed) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "INDEXED%s", seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
+ if (system_only) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "SYSTEM-ONLY%s", seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
schema_entry = talloc_asprintf_append(schema_entry,
")");
return schema_entry;
@@ -80,14 +128,12 @@ char *schema_attribute_description(TALLOC_CTX *mem_ctx,
char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute)
{
char *schema_description;
- const struct dsdb_syntax *map = find_syntax_map_by_ad_oid(attribute->attributeSyntax_oid);
- const char *syntax = map ? map->ldap_oid : attribute->attributeSyntax_oid;
+ const char *syntax = attribute->syntax->ldap_oid;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
if (!tmp_ctx) {
return NULL;
}
-
schema_description
= schema_attribute_description(mem_ctx,
TARGET_AD_SCHEMA_SUBENTRY,
@@ -96,6 +142,34 @@ char *schema_attribute_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_att
attribute->lDAPDisplayName,
NULL, NULL, talloc_asprintf(tmp_ctx, "'%s'", syntax),
attribute->isSingleValued,
+ attribute->systemOnly,/* TODO: is this correct? */
+ NULL, NULL, NULL, NULL,
+ false, false);
+ talloc_free(tmp_ctx);
+ return schema_description;
+}
+
+char *schema_attribute_to_extendedInfo(TALLOC_CTX *mem_ctx, const struct dsdb_attribute *attribute)
+{
+ char *schema_description;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return NULL;
+ }
+
+ schema_description
+ = schema_attribute_description(mem_ctx,
+ TARGET_AD_SCHEMA_SUBENTRY,
+ " ",
+ attribute->attributeID_oid,
+ attribute->lDAPDisplayName,
+ NULL, NULL, NULL,
+ false, false,
+ attribute->rangeLower,
+ attribute->rangeUpper,
+ GUID_hexstring(tmp_ctx, &attribute->schemaIDGUID),
+ GUID_hexstring(tmp_ctx, &attribute->attributeSecurityGUID),
+ (attribute->searchFlags & SEARCH_FLAG_ATTINDEX),
attribute->systemOnly);
talloc_free(tmp_ctx);
return schema_description;
@@ -142,7 +216,8 @@ char *schema_class_description(TALLOC_CTX *mem_ctx,
const char *subClassOf,
int objectClassCategory,
char **must,
- char **may)
+ char **may,
+ const char *schemaHexGUID)
{
char *schema_entry = talloc_asprintf(mem_ctx,
"(%s%s%s", seperator, oid, seperator);
@@ -225,7 +300,14 @@ char *schema_class_description(TALLOC_CTX *mem_ctx,
")%s", seperator);
IF_NULL_FAIL_RET(schema_entry);
}
-
+
+ if (schemaHexGUID) {
+ schema_entry = talloc_asprintf_append(schema_entry,
+ "CLASS-GUID '%s'%s",
+ schemaHexGUID, seperator);
+ IF_NULL_FAIL_RET(schema_entry);
+ }
+
schema_entry = talloc_asprintf_append(schema_entry,
")");
return schema_entry;
@@ -251,7 +333,8 @@ char *schema_class_to_description(TALLOC_CTX *mem_ctx, const struct dsdb_class *
dsdb_attribute_list(tmp_ctx,
class, DSDB_SCHEMA_ALL_MUST),
dsdb_attribute_list(tmp_ctx,
- class, DSDB_SCHEMA_ALL_MAY));
+ class, DSDB_SCHEMA_ALL_MAY),
+ NULL);
talloc_free(tmp_ctx);
return schema_description;
}
@@ -295,7 +378,38 @@ char *schema_class_to_dITContentRule(TALLOC_CTX *mem_ctx, const struct dsdb_clas
* ditContentRules
* per MS-ADTS
* 3.1.1.3.1.1.1 */
- -1, must_attr_list, may_attr_list);
+ -1, must_attr_list, may_attr_list,
+ NULL);
talloc_free(tmp_ctx);
return schema_description;
}
+
+char *schema_class_to_extendedInfo(TALLOC_CTX *mem_ctx, const struct dsdb_class *sclass)
+{
+ char *schema_description = NULL;
+ DATA_BLOB guid_blob;
+ char *guid_hex;
+ TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
+ if (!tmp_ctx) {
+ return NULL;
+ }
+
+ schema_description
+ = schema_class_description(mem_ctx,
+ TARGET_AD_SCHEMA_SUBENTRY,
+ " ",
+ sclass->governsID_oid,
+ sclass->lDAPDisplayName,
+ NULL,
+ NULL, /* Must not specify a
+ * SUP (subclass) in
+ * ditContentRules
+ * per MS-ADTS
+ * 3.1.1.3.1.1.1 */
+ -1, NULL, NULL,
+ GUID_hexstring(tmp_ctx, &sclass->schemaIDGUID));
+ talloc_free(tmp_ctx);
+ return schema_description;
+}
+
+
diff --git a/source4/dsdb/schema/schema_init.c b/source4/dsdb/schema/schema_init.c
index 6561e8ed88..763872cf2b 100644
--- a/source4/dsdb/schema/schema_init.c
+++ b/source4/dsdb/schema/schema_init.c
@@ -643,6 +643,24 @@ WERROR dsdb_read_prefixes_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb,
(p)->elem = samdb_result_uint(msg, attr, 0);\
} while (0)
+#define GET_UINT32_PTR_LDB(msg, attr, p, elem) do { \
+ uint64_t _v = samdb_result_uint64(msg, attr, UINT64_MAX);\
+ if (_v == UINT64_MAX) { \
+ (p)->elem = NULL; \
+ } else if (_v > UINT32_MAX) { \
+ d_printf("%s: %s == 0x%llX\n", __location__, \
+ attr, (unsigned long long)_v); \
+ return WERR_INVALID_PARAM; \
+ } else { \
+ (p)->elem = talloc(mem_ctx, uint32_t); \
+ if (!(p)->elem) { \
+ d_printf("%s: talloc failed for %s\n", __location__, attr); \
+ return WERR_NOMEM; \
+ } \
+ *(p)->elem = (uint32_t)_v; \
+ } \
+} while (0)
+
#define GET_GUID_LDB(msg, attr, p, elem) do { \
(p)->elem = samdb_result_guid(msg, attr);\
} while (0)
@@ -707,8 +725,8 @@ WERROR dsdb_attribute_from_ldb(const struct dsdb_schema *schema,
GET_BLOB_LDB(msg, "oMObjectClass", mem_ctx, attr, oMObjectClass);
GET_BOOL_LDB(msg, "isSingleValued", attr, isSingleValued, true);
- GET_UINT32_LDB(msg, "rangeLower", attr, rangeLower);
- GET_UINT32_LDB(msg, "rangeUpper", attr, rangeUpper);
+ GET_UINT32_PTR_LDB(msg, "rangeLower", attr, rangeLower);
+ GET_UINT32_PTR_LDB(msg, "rangeUpper", attr, rangeUpper);
GET_BOOL_LDB(msg, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
GET_UINT32_LDB(msg, "schemaFlagsEx", attr, schemaFlagsEx);
@@ -1260,6 +1278,23 @@ static struct drsuapi_DsReplicaAttribute *dsdb_find_object_attr_name(struct dsdb
} \
} while (0)
+#define GET_UINT32_PTR_DS(s, r, attr, p, elem) do { \
+ struct drsuapi_DsReplicaAttribute *_a; \
+ _a = dsdb_find_object_attr_name(s, r, attr, NULL); \
+ if (_a && _a->value_ctr.num_values >= 1 \
+ && _a->value_ctr.values[0].blob \
+ && _a->value_ctr.values[0].blob->length == 4) { \
+ (p)->elem = talloc(mem_ctx, uint32_t); \
+ if (!(p)->elem) { \
+ d_printf("%s: talloc failed for %s\n", __location__, attr); \
+ return WERR_NOMEM; \
+ } \
+ *(p)->elem = IVAL(_a->value_ctr.values[0].blob->data,0);\
+ } else { \
+ (p)->elem = NULL; \
+ } \
+} while (0)
+
#define GET_GUID_DS(s, r, attr, mem_ctx, p, elem) do { \
struct drsuapi_DsReplicaAttribute *_a; \
_a = dsdb_find_object_attr_name(s, r, attr, NULL); \
@@ -1330,8 +1365,8 @@ WERROR dsdb_attribute_from_drsuapi(struct dsdb_schema *schema,
GET_BLOB_DS(schema, r, "oMObjectClass", mem_ctx, attr, oMObjectClass);
GET_BOOL_DS(schema, r, "isSingleValued", attr, isSingleValued, true);
- GET_UINT32_DS(schema, r, "rangeLower", attr, rangeLower);
- GET_UINT32_DS(schema, r, "rangeUpper", attr, rangeUpper);
+ GET_UINT32_PTR_DS(schema, r, "rangeLower", attr, rangeLower);
+ GET_UINT32_PTR_DS(schema, r, "rangeUpper", attr, rangeUpper);
GET_BOOL_DS(schema, r, "extendedCharsAllowed", attr, extendedCharsAllowed, false);
GET_UINT32_DS(schema, r, "schemaFlagsEx", attr, schemaFlagsEx);
diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c
index e0e6b3fc77..7aed08605b 100644
--- a/source4/dsdb/schema/schema_syntax.c
+++ b/source4/dsdb/schema/schema_syntax.c
@@ -1278,9 +1278,9 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.attributeSyntax_oid = "2.5.5.7",
.drsuapi_to_ldb = dsdb_syntax_DN_BINARY_drsuapi_to_ldb,
.ldb_to_drsuapi = dsdb_syntax_DN_BINARY_ldb_to_drsuapi,
- .equality = "distinguishedNameMatch",
+ .equality = "octetStringMatch",
.comment = "OctetString: Binary+DN",
- .ldb_syntax = LDB_SYNTAX_DN,
+ .ldb_syntax = LDB_SYNTAX_OCTET_STRING,
},{
/* not used in w2k3 schema */
.name = "Object(OR-Name)",
@@ -1322,9 +1322,6 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.attributeSyntax_oid = "2.5.5.14",
.drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
.ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
- .equality = "distinguishedNameMatch",
- .comment = "OctetString: String+DN",
- .ldb_syntax = LDB_SYNTAX_DN,
},{
/* not used in w2k3 schema */
.name = "Object(DN-String)",
@@ -1334,6 +1331,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = {
.attributeSyntax_oid = "2.5.5.14",
.drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb,
.ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi,
+ .equality = "distinguishedNameMatch",
+ .comment = "OctetString: String+DN",
.ldb_syntax = LDB_SYNTAX_DN,
}
};
diff --git a/source4/headermap.txt b/source4/headermap.txt
index cb5a4fab4c..b6edaac414 100644
--- a/source4/headermap.txt
+++ b/source4/headermap.txt
@@ -43,6 +43,7 @@ librpc/gen_ndr/samr.h: gen_ndr/samr.h
librpc/gen_ndr/ndr_samr.h: gen_ndr/ndr_samr.h
librpc/gen_ndr/ndr_samr_c.h: gen_ndr/ndr_samr_c.h
librpc/gen_ndr/security.h: gen_ndr/security.h
+librpc/gen_ndr/dom_sid.h: gen_ndr/dom_sid.h
auth/credentials/credentials.h: credentials.h
auth/credentials/credentials_krb5.h: credentials/krb5.h
rpc_server/dcerpc_server.h: dcerpc_server.h
@@ -50,7 +51,7 @@ rpc_server/common/common.h: dcerpc_server/common.h
libcli/auth/credentials.h: domain_credentials.h
../lib/util/charset/charset.h: charset.h
libcli/ldap/ldap.h: ldap.h
-lib/torture/torture.h: torture.h
+../lib/torture/torture.h: torture.h
libcli/libcli.h: client.h
librpc/gen_ndr/nbt.h: gen_ndr/nbt.h
librpc/gen_ndr/ntp_signd.h: gen_ndr/ntp_signd.h
diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c
index d0417107f1..2adff2a1df 100644
--- a/source4/ldap_server/ldap_backend.c
+++ b/source4/ldap_server/ldap_backend.c
@@ -29,17 +29,13 @@
#include "lib/ldb/include/ldb_errors.h"
#include "lib/ldb_wrap.h"
-#define VALID_DN_SYNTAX(dn,i) do {\
+#define VALID_DN_SYNTAX(dn) do {\
if (!(dn)) {\
return NT_STATUS_NO_MEMORY;\
} else if ( ! ldb_dn_validate(dn)) {\
result = LDAP_INVALID_DN_SYNTAX;\
errstr = "Invalid DN format";\
goto reply;\
- } else if (ldb_dn_get_comp_num(dn) < (i)) {\
- result = LDAP_INVALID_DN_SYNTAX;\
- errstr = "Invalid DN (" #i " components needed for '" #dn "')";\
- goto reply;\
}\
} while(0)
@@ -179,7 +175,7 @@ static NTSTATUS ldapsrv_SearchRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
basedn = ldb_dn_new(local_ctx, samdb, req->basedn);
- VALID_DN_SYNTAX(basedn, 0);
+ VALID_DN_SYNTAX(basedn);
DEBUG(10, ("SearchRequest: basedn: [%s]\n", req->basedn));
DEBUG(10, ("SearchRequest: filter: [%s]\n", ldb_filter_from_tree(call, req->tree)));
@@ -349,7 +345,7 @@ static NTSTATUS ldapsrv_ModifyRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn, 0);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("ModifyRequest: dn: [%s]\n", req->dn));
@@ -452,7 +448,7 @@ static NTSTATUS ldapsrv_AddRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn,1);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("AddRequest: dn: [%s]\n", req->dn));
@@ -542,7 +538,7 @@ static NTSTATUS ldapsrv_DelRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn,1);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("DelRequest: dn: [%s]\n", req->dn));
@@ -588,10 +584,10 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
olddn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(olddn, 2);
+ VALID_DN_SYNTAX(olddn);
newrdn = ldb_dn_new(local_ctx, samdb, req->newrdn);
- VALID_DN_SYNTAX(newrdn, 1);
+ VALID_DN_SYNTAX(newrdn);
DEBUG(10, ("ModifyDNRequest: olddn: [%s]\n", req->dn));
DEBUG(10, ("ModifyDNRequest: newrdn: [%s]\n", req->newrdn));
@@ -605,7 +601,7 @@ static NTSTATUS ldapsrv_ModifyDNRequest(struct ldapsrv_call *call)
if (req->newsuperior) {
parentdn = ldb_dn_new(local_ctx, samdb, req->newsuperior);
- VALID_DN_SYNTAX(parentdn, 0);
+ VALID_DN_SYNTAX(parentdn);
DEBUG(10, ("ModifyDNRequest: newsuperior: [%s]\n", req->newsuperior));
if (ldb_dn_get_comp_num(parentdn) < 1) {
@@ -672,7 +668,7 @@ static NTSTATUS ldapsrv_CompareRequest(struct ldapsrv_call *call)
NT_STATUS_HAVE_NO_MEMORY(local_ctx);
dn = ldb_dn_new(local_ctx, samdb, req->dn);
- VALID_DN_SYNTAX(dn, 1);
+ VALID_DN_SYNTAX(dn);
DEBUG(10, ("CompareRequest: dn: [%s]\n", req->dn));
filter = talloc_asprintf(local_ctx, "(%s=%*s)", req->attribute,
diff --git a/source4/lib/ldb-samba/config.mk b/source4/lib/ldb-samba/config.mk
index f84b44dfc7..ceacf277e4 100644
--- a/source4/lib/ldb-samba/config.mk
+++ b/source4/lib/ldb-samba/config.mk
@@ -2,7 +2,7 @@
# Start SUBSYSTEM LDBSAMBA
[SUBSYSTEM::LDBSAMBA]
PUBLIC_DEPENDENCIES = LIBLDB
-PRIVATE_DEPENDENCIES = LIBSECURITY SAMDB_SCHEMA LIBNDR NDR_MISC NDR_DRSBLOBS
+PRIVATE_DEPENDENCIES = LIBSECURITY SAMDB_SCHEMA LIBNDR NDR_DRSBLOBS
# End SUBSYSTEM LDBSAMBA
################################################
diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c
index 538ff8feaa..69490e670b 100644
--- a/source4/lib/ldb/common/ldb_ldif.c
+++ b/source4/lib/ldb/common/ldb_ldif.c
@@ -328,8 +328,10 @@ int ldb_ldif_write(struct ldb_context *ldb,
for (j=0;j<msg->elements[i].num_values;j++) {
struct ldb_val v;
ret = a->syntax->ldif_write_fn(ldb, mem_ctx, &msg->elements[i].values[j], &v);
- CHECK_RET;
- if (ldb_should_b64_encode(&v)) {
+ if (ret != LDB_SUCCESS) {
+ v = msg->elements[i].values[j];
+ }
+ if (ret != LDB_SUCCESS || ldb_should_b64_encode(&v)) {
ret = fprintf_fn(private_data, "%s:: ",
msg->elements[i].name);
CHECK_RET;
diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i
index 35d443e809..0f05c1fbab 100644
--- a/source4/lib/ldb/ldb.i
+++ b/source4/lib/ldb/ldb.i
@@ -217,7 +217,7 @@ typedef struct ldb_dn {
we do it this way... */
talloc_steal(NULL, ret);
- if (ret == NULL)
+ if (ret == NULL || !ldb_dn_validate(ret))
SWIG_exception(SWIG_ValueError,
"unable to parse dn string");
fail:
@@ -263,7 +263,6 @@ fail:
{
char *dn = ldb_dn_get_linearized($self), *ret;
asprintf(&ret, "Dn('%s')", dn);
- talloc_free(dn);
return ret;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
index 34a4e03965..9e3ad80705 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c
@@ -1076,12 +1076,14 @@ static void ltdb_callback(struct event_context *ev,
}
if (!ctx->callback_failed) {
+ /* Once we are done, we do not need timeout events */
+ talloc_free(ctx->timeout_event);
ltdb_request_done(ctx->req, ret);
}
}
static int ltdb_handle_request(struct ldb_module *module,
- struct ldb_request *req)
+ struct ldb_request *req)
{
struct event_context *ev;
struct ltdb_context *ac;
@@ -1115,10 +1117,9 @@ static int ltdb_handle_request(struct ldb_module *module,
return LDB_ERR_OPERATIONS_ERROR;
}
-
tv.tv_sec = req->starttime + req->timeout;
- te = event_add_timed(ev, ac, tv, ltdb_timeout, ac);
- if (NULL == te) {
+ ac->timeout_event = event_add_timed(ev, ac, tv, ltdb_timeout, ac);
+ if (NULL == ac->timeout_event) {
return LDB_ERR_OPERATIONS_ERROR;
}
diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
index 61e90bccc6..c78a8172c7 100644
--- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h
+++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h
@@ -50,6 +50,7 @@ struct ltdb_context {
struct ldb_dn *base;
enum ldb_scope scope;
const char * const *attrs;
+ struct timed_event *timeout_event;
};
/* special record types */
diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c
index 194b562c30..4a34c1c998 100644
--- a/source4/lib/ldb/ldb_wrap.c
+++ b/source4/lib/ldb/ldb_wrap.c
@@ -2732,7 +2732,6 @@ SWIGINTERN char const *ldb_dn_canonical_ex_str(ldb_dn *self){
SWIGINTERN char *ldb_dn___repr__(ldb_dn *self){
char *dn = ldb_dn_get_linearized(self), *ret;
asprintf(&ret, "Dn('%s')", dn);
- talloc_free(dn);
return ret;
}
SWIGINTERN ldb_dn *ldb_dn___add__(ldb_dn *self,ldb_dn *other){
diff --git a/source4/lib/registry/config.mk b/source4/lib/registry/config.mk
index 2e2b45abe9..9af61f9632 100644
--- a/source4/lib/registry/config.mk
+++ b/source4/lib/registry/config.mk
@@ -97,7 +97,7 @@ regtree_OBJ_FILES = $(libregistrysrcdir)/tools/regtree.o
MANPAGES += $(libregistrysrcdir)/man/regtree.1
[SUBSYSTEM::torture_registry]
-PRIVATE_DEPENDENCIES = registry
+PRIVATE_DEPENDENCIES = torture registry
torture_registry_OBJ_FILES = $(addprefix $(libregistrysrcdir)/tests/, generic.o hive.o diff.o registry.o)
diff --git a/source4/lib/torture/config.mk b/source4/lib/torture/config.mk
deleted file mode 100644
index 8a7f2a3b6b..0000000000
--- a/source4/lib/torture/config.mk
+++ /dev/null
@@ -1,14 +0,0 @@
-# TORTURE subsystem
-[LIBRARY::torture]
-PUBLIC_DEPENDENCIES = \
- LIBSAMBA-HOSTCONFIG \
- LIBSAMBA-UTIL \
- LIBTALLOC
-
-torture_VERSION = 0.0.1
-torture_SOVERSION = 0
-
-PC_FILES += $(libtorturesrcdir)/torture.pc
-torture_OBJ_FILES = $(addprefix $(libtorturesrcdir)/, torture.o subunit.o)
-
-PUBLIC_HEADERS += $(libtorturesrcdir)/torture.h
diff --git a/source4/lib/torture/subunit.c b/source4/lib/torture/subunit.c
deleted file mode 100644
index d5ee344596..0000000000
--- a/source4/lib/torture/subunit.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Samba utility functions
- Copyright (C) Jelmer Vernooij <jelmer@samba.org> 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 "lib/torture/torture.h"
-
-static void subunit_init(struct torture_results *results)
-{
- /* FIXME: register segv and bus handler */
-}
-
-static void subunit_suite_start(struct torture_context *ctx,
- struct torture_suite *suite)
-{
-}
-
-static void subunit_print_testname(struct torture_context *ctx,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- if (!strcmp(tcase->name, test->name)) {
- printf("%s", test->name);
- } else {
- printf("%s.%s", tcase->name, test->name);
- }
-}
-
-static void subunit_test_start(struct torture_context *ctx,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- printf("test: ");
- subunit_print_testname(ctx, tcase, test);
- printf("\n");
-}
-
-static void subunit_test_result(struct torture_context *context,
- enum torture_result res, const char *reason)
-{
- switch (res) {
- case TORTURE_OK:
- printf("success: ");
- break;
- case TORTURE_FAIL:
- printf("failure: ");
- break;
- case TORTURE_ERROR:
- printf("error: ");
- break;
- case TORTURE_SKIP:
- printf("skip: ");
- break;
- }
- subunit_print_testname(context, context->active_tcase, context->active_test);
-
- if (reason)
- printf(" [\n%s\n]", reason);
- printf("\n");
-}
-
-static void subunit_comment(struct torture_context *test,
- const char *comment)
-{
- fprintf(stderr, "%s", comment);
-}
-
-static void subunit_warning(struct torture_context *test,
- const char *comment)
-{
- fprintf(stderr, "WARNING!: %s\n", comment);
-}
-
-const struct torture_ui_ops torture_subunit_ui_ops = {
- .init = subunit_init,
- .comment = subunit_comment,
- .warning = subunit_warning,
- .test_start = subunit_test_start,
- .test_result = subunit_test_result,
- .suite_start = subunit_suite_start
-};
diff --git a/source4/lib/torture/torture.c b/source4/lib/torture/torture.c
deleted file mode 100644
index e465529f6b..0000000000
--- a/source4/lib/torture/torture.c
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture UI functions
-
- Copyright (C) Jelmer Vernooij 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 "torture/torture.h"
-#include "../lib/util/dlinklist.h"
-#include "param/param.h"
-#include "system/filesys.h"
-
-struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops)
-{
- struct torture_results *results = talloc_zero(mem_ctx, struct torture_results);
-
- results->ui_ops = ui_ops;
- results->returncode = true;
-
- if (ui_ops->init)
- ui_ops->init(results);
-
- return results;
-}
-
-/**
- * Initialize a torture context
- */
-struct torture_context *torture_context_init(struct event_context *event_ctx,
- struct torture_results *results)
-{
- struct torture_context *torture = talloc_zero(event_ctx,
- struct torture_context);
-
- if (torture == NULL)
- return NULL;
-
- torture->ev = event_ctx;
- torture->results = talloc_reference(torture, results);
-
- return torture;
-}
-
-/**
- * Create a sub torture context
- */
-struct torture_context *torture_context_child(struct torture_context *parent)
-{
- struct torture_context *subtorture = talloc_zero(parent, struct torture_context);
-
- if (subtorture == NULL)
- return NULL;
-
- subtorture->level = parent->level+1;
- subtorture->ev = talloc_reference(subtorture, parent->ev);
- subtorture->lp_ctx = talloc_reference(subtorture, parent->lp_ctx);
- subtorture->outputdir = talloc_reference(subtorture, parent->outputdir);
- subtorture->results = talloc_reference(subtorture, parent->results);
-
- return subtorture;
-}
-
-/**
- create a temporary directory.
-*/
-_PUBLIC_ NTSTATUS torture_temp_dir(struct torture_context *tctx,
- const char *prefix,
- char **tempdir)
-{
- SMB_ASSERT(tctx->outputdir != NULL);
-
- *tempdir = talloc_asprintf(tctx, "%s/%s.XXXXXX", tctx->outputdir,
- prefix);
- NT_STATUS_HAVE_NO_MEMORY(*tempdir);
-
- if (mkdtemp(*tempdir) == NULL) {
- return map_nt_error_from_unix(errno);
- }
-
- return NT_STATUS_OK;
-}
-
-/**
- * Comment on the status/progress of a test
- */
-void torture_comment(struct torture_context *context, const char *comment, ...)
-{
- va_list ap;
- char *tmp;
-
- if (!context->results->ui_ops->comment)
- return;
-
- va_start(ap, comment);
- tmp = talloc_vasprintf(context, comment, ap);
-
- context->results->ui_ops->comment(context, tmp);
-
- talloc_free(tmp);
-}
-
-/**
- * Print a warning about the current test
- */
-void torture_warning(struct torture_context *context, const char *comment, ...)
-{
- va_list ap;
- char *tmp;
-
- if (!context->results->ui_ops->warning)
- return;
-
- va_start(ap, comment);
- tmp = talloc_vasprintf(context, comment, ap);
-
- context->results->ui_ops->warning(context, tmp);
-
- talloc_free(tmp);
-}
-
-/**
- * Store the result of a torture test.
- */
-void torture_result(struct torture_context *context,
- enum torture_result result, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
-
- if (context->last_reason) {
- torture_warning(context, "%s", context->last_reason);
- talloc_free(context->last_reason);
- }
-
- context->last_result = result;
- context->last_reason = talloc_vasprintf(context, fmt, ap);
- va_end(ap);
-}
-
-/**
- * Create a new torture suite
- */
-struct torture_suite *torture_suite_create(TALLOC_CTX *ctx, const char *name)
-{
- struct torture_suite *suite = talloc_zero(ctx, struct torture_suite);
-
- suite->name = talloc_strdup(suite, name);
- suite->testcases = NULL;
- suite->children = NULL;
-
- return suite;
-}
-
-/**
- * Set the setup() and teardown() functions for a testcase.
- */
-void torture_tcase_set_fixture(struct torture_tcase *tcase,
- bool (*setup) (struct torture_context *, void **),
- bool (*teardown) (struct torture_context *, void *))
-{
- tcase->setup = setup;
- tcase->teardown = teardown;
-}
-
-static bool wrap_test_with_testcase_const(struct torture_context *torture_ctx,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- bool (*fn) (struct torture_context *,
- const void *tcase_data,
- const void *test_data);
-
- fn = test->fn;
-
- return fn(torture_ctx, tcase->data, test->data);
-}
-
-/**
- * Add a test that uses const data to a testcase
- */
-struct torture_test *torture_tcase_add_test_const(struct torture_tcase *tcase,
- const char *name,
- bool (*run) (struct torture_context *, const void *tcase_data,
- const void *test_data),
- const void *data)
-{
- struct torture_test *test = talloc(tcase, struct torture_test);
-
- test->name = talloc_strdup(test, name);
- test->description = NULL;
- test->run = wrap_test_with_testcase_const;
- test->fn = run;
- test->dangerous = false;
- test->data = data;
-
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
-
- return test;
-}
-
-/**
- * Add a new testcase
- */
-bool torture_suite_init_tcase(struct torture_suite *suite,
- struct torture_tcase *tcase,
- const char *name)
-{
- tcase->name = talloc_strdup(tcase, name);
- tcase->description = NULL;
- tcase->setup = NULL;
- tcase->teardown = NULL;
- tcase->fixture_persistent = true;
- tcase->tests = NULL;
-
- DLIST_ADD_END(suite->testcases, tcase, struct torture_tcase *);
-
- return true;
-}
-
-
-struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite,
- const char *name)
-{
- struct torture_tcase *tcase = talloc(suite, struct torture_tcase);
-
- if (!torture_suite_init_tcase(suite, tcase, name))
- return NULL;
-
- return tcase;
-}
-
-/**
- * Run a torture test suite.
- */
-bool torture_run_suite(struct torture_context *context,
- struct torture_suite *suite)
-{
- bool ret = true;
- struct torture_tcase *tcase;
- struct torture_suite *tsuite;
- char *old_testname;
-
- context->level++;
- if (context->results->ui_ops->suite_start)
- context->results->ui_ops->suite_start(context, suite);
-
- old_testname = context->active_testname;
- if (old_testname != NULL)
- context->active_testname = talloc_asprintf(context, "%s-%s",
- old_testname, suite->name);
- else
- context->active_testname = talloc_strdup(context, suite->name);
-
- for (tcase = suite->testcases; tcase; tcase = tcase->next) {
- ret &= torture_run_tcase(context, tcase);
- }
-
- for (tsuite = suite->children; tsuite; tsuite = tsuite->next) {
- ret &= torture_run_suite(context, tsuite);
- }
-
- talloc_free(context->active_testname);
- context->active_testname = old_testname;
-
- if (context->results->ui_ops->suite_finish)
- context->results->ui_ops->suite_finish(context, suite);
-
- context->level--;
-
- return ret;
-}
-
-void torture_ui_test_start(struct torture_context *context,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- if (context->results->ui_ops->test_start)
- context->results->ui_ops->test_start(context, tcase, test);
-}
-
-void torture_ui_test_result(struct torture_context *context,
- enum torture_result result,
- const char *comment)
-{
- if (context->results->ui_ops->test_result)
- context->results->ui_ops->test_result(context, result, comment);
-
- if (result == TORTURE_ERROR || result == TORTURE_FAIL)
- context->results->returncode = false;
-}
-
-static bool internal_torture_run_test(struct torture_context *context,
- struct torture_tcase *tcase,
- struct torture_test *test,
- bool already_setup)
-{
- bool success;
- char *old_testname;
-
- if (tcase == NULL || strcmp(test->name, tcase->name) != 0) {
- old_testname = context->active_testname;
- context->active_testname = talloc_asprintf(context, "%s-%s", old_testname, test->name);
- }
-
- context->active_tcase = tcase;
- context->active_test = test;
-
- torture_ui_test_start(context, tcase, test);
-
- context->last_reason = NULL;
- context->last_result = TORTURE_OK;
-
- if (!already_setup && tcase->setup &&
- !tcase->setup(context, &(tcase->data))) {
- if (context->last_reason == NULL)
- context->last_reason = talloc_strdup(context, "Setup failure");
- context->last_result = TORTURE_ERROR;
- success = false;
- } else if (test->dangerous &&
- !torture_setting_bool(context, "dangerous", false)) {
- context->last_result = TORTURE_SKIP;
- context->last_reason = talloc_asprintf(context,
- "disabled %s - enable dangerous tests to use", test->name);
- success = true;
- } else {
- success = test->run(context, tcase, test);
-
- if (!success && context->last_result == TORTURE_OK) {
- if (context->last_reason == NULL)
- context->last_reason = talloc_strdup(context, "Unknown error/failure");
- context->last_result = TORTURE_ERROR;
- }
- }
-
- if (!already_setup && tcase->teardown && !tcase->teardown(context, tcase->data)) {
- if (context->last_reason == NULL)
- context->last_reason = talloc_strdup(context, "Setup failure");
- context->last_result = TORTURE_ERROR;
- success = false;
- }
-
- torture_ui_test_result(context, context->last_result,
- context->last_reason);
-
- talloc_free(context->last_reason);
-
- if (tcase == NULL || strcmp(test->name, tcase->name) != 0) {
- talloc_free(context->active_testname);
- context->active_testname = old_testname;
- }
- context->active_test = NULL;
- context->active_tcase = NULL;
-
- return success;
-}
-
-bool torture_run_tcase(struct torture_context *context,
- struct torture_tcase *tcase)
-{
- bool ret = true;
- char *old_testname;
- struct torture_test *test;
-
- context->level++;
-
- context->active_tcase = tcase;
- if (context->results->ui_ops->tcase_start)
- context->results->ui_ops->tcase_start(context, tcase);
-
- if (tcase->fixture_persistent && tcase->setup
- && !tcase->setup(context, &tcase->data)) {
- /* FIXME: Use torture ui ops for reporting this error */
- fprintf(stderr, "Setup failed: ");
- if (context->last_reason != NULL)
- fprintf(stderr, "%s", context->last_reason);
- fprintf(stderr, "\n");
- ret = false;
- goto done;
- }
-
- old_testname = context->active_testname;
- context->active_testname = talloc_asprintf(context, "%s-%s",
- old_testname, tcase->name);
- for (test = tcase->tests; test; test = test->next) {
- ret &= internal_torture_run_test(context, tcase, test,
- tcase->fixture_persistent);
- }
- talloc_free(context->active_testname);
- context->active_testname = old_testname;
-
- if (tcase->fixture_persistent && tcase->teardown &&
- !tcase->teardown(context, tcase->data))
- ret = false;
-
-done:
- context->active_tcase = NULL;
-
- if (context->results->ui_ops->tcase_finish)
- context->results->ui_ops->tcase_finish(context, tcase);
-
- context->level--;
-
- return ret;
-}
-
-bool torture_run_test(struct torture_context *context,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- return internal_torture_run_test(context, tcase, test, false);
-}
-
-int torture_setting_int(struct torture_context *test, const char *name,
- int default_value)
-{
- return lp_parm_int(test->lp_ctx, NULL, "torture", name, default_value);
-}
-
-double torture_setting_double(struct torture_context *test, const char *name,
- double default_value)
-{
- return lp_parm_double(test->lp_ctx, NULL, "torture", name, default_value);
-}
-
-bool torture_setting_bool(struct torture_context *test, const char *name,
- bool default_value)
-{
- return lp_parm_bool(test->lp_ctx, NULL, "torture", name, default_value);
-}
-
-const char *torture_setting_string(struct torture_context *test,
- const char *name,
- const char *default_value)
-{
- const char *ret;
-
- SMB_ASSERT(test != NULL);
- SMB_ASSERT(test->lp_ctx != NULL);
-
- ret = lp_parm_string(test->lp_ctx, NULL, "torture", name);
-
- if (ret == NULL)
- return default_value;
-
- return ret;
-}
-
-static bool wrap_test_with_simple_tcase_const (
- struct torture_context *torture_ctx,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- bool (*fn) (struct torture_context *, const void *tcase_data);
-
- fn = test->fn;
-
- return fn(torture_ctx, test->data);
-}
-
-struct torture_tcase *torture_suite_add_simple_tcase_const(
- struct torture_suite *suite, const char *name,
- bool (*run) (struct torture_context *test, const void *),
- const void *data)
-{
- struct torture_tcase *tcase;
- struct torture_test *test;
-
- tcase = torture_suite_add_tcase(suite, name);
-
- test = talloc(tcase, struct torture_test);
-
- test->name = talloc_strdup(test, name);
- test->description = NULL;
- test->run = wrap_test_with_simple_tcase_const;
- test->fn = run;
- test->data = data;
- test->dangerous = false;
-
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
-
- return tcase;
-}
-
-static bool wrap_simple_test(struct torture_context *torture_ctx,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- bool (*fn) (struct torture_context *);
-
- fn = test->fn;
-
- return fn(torture_ctx);
-}
-
-struct torture_tcase *torture_suite_add_simple_test(
- struct torture_suite *suite,
- const char *name,
- bool (*run) (struct torture_context *test))
-{
- struct torture_test *test;
- struct torture_tcase *tcase;
-
- tcase = torture_suite_add_tcase(suite, name);
-
- test = talloc(tcase, struct torture_test);
-
- test->name = talloc_strdup(test, name);
- test->description = NULL;
- test->run = wrap_simple_test;
- test->fn = run;
- test->dangerous = false;
-
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
-
- return tcase;
-}
-
-/**
- * Add a child testsuite to a testsuite.
- */
-bool torture_suite_add_suite(struct torture_suite *suite,
- struct torture_suite *child)
-{
- if (child == NULL)
- return false;
-
- DLIST_ADD_END(suite->children, child, struct torture_suite *);
-
- /* FIXME: Check for duplicates and return false if the
- * added suite already exists as a child */
-
- return true;
-}
-
-/**
- * Find the child testsuite with the specified name.
- */
-struct torture_suite *torture_find_suite(struct torture_suite *parent,
- const char *name)
-{
- struct torture_suite *child;
-
- for (child = parent->children; child; child = child->next)
- if (!strcmp(child->name, name))
- return child;
-
- return NULL;
-}
-
-static bool wrap_test_with_simple_test_const(struct torture_context *torture_ctx,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- bool (*fn) (struct torture_context *, const void *tcase_data);
-
- fn = test->fn;
-
- return fn(torture_ctx, tcase->data);
-}
-
-struct torture_test *torture_tcase_add_simple_test_const(
- struct torture_tcase *tcase,
- const char *name,
- bool (*run) (struct torture_context *test,
- const void *tcase_data))
-{
- struct torture_test *test;
-
- test = talloc(tcase, struct torture_test);
-
- test->name = talloc_strdup(test, name);
- test->description = NULL;
- test->run = wrap_test_with_simple_test_const;
- test->fn = run;
- test->data = NULL;
- test->dangerous = false;
-
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
-
- return test;
-}
-
-static bool wrap_test_with_simple_test(struct torture_context *torture_ctx,
- struct torture_tcase *tcase,
- struct torture_test *test)
-{
- bool (*fn) (struct torture_context *, void *tcase_data);
-
- fn = test->fn;
-
- return fn(torture_ctx, tcase->data);
-}
-
-struct torture_test *torture_tcase_add_simple_test(struct torture_tcase *tcase,
- const char *name,
- bool (*run) (struct torture_context *test, void *tcase_data))
-{
- struct torture_test *test;
-
- test = talloc(tcase, struct torture_test);
-
- test->name = talloc_strdup(test, name);
- test->description = NULL;
- test->run = wrap_test_with_simple_test;
- test->fn = run;
- test->data = NULL;
- test->dangerous = false;
-
- DLIST_ADD_END(tcase->tests, test, struct torture_test *);
-
- return test;
-}
diff --git a/source4/lib/torture/torture.h b/source4/lib/torture/torture.h
deleted file mode 100644
index f06ffe012b..0000000000
--- a/source4/lib/torture/torture.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- SMB torture UI functions
-
- Copyright (C) Jelmer Vernooij 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/>.
-*/
-
-#ifndef __TORTURE_UI_H__
-#define __TORTURE_UI_H__
-
-struct torture_test;
-struct torture_context;
-struct torture_suite;
-struct torture_tcase;
-struct torture_results;
-
-enum torture_result {
- TORTURE_OK=0,
- TORTURE_FAIL=1,
- TORTURE_ERROR=2,
- TORTURE_SKIP=3
-};
-
-/*
- * These callbacks should be implemented by any backend that wishes
- * to listen to reports from the torture tests.
- */
-struct torture_ui_ops
-{
- void (*init) (struct torture_results *);
- void (*comment) (struct torture_context *, const char *);
- void (*warning) (struct torture_context *, const char *);
- void (*suite_start) (struct torture_context *, struct torture_suite *);
- void (*suite_finish) (struct torture_context *, struct torture_suite *);
- void (*tcase_start) (struct torture_context *, struct torture_tcase *);
- void (*tcase_finish) (struct torture_context *, struct torture_tcase *);
- void (*test_start) (struct torture_context *,
- struct torture_tcase *,
- struct torture_test *);
- void (*test_result) (struct torture_context *,
- enum torture_result, const char *reason);
-};
-
-void torture_ui_test_start(struct torture_context *context,
- struct torture_tcase *tcase,
- struct torture_test *test);
-
-void torture_ui_test_result(struct torture_context *context,
- enum torture_result result,
- const char *comment);
-
-/*
- * Holds information about a specific run of the testsuite.
- * The data in this structure should be considered private to
- * the torture tests and should only be used directly by the torture
- * code and the ui backends.
- *
- * Torture tests should instead call the torture_*() macros and functions
- * specified below.
- */
-
-struct torture_context
-{
- struct torture_results *results;
-
- char *active_testname;
- struct torture_test *active_test;
- struct torture_tcase *active_tcase;
-
- enum torture_result last_result;
- char *last_reason;
-
- /** Directory used for temporary test data */
- const char *outputdir;
-
- /** Indentation level */
- int level;
-
- /** Event context */
- struct event_context *ev;
-
- /** Loadparm context (will go away in favor of torture_setting_ at some point) */
- struct loadparm_context *lp_ctx;
-};
-
-struct torture_results
-{
- const struct torture_ui_ops *ui_ops;
- void *ui_data;
-
- /** Whether tests should avoid writing output to stdout */
- bool quiet;
-
- bool returncode;
-
-
-};
-
-/*
- * Describes a particular torture test
- */
-struct torture_test {
- /** Short unique name for the test. */
- const char *name;
-
- /** Long description for the test. */
- const char *description;
-
- /** Whether this is a dangerous test
- * (can corrupt the remote servers data or bring it down). */
- bool dangerous;
-
- /** Function to call to run this test */
- bool (*run) (struct torture_context *torture_ctx,
- struct torture_tcase *tcase,
- struct torture_test *test);
-
- struct torture_test *prev, *next;
-
- /** Pointer to the actual test function. This is run by the
- * run() function above. */
- void *fn;
-
- /** Use data for this test */
- const void *data;
-};
-
-/*
- * Describes a particular test case.
- */
-struct torture_tcase {
- const char *name;
- const char *description;
- bool (*setup) (struct torture_context *tcase, void **data);
- bool (*teardown) (struct torture_context *tcase, void *data);
- bool fixture_persistent;
- void *data;
- struct torture_test *tests;
- struct torture_tcase *prev, *next;
-};
-
-struct torture_suite
-{
- const char *name;
- const char *description;
- struct torture_tcase *testcases;
- struct torture_suite *children;
-
- /* Pointers to siblings of this torture suite */
- struct torture_suite *prev, *next;
-};
-
-/** Create a new torture suite */
-struct torture_suite *torture_suite_create(TALLOC_CTX *mem_ctx,
- const char *name);
-
-/** Change the setup and teardown functions for a testcase */
-void torture_tcase_set_fixture(struct torture_tcase *tcase,
- bool (*setup) (struct torture_context *, void **),
- bool (*teardown) (struct torture_context *, void *));
-
-/* Add another test to run for a particular testcase */
-struct torture_test *torture_tcase_add_test_const(struct torture_tcase *tcase,
- const char *name,
- bool (*run) (struct torture_context *test,
- const void *tcase_data, const void *test_data),
- const void *test_data);
-
-/* Add a testcase to a testsuite */
-struct torture_tcase *torture_suite_add_tcase(struct torture_suite *suite,
- const char *name);
-
-/* Convenience wrapper that adds a testcase against only one
- * test will be run */
-struct torture_tcase *torture_suite_add_simple_tcase_const(
- struct torture_suite *suite,
- const char *name,
- bool (*run) (struct torture_context *test,
- const void *test_data),
- const void *data);
-
-/* Convenience function that adds a test which only
- * gets the test case data */
-struct torture_test *torture_tcase_add_simple_test_const(
- struct torture_tcase *tcase,
- const char *name,
- bool (*run) (struct torture_context *test,
- const void *tcase_data));
-
-/* Convenience wrapper that adds a test that doesn't need any
- * testcase data */
-struct torture_tcase *torture_suite_add_simple_test(
- struct torture_suite *suite,
- const char *name,
- bool (*run) (struct torture_context *test));
-
-/* Add a child testsuite to an existing testsuite */
-bool torture_suite_add_suite(struct torture_suite *suite,
- struct torture_suite *child);
-
-/* Run the specified testsuite recursively */
-bool torture_run_suite(struct torture_context *context,
- struct torture_suite *suite);
-
-/* Run the specified testcase */
-bool torture_run_tcase(struct torture_context *context,
- struct torture_tcase *tcase);
-
-/* Run the specified test */
-bool torture_run_test(struct torture_context *context,
- struct torture_tcase *tcase,
- struct torture_test *test);
-
-void torture_comment(struct torture_context *test, const char *comment, ...) PRINTF_ATTRIBUTE(2,3);
-void torture_warning(struct torture_context *test, const char *comment, ...) PRINTF_ATTRIBUTE(2,3);
-void torture_result(struct torture_context *test,
- enum torture_result, const char *reason, ...) PRINTF_ATTRIBUTE(3,4);
-
-#define torture_assert(torture_ctx,expr,cmt) \
- if (!(expr)) { \
- torture_result(torture_ctx, TORTURE_FAIL, __location__": Expression `%s' failed: %s", __STRING(expr), cmt); \
- return false; \
- }
-
-#define torture_assert_werr_equal(torture_ctx, got, expected, cmt) \
- do { WERROR __got = got, __expected = expected; \
- if (!W_ERROR_EQUAL(__got, __expected)) { \
- torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", win_errstr(__got), win_errstr(__expected), cmt); \
- return false; \
- } \
- } while (0)
-
-#define torture_assert_ntstatus_equal(torture_ctx,got,expected,cmt) \
- do { NTSTATUS __got = got, __expected = expected; \
- if (!NT_STATUS_EQUAL(__got, __expected)) { \
- torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", nt_errstr(__got), nt_errstr(__expected), cmt); \
- return false; \
- }\
- } while(0)
-
-#define torture_assert_ndr_err_equal(torture_ctx,got,expected,cmt) \
- do { enum ndr_err_code __got = got, __expected = expected; \
- if (__got != __expected) { \
- torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %d, expected %d (%s): %s", __got, __expected, __STRING(expected), cmt); \
- return false; \
- }\
- } while(0)
-
-#define torture_assert_casestr_equal(torture_ctx,got,expected,cmt) \
- do { const char *__got = (got), *__expected = (expected); \
- if (!strequal(__got, __expected)) { \
- torture_result(torture_ctx, TORTURE_FAIL, __location__": "#got" was %s, expected %s: %s", __got, __expected, cmt); \
- return false; \
- } \
- } while(0)
-
-#define torture_assert_str_equal(torture_ctx,got,expected,cmt)\
- do { const char *__got = (got), *__expected = (expected); \
- if (strcmp_safe(__got, __expected) != 0) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": "#got" was %s, expected %s: %s", \
- __got, __expected, cmt); \
- return false; \
- } \
- } while(0)
-
-#define torture_assert_mem_equal(torture_ctx,got,expected,len,cmt)\
- do { const void *__got = (got), *__expected = (expected); \
- if (memcmp(__got, __expected, len) != 0) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": "#got" of len %d did not match"#expected": %s", (int)len, cmt); \
- return false; \
- } \
- } while(0)
-
-#define torture_assert_file_contains_text(torture_ctx,filename,expected,cmt)\
- do { \
- char *__got; \
- const char *__expected = (expected); \
- size_t __size; \
- __got = file_load(filename, &__size, 0, torture_ctx); \
- if (__got == NULL) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": unable to open %s: %s\n", \
- filename, cmt); \
- return false; \
- } \
- \
- if (strcmp_safe(__got, __expected) != 0) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": %s contained:\n%sExpected: %s%s\n", \
- filename, __got, __expected, cmt); \
- talloc_free(__got); \
- return false; \
- } \
- talloc_free(__got); \
- } while(0)
-
-#define torture_assert_file_contains(torture_ctx,filename,expected,cmt)\
- do { const char *__got, *__expected = (expected); \
- size_t __size; \
- __got = file_load(filename, *size, 0, torture_ctx); \
- if (strcmp_safe(__got, __expected) != 0) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": %s contained:\n%sExpected: %s%s\n", \
- __got, __expected, cmt); \
- talloc_free(__got); \
- return false; \
- } \
- talloc_free(__got); \
- } while(0)
-
-#define torture_assert_int_equal(torture_ctx,got,expected,cmt)\
- do { int __got = (got), __expected = (expected); \
- if (__got != __expected) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": "#got" was %d, expected %d: %s", \
- __got, __expected, cmt); \
- return false; \
- } \
- } while(0)
-
-#define torture_assert_u64_equal(torture_ctx,got,expected,cmt)\
- do { uint64_t __got = (got), __expected = (expected); \
- if (__got != __expected) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": "#got" was %llu, expected %llu: %s", \
- (unsigned long long)__got, (unsigned long long)__expected, cmt); \
- return false; \
- } \
- } while(0)
-
-#define torture_assert_errno_equal(torture_ctx,expected,cmt)\
- do { int __expected = (expected); \
- if (errno != __expected) { \
- torture_result(torture_ctx, TORTURE_FAIL, \
- __location__": errno was %d (%s), expected %d: %s: %s", \
- errno, strerror(errno), __expected, \
- strerror(__expected), cmt); \
- return false; \
- } \
- } while(0)
-
-
-
-#define torture_skip(torture_ctx,cmt) do {\
- torture_result(torture_ctx, TORTURE_SKIP, __location__": %s", cmt);\
- return true; \
- } while(0)
-#define torture_fail(torture_ctx,cmt) do {\
- torture_result(torture_ctx, TORTURE_FAIL, __location__": %s", cmt);\
- return false; \
- } while (0)
-#define torture_fail_goto(torture_ctx,label,cmt) do {\
- torture_result(torture_ctx, TORTURE_FAIL, __location__": %s", cmt);\
- goto label; \
- } while (0)
-
-#define torture_out stderr
-
-/* Convenience macros */
-#define torture_assert_ntstatus_ok(torture_ctx,expr,cmt) \
- torture_assert_ntstatus_equal(torture_ctx,expr,NT_STATUS_OK,cmt)
-
-#define torture_assert_werr_ok(torture_ctx,expr,cmt) \
- torture_assert_werr_equal(torture_ctx,expr,WERR_OK,cmt)
-
-#define torture_assert_ndr_success(torture_ctx,expr,cmt) \
- torture_assert_ndr_err_equal(torture_ctx,expr,NDR_ERR_SUCCESS,cmt)
-
-/* Getting settings */
-const char *torture_setting_string(struct torture_context *test, \
- const char *name,
- const char *default_value);
-
-int torture_setting_int(struct torture_context *test,
- const char *name,
- int default_value);
-
-double torture_setting_double(struct torture_context *test,
- const char *name,
- double default_value);
-
-bool torture_setting_bool(struct torture_context *test,
- const char *name,
- bool default_value);
-
-struct torture_suite *torture_find_suite(struct torture_suite *parent,
- const char *name);
-
-NTSTATUS torture_temp_dir(struct torture_context *tctx,
- const char *prefix,
- char **tempdir);
-
-struct torture_test *torture_tcase_add_simple_test(struct torture_tcase *tcase,
- const char *name,
- bool (*run) (struct torture_context *test, void *tcase_data));
-
-
-bool torture_suite_init_tcase(struct torture_suite *suite,
- struct torture_tcase *tcase,
- const char *name);
-
-struct torture_context *torture_context_init(struct event_context *event_ctx, struct torture_results *results);
-
-struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops);
-
-struct torture_context *torture_context_child(struct torture_context *tctx);
-
-extern const struct torture_ui_ops torture_subunit_ui_ops;
-
-#endif /* __TORTURE_UI_H__ */
diff --git a/source4/lib/torture/torture.pc.in b/source4/lib/torture/torture.pc.in
deleted file mode 100644
index 6582816cb5..0000000000
--- a/source4/lib/torture/torture.pc.in
+++ /dev/null
@@ -1,12 +0,0 @@
-prefix=@prefix@
-exec_prefix=@exec_prefix@
-libdir=@libdir@
-includedir=@includedir@
-modulesdir=${prefix}/modules/torture
-
-Name: torture
-Description: Samba torture (test) suite
-Requires: talloc
-Version: 0.0.1
-Libs: -L${libdir} -ltorture
-Cflags: -I${includedir} -DHAVE_IMMEDIATE_STRUCTURES=1
diff --git a/source4/lib/wmi/config.mk b/source4/lib/wmi/config.mk
index 28f6c73dcd..3bb1690c7b 100644
--- a/source4/lib/wmi/config.mk
+++ b/source4/lib/wmi/config.mk
@@ -43,7 +43,7 @@ librpc/gen_ndr/dcom_p.c: idl
#######################
# Start LIBRARY swig_dcerpc
[PYTHON::pywmi]
-PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-CONFIG WMI
+PUBLIC_DEPENDENCIES = LIBCLI_SMB LIBNDR LIBSAMBA-UTIL LIBSAMBA-CONFIG WMI
$(eval $(call python_py_module_template,wmi.py,$(wmisrcdir)/wmi.py))
diff --git a/source4/libcli/clideltree.c b/source4/libcli/clideltree.c
index 28563d918e..d947ac3547 100644
--- a/source4/libcli/clideltree.c
+++ b/source4/libcli/clideltree.c
@@ -97,7 +97,8 @@ int smbcli_deltree(struct smbcli_tree *tree, const char *dname)
}
if (NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
- NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE)) {
+ NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_NO_SUCH_FILE) ||
+ NT_STATUS_EQUAL(smbcli_nt_error(tree), NT_STATUS_DOS(ERRDOS, ERRbadfile))) {
return 0;
}
if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c
index a12f7652a5..5e6a5faafa 100644
--- a/source4/libcli/ldap/ldap_bind.c
+++ b/source4/libcli/ldap/ldap_bind.c
@@ -286,7 +286,7 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn,
search = &sasl_mechs_msgs[0]->r.SearchResultEntry;
if (search->num_attributes != 1) {
- DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d\n",
+ DEBUG(1, ("Failed to inquire of target's available sasl mechs in rootdse search: wrong number of attributes: %d != 1\n",
search->num_attributes));
goto failed;
}
diff --git a/source4/libcli/resolve/host.c b/source4/libcli/resolve/host.c
index 1a695432ee..7d779b0678 100644
--- a/source4/libcli/resolve/host.c
+++ b/source4/libcli/resolve/host.c
@@ -53,10 +53,15 @@ struct host_state {
*/
static int host_destructor(struct host_state *state)
{
+ int status;
+
+ kill(state->child, SIGTERM);
close(state->child_fd);
- if (state->child != (pid_t)-1) {
- kill(state->child, SIGTERM);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
}
+
return 0;
}
@@ -90,16 +95,23 @@ static void pipe_handler(struct event_context *ev, struct fd_event *fde,
struct host_state *state = talloc_get_type(c->private_data, struct host_state);
char address[128];
int ret;
+ pid_t child = state->child;
+ int status;
/* if we get any event from the child then we know that we
won't need to kill it off */
- state->child = (pid_t)-1;
+ talloc_set_destructor(state, NULL);
/* yes, we don't care about EAGAIN or other niceities
here. They just can't happen with this parent/child
relationship, and even if they did then giving an error is
the right thing to do */
ret = read(state->child_fd, address, sizeof(address)-1);
+ close(state->child_fd);
+ if (waitpid(state->child, &status, WNOHANG) == 0) {
+ kill(state->child, SIGKILL);
+ waitpid(state->child, &status, 0);
+ }
if (ret <= 0) {
composite_error(c, NT_STATUS_OBJECT_NAME_NOT_FOUND);
return;
@@ -164,10 +176,6 @@ struct composite_context *resolve_name_host_send(TALLOC_CTX *mem_ctx,
return c;
}
- /* signal handling in posix really sucks - doing this in a library
- affects the whole app, but what else to do?? */
- signal(SIGCHLD, SIG_IGN);
-
state->child = fork();
if (state->child == (pid_t)-1) {
composite_error(c, map_nt_error_from_unix(errno));
diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk
index f2883d1ede..30b1f32935 100644
--- a/source4/libcli/security/config.mk
+++ b/source4/libcli/security/config.mk
@@ -1,5 +1,5 @@
[SUBSYSTEM::LIBSECURITY]
-PUBLIC_DEPENDENCIES = NDR_MISC LIBNDR
+PUBLIC_DEPENDENCIES = LIBNDR
LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \
security_token.o security_descriptor.o \
diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c
index e95f0228c1..e94ed36d39 100644
--- a/source4/libcli/util/nterr.c
+++ b/source4/libcli/util/nterr.c
@@ -548,6 +548,7 @@ static const nt_err_code_struct nt_errs[] =
{ "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED },
{ "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND },
{ "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED },
+ { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY },
{ "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES },
{ "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED },
{ "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP },
diff --git a/source4/libnet/groupinfo.c b/source4/libnet/groupinfo.c
index 1da6646702..5c94c34b1d 100644
--- a/source4/libnet/groupinfo.c
+++ b/source4/libnet/groupinfo.c
@@ -83,8 +83,8 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
if (s->monitor_fn) {
msg.type = mon_SamrLookupName;
msg_lookup = talloc(s, struct msg_rpc_lookup_name);
- msg_lookup->rid = s->lookup.out.rids.ids;
- msg_lookup->count = s->lookup.out.rids.count;
+ msg_lookup->rid = s->lookup.out.rids->ids;
+ msg_lookup->count = s->lookup.out.rids->count;
msg.data = (void*)msg_lookup;
msg.data_size = sizeof(*msg_lookup);
@@ -94,7 +94,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids.count == 0) {
+ if (s->lookup.out.rids->count == 0) {
composite_error(c, NT_STATUS_NO_SUCH_USER);
}
@@ -103,7 +103,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req)
/* prepare parameters for LookupNames */
s->opengroup.in.domain_handle = &s->domain_handle;
s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- s->opengroup.in.rid = s->lookup.out.rids.ids[0];
+ s->opengroup.in.rid = s->lookup.out.rids->ids[0];
s->opengroup.out.group_handle = &s->group_handle;
/* send request */
@@ -152,6 +152,8 @@ static void continue_groupinfo_opengroup(struct rpc_request *req)
/* prepare parameters for QueryGroupInfo call */
s->querygroupinfo.in.group_handle = &s->group_handle;
s->querygroupinfo.in.level = s->level;
+ s->querygroupinfo.out.info = talloc(s, union samr_GroupInfo *);
+ if (composite_nomem(s->querygroupinfo.out.info, c)) return;
/* queue rpc call, set event handling and new state */
querygroup_req = dcerpc_samr_QueryGroupInfo_send(s->pipe, c, &s->querygroupinfo);
@@ -185,7 +187,7 @@ static void continue_groupinfo_getgroup(struct rpc_request *req)
return;
}
- s->info = talloc_steal(s, s->querygroupinfo.out.info);
+ s->info = talloc_steal(s, *s->querygroupinfo.out.info);
/* issue a monitor message */
if (s->monitor_fn) {
@@ -301,7 +303,11 @@ struct composite_context *libnet_rpc_groupinfo_send(struct dcerpc_pipe *p,
s->lookup.in.names[0].string = talloc_strdup(s, io->in.groupname);
if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
-
+ s->lookup.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookup.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookup.out.rids, c)) return c;
+ if (composite_nomem(s->lookup.out.types, c)) return c;
+
/* send request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookup);
if (composite_nomem(lookup_req, c)) return c;
diff --git a/source4/libnet/groupman.c b/source4/libnet/groupman.c
index 58d5742336..4dfb2d8aab 100644
--- a/source4/libnet/groupman.c
+++ b/source4/libnet/groupman.c
@@ -174,6 +174,10 @@ struct composite_context* libnet_rpc_groupdel_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.groupname;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -205,12 +209,12 @@ static void continue_groupdel_name_found(struct rpc_request *req)
/* what to do when there's no group account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_GROUP;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -218,7 +222,7 @@ static void continue_groupdel_name_found(struct rpc_request *req)
/* prepare the arguments for rpc call */
s->opengroup.in.domain_handle = &s->domain_handle;
- s->opengroup.in.rid = s->lookupname.out.rids.ids[0];
+ s->opengroup.in.rid = s->lookupname.out.rids->ids[0];
s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->opengroup.out.group_handle = &s->group_handle;
diff --git a/source4/libnet/libnet_domain.c b/source4/libnet/libnet_domain.c
index ccdfdaf134..eb6920d88e 100644
--- a/source4/libnet/libnet_domain.c
+++ b/source4/libnet/libnet_domain.c
@@ -40,6 +40,7 @@ struct domain_open_samr_state {
uint32_t access_mask;
struct policy_handle connect_handle;
struct policy_handle domain_handle;
+ struct dom_sid2 *domain_sid;
/* information about the progress */
void (*monitor_fn)(struct monitor_msg*);
@@ -159,6 +160,8 @@ static void continue_domain_open_connect(struct rpc_request *req)
/* prepare for samr_LookupDomain call */
r->in.connect_handle = &s->connect_handle;
r->in.domain_name = &s->domain_name;
+ r->out.sid = talloc(s, struct dom_sid2 *);
+ if (composite_nomem(r->out.sid, c)) return;
lookup_req = dcerpc_samr_LookupDomain_send(s->pipe, c, r);
if (composite_nomem(lookup_req, c)) return;
@@ -209,7 +212,7 @@ static void continue_domain_open_lookup(struct rpc_request *req)
/* prepare for samr_OpenDomain call */
r->in.connect_handle = &s->connect_handle;
r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r->in.sid = s->lookup.out.sid;
+ r->in.sid = *s->lookup.out.sid;
r->out.domain_handle = &s->domain_handle;
opendom_req = dcerpc_samr_OpenDomain_send(s->pipe, c, r);
@@ -361,7 +364,7 @@ NTSTATUS libnet_DomainOpenSamr_recv(struct composite_context *c, struct libnet_c
libnet functions */
ctx->samr.connect_handle = s->connect_handle;
ctx->samr.handle = s->domain_handle;
- ctx->samr.sid = talloc_steal(ctx, s->lookup.out.sid);
+ ctx->samr.sid = talloc_steal(ctx, *s->lookup.out.sid);
ctx->samr.name = talloc_steal(ctx, s->domain_name.string);
ctx->samr.access_mask = s->access_mask;
}
@@ -998,6 +1001,10 @@ static void continue_samr_connect(struct rpc_request *req)
s->enumdom.in.resume_handle = &s->resume_handle;
s->enumdom.in.buf_size = s->buf_size;
s->enumdom.out.resume_handle = &s->resume_handle;
+ s->enumdom.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->enumdom.out.num_entries, c)) return;
+ s->enumdom.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->enumdom.out.sam, c)) return;
enumdom_req = dcerpc_samr_EnumDomains_send(s->ctx->samr.pipe, c, &s->enumdom);
if (composite_nomem(enumdom_req, c)) return;
@@ -1113,16 +1120,16 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
/* prepare domains array */
if (s->domains == NULL) {
s->domains = talloc_array(mem_ctx, struct domainlist,
- s->enumdom.out.num_entries);
+ *s->enumdom.out.num_entries);
} else {
s->domains = talloc_realloc(mem_ctx, s->domains, struct domainlist,
- s->count + s->enumdom.out.num_entries);
+ s->count + *s->enumdom.out.num_entries);
}
/* copy domain names returned from samr_EnumDomains call */
- for (i = s->count; i < s->count + s->enumdom.out.num_entries; i++)
+ for (i = s->count; i < s->count + *s->enumdom.out.num_entries; i++)
{
- struct lsa_String *domain_name = &s->enumdom.out.sam->entries[i - s->count].name;
+ struct lsa_String *domain_name = &(*s->enumdom.out.sam)->entries[i - s->count].name;
/* strdup name as a child of allocated array to make it follow the array
in case of talloc_steal or talloc_free */
@@ -1131,7 +1138,7 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis
}
/* number of entries returned (domains enumerated) */
- s->count += s->enumdom.out.num_entries;
+ s->count += *s->enumdom.out.num_entries;
return s->domains;
}
diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c
index eded378511..af5fe4d5d3 100644
--- a/source4/libnet/libnet_group.c
+++ b/source4/libnet/libnet_group.c
@@ -518,6 +518,10 @@ static void continue_domain_queried(struct rpc_request *req)
s->group_list.in.max_size = s->page_size;
s->group_list.in.resume_handle = &s->resume_index;
s->group_list.out.resume_handle = &s->resume_index;
+ s->group_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->group_list.out.num_entries, c)) return;
+ s->group_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->group_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -549,6 +553,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
s->group_list.in.max_size = s->page_size;
s->group_list.in.resume_handle = &s->resume_index;
s->group_list.out.resume_handle = &s->resume_index;
+ s->group_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->group_list.out.num_entries, c)) return;
+ s->group_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->group_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list);
@@ -587,15 +595,15 @@ static void continue_groups_enumerated(struct rpc_request *req)
/* get enumerated accounts counter and resume handle (the latter allows
making subsequent call to continue enumeration) */
s->resume_index = *s->group_list.out.resume_handle;
- s->count = s->group_list.out.num_entries;
+ s->count = *s->group_list.out.num_entries;
/* prepare returned group accounts array */
- s->groups = talloc_array(c, struct grouplist, s->group_list.out.sam->count);
+ s->groups = talloc_array(c, struct grouplist, (*s->group_list.out.sam)->count);
if (composite_nomem(s->groups, c)) return;
- for (i = 0; i < s->group_list.out.sam->count; i++) {
+ for (i = 0; i < (*s->group_list.out.sam)->count; i++) {
struct dom_sid *group_sid;
- struct samr_SamEntry *entry = &s->group_list.out.sam->entries[i];
+ struct samr_SamEntry *entry = &(*s->group_list.out.sam)->entries[i];
struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
/* construct group sid from returned rid and queried domain sid */
diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c
index 0ed5e8ae26..70fcb4a894 100644
--- a/source4/libnet/libnet_join.c
+++ b/source4/libnet/libnet_join.c
@@ -444,13 +444,16 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
struct samr_OpenDomain od;
struct policy_handle d_handle;
struct samr_LookupNames ln;
+ struct samr_Ids rids, types;
struct samr_OpenUser ou;
struct samr_CreateUser2 cu;
struct policy_handle *u_handle = NULL;
struct samr_QueryUserInfo qui;
+ union samr_UserInfo *uinfo;
struct samr_UserInfo21 u_info21;
union libnet_SetPassword r2;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
struct lsa_String samr_account_name;
uint32_t acct_flags, old_acct_flags;
@@ -559,9 +562,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
if (!connect_with_info->out.domain_sid) {
struct lsa_String name;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
name.string = connect_with_info->out.domain_name;
l.in.connect_handle = &p_handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(samr_pipe, tmp_ctx, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -571,7 +576,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
talloc_free(tmp_ctx);
return status;
}
- connect_with_info->out.domain_sid = l.out.sid;
+ connect_with_info->out.domain_sid = *l.out.sid;
}
/* prepare samr_OpenDomain */
@@ -611,6 +616,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
ln.in.domain_handle = &d_handle;
ln.in.num_names = 1;
ln.in.names = talloc_array(tmp_ctx, struct lsa_String, 1);
+ ln.out.rids = &rids;
+ ln.out.types = &types;
if (!ln.in.names) {
r->out.error_string = NULL;
talloc_free(tmp_ctx);
@@ -630,10 +637,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
}
/* check if we got one RID for the user */
- if (ln.out.rids.count != 1) {
+ if (ln.out.rids->count != 1) {
r->out.error_string = talloc_asprintf(mem_ctx,
"samr_LookupNames for [%s] returns %d RIDs",
- r->in.account_name, ln.out.rids.count);
+ r->in.account_name, ln.out.rids->count);
talloc_free(tmp_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
@@ -642,7 +649,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
ZERO_STRUCTP(u_handle);
ou.in.domain_handle = &d_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- ou.in.rid = ln.out.rids.ids[0];
+ ou.in.rid = ln.out.rids->ids[0];
rid = ou.in.rid;
ou.out.user_handle = u_handle;
@@ -694,6 +701,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
/* prepare samr_QueryUserInfo (get flags) */
qui.in.user_handle = u_handle;
qui.in.level = 16;
+ qui.out.info = &uinfo;
status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
if (!NT_STATUS_IS_OK(status)) {
@@ -705,7 +713,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- if (!qui.out.info) {
+ if (!uinfo) {
status = NT_STATUS_INVALID_PARAMETER;
r->out.error_string
= talloc_asprintf(mem_ctx,
@@ -715,7 +723,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return status;
}
- old_acct_flags = (qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
+ old_acct_flags = (uinfo->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST));
/* Possibly bail if the account is of the wrong type */
if (old_acct_flags
!= r->in.acct_type) {
@@ -771,17 +779,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru
return NT_STATUS_USER_EXISTS;
}
} else {
- acct_flags = qui.out.info->info16.acct_flags;
+ acct_flags = uinfo->info16.acct_flags;
}
acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ));
/* Find out what password policy this user has */
pwp.in.user_handle = u_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
/* Grab a password of that minimum length */
diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c
index de2ed01abd..80de6134b5 100644
--- a/source4/libnet/libnet_passwd.c
+++ b/source4/libnet/libnet_passwd.c
@@ -50,6 +50,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
struct samr_Password nt_verifier, lm_verifier;
uint8_t old_nt_hash[16], new_nt_hash[16];
uint8_t old_lm_hash[16], new_lm_hash[16];
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
/* prepare connect to the SAMR pipe of the users domain PDC */
c.level = LIBNET_RPC_CONNECT_PDC;
@@ -92,6 +94,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT
pw3.in.lm_password = &lm_pass;
pw3.in.lm_verifier = &lm_verifier;
pw3.in.password3 = NULL;
+ pw3.out.dominfo = &dominfo;
+ pw3.out.reject = &reject;
/* 2. try samr_ChangePasswordUser3 */
status = dcerpc_samr_ChangePasswordUser3(c.out.dcerpc_pipe, mem_ctx, &pw3);
@@ -303,7 +307,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_26(struct libnet_context *ctx, TA
/* prepare samr_SetUserInfo2 level 26 */
ZERO_STRUCT(u_info);
encode_pw_buffer(u_info.info26.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
- u_info.info26.pw_len = strlen(r->samr_handle.in.newpassword);
+ u_info.info26.password_expired = 0;
status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -406,8 +410,7 @@ static NTSTATUS libnet_SetPassword_samr_handle_24(struct libnet_context *ctx, TA
/* prepare samr_SetUserInfo2 level 24 */
ZERO_STRUCT(u_info);
encode_pw_buffer(u_info.info24.password.data, r->samr_handle.in.newpassword, STR_UNICODE);
- /* w2k3 ignores this length */
- u_info.info24.pw_len = strlen_m(r->samr_handle.in.newpassword)*2;
+ u_info.info24.password_expired = 0;
status = dcerpc_fetch_session_key(r->samr_handle.in.dcerpc_pipe, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -527,10 +530,12 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
struct samr_Connect sc;
struct policy_handle p_handle;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct lsa_String d_name;
struct samr_OpenDomain od;
struct policy_handle d_handle;
struct samr_LookupNames ln;
+ struct samr_Ids rids, types;
struct samr_OpenUser ou;
struct policy_handle u_handle;
union libnet_SetPassword r2;
@@ -568,6 +573,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
d_name.string = r->samr.in.domain_name;
ld.in.connect_handle = &p_handle;
ld.in.domain_name = &d_name;
+ ld.out.sid = &sid;
/* 3. do a samr_LookupDomain to get the domain sid */
status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld);
@@ -582,7 +588,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ZERO_STRUCT(d_handle);
od.in.connect_handle = &p_handle;
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- od.in.sid = ld.out.sid;
+ od.in.sid = *ld.out.sid;
od.out.domain_handle = &d_handle;
/* 4. do a samr_OpenDomain to get a domain handle */
@@ -598,6 +604,8 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ln.in.domain_handle = &d_handle;
ln.in.num_names = 1;
ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
+ ln.out.rids = &rids;
+ ln.out.types = &types;
if (!ln.in.names) {
r->samr.out.error_string = "Out of Memory";
return NT_STATUS_NO_MEMORY;
@@ -614,10 +622,10 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
}
/* check if we got one RID for the user */
- if (ln.out.rids.count != 1) {
+ if (ln.out.rids->count != 1) {
r->samr.out.error_string = talloc_asprintf(mem_ctx,
"samr_LookupNames for [%s] returns %d RIDs",
- r->samr.in.account_name, ln.out.rids.count);
+ r->samr.in.account_name, ln.out.rids->count);
status = NT_STATUS_INVALID_PARAMETER;
goto disconnect;
}
@@ -626,7 +634,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX *
ZERO_STRUCT(u_handle);
ou.in.domain_handle = &d_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- ou.in.rid = ln.out.rids.ids[0];
+ ou.in.rid = ln.out.rids->ids[0];
ou.out.user_handle = &u_handle;
/* 6. do a samr_OpenUser to get a user handle */
diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c
index 8b7dd1f598..160b4b3e19 100644
--- a/source4/libnet/libnet_samsync_ldb.c
+++ b/source4/libnet/libnet_samsync_ldb.c
@@ -384,7 +384,11 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx,
}
ADD_OR_DEL(string, "comment", comment.string);
- ADD_OR_DEL(string, "userParameters", parameters.string);
+
+ if (samdb_msg_add_parameters(state->sam_ldb, mem_ctx, msg, "userParameters", &user->parameters) != 0) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
ADD_OR_DEL(uint, "countryCode", country_code);
ADD_OR_DEL(uint, "codePage", code_page);
diff --git a/source4/libnet/libnet_user.c b/source4/libnet/libnet_user.c
index c768319452..8606d0856e 100644
--- a/source4/libnet/libnet_user.c
+++ b/source4/libnet/libnet_user.c
@@ -1032,6 +1032,10 @@ static void continue_domain_queried(struct rpc_request *req)
s->user_list.in.resume_handle = &s->resume_index;
s->user_list.in.acct_flags = ACB_NORMAL;
s->user_list.out.resume_handle = &s->resume_index;
+ s->user_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->user_list.out.num_entries, c)) return;
+ s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->user_list.out.sam, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1064,6 +1068,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx)
s->user_list.in.resume_handle = &s->resume_index;
s->user_list.in.acct_flags = ACB_NORMAL;
s->user_list.out.resume_handle = &s->resume_index;
+ s->user_list.out.sam = talloc(s, struct samr_SamArray *);
+ if (composite_nomem(s->user_list.out.sam, c)) return;
+ s->user_list.out.num_entries = talloc(s, uint32_t);
+ if (composite_nomem(s->user_list.out.num_entries, c)) return;
/* send the request */
enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list);
@@ -1102,15 +1110,15 @@ static void continue_users_enumerated(struct rpc_request *req)
/* get enumerated accounts counter and resume handle (the latter allows
making subsequent call to continue enumeration) */
s->resume_index = *s->user_list.out.resume_handle;
- s->count = s->user_list.out.num_entries;
+ s->count = *s->user_list.out.num_entries;
/* prepare returned user accounts array */
- s->users = talloc_array(c, struct userlist, s->user_list.out.sam->count);
+ s->users = talloc_array(c, struct userlist, (*s->user_list.out.sam)->count);
if (composite_nomem(s->users, c)) return;
- for (i = 0; i < s->user_list.out.sam->count; i++) {
+ for (i = 0; i < (*s->user_list.out.sam)->count; i++) {
struct dom_sid *user_sid;
- struct samr_SamEntry *entry = &s->user_list.out.sam->entries[i];
+ struct samr_SamEntry *entry = &(*s->user_list.out.sam)->entries[i];
struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid;
/* construct user sid from returned rid and queried domain sid */
diff --git a/source4/libnet/userinfo.c b/source4/libnet/userinfo.c
index e8b6b090c7..710154d41e 100644
--- a/source4/libnet/userinfo.c
+++ b/source4/libnet/userinfo.c
@@ -82,8 +82,8 @@ static void continue_userinfo_lookup(struct rpc_request *req)
if (s->monitor_fn) {
msg.type = mon_SamrLookupName;
msg_lookup = talloc(s, struct msg_rpc_lookup_name);
- msg_lookup->rid = s->lookup.out.rids.ids;
- msg_lookup->count = s->lookup.out.rids.count;
+ msg_lookup->rid = s->lookup.out.rids->ids;
+ msg_lookup->count = s->lookup.out.rids->count;
msg.data = (void*)msg_lookup;
msg.data_size = sizeof(*msg_lookup);
@@ -93,7 +93,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
/* have we actually got name resolved
- we're looking for only one at the moment */
- if (s->lookup.out.rids.count == 0) {
+ if (s->lookup.out.rids->count == 0) {
composite_error(c, NT_STATUS_NO_SUCH_USER);
}
@@ -102,7 +102,7 @@ static void continue_userinfo_lookup(struct rpc_request *req)
/* prepare parameters for LookupNames */
s->openuser.in.domain_handle = &s->domain_handle;
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- s->openuser.in.rid = s->lookup.out.rids.ids[0];
+ s->openuser.in.rid = s->lookup.out.rids->ids[0];
s->openuser.out.user_handle = &s->user_handle;
/* send request */
@@ -151,6 +151,8 @@ static void continue_userinfo_openuser(struct rpc_request *req)
/* prepare parameters for QueryUserInfo call */
s->queryuserinfo.in.user_handle = &s->user_handle;
s->queryuserinfo.in.level = s->level;
+ s->queryuserinfo.out.info = talloc(s, union samr_UserInfo *);
+ if (composite_nomem(s->queryuserinfo.out.info, c)) return;
/* queue rpc call, set event handling and new state */
queryuser_req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &s->queryuserinfo);
@@ -184,7 +186,7 @@ static void continue_userinfo_getuser(struct rpc_request *req)
return;
}
- s->info = talloc_steal(s, s->queryuserinfo.out.info);
+ s->info = talloc_steal(s, *(s->queryuserinfo.out.info));
/* issue a monitor message */
if (s->monitor_fn) {
@@ -297,6 +299,10 @@ struct composite_context *libnet_rpc_userinfo_send(struct dcerpc_pipe *p,
s->lookup.in.num_names = 1;
s->lookup.in.names = talloc_array(s, struct lsa_String, 1);
if (composite_nomem(s->lookup.in.names, c)) return c;
+ s->lookup.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookup.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookup.out.rids, c)) return c;
+ if (composite_nomem(s->lookup.out.types, c)) return c;
s->lookup.in.names[0].string = talloc_strdup(s, io->in.username);
if (composite_nomem(s->lookup.in.names[0].string, c)) return c;
diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c
index 398d9f2cb0..c638d8af32 100644
--- a/source4/libnet/userman.c
+++ b/source4/libnet/userman.c
@@ -236,12 +236,12 @@ static void continue_userdel_name_found(struct rpc_request *req)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_USER;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -251,8 +251,8 @@ static void continue_userdel_name_found(struct rpc_request *req)
if (s->monitor_fn) {
struct msg_rpc_lookup_name msg_lookup;
- msg_lookup.rid = s->lookupname.out.rids.ids;
- msg_lookup.count = s->lookupname.out.rids.count;
+ msg_lookup.rid = s->lookupname.out.rids->ids;
+ msg_lookup.count = s->lookupname.out.rids->count;
msg.type = mon_SamrLookupName;
msg.data = (void*)&msg_lookup;
@@ -262,7 +262,7 @@ static void continue_userdel_name_found(struct rpc_request *req)
/* prepare the arguments for rpc call */
s->openuser.in.domain_handle = &s->domain_handle;
- s->openuser.in.rid = s->lookupname.out.rids.ids[0];
+ s->openuser.in.rid = s->lookupname.out.rids->ids[0];
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->openuser.out.user_handle = &s->user_handle;
@@ -393,6 +393,10 @@ struct composite_context *libnet_rpc_userdel_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.username;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
@@ -500,12 +504,12 @@ static void continue_usermod_name_found(struct rpc_request *req)
/* what to do when there's no user account to delete
and what if there's more than one rid resolved */
- if (!s->lookupname.out.rids.count) {
+ if (!s->lookupname.out.rids->count) {
c->status = NT_STATUS_NO_SUCH_USER;
composite_error(c, c->status);
return;
- } else if (!s->lookupname.out.rids.count > 1) {
+ } else if (!s->lookupname.out.rids->count > 1) {
c->status = NT_STATUS_INVALID_ACCOUNT_NAME;
composite_error(c, c->status);
return;
@@ -515,8 +519,8 @@ static void continue_usermod_name_found(struct rpc_request *req)
if (s->monitor_fn) {
struct msg_rpc_lookup_name msg_lookup;
- msg_lookup.rid = s->lookupname.out.rids.ids;
- msg_lookup.count = s->lookupname.out.rids.count;
+ msg_lookup.rid = s->lookupname.out.rids->ids;
+ msg_lookup.count = s->lookupname.out.rids->count;
msg.type = mon_SamrLookupName;
msg.data = (void*)&msg_lookup;
@@ -526,7 +530,7 @@ static void continue_usermod_name_found(struct rpc_request *req)
/* prepare the next rpc call */
s->openuser.in.domain_handle = &s->domain_handle;
- s->openuser.in.rid = s->lookupname.out.rids.ids[0];
+ s->openuser.in.rid = s->lookupname.out.rids->ids[0];
s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
s->openuser.out.user_handle = &s->user_handle;
@@ -679,6 +683,9 @@ static NTSTATUS usermod_change(struct composite_context *c,
if (!do_set) {
s->queryuser.in.user_handle = &s->user_handle;
s->queryuser.in.level = level;
+ s->queryuser.out.info = talloc(s, union samr_UserInfo *);
+ if (composite_nomem(s->queryuser.out.info, c)) return;
+
/* send query user info request to retrieve complete data of
a particular info level */
@@ -751,7 +758,7 @@ static void continue_usermod_user_queried(struct rpc_request *req)
/* get returned user data and make a change (potentially one
of many) */
- s->info = *s->queryuser.out.info;
+ s->info = *(*s->queryuser.out.info);
usermod_setfields(s, &level, i, true);
@@ -834,6 +841,10 @@ struct composite_context *libnet_rpc_usermod_send(struct dcerpc_pipe *p,
s->lookupname.in.num_names = 1;
s->lookupname.in.names = talloc_zero(s, struct lsa_String);
s->lookupname.in.names->string = io->in.username;
+ s->lookupname.out.rids = talloc_zero(s, struct samr_Ids);
+ s->lookupname.out.types = talloc_zero(s, struct samr_Ids);
+ if (composite_nomem(s->lookupname.out.rids, c)) return c;
+ if (composite_nomem(s->lookupname.out.types, c)) return c;
/* send the rpc request */
lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname);
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index b2b9f2e7a7..97da760832 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -8,7 +8,7 @@ dcerpcsrcdir = $(librpcsrcdir)/rpc
PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBTALLOC LIBSAMBA-UTIL CHARSET \
LIBSAMBA-HOSTCONFIG
-LIBNDR_OBJ_FILES = $(addprefix $(ndrsrcdir)/, ndr_string.o) ../librpc/ndr/ndr_basic.o ../librpc/ndr/uuid.o ../librpc/ndr/ndr.o
+LIBNDR_OBJ_FILES = $(addprefix $(ndrsrcdir)/, ndr_string.o) ../librpc/ndr/ndr_basic.o ../librpc/ndr/uuid.o ../librpc/ndr/ndr.o $(gen_ndrsrcdir)/ndr_misc.o ../librpc/ndr/ndr_misc.o
PC_FILES += ../librpc/ndr.pc
LIBNDR_VERSION = 0.0.1
@@ -18,6 +18,7 @@ LIBNDR_SOVERSION = 0
################################################
PUBLIC_HEADERS += ../librpc/ndr/libndr.h
+PUBLIC_HEADERS += $(gen_ndrsrcdir)/misc.h $(gen_ndrsrcdir)/ndr_misc.h
#################################
# Start BINARY ndrdump
@@ -49,17 +50,26 @@ PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBNDR
NDR_COMPRESSION_OBJ_FILES = ../librpc/ndr/ndr_compression.o
[SUBSYSTEM::NDR_SECURITY]
-PUBLIC_DEPENDENCIES = NDR_MISC LIBSECURITY
+PUBLIC_DEPENDENCIES = LIBNDR LIBSECURITY
+
+NDR_SECURITY_OBJ_FILES = $(gen_ndrsrcdir)/ndr_security.o \
+ ../librpc/ndr/ndr_sec_helper.o \
+ $(gen_ndrsrcdir)/ndr_dom_sid.o \
+ $(ndrsrcdir)/ndr_dom_sid.o
-NDR_SECURITY_OBJ_FILES = $(gen_ndrsrcdir)/ndr_security.o $(ndrsrcdir)/ndr_sec_helper.o
+PUBLIC_HEADERS += $(addprefix $(gen_ndrsrcdir)/, security.h dom_sid.h)
-PUBLIC_HEADERS += $(gen_ndrsrcdir)/security.h
[SUBSYSTEM::NDR_AUDIOSRV]
PUBLIC_DEPENDENCIES = LIBNDR
NDR_AUDIOSRV_OBJ_FILES = $(gen_ndrsrcdir)/ndr_audiosrv.o
+[SUBSYSTEM::NDR_NAMED_PIPE_AUTH]
+PUBLIC_DEPENDENCIES = LIBNDR
+
+NDR_NAMED_PIPE_AUTH_OBJ_FILES = $(gen_ndrsrcdir)/ndr_named_pipe_auth.o
+
[SUBSYSTEM::NDR_DNSSERVER]
PUBLIC_DEPENDENCIES = LIBNDR
@@ -100,13 +110,6 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_EFS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_efs.o
-[SUBSYSTEM::NDR_MISC]
-PUBLIC_DEPENDENCIES = LIBNDR
-
-NDR_MISC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_misc.o ../librpc/ndr/ndr_misc.o
-
-PUBLIC_HEADERS += $(gen_ndrsrcdir)/misc.h $(gen_ndrsrcdir)/ndr_misc.h
-
[SUBSYSTEM::NDR_ROT]
PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
@@ -120,7 +123,7 @@ NDR_LSA_OBJ_FILES = $(gen_ndrsrcdir)/ndr_lsa.o
PUBLIC_HEADERS += $(gen_ndrsrcdir)/lsa.h
[SUBSYSTEM::NDR_DFS]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_DFS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dfs.o
@@ -140,7 +143,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL
NDR_DRSUAPI_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsuapi.o ../librpc/ndr/ndr_drsuapi.o
[SUBSYSTEM::NDR_DRSBLOBS]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI
+PUBLIC_DEPENDENCIES = LIBNDR NDR_DRSUAPI
NDR_DRSBLOBS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsblobs.o ../librpc/ndr/ndr_drsblobs.o
@@ -160,14 +163,14 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_UNIXINFO_OBJ_FILES = $(gen_ndrsrcdir)/ndr_unixinfo.o
[SUBSYSTEM::NDR_SAMR]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_LSA NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA NDR_SECURITY
NDR_SAMR_OBJ_FILES = $(gen_ndrsrcdir)/ndr_samr.o
PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/samr.h gen_ndr/ndr_samr.h gen_ndr/ndr_samr_c.h)
[SUBSYSTEM::NDR_NFS4ACL]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_SECURITY
NDR_NFS4ACL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nfs4acl.o
@@ -183,7 +186,7 @@ NDR_SPOOLSS_BUF_OBJ_FILES = $(ndrsrcdir)/ndr_spoolss_buf.o
$(eval $(call proto_header_template,$(ndrsrcdir)/ndr_spoolss_buf.h,$(NDR_SPOOLSS_BUF_OBJ_FILES:.o=.c)))
[SUBSYSTEM::NDR_WKSSVC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_MISC NDR_SECURITY
+PUBLIC_DEPENDENCIES = LIBNDR NDR_SRVSVC NDR_SECURITY
NDR_WKSSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wkssvc.o
@@ -193,7 +196,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_SVCCTL NDR_SECURITY
NDR_SRVSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_srvsvc.o
[SUBSYSTEM::NDR_SVCCTL]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_SVCCTL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_svcctl.o
@@ -212,7 +215,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_LSA
NDR_EVENTLOG_OBJ_FILES = $(gen_ndrsrcdir)/ndr_eventlog.o
[SUBSYSTEM::NDR_EPMAPPER]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_EPMAPPER_OBJ_FILES = $(gen_ndrsrcdir)/ndr_epmapper.o
@@ -222,7 +225,7 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_DBGIDL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dbgidl.o
[SUBSYSTEM::NDR_DSSETUP]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_DSSETUP_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dssetup.o
@@ -237,7 +240,7 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_WINS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_wins.o
[SUBSYSTEM::NDR_WINREG]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR NDR_INITSHUTDOWN NDR_SECURITY
NDR_WINREG_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winreg.o
@@ -262,12 +265,12 @@ PUBLIC_DEPENDENCIES = LIBNDR
NDR_ORPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_orpc.o ../librpc/ndr/ndr_orpc.o
[SUBSYSTEM::NDR_OXIDRESOLVER]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
NDR_OXIDRESOLVER_OBJ_FILES = $(gen_ndrsrcdir)/ndr_oxidresolver.o
[SUBSYSTEM::NDR_REMACT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR NDR_ORPC
NDR_REMACT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_remact.o
@@ -299,7 +302,7 @@ NDR_NTSVCS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_ntsvcs.o
[SUBSYSTEM::NDR_NETLOGON]
PUBLIC_DEPENDENCIES = LIBNDR NDR_SAMR NDR_LSA NDR_SECURITY
-NDR_NETLOGON_OBJ_FILES = $(gen_ndrsrcdir)/ndr_netlogon.o
+NDR_NETLOGON_OBJ_FILES = $(gen_ndrsrcdir)/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o
PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/netlogon.h)
@@ -339,7 +342,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT
NDR_SCHANNEL_OBJ_FILES = $(gen_ndrsrcdir)/ndr_schannel.o
[SUBSYSTEM::NDR_NBT]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
+PUBLIC_DEPENDENCIES = LIBNDR NDR_NBT_BUF NDR_SVCCTL NDR_SECURITY NDR_SAMR LIBCLI_NDR_NETLOGON
NDR_NBT_OBJ_FILES = $(gen_ndrsrcdir)/ndr_nbt.o
@@ -362,7 +365,7 @@ NDR_WINBIND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winbind.o
#PUBLIC_HEADERS += $(gen_ndrsrcdir)/winbind.h
$(librpcsrcdir)/idl-deps:
- $(PERL) $(librpcsrcdir)/idl-deps.pl $(filter-out ../librpc/idl/security.idl,$(wildcard $(librpcsrcdir)/idl/*.idl ../librpc/idl/*.idl)) >$@
+ $(PERL) $(librpcsrcdir)/idl-deps.pl $(wildcard $(librpcsrcdir)/idl/*.idl ../librpc/idl/*.idl) >$@
clean::
rm -f $(librpcsrcdir)/idl-deps
@@ -377,7 +380,7 @@ $(gen_ndrsrcdir)/tables.c: $(IDL_NDR_PARSE_H_FILES)
[SUBSYSTEM::NDR_TABLE]
PUBLIC_DEPENDENCIES = \
NDR_AUDIOSRV NDR_ECHO NDR_DCERPC \
- NDR_DSBACKUP NDR_EFS NDR_MISC NDR_LSA NDR_DFS NDR_DRSUAPI \
+ NDR_DSBACKUP NDR_EFS NDR_LSA NDR_DFS NDR_DRSUAPI \
NDR_POLICYAGENT NDR_UNIXINFO NDR_SAMR NDR_SPOOLSS NDR_WKSSVC NDR_SRVSVC NDR_ATSVC \
NDR_EVENTLOG NDR_EPMAPPER NDR_DBGIDL NDR_DSSETUP NDR_MSGSVC NDR_WINS \
NDR_WINREG NDR_MGMT NDR_PROTECTED_STORAGE NDR_OXIDRESOLVER \
@@ -386,7 +389,7 @@ PUBLIC_DEPENDENCIES = \
NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \
NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \
NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \
- NDR_DCOM NDR_WMI
+ NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH
NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o
@@ -588,7 +591,7 @@ PUBLIC_DEPENDENCIES = dcerpc NDR_KEYSVC
RPC_NDR_KEYSVC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_keysvc_c.o
[SUBSYSTEM::NDR_DCERPC]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC
+PUBLIC_DEPENDENCIES = LIBNDR
NDR_DCERPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dcerpc.o
@@ -626,7 +629,7 @@ PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, rpc/dcerpc.h \
[PYTHON::python_dcerpc]
LIBRARY_REALNAME = samba/dcerpc/base.$(SHLIBEXT)
-PUBLIC_DEPENDENCIES = LIBCLI_SMB NDR_MISC LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG dcerpc_samr RPC_NDR_LSA DYNCONFIG swig_credentials param
+PUBLIC_DEPENDENCIES = LIBCLI_SMB LIBSAMBA-UTIL LIBSAMBA-HOSTCONFIG dcerpc_samr RPC_NDR_LSA DYNCONFIG swig_credentials param
python_dcerpc_OBJ_FILES = $(dcerpcsrcdir)/pyrpc.o
@@ -729,9 +732,15 @@ PRIVATE_DEPENDENCIES = RPC_NDR_DRSUAPI PYTALLOC param swig_credentials python_dc
python_drsuapi_OBJ_FILES = $(gen_ndrsrcdir)/py_drsuapi.o
+[PYTHON::python_dcerpc_dom_sid]
+LIBRARY_REALNAME = samba/dcerpc/dom_sid.$(SHLIBEXT)
+PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc
+
+python_dcerpc_dom_sid_OBJ_FILES = $(gen_ndrsrcdir)/py_dom_sid.o
+
[PYTHON::python_dcerpc_security]
LIBRARY_REALNAME = samba/dcerpc/security.$(SHLIBEXT)
-PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc
+PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc_dom_sid python_dcerpc
python_dcerpc_security_OBJ_FILES = $(gen_ndrsrcdir)/py_security.o
diff --git a/source4/librpc/idl/dom_sid.idl b/source4/librpc/idl/dom_sid.idl
new file mode 100644
index 0000000000..80df11dbfe
--- /dev/null
+++ b/source4/librpc/idl/dom_sid.idl
@@ -0,0 +1,42 @@
+/*
+ use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really
+ just a dom sid, but with the sub_auths represented as a conformant
+ array. As with all in-structure conformant arrays, the array length
+ is placed before the start of the structure. That's what gives rise
+ to the extra num_auths elemenent. We don't want the Samba code to
+ have to bother with such esoteric NDR details, so its easier to just
+ define it as a dom_sid and use pidl magic to make it all work. It
+ just means you need to mark a sid as a "dom_sid2" in the IDL when you
+ know it is of the conformant array variety
+*/
+cpp_quote("#define dom_sid2 dom_sid")
+
+/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */
+cpp_quote("#define dom_sid28 dom_sid")
+
+/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */
+cpp_quote("#define dom_sid0 dom_sid")
+
+[
+ pointer_default(unique)
+]
+interface dom_sid
+{
+ /* a domain SID. Note that unlike Samba3 this contains a pointer,
+ so you can't copy them using assignment */
+ typedef [public,gensize,noprint,noejs,nosize] struct {
+ uint8 sid_rev_num; /**< SID revision number */
+ [range(0,15)] int8 num_auths; /**< Number of sub-authorities */
+ uint8 id_auth[6]; /**< Identifier Authority */
+ uint32 sub_auths[num_auths];
+ } dom_sid;
+
+ /* id used to identify a endpoint, possibly in a cluster */
+ typedef [public] struct {
+ hyper id;
+ uint32 id2;
+ uint32 node;
+ } server_id;
+
+}
+
diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl
deleted file mode 100644
index 47882dfb84..0000000000
--- a/source4/librpc/idl/samr.idl
+++ /dev/null
@@ -1,1424 +0,0 @@
-#include "idl_types.h"
-
-/*
- samr interface definition
-*/
-import "misc.idl", "lsa.idl", "security.idl";
-
-/*
- Thanks to Todd Sabin for some information from his samr.idl in acltools
-*/
-
-[ uuid("12345778-1234-abcd-ef00-0123456789ac"),
- version(1.0),
- endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:", "ncalrpc:"),
- pointer_default(unique)
-] interface samr
-{
- typedef bitmap security_secinfo security_secinfo;
-
- /* account control (acct_flags) bits */
- typedef [public,bitmap32bit] bitmap {
- ACB_DISABLED = 0x00000001, /* 1 = User account disabled */
- ACB_HOMDIRREQ = 0x00000002, /* 1 = Home directory required */
- ACB_PWNOTREQ = 0x00000004, /* 1 = User password not required */
- ACB_TEMPDUP = 0x00000008, /* 1 = Temporary duplicate account */
- ACB_NORMAL = 0x00000010, /* 1 = Normal user account */
- ACB_MNS = 0x00000020, /* 1 = MNS logon user account */
- ACB_DOMTRUST = 0x00000040, /* 1 = Interdomain trust account */
- ACB_WSTRUST = 0x00000080, /* 1 = Workstation trust account */
- ACB_SVRTRUST = 0x00000100, /* 1 = Server trust account */
- ACB_PWNOEXP = 0x00000200, /* 1 = User password does not expire */
- ACB_AUTOLOCK = 0x00000400, /* 1 = Account auto locked */
- ACB_ENC_TXT_PWD_ALLOWED = 0x00000800, /* 1 = Encryped text password is allowed */
- ACB_SMARTCARD_REQUIRED = 0x00001000, /* 1 = Smart Card required */
- ACB_TRUSTED_FOR_DELEGATION = 0x00002000, /* 1 = Trusted for Delegation */
- ACB_NOT_DELEGATED = 0x00004000, /* 1 = Not delegated */
- ACB_USE_DES_KEY_ONLY = 0x00008000, /* 1 = Use DES key only */
- ACB_DONT_REQUIRE_PREAUTH = 0x00010000, /* 1 = Preauth not required */
- ACB_PW_EXPIRED = 0x00020000, /* 1 = Password Expired */
- ACB_NO_AUTH_DATA_REQD = 0x00080000 /* 1 = No authorization data required */
- } samr_AcctFlags;
-
- typedef [bitmap32bit] bitmap {
- SAMR_ACCESS_CONNECT_TO_SERVER = 0x00000001,
- SAMR_ACCESS_SHUTDOWN_SERVER = 0x00000002,
- SAMR_ACCESS_INITIALIZE_SERVER = 0x00000004,
- SAMR_ACCESS_CREATE_DOMAIN = 0x00000008,
- SAMR_ACCESS_ENUM_DOMAINS = 0x00000010,
- SAMR_ACCESS_OPEN_DOMAIN = 0x00000020
- } samr_ConnectAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_USER_ACCESS_GET_NAME_ETC = 0x00000001,
- SAMR_USER_ACCESS_GET_LOCALE = 0x00000002,
- SAMR_USER_ACCESS_SET_LOC_COM = 0x00000004,
- SAMR_USER_ACCESS_GET_LOGONINFO = 0x00000008,
- SAMR_USER_ACCESS_GET_ATTRIBUTES = 0x00000010,
- SAMR_USER_ACCESS_SET_ATTRIBUTES = 0x00000020,
- SAMR_USER_ACCESS_CHANGE_PASSWORD = 0x00000040,
- SAMR_USER_ACCESS_SET_PASSWORD = 0x00000080,
- SAMR_USER_ACCESS_GET_GROUPS = 0x00000100,
- SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP = 0x00000200,
- SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP = 0x00000400
- } samr_UserAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 = 0x00000001,
- SAMR_DOMAIN_ACCESS_SET_INFO_1 = 0x00000002,
- SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 = 0x00000004,
- SAMR_DOMAIN_ACCESS_SET_INFO_2 = 0x00000008,
- SAMR_DOMAIN_ACCESS_CREATE_USER = 0x00000010,
- SAMR_DOMAIN_ACCESS_CREATE_GROUP = 0x00000020,
- SAMR_DOMAIN_ACCESS_CREATE_ALIAS = 0x00000040,
- SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS = 0x00000080,
- SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS = 0x00000100,
- SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT = 0x00000200,
- SAMR_DOMAIN_ACCESS_SET_INFO_3 = 0x00000400
- } samr_DomainAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_GROUP_ACCESS_LOOKUP_INFO = 0x00000001,
- SAMR_GROUP_ACCESS_SET_INFO = 0x00000002,
- SAMR_GROUP_ACCESS_ADD_MEMBER = 0x00000004,
- SAMR_GROUP_ACCESS_REMOVE_MEMBER = 0x00000008,
- SAMR_GROUP_ACCESS_GET_MEMBERS = 0x00000010
- } samr_GroupAccessMask;
-
- typedef [bitmap32bit] bitmap {
- SAMR_ALIAS_ACCESS_ADD_MEMBER = 0x00000001,
- SAMR_ALIAS_ACCESS_REMOVE_MEMBER = 0x00000002,
- SAMR_ALIAS_ACCESS_GET_MEMBERS = 0x00000004,
- SAMR_ALIAS_ACCESS_LOOKUP_INFO = 0x00000008,
- SAMR_ALIAS_ACCESS_SET_INFO = 0x00000010
- } samr_AliasAccessMask;
-
- /******************/
- /* Function: 0x00 */
- NTSTATUS samr_Connect (
- /* notice the lack of [string] */
- [in,unique] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
-
- /******************/
- /* Function: 0x01 */
- [public] NTSTATUS samr_Close (
- [in,out,ref] policy_handle *handle
- );
-
- /******************/
- /* Function: 0x02 */
-
- NTSTATUS samr_SetSecurity (
- [in,ref] policy_handle *handle,
- [in] security_secinfo sec_info,
- [in,ref] sec_desc_buf *sdbuf
- );
-
- /******************/
- /* Function: 0x03 */
-
- NTSTATUS samr_QuerySecurity (
- [in,ref] policy_handle *handle,
- [in] security_secinfo sec_info,
- [out,unique] sec_desc_buf *sdbuf
- );
-
- /******************/
- /* Function: 0x04 */
-
- /*
- shutdown the SAM - once you call this the SAM will be dead
- */
- NTSTATUS samr_Shutdown (
- [in,ref] policy_handle *connect_handle
- );
-
- /******************/
- /* Function: 0x05 */
- NTSTATUS samr_LookupDomain (
- [in,ref] policy_handle *connect_handle,
- [in,ref] lsa_String *domain_name,
- [out,unique] dom_sid2 *sid
- );
-
-
- /******************/
- /* Function: 0x06 */
-
- typedef struct {
- uint32 idx;
- lsa_String name;
- } samr_SamEntry;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_SamEntry *entries;
- } samr_SamArray;
-
- NTSTATUS samr_EnumDomains (
- [in,ref] policy_handle *connect_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] uint32 buf_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
-
- /************************/
- /* Function 0x07 */
- [public] NTSTATUS samr_OpenDomain(
- [in,ref] policy_handle *connect_handle,
- [in] samr_DomainAccessMask access_mask,
- [in,ref] dom_sid2 *sid,
- [out,ref] policy_handle *domain_handle
- );
-
- /************************/
- /* Function 0x08 */
- /* server roles */
- typedef [v1_enum] enum {
- SAMR_ROLE_STANDALONE = 0,
- SAMR_ROLE_DOMAIN_MEMBER = 1,
- SAMR_ROLE_DOMAIN_BDC = 2,
- SAMR_ROLE_DOMAIN_PDC = 3
- } samr_Role;
-
- /* password properties flags */
- typedef [public,bitmap32bit] bitmap {
- DOMAIN_PASSWORD_COMPLEX = 0x00000001,
- DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002,
- DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004,
- DOMAIN_PASSWORD_LOCKOUT_ADMINS = 0x00000008,
- DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010,
- DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020
- } samr_PasswordProperties;
-
- typedef struct {
- uint16 min_password_length;
- uint16 password_history_length;
- samr_PasswordProperties password_properties;
- /* yes, these are signed. They are in negative 100ns */
- dlong max_password_age;
- dlong min_password_age;
- } samr_DomInfo1;
-
- typedef struct {
- NTTIME force_logoff_time;
- lsa_String oem_information; /* comment */
- lsa_String domain_name;
- lsa_String primary; /* PDC name if this is a BDC */
- udlong sequence_num;
- uint32 unknown2;
- samr_Role role;
- uint32 unknown3;
- uint32 num_users;
- uint32 num_groups;
- uint32 num_aliases;
- } samr_DomGeneralInformation;
-
- typedef struct {
- NTTIME force_logoff_time;
- } samr_DomInfo3;
-
- typedef struct {
- lsa_String oem_information; /* comment */
- } samr_DomOEMInformation;
-
- typedef struct {
- lsa_String domain_name;
- } samr_DomInfo5;
-
- typedef struct {
- lsa_String primary;
- } samr_DomInfo6;
-
- typedef struct {
- samr_Role role;
- } samr_DomInfo7;
-
- typedef struct {
- hyper sequence_num;
- NTTIME domain_create_time;
- } samr_DomInfo8;
-
- typedef struct {
- uint32 unknown; /* w2k3 returns 1 */
- } samr_DomInfo9;
-
- typedef struct {
- samr_DomGeneralInformation general;
- hyper lockout_duration;
- hyper lockout_window;
- uint16 lockout_threshold;
- } samr_DomGeneralInformation2;
-
- typedef struct {
- hyper lockout_duration;
- hyper lockout_window;
- uint16 lockout_threshold;
- } samr_DomInfo12;
-
- typedef struct {
- hyper sequence_num;
- NTTIME domain_create_time;
- uint32 unknown1;
- uint32 unknown2;
- } samr_DomInfo13;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_DomInfo1 info1;
- [case(2)] samr_DomGeneralInformation general;
- [case(3)] samr_DomInfo3 info3;
- [case(4)] samr_DomOEMInformation oem;
- [case(5)] samr_DomInfo5 info5;
- [case(6)] samr_DomInfo6 info6;
- [case(7)] samr_DomInfo7 info7;
- [case(8)] samr_DomInfo8 info8;
- [case(9)] samr_DomInfo9 info9;
- [case(11)] samr_DomGeneralInformation2 general2;
- [case(12)] samr_DomInfo12 info12;
- [case(13)] samr_DomInfo13 info13;
- } samr_DomainInfo;
-
- NTSTATUS samr_QueryDomainInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [out,switch_is(level),unique] samr_DomainInfo *info
- );
-
- /************************/
- /* Function 0x09 */
- /*
- only levels 1, 3, 4, 6, 7, 9, 12 are valid for this
- call in w2k3
- */
- NTSTATUS samr_SetDomainInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in,switch_is(level),ref] samr_DomainInfo *info
- );
-
-
- /************************/
- /* Function 0x0a */
- NTSTATUS samr_CreateDomainGroup(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *name,
- [in] samr_GroupAccessMask access_mask,
- [out,ref] policy_handle *group_handle,
- [out,ref] uint32 *rid
- );
-
-
- /************************/
- /* Function 0x0b */
- NTSTATUS samr_EnumDomainGroups(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] uint32 max_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x0c */
- NTSTATUS samr_CreateUser(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *account_name,
- [in] samr_UserAccessMask access_mask,
- [out,ref] policy_handle *user_handle,
- [out,ref] uint32 *rid
- );
-
- /************************/
- /* Function 0x0d */
-
-
- /* w2k3 treats max_size as max_users*54 and sets the
- resume_handle as the rid of the last user sent
- */
- const int SAMR_ENUM_USERS_MULTIPLIER = 54;
-
- NTSTATUS samr_EnumDomainUsers(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] samr_AcctFlags acct_flags,
- [in] uint32 max_size,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x0e */
- NTSTATUS samr_CreateDomAlias(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *alias_name,
- [in] samr_AliasAccessMask access_mask,
- [out,ref] policy_handle *alias_handle,
- [out,ref] uint32 *rid
- );
-
- /************************/
- /* Function 0x0f */
- NTSTATUS samr_EnumDomainAliases(
- [in,ref] policy_handle *domain_handle,
- [in,out,ref] uint32 *resume_handle,
- [in] samr_AcctFlags acct_flags,
- [out,unique] samr_SamArray *sam,
- [out] uint32 num_entries
- );
-
- /************************/
- /* Function 0x10 */
-
- typedef struct {
- [range(0,1024)] uint32 count;
- [size_is(count)] uint32 *ids;
- } samr_Ids;
-
- NTSTATUS samr_GetAliasMembership(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_SidArray *sids,
- [out,ref] samr_Ids *rids
- );
-
- /************************/
- /* Function 0x11 */
-
- [public] NTSTATUS samr_LookupNames(
- [in,ref] policy_handle *domain_handle,
- [in,range(0,1000)] uint32 num_names,
- [in,size_is(1000),length_is(num_names)] lsa_String names[],
- [out] samr_Ids rids,
- [out] samr_Ids types
- );
-
-
- /************************/
- /* Function 0x12 */
- NTSTATUS samr_LookupRids(
- [in,ref] policy_handle *domain_handle,
- [in,range(0,1000)] uint32 num_rids,
- [in,size_is(1000),length_is(num_rids)] uint32 rids[],
- [out] lsa_Strings names,
- [out] samr_Ids types
- );
-
- /************************/
- /* Function 0x13 */
- NTSTATUS samr_OpenGroup(
- [in,ref] policy_handle *domain_handle,
- [in] samr_GroupAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *group_handle
- );
-
- /* Group attributes */
- typedef [public,bitmap32bit] bitmap {
- SE_GROUP_MANDATORY = 0x00000001,
- SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002,
- SE_GROUP_ENABLED = 0x00000004,
- SE_GROUP_OWNER = 0x00000008,
- SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010,
- SE_GROUP_RESOURCE = 0x20000000,
- SE_GROUP_LOGON_ID = 0xC0000000
- } samr_GroupAttrs;
-
- /************************/
- /* Function 0x14 */
-
- typedef struct {
- lsa_String name;
- samr_GroupAttrs attributes;
- uint32 num_members;
- lsa_String description;
- } samr_GroupInfoAll;
-
- typedef struct {
- samr_GroupAttrs attributes;
- } samr_GroupInfoAttributes;
-
- typedef struct {
- lsa_String description;
- } samr_GroupInfoDescription;
-
- typedef enum {
- GROUPINFOALL = 1,
- GROUPINFONAME = 2,
- GROUPINFOATTRIBUTES = 3,
- GROUPINFODESCRIPTION = 4,
- GROUPINFOALL2 = 5
- } samr_GroupInfoEnum;
-
- typedef [switch_type(samr_GroupInfoEnum)] union {
- [case(GROUPINFOALL)] samr_GroupInfoAll all;
- [case(GROUPINFONAME)] lsa_String name;
- [case(GROUPINFOATTRIBUTES)] samr_GroupInfoAttributes attributes;
- [case(GROUPINFODESCRIPTION)] lsa_String description;
- [case(GROUPINFOALL2)] samr_GroupInfoAll all2;
- } samr_GroupInfo;
-
- NTSTATUS samr_QueryGroupInfo(
- [in,ref] policy_handle *group_handle,
- [in] samr_GroupInfoEnum level,
- [out,switch_is(level),unique] samr_GroupInfo *info
- );
-
- /************************/
- /* Function 0x15 */
- NTSTATUS samr_SetGroupInfo(
- [in,ref] policy_handle *group_handle,
- [in] samr_GroupInfoEnum level,
- [in,switch_is(level),ref] samr_GroupInfo *info
- );
-
- /************************/
- /* Function 0x16 */
- NTSTATUS samr_AddGroupMember(
- [in,ref] policy_handle *group_handle,
- [in] uint32 rid,
- [in] uint32 flags
- );
-
- /************************/
- /* Function 0x17 */
- NTSTATUS samr_DeleteDomainGroup(
- [in,out,ref] policy_handle *group_handle
- );
-
- /************************/
- /* Function 0x18 */
- NTSTATUS samr_DeleteGroupMember(
- [in,ref] policy_handle *group_handle,
- [in] uint32 rid
- );
-
-
- /************************/
- /* Function 0x19 */
- typedef struct {
- uint32 count;
- [size_is(count)] uint32 *rids;
- [size_is(count)] uint32 *types;
- } samr_RidTypeArray;
-
- NTSTATUS samr_QueryGroupMember(
- [in,ref] policy_handle *group_handle,
- [out,unique] samr_RidTypeArray *rids
- );
-
-
- /************************/
- /* Function 0x1a */
-
- /*
- win2003 seems to accept any data at all for the two integers
- below, and doesn't seem to do anything with them that I can
- see. Weird. I really expected the first integer to be a rid
- and the second to be the attributes for that rid member.
- */
- NTSTATUS samr_SetMemberAttributesOfGroup(
- [in,ref] policy_handle *group_handle,
- [in] uint32 unknown1,
- [in] uint32 unknown2
- );
-
-
- /************************/
- /* Function 0x1b */
- NTSTATUS samr_OpenAlias (
- [in,ref] policy_handle *domain_handle,
- [in] samr_AliasAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *alias_handle
- );
-
-
- /************************/
- /* Function 0x1c */
-
- typedef struct {
- lsa_String name;
- uint32 num_members;
- lsa_String description;
- } samr_AliasInfoAll;
-
- typedef enum {
- ALIASINFOALL = 1,
- ALIASINFONAME = 2,
- ALIASINFODESCRIPTION = 3
- } samr_AliasInfoEnum;
-
- typedef [switch_type(samr_AliasInfoEnum)] union {
- [case(ALIASINFOALL)] samr_AliasInfoAll all;
- [case(ALIASINFONAME)] lsa_String name;
- [case(ALIASINFODESCRIPTION)] lsa_String description;
- } samr_AliasInfo;
-
- NTSTATUS samr_QueryAliasInfo(
- [in,ref] policy_handle *alias_handle,
- [in] samr_AliasInfoEnum level,
- [out,switch_is(level),unique] samr_AliasInfo *info
- );
-
- /************************/
- /* Function 0x1d */
- NTSTATUS samr_SetAliasInfo(
- [in,ref] policy_handle *alias_handle,
- [in] samr_AliasInfoEnum level,
- [in,switch_is(level),ref] samr_AliasInfo *info
- );
-
- /************************/
- /* Function 0x1e */
- NTSTATUS samr_DeleteDomAlias(
- [in,out,ref] policy_handle *alias_handle
- );
-
- /************************/
- /* Function 0x1f */
- NTSTATUS samr_AddAliasMember(
- [in,ref] policy_handle *alias_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x20 */
- NTSTATUS samr_DeleteAliasMember(
- [in,ref] policy_handle *alias_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x21 */
- NTSTATUS samr_GetMembersInAlias(
- [in,ref] policy_handle *alias_handle,
- [out,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x22 */
- [public] NTSTATUS samr_OpenUser(
- [in,ref] policy_handle *domain_handle,
- [in] samr_UserAccessMask access_mask,
- [in] uint32 rid,
- [out,ref] policy_handle *user_handle
- );
-
- /************************/
- /* Function 0x23 */
- NTSTATUS samr_DeleteUser(
- [in,out,ref] policy_handle *user_handle
- );
-
- /************************/
- /* Function 0x24 */
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 primary_gid;
- lsa_String description;
- lsa_String comment;
- } samr_UserInfo1;
-
- typedef struct {
- lsa_String comment;
- lsa_String unknown; /* settable, but doesn't stick. probably obsolete */
- uint16 country_code;
- uint16 code_page;
- } samr_UserInfo2;
-
- /* this is also used in samr and netlogon */
- typedef [public, flag(NDR_PAHEX)] struct {
- uint16 units_per_week;
- [size_is(1260), length_is(units_per_week/8)] uint8 *bits;
- } samr_LogonHours;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 rid;
- uint32 primary_gid;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String workstations;
- NTTIME last_logon;
- NTTIME last_logoff;
- NTTIME last_password_change;
- NTTIME allow_password_change;
- NTTIME force_password_change;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- samr_AcctFlags acct_flags;
- } samr_UserInfo3;
-
- typedef struct {
- samr_LogonHours logon_hours;
- } samr_UserInfo4;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- uint32 rid;
- uint32 primary_gid;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String description;
- lsa_String workstations;
- NTTIME last_logon;
- NTTIME last_logoff;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- NTTIME last_password_change;
- NTTIME acct_expiry;
- samr_AcctFlags acct_flags;
- } samr_UserInfo5;
-
- typedef struct {
- lsa_String account_name;
- lsa_String full_name;
- } samr_UserInfo6;
-
- typedef struct {
- lsa_String account_name;
- } samr_UserInfo7;
-
- typedef struct {
- lsa_String full_name;
- } samr_UserInfo8;
-
- typedef struct {
- uint32 primary_gid;
- } samr_UserInfo9;
-
- typedef struct {
- lsa_String home_directory;
- lsa_String home_drive;
- } samr_UserInfo10;
-
- typedef struct {
- lsa_String logon_script;
- } samr_UserInfo11;
-
- typedef struct {
- lsa_String profile_path;
- } samr_UserInfo12;
-
- typedef struct {
- lsa_String description;
- } samr_UserInfo13;
-
- typedef struct {
- lsa_String workstations;
- } samr_UserInfo14;
-
- typedef struct {
- samr_AcctFlags acct_flags;
- } samr_UserInfo16;
-
- typedef struct {
- NTTIME acct_expiry;
- } samr_UserInfo17;
-
- typedef [public, flag(NDR_PAHEX)] struct {
- uint8 hash[16];
- } samr_Password;
-
- typedef struct {
- samr_Password lm_pwd;
- samr_Password nt_pwd;
- boolean8 lm_pwd_active;
- boolean8 nt_pwd_active;
- } samr_UserInfo18;
-
- typedef struct {
- lsa_String parameters;
- } samr_UserInfo20;
-
- /* this defines the bits used for fields_present in info21 */
- typedef [bitmap32bit] bitmap {
- SAMR_FIELD_ACCOUNT_NAME = 0x00000001,
- SAMR_FIELD_FULL_NAME = 0x00000002,
- SAMR_FIELD_RID = 0x00000004,
- SAMR_FIELD_PRIMARY_GID = 0x00000008,
- SAMR_FIELD_DESCRIPTION = 0x00000010,
- SAMR_FIELD_COMMENT = 0x00000020,
- SAMR_FIELD_HOME_DIRECTORY = 0x00000040,
- SAMR_FIELD_HOME_DRIVE = 0x00000080,
- SAMR_FIELD_LOGON_SCRIPT = 0x00000100,
- SAMR_FIELD_PROFILE_PATH = 0x00000200,
- SAMR_FIELD_WORKSTATIONS = 0x00000400,
- SAMR_FIELD_LAST_LOGON = 0x00000800,
- SAMR_FIELD_LAST_LOGOFF = 0x00001000,
- SAMR_FIELD_LOGON_HOURS = 0x00002000,
- SAMR_FIELD_BAD_PWD_COUNT = 0x00004000,
- SAMR_FIELD_NUM_LOGONS = 0x00008000,
- SAMR_FIELD_ALLOW_PWD_CHANGE = 0x00010000,
- SAMR_FIELD_FORCE_PWD_CHANGE = 0x00020000,
- SAMR_FIELD_LAST_PWD_CHANGE = 0x00040000,
- SAMR_FIELD_ACCT_EXPIRY = 0x00080000,
- SAMR_FIELD_ACCT_FLAGS = 0x00100000,
- SAMR_FIELD_PARAMETERS = 0x00200000,
- SAMR_FIELD_COUNTRY_CODE = 0x00400000,
- SAMR_FIELD_CODE_PAGE = 0x00800000,
- SAMR_FIELD_PASSWORD = 0x01000000, /* either of these */
- SAMR_FIELD_PASSWORD2 = 0x02000000, /* two bits seems to work */
- SAMR_FIELD_PRIVATE_DATA = 0x04000000,
- SAMR_FIELD_EXPIRED_FLAG = 0x08000000,
- SAMR_FIELD_SEC_DESC = 0x10000000,
- SAMR_FIELD_OWF_PWD = 0x20000000
- } samr_FieldsPresent;
-
- /* used for 'password_expired' in samr_UserInfo21 */
- const int PASS_MUST_CHANGE_AT_NEXT_LOGON = 0x01;
- const int PASS_DONT_CHANGE_AT_NEXT_LOGON = 0x00;
-
- typedef struct {
- NTTIME last_logon;
- NTTIME last_logoff;
- NTTIME last_password_change;
- NTTIME acct_expiry;
- NTTIME allow_password_change;
- NTTIME force_password_change;
- lsa_String account_name;
- lsa_String full_name;
- lsa_String home_directory;
- lsa_String home_drive;
- lsa_String logon_script;
- lsa_String profile_path;
- lsa_String description;
- lsa_String workstations;
- lsa_String comment;
- lsa_String parameters;
- lsa_String unknown1;
- lsa_String unknown2;
- lsa_String unknown3;
- uint32 buf_count;
- [size_is(buf_count)] uint8 *buffer;
- uint32 rid;
- uint32 primary_gid;
- samr_AcctFlags acct_flags;
- samr_FieldsPresent fields_present;
- samr_LogonHours logon_hours;
- uint16 bad_password_count;
- uint16 logon_count;
- uint16 country_code;
- uint16 code_page;
- uint8 nt_password_set;
- uint8 lm_password_set;
- uint8 password_expired;
- uint8 unknown4;
- } samr_UserInfo21;
-
- typedef [public, flag(NDR_PAHEX)] struct {
- uint8 data[516];
- } samr_CryptPassword;
-
- typedef struct {
- samr_UserInfo21 info;
- samr_CryptPassword password;
- } samr_UserInfo23;
-
- typedef struct {
- samr_CryptPassword password;
- uint8 pw_len;
- } samr_UserInfo24;
-
- typedef [flag(NDR_PAHEX)] struct {
- uint8 data[532];
- } samr_CryptPasswordEx;
-
- typedef struct {
- samr_UserInfo21 info;
- samr_CryptPasswordEx password;
- } samr_UserInfo25;
-
- typedef struct {
- samr_CryptPasswordEx password;
- uint8 pw_len;
- } samr_UserInfo26;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_UserInfo1 info1;
- [case(2)] samr_UserInfo2 info2;
- [case(3)] samr_UserInfo3 info3;
- [case(4)] samr_UserInfo4 info4;
- [case(5)] samr_UserInfo5 info5;
- [case(6)] samr_UserInfo6 info6;
- [case(7)] samr_UserInfo7 info7;
- [case(8)] samr_UserInfo8 info8;
- [case(9)] samr_UserInfo9 info9;
- [case(10)] samr_UserInfo10 info10;
- [case(11)] samr_UserInfo11 info11;
- [case(12)] samr_UserInfo12 info12;
- [case(13)] samr_UserInfo13 info13;
- [case(14)] samr_UserInfo14 info14;
- [case(16)] samr_UserInfo16 info16;
- [case(17)] samr_UserInfo17 info17;
- [case(18)] samr_UserInfo18 info18;
- [case(20)] samr_UserInfo20 info20;
- [case(21)] samr_UserInfo21 info21;
- [case(23)] samr_UserInfo23 info23;
- [case(24)] samr_UserInfo24 info24;
- [case(25)] samr_UserInfo25 info25;
- [case(26)] samr_UserInfo26 info26;
- } samr_UserInfo;
-
- [public] NTSTATUS samr_QueryUserInfo(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_UserInfo *info
- );
-
-
- /************************/
- /* Function 0x25 */
- [public] NTSTATUS samr_SetUserInfo(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [in,ref,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x26 */
- /*
- this is a password change interface that doesn't give
- the server the plaintext password. Depricated.
- */
- NTSTATUS samr_ChangePasswordUser(
- [in,ref] policy_handle *user_handle,
- [in] boolean8 lm_present,
- [in,unique] samr_Password *old_lm_crypted,
- [in,unique] samr_Password *new_lm_crypted,
- [in] boolean8 nt_present,
- [in,unique] samr_Password *old_nt_crypted,
- [in,unique] samr_Password *new_nt_crypted,
- [in] boolean8 cross1_present,
- [in,unique] samr_Password *nt_cross,
- [in] boolean8 cross2_present,
- [in,unique] samr_Password *lm_cross
- );
-
- /************************/
- /* Function 0x27 */
-
- typedef [public] struct {
- uint32 rid;
- samr_GroupAttrs attributes;
- } samr_RidWithAttribute;
-
- typedef [public] struct {
- uint32 count;
- [size_is(count)] samr_RidWithAttribute *rids;
- } samr_RidWithAttributeArray;
-
- NTSTATUS samr_GetGroupsForUser(
- [in,ref] policy_handle *user_handle,
- [out,unique] samr_RidWithAttributeArray *rids
- );
-
- /************************/
- /* Function 0x28 */
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_AcctFlags acct_flags;
- lsa_String account_name;
- lsa_String description;
- lsa_String full_name;
- } samr_DispEntryGeneral;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryGeneral *entries;
- } samr_DispInfoGeneral;
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_AcctFlags acct_flags;
- lsa_String account_name;
- lsa_String description;
- } samr_DispEntryFull;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryFull *entries;
- } samr_DispInfoFull;
-
- typedef struct {
- uint32 idx;
- uint32 rid;
- samr_GroupAttrs acct_flags;
- lsa_String account_name;
- lsa_String description;
- } samr_DispEntryFullGroup;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryFullGroup *entries;
- } samr_DispInfoFullGroups;
-
- typedef struct {
- uint32 idx;
- lsa_AsciiStringLarge account_name;
- } samr_DispEntryAscii;
-
- typedef struct {
- uint32 count;
- [size_is(count)] samr_DispEntryAscii *entries;
- } samr_DispInfoAscii;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_DispInfoGeneral info1;/* users */
- [case(2)] samr_DispInfoFull info2; /* trust accounts? */
- [case(3)] samr_DispInfoFullGroups info3; /* groups */
- [case(4)] samr_DispInfoAscii info4; /* users */
- [case(5)] samr_DispInfoAscii info5; /* groups */
- } samr_DispInfo;
-
- NTSTATUS samr_QueryDisplayInfo(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
-
- /************************/
- /* Function 0x29 */
-
- /*
- this seems to be an alphabetic search function. The returned index
- is the index for samr_QueryDisplayInfo needed to get names occurring
- after the specified name. The supplied name does not need to exist
- in the database (for example you can supply just a first letter for
- searching starting at that letter)
-
- The level corresponds to the samr_QueryDisplayInfo level
- */
- NTSTATUS samr_GetDisplayEnumerationIndex(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] lsa_String name,
- [out] uint32 idx
- );
-
-
-
- /************************/
- /* Function 0x2a */
-
- /*
- w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
- */
- NTSTATUS samr_TestPrivateFunctionsDomain(
- [in,ref] policy_handle *domain_handle
- );
-
-
- /************************/
- /* Function 0x2b */
-
- /*
- w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this
- */
- NTSTATUS samr_TestPrivateFunctionsUser(
- [in,ref] policy_handle *user_handle
- );
-
-
- /************************/
- /* Function 0x2c */
-
- typedef struct {
- uint16 min_password_length;
- samr_PasswordProperties password_properties;
- } samr_PwInfo;
-
- [public] NTSTATUS samr_GetUserPwInfo(
- [in,ref] policy_handle *user_handle,
- [out] samr_PwInfo info
- );
-
- /************************/
- /* Function 0x2d */
- NTSTATUS samr_RemoveMemberFromForeignDomain(
- [in,ref] policy_handle *domain_handle,
- [in,ref] dom_sid2 *sid
- );
-
- /************************/
- /* Function 0x2e */
-
- /*
- how is this different from QueryDomainInfo ??
- */
- NTSTATUS samr_QueryDomainInfo2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_DomainInfo *info
- );
-
- /************************/
- /* Function 0x2f */
-
- /*
- how is this different from QueryUserInfo ??
- */
- NTSTATUS samr_QueryUserInfo2(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [out,unique,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x30 */
-
- /*
- how is this different from QueryDisplayInfo??
- */
- NTSTATUS samr_QueryDisplayInfo2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
- /************************/
- /* Function 0x31 */
-
- /*
- how is this different from GetDisplayEnumerationIndex ??
- */
- NTSTATUS samr_GetDisplayEnumerationIndex2(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] lsa_String name,
- [out] uint32 idx
- );
-
-
- /************************/
- /* Function 0x32 */
- NTSTATUS samr_CreateUser2(
- [in,ref] policy_handle *domain_handle,
- [in,ref] lsa_String *account_name,
- [in] samr_AcctFlags acct_flags,
- [in] samr_UserAccessMask access_mask,
- [out,ref] policy_handle *user_handle,
- [out,ref] uint32 *access_granted,
- [out,ref] uint32 *rid
- );
-
-
- /************************/
- /* Function 0x33 */
-
- /*
- another duplicate. There must be a reason ....
- */
- NTSTATUS samr_QueryDisplayInfo3(
- [in,ref] policy_handle *domain_handle,
- [in] uint16 level,
- [in] uint32 start_idx,
- [in] uint32 max_entries,
- [in] uint32 buf_size,
- [out] uint32 total_size,
- [out] uint32 returned_size,
- [out,switch_is(level)] samr_DispInfo info
- );
-
- /************************/
- /* Function 0x34 */
- NTSTATUS samr_AddMultipleMembersToAlias(
- [in,ref] policy_handle *alias_handle,
- [in,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x35 */
- NTSTATUS samr_RemoveMultipleMembersFromAlias(
- [in,ref] policy_handle *alias_handle,
- [in,ref] lsa_SidArray *sids
- );
-
- /************************/
- /* Function 0x36 */
-
- NTSTATUS samr_OemChangePasswordUser2(
- [in,unique] lsa_AsciiString *server,
- [in,ref] lsa_AsciiString *account,
- [in,unique] samr_CryptPassword *password,
- [in,unique] samr_Password *hash
- );
-
- /************************/
- /* Function 0x37 */
- NTSTATUS samr_ChangePasswordUser2(
- [in,unique] lsa_String *server,
- [in,ref] lsa_String *account,
- [in,unique] samr_CryptPassword *nt_password,
- [in,unique] samr_Password *nt_verifier,
- [in] boolean8 lm_change,
- [in,unique] samr_CryptPassword *lm_password,
- [in,unique] samr_Password *lm_verifier
- );
-
- /************************/
- /* Function 0x38 */
- NTSTATUS samr_GetDomPwInfo(
- [in,unique] lsa_String *domain_name,
- [out] samr_PwInfo info
- );
-
- /************************/
- /* Function 0x39 */
- NTSTATUS samr_Connect2(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3a */
- /*
- seems to be an exact alias for samr_SetUserInfo()
- */
- [public] NTSTATUS samr_SetUserInfo2(
- [in,ref] policy_handle *user_handle,
- [in] uint16 level,
- [in,ref,switch_is(level)] samr_UserInfo *info
- );
-
- /************************/
- /* Function 0x3b */
- /*
- this one is mysterious. I have a few guesses, but nothing working yet
- */
- NTSTATUS samr_SetBootKeyInformation(
- [in,ref] policy_handle *connect_handle,
- [in] uint32 unknown1,
- [in] uint32 unknown2,
- [in] uint32 unknown3
- );
-
- /************************/
- /* Function 0x3c */
- NTSTATUS samr_GetBootKeyInformation(
- [in,ref] policy_handle *domain_handle,
- [out] uint32 unknown
- );
-
- /************************/
- /* Function 0x3d */
- NTSTATUS samr_Connect3(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- /* this unknown value seems to be completely ignored by w2k3 */
- [in] uint32 unknown,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3e */
-
- typedef enum {
- SAMR_CONNECT_PRE_W2K = 1,
- SAMR_CONNECT_W2K = 2,
- SAMR_CONNECT_AFTER_W2K = 3
- } samr_ConnectVersion;
-
- NTSTATUS samr_Connect4(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectVersion client_version,
- [in] samr_ConnectAccessMask access_mask,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x3f */
-
- typedef enum samr_RejectReason samr_RejectReason;
-
- typedef struct {
- samr_RejectReason reason;
- uint32 unknown1;
- uint32 unknown2;
- } samr_ChangeReject;
-
- NTSTATUS samr_ChangePasswordUser3(
- [in,unique] lsa_String *server,
- [in,ref] lsa_String *account,
- [in,unique] samr_CryptPassword *nt_password,
- [in,unique] samr_Password *nt_verifier,
- [in] boolean8 lm_change,
- [in,unique] samr_CryptPassword *lm_password,
- [in,unique] samr_Password *lm_verifier,
- [in,unique] samr_CryptPassword *password3,
- [out,unique] samr_DomInfo1 *dominfo,
- [out,unique] samr_ChangeReject *reject
- );
-
- /************************/
- /* Function 0x40 */
-
- typedef struct {
- samr_ConnectVersion client_version; /* w2k3 gives 3 */
- uint32 unknown2; /* w2k3 gives 0 */
- } samr_ConnectInfo1;
-
- typedef union {
- [case(1)] samr_ConnectInfo1 info1;
- } samr_ConnectInfo;
-
- [public] NTSTATUS samr_Connect5(
- [in,unique,string,charset(UTF16)] uint16 *system_name,
- [in] samr_ConnectAccessMask access_mask,
- [in,out] uint32 level,
- [in,out,switch_is(level),ref] samr_ConnectInfo *info,
- [out,ref] policy_handle *connect_handle
- );
-
- /************************/
- /* Function 0x41 */
- NTSTATUS samr_RidToSid(
- [in,ref] policy_handle *domain_handle,
- [in] uint32 rid,
- [out,unique] dom_sid2 *sid
- );
-
-
- /************************/
- /* Function 0x42 */
-
- /*
- this should set the DSRM password for the server, which is used
- when booting into Directory Services Recovery Mode on a DC. Win2003
- gives me NT_STATUS_NOT_SUPPORTED
- */
-
- NTSTATUS samr_SetDsrmPassword(
- [in,unique] lsa_String *name,
- [in] uint32 unknown,
- [in,unique] samr_Password *hash
- );
-
-
- /************************/
- /* Function 0x43 */
- /************************/
- typedef [bitmap32bit] bitmap {
- SAMR_VALIDATE_FIELD_PASSWORD_LAST_SET = 0x00000001,
- SAMR_VALIDATE_FIELD_BAD_PASSWORD_TIME = 0x00000002,
- SAMR_VALIDATE_FIELD_LOCKOUT_TIME = 0x00000004,
- SAMR_VALIDATE_FIELD_BAD_PASSWORD_COUNT = 0x00000008,
- SAMR_VALIDATE_FIELD_PASSWORD_HISTORY_LENGTH = 0x00000010,
- SAMR_VALIDATE_FIELD_PASSWORD_HISTORY = 0x00000020
- } samr_ValidateFieldsPresent;
-
- typedef enum {
- NetValidateAuthentication = 1,
- NetValidatePasswordChange= 2,
- NetValidatePasswordReset = 3
- } samr_ValidatePasswordLevel;
-
- /* NetApi maps samr_ValidationStatus errors to WERRORs. Haven't
- * identified the mapping of
- * - NERR_PasswordFilterError
- * - NERR_PasswordExpired and
- * - NERR_PasswordCantChange
- * yet - Guenther
- */
-
- typedef enum {
- SAMR_VALIDATION_STATUS_SUCCESS = 0,
- SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1,
- SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2,
- SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4,
- SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5,
- SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6,
- SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7,
- SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8,
- SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9
- } samr_ValidationStatus;
-
- typedef struct {
- uint32 length;
- [size_is(length)] uint8 *data;
- } samr_ValidationBlob;
-
- typedef struct {
- samr_ValidateFieldsPresent fields_present;
- NTTIME_hyper last_password_change;
- NTTIME_hyper bad_password_time;
- NTTIME_hyper lockout_time;
- uint32 bad_pwd_count;
- uint32 pwd_history_len;
- [size_is(pwd_history_len)] samr_ValidationBlob *pwd_history;
- } samr_ValidatePasswordInfo;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- samr_ValidationStatus status;
- } samr_ValidatePasswordRepCtr;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_ValidatePasswordRepCtr ctr1;
- [case(2)] samr_ValidatePasswordRepCtr ctr2;
- [case(3)] samr_ValidatePasswordRepCtr ctr3;
- } samr_ValidatePasswordRep;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- lsa_StringLarge password;
- lsa_StringLarge account;
- samr_ValidationBlob hash;
- boolean8 pwd_must_change_at_next_logon;
- boolean8 clear_lockout;
- } samr_ValidatePasswordReq3;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- lsa_StringLarge password;
- lsa_StringLarge account;
- samr_ValidationBlob hash;
- boolean8 password_matched;
- } samr_ValidatePasswordReq2;
-
- typedef struct {
- samr_ValidatePasswordInfo info;
- boolean8 password_matched;
- } samr_ValidatePasswordReq1;
-
- typedef [switch_type(uint16)] union {
- [case(1)] samr_ValidatePasswordReq1 req1;
- [case(2)] samr_ValidatePasswordReq2 req2;
- [case(3)] samr_ValidatePasswordReq3 req3;
- } samr_ValidatePasswordReq;
-
- NTSTATUS samr_ValidatePassword(
- [in] samr_ValidatePasswordLevel level,
- [in,switch_is(level)] samr_ValidatePasswordReq req,
- [out,unique,switch_is(level)] samr_ValidatePasswordRep *rep
- );
-}
diff --git a/source4/librpc/idl/security.cnf b/source4/librpc/idl/security.cnf
deleted file mode 100644
index 37da8c7423..0000000000
--- a/source4/librpc/idl/security.cnf
+++ /dev/null
@@ -1 +0,0 @@
-NOEMIT
diff --git a/source4/librpc/idl/security.idl b/source4/librpc/idl/security.idl
deleted file mode 100644
index 40aa698176..0000000000
--- a/source4/librpc/idl/security.idl
+++ /dev/null
@@ -1,410 +0,0 @@
-#include "idl_types.h"
-
-/*
- security IDL structures
-*/
-
-import "misc.idl";
-
-/*
- use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really
- just a dom sid, but with the sub_auths represented as a conformant
- array. As with all in-structure conformant arrays, the array length
- is placed before the start of the structure. That's what gives rise
- to the extra num_auths elemenent. We don't want the Samba code to
- have to bother with such esoteric NDR details, so its easier to just
- define it as a dom_sid and use pidl magic to make it all work. It
- just means you need to mark a sid as a "dom_sid2" in the IDL when you
- know it is of the conformant array variety
-*/
-cpp_quote("#define dom_sid2 dom_sid")
-
-/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */
-cpp_quote("#define dom_sid28 dom_sid")
-
-/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */
-cpp_quote("#define dom_sid0 dom_sid")
-
-[
- pointer_default(unique)
-]
-interface security
-{
- /*
- access masks are divided up like this:
- 0xabccdddd
- where
- a = generic rights bits SEC_GENERIC_
- b = flags SEC_FLAG_
- c = standard rights bits SEC_STD_
- d = object type specific bits SEC_{FILE,DIR,REG,xxx}_
-
- common combinations of bits are prefixed with SEC_RIGHTS_
- */
- const int SEC_MASK_GENERIC = 0xF0000000;
- const int SEC_MASK_FLAGS = 0x0F000000;
- const int SEC_MASK_STANDARD = 0x00FF0000;
- const int SEC_MASK_SPECIFIC = 0x0000FFFF;
-
- /* generic bits */
- const int SEC_GENERIC_ALL = 0x10000000;
- const int SEC_GENERIC_EXECUTE = 0x20000000;
- const int SEC_GENERIC_WRITE = 0x40000000;
- const int SEC_GENERIC_READ = 0x80000000;
-
- /* flag bits */
- const int SEC_FLAG_SYSTEM_SECURITY = 0x01000000;
- const int SEC_FLAG_MAXIMUM_ALLOWED = 0x02000000;
-
- /* standard bits */
- const int SEC_STD_DELETE = 0x00010000;
- const int SEC_STD_READ_CONTROL = 0x00020000;
- const int SEC_STD_WRITE_DAC = 0x00040000;
- const int SEC_STD_WRITE_OWNER = 0x00080000;
- const int SEC_STD_SYNCHRONIZE = 0x00100000;
- const int SEC_STD_REQUIRED = 0x000F0000;
- const int SEC_STD_ALL = 0x001F0000;
-
- /* file specific bits */
- const int SEC_FILE_READ_DATA = 0x00000001;
- const int SEC_FILE_WRITE_DATA = 0x00000002;
- const int SEC_FILE_APPEND_DATA = 0x00000004;
- const int SEC_FILE_READ_EA = 0x00000008;
- const int SEC_FILE_WRITE_EA = 0x00000010;
- const int SEC_FILE_EXECUTE = 0x00000020;
- const int SEC_FILE_READ_ATTRIBUTE = 0x00000080;
- const int SEC_FILE_WRITE_ATTRIBUTE = 0x00000100;
- const int SEC_FILE_ALL = 0x000001ff;
-
- /* directory specific bits */
- const int SEC_DIR_LIST = 0x00000001;
- const int SEC_DIR_ADD_FILE = 0x00000002;
- const int SEC_DIR_ADD_SUBDIR = 0x00000004;
- const int SEC_DIR_READ_EA = 0x00000008;
- const int SEC_DIR_WRITE_EA = 0x00000010;
- const int SEC_DIR_TRAVERSE = 0x00000020;
- const int SEC_DIR_DELETE_CHILD = 0x00000040;
- const int SEC_DIR_READ_ATTRIBUTE = 0x00000080;
- const int SEC_DIR_WRITE_ATTRIBUTE = 0x00000100;
-
- /* registry entry specific bits */
- const int SEC_REG_QUERY_VALUE = 0x00000001;
- const int SEC_REG_SET_VALUE = 0x00000002;
- const int SEC_REG_CREATE_SUBKEY = 0x00000004;
- const int SEC_REG_ENUM_SUBKEYS = 0x00000008;
- const int SEC_REG_NOTIFY = 0x00000010;
- const int SEC_REG_CREATE_LINK = 0x00000020;
-
- /* ldap specific access bits */
- const int SEC_ADS_CREATE_CHILD = 0x00000001;
- const int SEC_ADS_DELETE_CHILD = 0x00000002;
- const int SEC_ADS_LIST = 0x00000004;
- const int SEC_ADS_SELF_WRITE = 0x00000008;
- const int SEC_ADS_READ_PROP = 0x00000010;
- const int SEC_ADS_WRITE_PROP = 0x00000020;
- const int SEC_ADS_DELETE_TREE = 0x00000040;
- const int SEC_ADS_LIST_OBJECT = 0x00000080;
- const int SEC_ADS_CONTROL_ACCESS = 0x00000100;
-
- /* invalid bits */
- const int SEC_MASK_INVALID = 0x0ce0fe00;
-
- /* generic->specific mappings for files */
- const int SEC_RIGHTS_FILE_READ = SEC_STD_READ_CONTROL |
- SEC_STD_SYNCHRONIZE |
- SEC_FILE_READ_DATA |
- SEC_FILE_READ_ATTRIBUTE |
- SEC_FILE_READ_EA;
-
- const int SEC_RIGHTS_FILE_WRITE = SEC_STD_READ_CONTROL |
- SEC_STD_SYNCHRONIZE |
- SEC_FILE_WRITE_DATA |
- SEC_FILE_WRITE_ATTRIBUTE |
- SEC_FILE_WRITE_EA |
- SEC_FILE_APPEND_DATA;
-
- const int SEC_RIGHTS_FILE_EXECUTE = SEC_STD_SYNCHRONIZE |
- SEC_STD_READ_CONTROL |
- SEC_FILE_READ_ATTRIBUTE |
- SEC_FILE_EXECUTE;
-
- const int SEC_RIGHTS_FILE_ALL = SEC_STD_ALL | SEC_FILE_ALL;
-
- /* generic->specific mappings for directories (same as files) */
- const int SEC_RIGHTS_DIR_READ = SEC_RIGHTS_FILE_READ;
- const int SEC_RIGHTS_DIR_WRITE = SEC_RIGHTS_FILE_WRITE;
- const int SEC_RIGHTS_DIR_EXECUTE = SEC_RIGHTS_FILE_EXECUTE;
- const int SEC_RIGHTS_DIR_ALL = SEC_RIGHTS_FILE_ALL;
-
-
- /***************************************************************/
- /* WELL KNOWN SIDS */
-
- /* a NULL sid */
- const string SID_NULL = "S-1-0-0";
-
- /* the world domain */
- const string NAME_WORLD = "WORLD";
-
- const string SID_WORLD_DOMAIN = "S-1-1";
- const string SID_WORLD = "S-1-1-0";
-
- /* SECURITY_CREATOR_SID_AUTHORITY */
- const string SID_CREATOR_OWNER_DOMAIN = "S-1-3";
- const string SID_CREATOR_OWNER = "S-1-3-0";
- const string SID_CREATOR_GROUP = "S-1-3-1";
- const string SID_OWNER_RIGHTS = "S-1-3-4";
-
- /* SECURITY_NT_AUTHORITY */
- const string NAME_NT_AUTHORITY = "NT AUTHORITY";
-
- const string SID_NT_AUTHORITY = "S-1-5";
- const string SID_NT_DIALUP = "S-1-5-1";
- const string SID_NT_NETWORK = "S-1-5-2";
- const string SID_NT_BATCH = "S-1-5-3";
- const string SID_NT_INTERACTIVE = "S-1-5-4";
- const string SID_NT_SERVICE = "S-1-5-6";
- const string SID_NT_ANONYMOUS = "S-1-5-7";
- const string SID_NT_PROXY = "S-1-5-8";
- const string SID_NT_ENTERPRISE_DCS = "S-1-5-9";
- const string SID_NT_SELF = "S-1-5-10";
- const string SID_NT_AUTHENTICATED_USERS = "S-1-5-11";
- const string SID_NT_RESTRICTED = "S-1-5-12";
- const string SID_NT_TERMINAL_SERVER_USERS = "S-1-5-13";
- const string SID_NT_REMOTE_INTERACTIVE = "S-1-5-14";
- const string SID_NT_THIS_ORGANISATION = "S-1-5-15";
- const string SID_NT_IUSR = "S-1-5-17";
- const string SID_NT_SYSTEM = "S-1-5-18";
- const string SID_NT_LOCAL_SERVICE = "S-1-5-19";
- const string SID_NT_NETWORK_SERVICE = "S-1-5-20";
- const string SID_NT_DIGEST_AUTHENTICATION = "S-1-5-64-21";
- const string SID_NT_NTLM_AUTHENTICATION = "S-1-5-64-10";
- const string SID_NT_SCHANNEL_AUTHENTICATION = "S-1-5-64-14";
- const string SID_NT_OTHER_ORGANISATION = "S-1-5-1000";
-
- /* SECURITY_BUILTIN_DOMAIN_RID */
- const string NAME_BUILTIN = "BUILTIN";
-
- const string SID_BUILTIN = "S-1-5-32";
- const string SID_BUILTIN_ADMINISTRATORS = "S-1-5-32-544";
- const string SID_BUILTIN_USERS = "S-1-5-32-545";
- const string SID_BUILTIN_GUESTS = "S-1-5-32-546";
- const string SID_BUILTIN_POWER_USERS = "S-1-5-32-547";
- const string SID_BUILTIN_ACCOUNT_OPERATORS = "S-1-5-32-548";
- const string SID_BUILTIN_SERVER_OPERATORS = "S-1-5-32-549";
- const string SID_BUILTIN_PRINT_OPERATORS = "S-1-5-32-550";
- const string SID_BUILTIN_BACKUP_OPERATORS = "S-1-5-32-551";
- const string SID_BUILTIN_REPLICATOR = "S-1-5-32-552";
- const string SID_BUILTIN_RAS_SERVERS = "S-1-5-32-553";
- const string SID_BUILTIN_PREW2K = "S-1-5-32-554";
-
- /* well-known domain RIDs */
- const int DOMAIN_RID_LOGON = 9;
- const int DOMAIN_RID_ADMINISTRATOR = 500;
- const int DOMAIN_RID_GUEST = 501;
- const int DOMAIN_RID_ADMINS = 512;
- const int DOMAIN_RID_USERS = 513;
- const int DOMAIN_RID_DOMAIN_MEMBERS = 515;
- const int DOMAIN_RID_DCS = 516;
- const int DOMAIN_RID_CERT_ADMINS = 517;
- const int DOMAIN_RID_SCHEMA_ADMINS = 518;
- const int DOMAIN_RID_ENTERPRISE_ADMINS = 519;
-
-
- /*
- privilege IDs. Please keep the IDs below 64. If we get more
- than 64 then we need to change security_token
- */
- typedef enum {
- SEC_PRIV_SECURITY = 1,
- SEC_PRIV_BACKUP = 2,
- SEC_PRIV_RESTORE = 3,
- SEC_PRIV_SYSTEMTIME = 4,
- SEC_PRIV_SHUTDOWN = 5,
- SEC_PRIV_REMOTE_SHUTDOWN = 6,
- SEC_PRIV_TAKE_OWNERSHIP = 7,
- SEC_PRIV_DEBUG = 8,
- SEC_PRIV_SYSTEM_ENVIRONMENT = 9,
- SEC_PRIV_SYSTEM_PROFILE = 10,
- SEC_PRIV_PROFILE_SINGLE_PROCESS = 11,
- SEC_PRIV_INCREASE_BASE_PRIORITY = 12,
- SEC_PRIV_LOAD_DRIVER = 13,
- SEC_PRIV_CREATE_PAGEFILE = 14,
- SEC_PRIV_INCREASE_QUOTA = 15,
- SEC_PRIV_CHANGE_NOTIFY = 16,
- SEC_PRIV_UNDOCK = 17,
- SEC_PRIV_MANAGE_VOLUME = 18,
- SEC_PRIV_IMPERSONATE = 19,
- SEC_PRIV_CREATE_GLOBAL = 20,
- SEC_PRIV_ENABLE_DELEGATION = 21,
- SEC_PRIV_INTERACTIVE_LOGON = 22,
- SEC_PRIV_NETWORK_LOGON = 23,
- SEC_PRIV_REMOTE_INTERACTIVE_LOGON = 24
- } sec_privilege;
-
-
- /* a domain SID. Note that unlike Samba3 this contains a pointer,
- so you can't copy them using assignment */
- typedef [public,gensize,noprint,noejs,nosize] struct {
- uint8 sid_rev_num; /**< SID revision number */
- [range(0,15)] int8 num_auths; /**< Number of sub-authorities */
- uint8 id_auth[6]; /**< Identifier Authority */
- uint32 sub_auths[num_auths];
- } dom_sid;
-
- /* id used to identify a endpoint, possibly in a cluster */
- typedef [public] struct {
- hyper id;
- uint32 id2;
- uint32 node;
- } server_id;
-
- typedef [bitmap8bit] bitmap {
- SEC_ACE_FLAG_OBJECT_INHERIT = 0x01,
- SEC_ACE_FLAG_CONTAINER_INHERIT = 0x02,
- SEC_ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04,
- SEC_ACE_FLAG_INHERIT_ONLY = 0x08,
- SEC_ACE_FLAG_INHERITED_ACE = 0x10,
- SEC_ACE_FLAG_VALID_INHERIT = 0x0f,
- SEC_ACE_FLAG_SUCCESSFUL_ACCESS = 0x40,
- SEC_ACE_FLAG_FAILED_ACCESS = 0x80
- } security_ace_flags;
-
- typedef [enum8bit] enum {
- SEC_ACE_TYPE_ACCESS_ALLOWED = 0,
- SEC_ACE_TYPE_ACCESS_DENIED = 1,
- SEC_ACE_TYPE_SYSTEM_AUDIT = 2,
- SEC_ACE_TYPE_SYSTEM_ALARM = 3,
- SEC_ACE_TYPE_ALLOWED_COMPOUND = 4,
- SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT = 5,
- SEC_ACE_TYPE_ACCESS_DENIED_OBJECT = 6,
- SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT = 7,
- SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT = 8
- } security_ace_type;
-
- typedef [bitmap32bit] bitmap {
- SEC_ACE_OBJECT_TYPE_PRESENT = 0x00000001,
- SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x00000002
- } security_ace_object_flags;
-
- typedef [nodiscriminant] union {
- /* this is the 'schemaIDGUID' attribute of the attribute object in the schema naming context */
- [case(SEC_ACE_OBJECT_TYPE_PRESENT)] GUID type;
- [default];
- } security_ace_object_type;
-
- typedef [nodiscriminant] union {
- /* this is the 'schemaIDGUID' attribute of the objectclass object in the schema naming context
- * (of the parent container)
- */
- [case(SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] GUID inherited_type;
- [default];
- } security_ace_object_inherited_type;
-
- typedef struct {
- security_ace_object_flags flags;
- [switch_is(flags & SEC_ACE_OBJECT_TYPE_PRESENT)] security_ace_object_type type;
- [switch_is(flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] security_ace_object_inherited_type inherited_type;
- } security_ace_object;
-
- typedef [nodiscriminant] union {
- [case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] security_ace_object object;
- [case(SEC_ACE_TYPE_ACCESS_DENIED_OBJECT)] security_ace_object object;
- [case(SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT)] security_ace_object object;
- [case(SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT)] security_ace_object object;
- [default];
- } security_ace_object_ctr;
-
- typedef [public,gensize,nosize] struct {
- security_ace_type type; /* SEC_ACE_TYPE_* */
- security_ace_flags flags; /* SEC_ACE_FLAG_* */
- [value(ndr_size_security_ace(r,ndr->flags))] uint16 size;
- uint32 access_mask;
- [switch_is(type)] security_ace_object_ctr object;
- dom_sid trustee;
- } security_ace;
-
- typedef enum {
- SECURITY_ACL_REVISION_NT4 = 2,
- SECURITY_ACL_REVISION_ADS = 4
- } security_acl_revision;
-
- const uint NT4_ACL_REVISION = SECURITY_ACL_REVISION_NT4;
-
- typedef [public,gensize,nosize] struct {
- security_acl_revision revision;
- [value(ndr_size_security_acl(r,ndr->flags))] uint16 size;
- [range(0,1000)] uint32 num_aces;
- security_ace aces[num_aces];
- } security_acl;
-
- /* default revision for new ACLs */
- typedef [enum8bit] enum {
- SECURITY_DESCRIPTOR_REVISION_1 = 1
- } security_descriptor_revision;
-
- const int SD_REVISION = SECURITY_DESCRIPTOR_REVISION_1;
-
- /* security_descriptor->type bits */
- typedef [bitmap16bit] bitmap {
- SEC_DESC_OWNER_DEFAULTED = 0x0001,
- SEC_DESC_GROUP_DEFAULTED = 0x0002,
- SEC_DESC_DACL_PRESENT = 0x0004,
- SEC_DESC_DACL_DEFAULTED = 0x0008,
- SEC_DESC_SACL_PRESENT = 0x0010,
- SEC_DESC_SACL_DEFAULTED = 0x0020,
- SEC_DESC_DACL_TRUSTED = 0x0040,
- SEC_DESC_SERVER_SECURITY = 0x0080,
- SEC_DESC_DACL_AUTO_INHERIT_REQ = 0x0100,
- SEC_DESC_SACL_AUTO_INHERIT_REQ = 0x0200,
- SEC_DESC_DACL_AUTO_INHERITED = 0x0400,
- SEC_DESC_SACL_AUTO_INHERITED = 0x0800,
- SEC_DESC_DACL_PROTECTED = 0x1000,
- SEC_DESC_SACL_PROTECTED = 0x2000,
- SEC_DESC_RM_CONTROL_VALID = 0x4000,
- SEC_DESC_SELF_RELATIVE = 0x8000
- } security_descriptor_type;
-
- typedef [gensize,nosize,public,flag(NDR_LITTLE_ENDIAN)] struct {
- security_descriptor_revision revision;
- security_descriptor_type type; /* SEC_DESC_xxxx flags */
- [relative] dom_sid *owner_sid;
- [relative] dom_sid *group_sid;
- [relative] security_acl *sacl; /* system ACL */
- [relative] security_acl *dacl; /* user (discretionary) ACL */
- } security_descriptor;
-
- typedef [public] struct {
- [range(0,0x40000),value(ndr_size_security_descriptor(sd,ndr->flags))] uint32 sd_size;
- [subcontext(4)] security_descriptor *sd;
- } sec_desc_buf;
-
- typedef [public] struct {
- dom_sid *user_sid;
- dom_sid *group_sid;
- uint32 num_sids;
- [size_is(num_sids)] dom_sid *sids[*];
- udlong privilege_mask;
- } security_token;
-
- /* bits that determine which parts of a security descriptor
- are being queried/set */
- typedef [public,bitmap32bit] bitmap {
- SECINFO_OWNER = 0x00000001,
- SECINFO_GROUP = 0x00000002,
- SECINFO_DACL = 0x00000004,
- SECINFO_SACL = 0x00000008,
- SECINFO_UNPROTECTED_SACL = 0x10000000,
- SECINFO_UNPROTECTED_DACL = 0x20000000,
- SECINFO_PROTECTED_SACL = 0x40000000,
- SECINFO_PROTECTED_DACL = 0x80000000
- } security_secinfo;
-
- typedef [public,bitmap32bit] bitmap {
- KERB_ENCTYPE_DES_CBC_CRC = 0x00000001,
- KERB_ENCTYPE_DES_CBC_MD5 = 0x00000002,
- KERB_ENCTYPE_RC4_HMAC_MD5 = 0x00000004,
- KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 = 0x00000008,
- KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010
- } kerb_EncTypes;
-}
diff --git a/source4/librpc/ndr/ndr_sec_helper.c b/source4/librpc/ndr/ndr_dom_sid.c
index 1256d7dd2d..b986231b4f 100644
--- a/source4/librpc/ndr/ndr_sec_helper.c
+++ b/source4/librpc/ndr/ndr_dom_sid.c
@@ -4,6 +4,7 @@
fast routines for getting the wire size of security objects
Copyright (C) Andrew Tridgell 2003
+ Copyright (C) Stefan Metzmacher 2006-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
@@ -54,68 +55,6 @@ size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags)
}
/*
- return the wire size of a security_ace
-*/
-size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
-{
- size_t ret;
-
- if (!ace) return 0;
-
- ret = 8 + ndr_size_dom_sid(&ace->trustee, flags);
-
- switch (ace->type) {
- case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
- case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
- case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
- case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT:
- ret += 4; /* uint32 bitmap ace->object.object.flags */
- if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
- ret += 16; /* GUID ace->object.object.type.type */
- }
- if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
- ret += 16; /* GUID ace->object.object.inherited_typeinherited_type */
- }
- break;
- default:
- break;
- }
-
- return ret;
-}
-
-/*
- return the wire size of a security_acl
-*/
-size_t ndr_size_security_acl(const struct security_acl *acl, int flags)
-{
- size_t ret;
- int i;
- if (!acl) return 0;
- ret = 8;
- for (i=0;i<acl->num_aces;i++) {
- ret += ndr_size_security_ace(&acl->aces[i], flags);
- }
- return ret;
-}
-
-/*
- return the wire size of a security descriptor
-*/
-size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags)
-{
- size_t ret;
- if (!sd) return 0;
-
- ret = 20;
- ret += ndr_size_dom_sid(sd->owner_sid, flags);
- ret += ndr_size_dom_sid(sd->group_sid, flags);
- ret += ndr_size_security_acl(sd->dacl, flags);
- ret += ndr_size_security_acl(sd->sacl, flags);
- return ret;
-}
-
-/*
print a dom_sid
*/
void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
diff --git a/source4/main.mk b/source4/main.mk
index 278c38454d..0a72487f8a 100644
--- a/source4/main.mk
+++ b/source4/main.mk
@@ -23,7 +23,7 @@ mkinclude ../lib/util/config.mk
mkinclude lib/tdr/config.mk
mkinclude lib/dbwrap/config.mk
mkinclude ../lib/crypto/config.mk
-mkinclude lib/torture/config.mk
+mkinclude ../lib/torture/config.mk
mkinclude lib/basic.mk
mkinclude lib/com/config.mk
# WMI fails at the moment
diff --git a/source4/ntvfs/posix/pvfs_resolve.c b/source4/ntvfs/posix/pvfs_resolve.c
index 1e13474b9e..f08de72a38 100644
--- a/source4/ntvfs/posix/pvfs_resolve.c
+++ b/source4/ntvfs/posix/pvfs_resolve.c
@@ -186,23 +186,49 @@ static NTSTATUS pvfs_case_search(struct pvfs_state *pvfs,
/*
parse a alternate data stream name
*/
-static NTSTATUS parse_stream_name(struct pvfs_filename *name, const char *s)
+static NTSTATUS parse_stream_name(struct smb_iconv_convenience *ic,
+ struct pvfs_filename *name,
+ const char *s)
{
char *p;
+ if (s[1] == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
name->stream_name = talloc_strdup(name, s+1);
if (name->stream_name == NULL) {
return NT_STATUS_NO_MEMORY;
}
- p = strchr_m(name->stream_name, ':');
- if (p == NULL) {
- name->stream_id = pvfs_name_hash(name->stream_name,
- strlen(name->stream_name));
- return NT_STATUS_OK;
- }
- if (strcasecmp_m(p, ":$DATA") != 0) {
- return NT_STATUS_OBJECT_NAME_INVALID;
+
+ p = name->stream_name;
+
+ while (*p) {
+ size_t c_size;
+ codepoint_t c = next_codepoint_convenience(ic, p, &c_size);
+
+ switch (c) {
+ case '/':
+ case '\\':
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ case ':':
+ *p= 0;
+ p++;
+ if (*p == '\0') {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ if (strcasecmp_m(p, "$DATA") != 0) {
+ if (strchr_m(p, ':')) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ c_size = 0;
+ p--;
+ break;
+ }
+
+ p += c_size;
}
- *p = 0;
+
if (strcmp(name->stream_name, "") == 0) {
/*
* we don't set stream_name to NULL, here
@@ -233,6 +259,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
uint_t flags, struct pvfs_filename *name)
{
char *ret, *p, *p_start;
+ struct smb_iconv_convenience *ic = NULL;
NTSTATUS status;
name->original_name = talloc_strdup(name, cifs_name);
@@ -263,15 +290,21 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
for legal characters */
p_start = p;
+ ic = lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx);
while (*p) {
size_t c_size;
- codepoint_t c = next_codepoint_convenience(lp_iconv_convenience(pvfs->ntvfs->ctx->lp_ctx), p, &c_size);
+ codepoint_t c = next_codepoint_convenience(ic, p, &c_size);
+
+ if (c <= 0x1F) {
+ return NT_STATUS_OBJECT_NAME_INVALID;
+ }
+
switch (c) {
case '\\':
if (name->has_wildcard) {
/* wildcards are only allowed in the last part
of a name */
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
if (p > p_start && (p[1] == '\\' || p[1] == '\0')) {
/* see if it is definately a "\\" or
@@ -288,12 +321,12 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
break;
case ':':
if (!(flags & PVFS_RESOLVE_STREAMS)) {
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
if (name->has_wildcard) {
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
}
- status = parse_stream_name(name, p);
+ status = parse_stream_name(ic, name, p);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -311,7 +344,7 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
break;
case '/':
case '|':
- return NT_STATUS_ILLEGAL_CHARACTER;
+ return NT_STATUS_OBJECT_NAME_INVALID;
case '.':
/* see if it is definately a .. or
. component. If it is then fail here, and
diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c
index 6f3f6799e7..6e888e5259 100644
--- a/source4/rpc_server/dcerpc_server.c
+++ b/source4/rpc_server/dcerpc_server.c
@@ -251,8 +251,8 @@ _PUBLIC_ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
return NT_STATUS_OK;
}
-static NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
- DATA_BLOB *session_key)
+NTSTATUS dcesrv_inherited_session_key(struct dcesrv_connection *p,
+ DATA_BLOB *session_key)
{
if (p->auth_state.session_info->session_key.length) {
*session_key = p->auth_state.session_info->session_key;
diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c
index b3118d772d..e1fb187c52 100644
--- a/source4/rpc_server/samr/dcesrv_samr.c
+++ b/source4/rpc_server/samr/dcesrv_samr.c
@@ -37,26 +37,28 @@
#include "../lib/util/util_ldb.h"
#include "param/param.h"
-/* these query macros make samr_Query[User|Group]Info a bit easier to read */
+/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
#define QUERY_STRING(msg, field, attr) \
- r->out.info->field.string = samdb_result_string(msg, attr, "");
+ info->field.string = samdb_result_string(msg, attr, "");
#define QUERY_UINT(msg, field, attr) \
- r->out.info->field = samdb_result_uint(msg, attr, 0);
+ info->field = samdb_result_uint(msg, attr, 0);
#define QUERY_RID(msg, field, attr) \
- r->out.info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
+ info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0);
#define QUERY_UINT64(msg, field, attr) \
- r->out.info->field = samdb_result_uint64(msg, attr, 0);
+ info->field = samdb_result_uint64(msg, attr, 0);
#define QUERY_APASSC(msg, field, attr) \
- r->out.info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg, attr);
+ info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg, attr);
#define QUERY_FPASSC(msg, field, attr) \
- r->out.info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
- a_state->domain_state->domain_dn, msg);
+ info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
+ a_state->domain_state->domain_dn, msg);
#define QUERY_LHOURS(msg, field, attr) \
- r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
+ info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
#define QUERY_AFLAGS(msg, field, attr) \
- r->out.info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+ info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn);
+#define QUERY_PARAMETERS(msg, field, attr) \
+ info->field = samdb_result_parameters(mem_ctx, msg, attr);
/* these are used to make the Set[User|Group]Info code easier to follow */
@@ -136,6 +138,16 @@
set_el->flags = LDB_FLAG_MOD_REPLACE; \
} while (0)
+#define SET_PARAMETERS(msg, field, attr) do { \
+ struct ldb_message_element *set_el; \
+ if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \
+ return NT_STATUS_NO_MEMORY; \
+ } \
+ set_el = ldb_msg_find_element(msg, attr); \
+ set_el->flags = LDB_FLAG_MOD_REPLACE; \
+} while (0)
+
+
/*
samr_Connect
@@ -217,7 +229,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
struct dcesrv_handle *h;
struct sec_desc_buf *sd;
- r->out.sdbuf = NULL;
+ *r->out.sdbuf = NULL;
DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
@@ -228,7 +240,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA
sd->sd = samdb_default_security_descriptor(mem_ctx);
- r->out.sdbuf = sd;
+ *r->out.sdbuf = sd;
return NT_STATUS_OK;
}
@@ -265,7 +277,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
int ret;
struct ldb_dn *partitions_basedn;
- r->out.sid = NULL;
+ *r->out.sid = NULL;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
@@ -307,7 +319,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_NO_SUCH_DOMAIN;
}
- r->out.sid = sid;
+ *r->out.sid = sid;
return NT_STATUS_OK;
}
@@ -332,8 +344,8 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
struct ldb_dn *partitions_basedn;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
@@ -389,9 +401,9 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL
}
}
- r->out.sam = array;
- r->out.num_entries = i;
- array->count = r->out.num_entries;
+ *r->out.sam = array;
+ *r->out.num_entries = i;
+ array->count = *r->out.num_entries;
return NT_STATUS_OK;
}
@@ -692,7 +704,7 @@ static NTSTATUS dcesrv_samr_info_DomInfo9(struct samr_domain_state *state,
struct ldb_message **dom_msgs,
struct samr_DomInfo9 *info)
{
- info->unknown = 1;
+ info->domain_server_state = DOMAIN_SERVER_ENABLED;
return NT_STATUS_OK;
}
@@ -765,18 +777,19 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
{
struct dcesrv_handle *h;
struct samr_domain_state *d_state;
+ union samr_DomainInfo *info;
struct ldb_message **dom_msgs;
const char * const *attrs = NULL;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
d_state = h->data;
- r->out.info = talloc(mem_ctx, union samr_DomainInfo);
- if (!r->out.info) {
+ info = talloc(mem_ctx, union samr_DomainInfo);
+ if (!info) {
return NT_STATUS_NO_MEMORY;
}
@@ -881,47 +894,49 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call,
}
}
- ZERO_STRUCTP(r->out.info);
+ *r->out.info = info;
+
+ ZERO_STRUCTP(info);
switch (r->in.level) {
case 1:
return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs,
- &r->out.info->info1);
+ &info->info1);
case 2:
return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs,
- &r->out.info->general);
+ &info->general);
case 3:
return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs,
- &r->out.info->info3);
+ &info->info3);
case 4:
return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs,
- &r->out.info->oem);
+ &info->oem);
case 5:
return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs,
- &r->out.info->info5);
+ &info->info5);
case 6:
return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs,
- &r->out.info->info6);
+ &info->info6);
case 7:
return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs,
- &r->out.info->info7);
+ &info->info7);
case 8:
return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs,
- &r->out.info->info8);
+ &info->info8);
case 9:
return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs,
- &r->out.info->info9);
+ &info->info9);
case 11:
return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs,
- &r->out.info->general2);
+ &info->general2);
case 12:
return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs,
- &r->out.info->info12);
+ &info->info12);
case 13:
return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs,
- &r->out.info->info13);
+ &info->info13);
}
-
+
return NT_STATUS_INVALID_INFO_CLASS;
}
@@ -1135,10 +1150,11 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1189,20 +1205,22 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call,
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
- r->out.num_entries = count - first;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ if (*r->out.num_entries < count - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1492,10 +1510,11 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
int ret, num_filtered_entries, i, first;
struct samr_SamEntry *entries;
const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1539,24 +1558,26 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call,
/* return the rest, limit by max_size. Note that we
use the w2k3 element size value of 54 */
- r->out.num_entries = num_filtered_entries - first;
- r->out.num_entries = MIN(r->out.num_entries,
+ *r->out.num_entries = num_filtered_entries - first;
+ *r->out.num_entries = MIN(*r->out.num_entries,
1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER));
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
if (first == num_filtered_entries) {
return NT_STATUS_OK;
}
- if (r->out.num_entries < num_filtered_entries - first) {
- *r->out.resume_handle = entries[first+r->out.num_entries-1].idx;
+ if (*r->out.num_entries < num_filtered_entries - first) {
+ *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1685,10 +1706,11 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
int ldb_cnt, count, i, first;
struct samr_SamEntry *entries;
const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL };
+ struct samr_SamArray *sam;
*r->out.resume_handle = 0;
- r->out.sam = NULL;
- r->out.num_entries = 0;
+ *r->out.sam = NULL;
+ *r->out.num_entries = 0;
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1748,20 +1770,22 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call
return NT_STATUS_OK;
}
- r->out.num_entries = count - first;
- r->out.num_entries = MIN(r->out.num_entries, 1000);
+ *r->out.num_entries = count - first;
+ *r->out.num_entries = MIN(*r->out.num_entries, 1000);
- r->out.sam = talloc(mem_ctx, struct samr_SamArray);
- if (!r->out.sam) {
+ sam = talloc(mem_ctx, struct samr_SamArray);
+ if (!sam) {
return NT_STATUS_NO_MEMORY;
}
- r->out.sam->entries = entries+first;
- r->out.sam->count = r->out.num_entries;
+ sam->entries = entries+first;
+ sam->count = *r->out.num_entries;
+
+ *r->out.sam = sam;
- if (r->out.num_entries < count - first) {
+ if (*r->out.num_entries < count - first) {
*r->out.resume_handle =
- entries[first+r->out.num_entries-1].idx;
+ entries[first+*r->out.num_entries-1].idx;
return STATUS_MORE_ENTRIES;
}
@@ -1859,8 +1883,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
const char * const attrs[] = { "sAMAccountType", "objectSid", NULL };
int count;
- ZERO_STRUCT(r->out.rids);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.rids);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -1870,13 +1894,13 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
return NT_STATUS_OK;
}
- r->out.rids.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- r->out.types.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
- if (!r->out.rids.ids || !r->out.types.ids) {
+ r->out.rids->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ r->out.types->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names);
+ if (!r->out.rids->ids || !r->out.types->ids) {
return NT_STATUS_NO_MEMORY;
}
- r->out.rids.count = r->in.num_names;
- r->out.types.count = r->in.num_names;
+ r->out.rids->count = r->in.num_names;
+ r->out.types->count = r->in.num_names;
num_mapped = 0;
@@ -1885,8 +1909,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
struct dom_sid *sid;
uint32_t atype, rtype;
- r->out.rids.ids[i] = 0;
- r->out.types.ids[i] = SID_NAME_UNKNOWN;
+ r->out.rids->ids[i] = 0;
+ r->out.types->ids[i] = SID_NAME_UNKNOWN;
count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs,
"sAMAccountName=%s",
@@ -1915,8 +1939,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL
continue;
}
- r->out.rids.ids[i] = sid->sub_auths[sid->num_auths-1];
- r->out.types.ids[i] = rtype;
+ r->out.rids->ids[i] = sid->sub_auths[sid->num_auths-1];
+ r->out.types->ids[i] = rtype;
num_mapped++;
}
@@ -1940,8 +1964,8 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
struct lsa_String *names;
uint32_t *ids;
- ZERO_STRUCT(r->out.names);
- ZERO_STRUCT(r->out.types);
+ ZERO_STRUCTP(r->out.names);
+ ZERO_STRUCTP(r->out.types);
DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN);
@@ -2002,11 +2026,11 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO
}
}
- r->out.names.names = names;
- r->out.names.count = r->in.num_rids;
+ r->out.names->names = names;
+ r->out.names->count = r->in.num_rids;
- r->out.types.ids = ids;
- r->out.types.count = r->in.num_rids;
+ r->out.types->ids = ids;
+ r->out.types->count = r->in.num_rids;
return status;
}
@@ -2103,8 +2127,9 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
+ union samr_GroupInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP);
@@ -2127,17 +2152,16 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
msg = res->msgs[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_GroupInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_GroupInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* Fill in the level */
switch (r->in.level) {
case GROUPINFOALL:
QUERY_STRING(msg, all.name, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all.num_members, "numMembers")
QUERY_STRING(msg, all.description, "description");
break;
@@ -2145,22 +2169,24 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T
QUERY_STRING(msg, name, "sAMAccountName");
break;
case GROUPINFOATTRIBUTES:
- r->out.info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
break;
case GROUPINFODESCRIPTION:
QUERY_STRING(msg, description, "description");
break;
case GROUPINFOALL2:
QUERY_STRING(msg, all2.name, "sAMAccountName");
- r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
+ info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */
QUERY_UINT (msg, all2.num_members, "numMembers")
QUERY_STRING(msg, all2.description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -2467,7 +2493,7 @@ static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call,
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
@@ -2574,8 +2600,9 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
const char * const attrs[4] = { "sAMAccountName", "description",
"numMembers", NULL };
int ret;
+ union samr_AliasInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS);
@@ -2590,11 +2617,10 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_AliasInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_AliasInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
switch(r->in.level) {
case ALIASINFOALL:
@@ -2609,10 +2635,12 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T
QUERY_STRING(msg, description, "description");
break;
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -2989,8 +3017,9 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
struct ldb_context *sam_ctx;
const char * const *attrs = NULL;
+ union samr_UserInfo *info;
- r->out.info = NULL;
+ *r->out.info = NULL;
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
@@ -3175,11 +3204,10 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
msg = res[0];
/* allocate the info structure */
- r->out.info = talloc(mem_ctx, union samr_UserInfo);
- if (r->out.info == NULL) {
+ info = talloc_zero(mem_ctx, union samr_UserInfo);
+ if (info == NULL) {
return NT_STATUS_NO_MEMORY;
}
- ZERO_STRUCTP(r->out.info);
/* fill in the reply */
switch (r->in.level) {
@@ -3290,7 +3318,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
break;
case 20:
- QUERY_STRING(msg, info20.parameters, "userParameters");
+ QUERY_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
@@ -3309,11 +3337,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
QUERY_STRING(msg, info21.description, "description");
QUERY_STRING(msg, info21.workstations, "userWorkstations");
QUERY_STRING(msg, info21.comment, "comment");
- QUERY_STRING(msg, info21.parameters, "userParameters");
+ QUERY_PARAMETERS(msg, info21.parameters, "userParameters");
QUERY_RID (msg, info21.rid, "objectSid");
QUERY_UINT (msg, info21.primary_gid, "primaryGroupID");
QUERY_AFLAGS(msg, info21.acct_flags, "userAccountControl");
- r->out.info->info21.fields_present = 0x00FFFFFF;
+ info->info21.fields_present = 0x00FFFFFF;
QUERY_LHOURS(msg, info21.logon_hours, "logonHours");
QUERY_UINT (msg, info21.bad_password_count, "badPwdCount");
QUERY_UINT (msg, info21.logon_count, "logonCount");
@@ -3323,10 +3351,12 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
default:
- r->out.info = NULL;
+ talloc_free(info);
return NT_STATUS_INVALID_INFO_CLASS;
}
-
+
+ *r->out.info = info;
+
return NT_STATUS_OK;
}
@@ -3416,7 +3446,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
break;
case 20:
- SET_STRING(msg, info20.parameters, "userParameters");
+ SET_PARAMETERS(msg, info20.parameters, "userParameters");
break;
case 21:
@@ -3446,7 +3476,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info21.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info21.parameters, "userParameters");
+ SET_PARAMETERS(msg, info21.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info21.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3477,7 +3507,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info23.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info23.info.parameters, "userParameters");
+ SET_PARAMETERS(msg, info23.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info23.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3533,7 +3563,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL
IFSET(SAMR_FIELD_ACCT_FLAGS)
SET_AFLAGS(msg, info25.info.acct_flags, "userAccountControl");
IFSET(SAMR_FIELD_PARAMETERS)
- SET_STRING(msg, info25.info.parameters, "userParameters");
+ SET_PARAMETERS(msg, info25.info.parameters, "userParameters");
IFSET(SAMR_FIELD_COUNTRY_CODE)
SET_UINT (msg, info25.info.country_code, "countryCode");
IFSET(SAMR_FIELD_CODE_PAGE)
@@ -3650,7 +3680,7 @@ static NTSTATUS dcesrv_samr_GetGroupsForUser(struct dcesrv_call_state *dce_call,
}
}
- r->out.rids = array;
+ *r->out.rids = array;
return NT_STATUS_OK;
}
@@ -3808,65 +3838,65 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call,
count += 1;
}
- r->out.total_size = count;
+ *r->out.total_size = count;
if (r->in.start_idx >= count) {
- r->out.returned_size = 0;
+ *r->out.returned_size = 0;
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries = NULL;
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries = NULL;
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries = NULL;
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries = NULL;
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries = NULL;
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries = NULL;
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries = NULL;
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries = NULL;
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries = NULL;
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries = NULL;
break;
}
} else {
- r->out.returned_size = MIN(count - r->in.start_idx,
+ *r->out.returned_size = MIN(count - r->in.start_idx,
r->in.max_entries);
switch(r->in.level) {
case 1:
- r->out.info.info1.count = r->out.returned_size;
- r->out.info.info1.entries =
+ r->out.info->info1.count = *r->out.returned_size;
+ r->out.info->info1.entries =
&(entriesGeneral[r->in.start_idx]);
break;
case 2:
- r->out.info.info2.count = r->out.returned_size;
- r->out.info.info2.entries =
+ r->out.info->info2.count = *r->out.returned_size;
+ r->out.info->info2.entries =
&(entriesFull[r->in.start_idx]);
break;
case 3:
- r->out.info.info3.count = r->out.returned_size;
- r->out.info.info3.entries =
+ r->out.info->info3.count = *r->out.returned_size;
+ r->out.info->info3.entries =
&(entriesFullGroup[r->in.start_idx]);
break;
case 4:
- r->out.info.info4.count = r->out.returned_size;
- r->out.info.info4.entries =
+ r->out.info->info4.count = *r->out.returned_size;
+ r->out.info->info4.entries =
&(entriesAscii[r->in.start_idx]);
break;
case 5:
- r->out.info.info5.count = r->out.returned_size;
- r->out.info.info5.entries =
+ r->out.info->info5.count = *r->out.returned_size;
+ r->out.info->info5.entries =
&(entriesAscii[r->in.start_idx]);
break;
}
}
- return (r->out.returned_size < (count - r->in.start_idx)) ?
+ return (*r->out.returned_size < (count - r->in.start_idx)) ?
STATUS_MORE_ENTRIES : NT_STATUS_OK;
}
@@ -3910,18 +3940,18 @@ static NTSTATUS dcesrv_samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TA
struct dcesrv_handle *h;
struct samr_account_state *a_state;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
a_state = h->data;
- r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->domain_state->domain_dn, "minPwdLength",
- NULL);
- r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
- a_state->account_dn,
- "pwdProperties", NULL);
+ r->out.info->min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->domain_state->domain_dn, "minPwdLength",
+ NULL);
+ r->out.info->password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0,
+ a_state->account_dn,
+ "pwdProperties", NULL);
return NT_STATUS_OK;
}
@@ -4008,11 +4038,10 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo2(struct dcesrv_call_state *dce_call,
ZERO_STRUCT(r1.out);
r1.in.domain_handle = r->in.domain_handle;
r1.in.level = r->in.level;
-
+ r1.out.info = r->out.info;
+
status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1);
- r->out.info = r1.out.info;
-
return status;
}
@@ -4028,13 +4057,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, T
struct samr_QueryUserInfo r1;
NTSTATUS status;
- ZERO_STRUCT(r1.out);
r1.in.user_handle = r->in.user_handle;
r1.in.level = r->in.level;
+ r1.out.info = r->out.info;
status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1);
-
- r->out.info = r1.out.info;
return status;
}
@@ -4054,14 +4081,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
@@ -4090,14 +4115,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call
q.in.start_idx = r->in.start_idx;
q.in.max_entries = r->in.max_entries;
q.in.buf_size = r->in.buf_size;
- ZERO_STRUCT(q.out);
+ q.out.total_size = r->out.total_size;
+ q.out.returned_size = r->out.returned_size;
+ q.out.info = r->out.info;
result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q);
- r->out.total_size = q.out.total_size;
- r->out.returned_size = q.out.returned_size;
- r->out.info = q.out.info;
-
return result;
}
@@ -4138,7 +4161,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL };
struct ldb_context *sam_ctx;
- ZERO_STRUCT(r->out.info);
+ ZERO_STRUCTP(r->out.info);
sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
if (sam_ctx == NULL) {
@@ -4156,8 +4179,8 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
- r->out.info.min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
- r->out.info.password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
+ r->out.info->min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0);
+ r->out.info->password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1);
talloc_free(msgs);
@@ -4267,9 +4290,9 @@ static NTSTATUS dcesrv_samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_
status = dcesrv_samr_Connect(dce_call, mem_ctx, &c);
- r->out.info->info1.client_version = SAMR_CONNECT_AFTER_W2K;
- r->out.info->info1.unknown2 = 0;
- r->out.level = r->in.level;
+ r->out.info_out->info1.client_version = SAMR_CONNECT_AFTER_W2K;
+ r->out.info_out->info1.unknown2 = 0;
+ *r->out.level_out = r->in.level_in;
return status;
}
@@ -4289,8 +4312,8 @@ static NTSTATUS dcesrv_samr_RidToSid(struct dcesrv_call_state *dce_call, TALLOC_
d_state = h->data;
/* form the users SID */
- r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
- if (!r->out.sid) {
+ *r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid);
+ if (!*r->out.sid) {
return NT_STATUS_NO_MEMORY;
}
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 1eb6a4f37c..ff8215a673 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -352,7 +352,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
uint8_t new_nt_hash[16], new_lm_hash[16];
struct samr_Password nt_verifier, lm_verifier;
- ZERO_STRUCT(r->out);
+ *r->out.dominfo = NULL;
+ *r->out.reject = NULL;
if (r->in.nt_password == NULL ||
r->in.nt_verifier == NULL) {
@@ -495,8 +496,8 @@ failed:
talloc_free(sam_ctx);
reject = talloc(mem_ctx, struct samr_ChangeReject);
- r->out.dominfo = dominfo;
- r->out.reject = reject;
+ *r->out.dominfo = dominfo;
+ *r->out.reject = reject;
if (reject == NULL) {
return status;
@@ -518,6 +519,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
struct samr_ChangePasswordUser2 *r)
{
struct samr_ChangePasswordUser3 r2;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
r2.in.server = r->in.server;
r2.in.account = r->in.account;
@@ -527,6 +530,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL
r2.in.lm_password = r->in.lm_password;
r2.in.lm_verifier = r->in.lm_verifier;
r2.in.password3 = NULL;
+ r2.out.dominfo = &dominfo;
+ r2.out.reject = &reject;
return dcesrv_samr_ChangePasswordUser3(dce_call, mem_ctx, &r2);
}
diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c
index f168614ad5..bb4d6bdaf2 100644
--- a/source4/rpc_server/service_rpc.c
+++ b/source4/rpc_server/service_rpc.c
@@ -27,6 +27,7 @@
#include "auth/gensec/gensec.h"
#include "../lib/util/dlinklist.h"
#include "rpc_server/dcerpc_server.h"
+#include "rpc_server/dcerpc_server_proto.h"
#include "lib/events/events.h"
#include "smbd/service_task.h"
#include "smbd/service_stream.h"
@@ -139,6 +140,10 @@ static void dcesrv_sock_accept(struct stream_connection *srv_conn)
dcesrv_conn->transport.get_my_addr = dcesrv_sock_get_my_addr;
dcesrv_conn->transport.get_peer_addr = dcesrv_sock_get_peer_addr;
+ if (dcesrv_sock->endpoint->ep_description->transport == NCACN_NP) {
+ dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
+ }
+
srv_conn->private = dcesrv_conn;
irpc_add_name(srv_conn->msg_ctx, "rpc_server");
@@ -287,12 +292,10 @@ static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx,
return status;
}
-
-/*
- add a socket address to the list of events, one event per dcerpc endpoint
-*/
-static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e,
- struct event_context *event_ctx, const struct model_ops *model_ops)
+static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
+ struct loadparm_context *lp_ctx,
+ struct dcesrv_endpoint *e,
+ struct event_context *event_ctx, const struct model_ops *model_ops)
{
struct dcesrv_socket_context *dcesrv_sock;
NTSTATUS status;
@@ -309,30 +312,16 @@ static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct
dcesrv_sock->endpoint = e;
dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
- status = NT_STATUS_OK;
-#if 0
-
- status = stream_setup_smb_pipe(event_ctx, model_ops, &dcesrv_stream_ops,
- e->ep_description->endpoint, dcesrv_sock);
+ status = stream_setup_named_pipe(event_ctx, lp_ctx,
+ model_ops, &dcesrv_stream_ops,
+ e->ep_description->endpoint, dcesrv_sock);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
+ DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
e->ep_description->endpoint, nt_errstr(status)));
+ return status;
}
-#endif
- return status;
-}
-
-static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx,
- struct loadparm_context *lp_ctx,
- struct dcesrv_endpoint *e,
- struct event_context *event_ctx, const struct model_ops *model_ops)
-{
- NTSTATUS status;
-
- status = add_socket_rpc_pipe_iface(dce_ctx, e, event_ctx, model_ops);
- NT_STATUS_NOT_OK_RETURN(status);
- return status;
+ return NT_STATUS_OK;
}
/*
diff --git a/source4/selftest/knownfail b/source4/selftest/knownfail
index f99db4fb1b..9649a1f644 100644
--- a/source4/selftest/knownfail
+++ b/source4/selftest/knownfail
@@ -35,6 +35,7 @@ rpc.netlogon.*.DsRAddressToSitenamesW
rpc.netlogon.*.DsRAddressToSitenamesExW
rpc.netlogon.*.GetPassword
rpc.netlogon.*.GetTrustPasswords
+rpc.netlogon.*.DatabaseRedo
base.charset.*.Testing partial surrogate
.*net.api.delshare.* # DelShare isn't implemented yet
rap.*netservergetinfo
diff --git a/source4/selftest/skip b/source4/selftest/skip
index e3e2d2d525..f1500ff315 100644
--- a/source4/selftest/skip
+++ b/source4/selftest/skip
@@ -23,6 +23,7 @@ base.scan.maxfid
raw.hold.oplock # Not a test, but a way to block other clients for a test
raw.ping.pong # Needs second server to test
rpc.samr_accessmask
+samba4.rpc.samr.passwords.pwdlastset # Not provided by Samba 4 yet
raw.scan.eamax
samba4.ntvfs.cifs.raw.qfileinfo.ipc
smb2.notify
@@ -49,6 +50,7 @@ rpc.initshutdown # Not provided by Samba 4
rpc.svcctl # Not provided by Samba 4
rpc.atsvc # Not provided by Samba 4
rpc.frsapi # Not provided by Samba 4
+rpc.ntsvcs # Not provided by Samba 4
^samba4.base.samba3.* # Samba3-specific test
^samba4.ntvfs.cifs.base.samba3.* # Samba3-specific test
^samba4.raw.samba3.* # Samba3-specific test
diff --git a/source4/setup/schema-map-fedora-ds-1.0 b/source4/setup/schema-map-fedora-ds-1.0
index e55ef0a9e7..74d9e2ac5a 100644
--- a/source4/setup/schema-map-fedora-ds-1.0
+++ b/source4/setup/schema-map-fedora-ds-1.0
@@ -23,9 +23,9 @@ aci
1.2.840.113556.1.4.906:1.3.6.1.4.1.1466.115.121.1.27
#This case insensitive string isn't available
1.2.840.113556.1.4.905:1.3.6.1.4.1.1466.115.121.1.15
-#This type of DN isn't in OpenLDAP
-1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.12
#Treat Security Descriptors as binary
1.2.840.113556.1.4.907:1.3.6.1.4.1.1466.115.121.1.40
#NumbericString is not supported in Fedora DS 1.0, map to a directory string
1.3.6.1.4.1.1466.115.121.1.36:1.3.6.1.4.1.1466.115.121.1.15
+#Treat Object(DN-Binary) as a binary blob
+1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.40
diff --git a/source4/setup/schema-map-openldap-2.3 b/source4/setup/schema-map-openldap-2.3
index 7de2e67b5e..bff1695c8f 100644
--- a/source4/setup/schema-map-openldap-2.3
+++ b/source4/setup/schema-map-openldap-2.3
@@ -35,10 +35,10 @@ modifyTimeStamp:samba4ModifyTimestamp
1.2.840.113556.1.4.906:1.3.6.1.4.1.1466.115.121.1.27
#This case insensitive string isn't available
1.2.840.113556.1.4.905:1.3.6.1.4.1.1466.115.121.1.44
-#This type of DN isn't in OpenLDAP
-1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.12
#Treat Security Descriptors as binary
1.2.840.113556.1.4.907:1.3.6.1.4.1.1466.115.121.1.40
#Treat OIDs as case insensitive strings (as otherwise ldap class and
#attribute names, declared at OIDs fail
1.3.6.1.4.1.1466.115.121.1.38:1.3.6.1.4.1.1466.115.121.1.44
+#Treat Object(DN-Binary) as a binary blob
+1.2.840.113556.1.4.903:1.3.6.1.4.1.1466.115.121.1.40
diff --git a/source4/smbd/config.mk b/source4/smbd/config.mk
index b5babd4d69..63105d368c 100644
--- a/source4/smbd/config.mk
+++ b/source4/smbd/config.mk
@@ -2,11 +2,12 @@
[SUBSYSTEM::service]
PRIVATE_DEPENDENCIES = \
- MESSAGING samba-socket
+ MESSAGING samba-socket NDR_NAMED_PIPE_AUTH
service_OBJ_FILES = $(addprefix $(smbdsrcdir)/, \
service.o \
service_stream.o \
+ service_named_pipe.o \
service_task.o)
$(eval $(call proto_header_template,$(smbdsrcdir)/service_proto.h,$(service_OBJ_FILES:.o=.c)))
diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c
new file mode 100644
index 0000000000..b2b102c01f
--- /dev/null
+++ b/source4/smbd/service_named_pipe.c
@@ -0,0 +1,366 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ helper functions for NAMED PIPE servers
+
+ Copyright (C) Stefan (metze) Metzmacher 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 "lib/socket/socket.h"
+#include "smbd/service.h"
+#include "param/param.h"
+#include "auth/session.h"
+#include "lib/stream/packet.h"
+#include "librpc/gen_ndr/ndr_named_pipe_auth.h"
+#include "system/passwd.h"
+
+struct named_pipe_socket {
+ const char *pipe_name;
+ const char *pipe_path;
+ const struct stream_server_ops *ops;
+ void *private_data;
+};
+
+struct named_pipe_connection {
+ struct stream_connection *connection;
+ struct packet_context *packet;
+ const struct named_pipe_socket *pipe_sock;
+ NTSTATUS status;
+};
+
+static void named_pipe_handover_connection(void *private_data)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ private_data, struct named_pipe_connection);
+ struct stream_connection *conn = pipe_conn->connection;
+
+ EVENT_FD_NOT_WRITEABLE(conn->event.fde);
+
+ if (!NT_STATUS_IS_OK(pipe_conn->status)) {
+ stream_terminate_connection(conn, nt_errstr(pipe_conn->status));
+ return;
+ }
+
+ /*
+ * remove the named_pipe layer together with its packet layer
+ */
+ conn->ops = pipe_conn->pipe_sock->ops;
+ conn->private = pipe_conn->pipe_sock->private_data;
+ talloc_free(pipe_conn);
+
+ /* we're now ready to start receiving events on this stream */
+ EVENT_FD_READABLE(conn->event.fde);
+
+ /*
+ * hand over to the real pipe implementation,
+ * now that we have setup the transport session_info
+ */
+ conn->ops->accept_connection(conn);
+
+ DEBUG(10,("named_pipe_handover_connection[%s]: succeeded\n",
+ conn->ops->name));
+}
+
+static NTSTATUS named_pipe_recv_auth_request(void *private_data,
+ DATA_BLOB req_blob)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ private_data, struct named_pipe_connection);
+ struct stream_connection *conn = pipe_conn->connection;
+ enum ndr_err_code ndr_err;
+ struct named_pipe_auth_req req;
+ union netr_Validation val;
+ struct auth_serversupplied_info *server_info;
+ struct named_pipe_auth_rep rep;
+ DATA_BLOB rep_blob;
+ NTSTATUS status;
+
+ /*
+ * make sure nothing happens on the socket untill the
+ * real implemenation takes over
+ */
+ packet_recv_disable(pipe_conn->packet);
+
+ /*
+ * TODO: check it's a root (uid == 0) pipe
+ */
+
+ ZERO_STRUCT(rep);
+ rep.level = 0;
+ rep.status = NT_STATUS_INTERNAL_ERROR;
+
+ DEBUG(10,("named_pipe_auth: req_blob.length[%u]\n",
+ (unsigned int)req_blob.length));
+ dump_data(10, req_blob.data, req_blob.length);
+
+ /* parse the passed credentials */
+ ndr_err = ndr_pull_struct_blob_all(
+ &req_blob,
+ pipe_conn,
+ lp_iconv_convenience(conn->lp_ctx),
+ &req,
+ (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ rep.status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(2, ("Could not unmarshall named_pipe_auth_req: %s\n",
+ nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ if (strcmp(NAMED_PIPE_AUTH_MAGIC, req.magic) != 0) {
+ DEBUG(2, ("named_pipe_auth_req: invalid magic '%s' != %s\n",
+ req.magic, NAMED_PIPE_AUTH_MAGIC));
+ rep.status = NT_STATUS_INVALID_PARAMETER;
+ goto reply;
+ }
+
+ switch (req.level) {
+ case 0:
+ /*
+ * anon connection, we don't create a session info
+ * and leave it NULL
+ */
+ rep.level = 0;
+ rep.status = NT_STATUS_OK;
+ break;
+ case 1:
+ val.sam3 = &req.info.info1;
+
+ rep.level = 1;
+ rep.status = make_server_info_netlogon_validation(pipe_conn,
+ "TODO",
+ 3, &val,
+ &server_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("make_server_info_netlogon_validation returned "
+ "%s\n", nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ /* setup the session_info on the connection */
+ rep.status = auth_generate_session_info(conn,
+ conn->event.ctx,
+ conn->lp_ctx,
+ server_info,
+ &conn->session_info);
+ if (!NT_STATUS_IS_OK(rep.status)) {
+ DEBUG(2, ("auth_generate_session_info failed: %s\n",
+ nt_errstr(rep.status)));
+ goto reply;
+ }
+
+ break;
+ default:
+ DEBUG(2, ("named_pipe_auth_req: unknown level %u\n",
+ req.level));
+ rep.level = 0;
+ rep.status = NT_STATUS_INVALID_LEVEL;
+ goto reply;
+ }
+
+reply:
+ /* create the output */
+ ndr_err = ndr_push_struct_blob(&rep_blob, pipe_conn,
+ lp_iconv_convenience(conn->lp_ctx),
+ &rep,
+ (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ status = ndr_map_error2ntstatus(ndr_err);
+ DEBUG(2, ("Could not marshall named_pipe_auth_rep: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ pipe_conn->status = rep.status;
+
+ DEBUG(10,("named_pipe_auth reply[%u]\n", rep_blob.length));
+ dump_data(10, rep_blob.data, rep_blob.length);
+ status = packet_send_callback(pipe_conn->packet, rep_blob,
+ named_pipe_handover_connection,
+ pipe_conn);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("packet_send_callback returned %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/*
+ called when a pipe socket becomes readable
+*/
+static void named_pipe_recv(struct stream_connection *conn, uint16_t flags)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ conn->private, struct named_pipe_connection);
+
+ DEBUG(10,("named_pipe_recv\n"));
+
+ packet_recv(pipe_conn->packet);
+}
+
+/*
+ called when a pipe socket becomes writable
+*/
+static void named_pipe_send(struct stream_connection *conn, uint16_t flags)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ conn->private, struct named_pipe_connection);
+
+ packet_queue_run(pipe_conn->packet);
+}
+
+/*
+ handle socket recv errors
+*/
+static void named_pipe_recv_error(void *private_data, NTSTATUS status)
+{
+ struct named_pipe_connection *pipe_conn = talloc_get_type(
+ private_data, struct named_pipe_connection);
+
+ stream_terminate_connection(pipe_conn->connection, nt_errstr(status));
+}
+
+static NTSTATUS named_pipe_full_request(void *private, DATA_BLOB blob, size_t *size)
+{
+ if (blob.length < 8) {
+ return STATUS_MORE_ENTRIES;
+ }
+
+ if (memcmp(NAMED_PIPE_AUTH_MAGIC, &blob.data[4], 4) != 0) {
+ DEBUG(0,("named_pipe_full_request: wrong protocol\n"));
+ *size = blob.length;
+ /* the error will be handled in named_pipe_recv_auth_request */
+ return NT_STATUS_OK;
+ }
+
+ *size = 4 + RIVAL(blob.data, 0);
+ if (*size > blob.length) {
+ return STATUS_MORE_ENTRIES;
+ }
+
+ return NT_STATUS_OK;
+}
+
+static void named_pipe_accept(struct stream_connection *conn)
+{
+ struct named_pipe_socket *pipe_sock = talloc_get_type(
+ conn->private, struct named_pipe_socket);
+ struct named_pipe_connection *pipe_conn;
+
+ DEBUG(5,("named_pipe_accept\n"));
+
+ pipe_conn = talloc_zero(conn, struct named_pipe_connection);
+ if (!pipe_conn) {
+ stream_terminate_connection(conn, "out of memory");
+ return;
+ }
+
+ pipe_conn->packet = packet_init(pipe_conn);
+ if (!pipe_conn->packet) {
+ stream_terminate_connection(conn, "out of memory");
+ return;
+ }
+ packet_set_private(pipe_conn->packet, pipe_conn);
+ packet_set_socket(pipe_conn->packet, conn->socket);
+ packet_set_callback(pipe_conn->packet, named_pipe_recv_auth_request);
+ packet_set_full_request(pipe_conn->packet, named_pipe_full_request);
+ packet_set_error_handler(pipe_conn->packet, named_pipe_recv_error);
+ packet_set_event_context(pipe_conn->packet, conn->event.ctx);
+ packet_set_fde(pipe_conn->packet, conn->event.fde);
+ packet_set_serialise(pipe_conn->packet);
+ packet_set_initial_read(pipe_conn->packet, 8);
+
+ pipe_conn->pipe_sock = pipe_sock;
+
+ pipe_conn->connection = conn;
+ conn->private = pipe_conn;
+}
+
+static const struct stream_server_ops named_pipe_stream_ops = {
+ .name = "named_pipe",
+ .accept_connection = named_pipe_accept,
+ .recv_handler = named_pipe_recv,
+ .send_handler = named_pipe_send,
+};
+
+NTSTATUS stream_setup_named_pipe(struct event_context *event_context,
+ struct loadparm_context *lp_ctx,
+ const struct model_ops *model_ops,
+ const struct stream_server_ops *stream_ops,
+ const char *pipe_name,
+ void *private_data)
+{
+ char *dirname;
+ struct named_pipe_socket *pipe_sock;
+ NTSTATUS status = NT_STATUS_NO_MEMORY;;
+
+ pipe_sock = talloc(event_context, struct named_pipe_socket);
+ if (pipe_sock == NULL) {
+ goto fail;
+ }
+
+ /* remember the details about the pipe */
+ pipe_sock->pipe_name = talloc_strdup(pipe_sock, pipe_name);
+ if (pipe_sock->pipe_name == NULL) {
+ goto fail;
+ }
+
+ dirname = talloc_asprintf(pipe_sock, "%s/np", lp_ncalrpc_dir(lp_ctx));
+ if (dirname == NULL) {
+ goto fail;
+ }
+
+ if (!directory_create_or_exist(dirname, geteuid(), 0700)) {
+ status = map_nt_error_from_unix(errno);
+ goto fail;
+ }
+
+ if (strncmp(pipe_name, "\\pipe\\", 6) == 0) {
+ pipe_name += 6;
+ }
+
+ pipe_sock->pipe_path = talloc_asprintf(pipe_sock, "%s/%s", dirname,
+ pipe_name);
+ if (pipe_sock->pipe_path == NULL) {
+ goto fail;
+ }
+
+ talloc_free(dirname);
+
+ pipe_sock->ops = stream_ops;
+ pipe_sock->private_data = talloc_reference(pipe_sock, private_data);
+
+ status = stream_setup_socket(event_context,
+ lp_ctx,
+ model_ops,
+ &named_pipe_stream_ops,
+ "unix",
+ pipe_sock->pipe_path,
+ NULL,
+ NULL,
+ pipe_sock);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+ return NT_STATUS_OK;
+
+ fail:
+ talloc_free(pipe_sock);
+ return status;
+}
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index 8b12f36f95..4b4664f101 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -1,6 +1,6 @@
[SUBSYSTEM::TORTURE_UTIL]
PRIVATE_DEPENDENCIES = LIBCLI_RAW
-PUBLIC_DEPENDENCIES = POPT_CREDENTIALS
+PUBLIC_DEPENDENCIES = torture POPT_CREDENTIALS
TORTURE_UTIL_OBJ_FILES = $(addprefix $(torturesrcdir)/, util_smb.o)
@@ -89,6 +89,7 @@ mkinclude smb2/config.mk
mkinclude winbind/config.mk
[SUBSYSTEM::TORTURE_NDR]
+PRIVATE_DEPENDENCIES = torture
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)
@@ -105,7 +106,7 @@ PRIVATE_DEPENDENCIES = \
RPC_NDR_NETLOGON dcerpc_atsvc dcerpc_mgmt RPC_NDR_DRSUAPI \
RPC_NDR_LSA RPC_NDR_EPMAPPER RPC_NDR_DFS RPC_NDR_FRSAPI RPC_NDR_SPOOLSS \
RPC_NDR_SRVSVC RPC_NDR_WKSSVC RPC_NDR_ROT RPC_NDR_DSSETUP \
- RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER WB_HELPER LIBSAMBA-NET \
+ RPC_NDR_REMACT RPC_NDR_OXIDRESOLVER RPC_NDR_NTSVCS WB_HELPER LIBSAMBA-NET \
LIBCLI_AUTH POPT_CREDENTIALS TORTURE_LDAP TORTURE_UTIL TORTURE_RAP \
dcerpc_server service process_model ntvfs SERVICE_SMB
@@ -116,7 +117,7 @@ torture_rpc_OBJ_FILES = $(addprefix $(torturesrcdir)/rpc/, \
eventlog.o epmapper.o winreg.o initshutdown.o oxidresolve.o remact.o mgmt.o \
scanner.o autoidl.o countcalls.o testjoin.o schannel.o netlogon.o remote_pac.o samlogon.o \
samsync.o bind.o dssetup.o alter_context.o bench.o samba3rpc.o rpc.o async_bind.o \
- handles.o frsapi.o object_uuid.o)
+ handles.o frsapi.o object_uuid.o ntsvcs.o)
$(eval $(call proto_header_template,$(torturesrcdir)/rpc/proto.h,$(torture_rpc_OBJ_FILES:.o=.c)))
@@ -139,7 +140,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/rap/proto.h,$(TORTURE_RAP_O
SUBSYSTEM = smbtorture
PRIVATE_DEPENDENCIES = \
LIBCLI_SMB gensec auth KERBEROS \
- POPT_CREDENTIALS SMBPASSWD
+ POPT_CREDENTIALS SMBPASSWD torture
# End SUBSYSTEM TORTURE_AUTH
#################################
@@ -181,7 +182,7 @@ $(eval $(call proto_header_template,$(torturesrcdir)/unix/proto.h,$(TORTURE_UNIX
SUBSYSTEM = smbtorture
INIT_FUNCTION = torture_ldap_init
PRIVATE_DEPENDENCIES = \
- LIBCLI_LDAP LIBCLI_CLDAP SAMDB POPT_CREDENTIALS
+ LIBCLI_LDAP LIBCLI_CLDAP SAMDB POPT_CREDENTIALS torture
# End SUBSYSTEM TORTURE_LDAP
#################################
diff --git a/source4/torture/libnet/libnet_domain.c b/source4/torture/libnet/libnet_domain.c
index 7d5be368c2..3c28d1a019 100644
--- a/source4/torture/libnet/libnet_domain.c
+++ b/source4/torture/libnet/libnet_domain.c
@@ -35,12 +35,13 @@
static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct lsa_String *domname,
- uint32_t *access_mask, struct dom_sid **sid)
+ uint32_t *access_mask, struct dom_sid **sid_p)
{
NTSTATUS status;
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -59,6 +60,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -70,7 +72,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = *access_mask;
- r3.in.sid = *sid = r2.out.sid;
+ r3.in.sid = *sid_p = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/libnet_group.c b/source4/torture/libnet/libnet_group.c
index 12b8167a86..9c9ecfd525 100644
--- a/source4/torture/libnet/libnet_group.c
+++ b/source4/torture/libnet/libnet_group.c
@@ -42,12 +42,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle group_handle;
+ struct samr_Ids rids, types;
names[0].string = groupname;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("group account lookup '%s'\n", groupname);
@@ -57,7 +60,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -139,6 +142,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -155,6 +159,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -166,7 +171,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/libnet_user.c b/source4/torture/libnet/libnet_user.c
index 6d3e682976..18007dccad 100644
--- a/source4/torture/libnet/libnet_user.c
+++ b/source4/torture/libnet/libnet_user.c
@@ -40,12 +40,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
names[0].string = username;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("user account lookup '%s'\n", username);
@@ -55,7 +58,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -92,6 +95,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
printf("connecting\n");
@@ -108,6 +112,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
@@ -119,7 +124,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
printf("opening domain\n");
diff --git a/source4/torture/libnet/utils.c b/source4/torture/libnet/utils.c
index 54c5f2c29c..942540c80e 100644
--- a/source4/torture/libnet/utils.c
+++ b/source4/torture/libnet/utils.c
@@ -32,12 +32,13 @@
bool test_opendomain(struct torture_context *tctx,
struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct lsa_String *domname,
- struct dom_sid2 *sid)
+ struct dom_sid2 *sid_p)
{
NTSTATUS status;
struct policy_handle h, domain_handle;
struct samr_Connect r1;
struct samr_LookupDomain r2;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain r3;
torture_comment(tctx, "connecting\n");
@@ -51,6 +52,7 @@ bool test_opendomain(struct torture_context *tctx,
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
torture_comment(tctx, "domain lookup on %s\n", domname->string);
@@ -59,7 +61,7 @@ bool test_opendomain(struct torture_context *tctx,
r3.in.connect_handle = &h;
r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r3.in.sid = r2.out.sid;
+ r3.in.sid = *r2.out.sid;
r3.out.domain_handle = &domain_handle;
torture_comment(tctx, "opening domain\n");
@@ -68,7 +70,7 @@ bool test_opendomain(struct torture_context *tctx,
torture_assert_ntstatus_ok(tctx, status, "OpenDomain failed");
*handle = domain_handle;
- *sid = *r2.out.sid;
+ *sid_p = **r2.out.sid;
return true;
}
@@ -84,19 +86,22 @@ bool test_user_cleanup(struct torture_context *tctx, struct dcerpc_pipe *p,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
names[0].string = name;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
torture_comment(tctx, "user account lookup '%s'\n", name);
status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
torture_assert_ntstatus_ok(tctx, status, "LookupNames failed");
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
@@ -174,12 +179,15 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct lsa_String names[2];
uint32_t rid;
struct policy_handle group_handle;
+ struct samr_Ids rids, types;
names[0].string = name;
r1.in.domain_handle = domain_handle;
r1.in.num_names = 1;
r1.in.names = names;
+ r1.out.rids = &rids;
+ r1.out.types = &types;
printf("group account lookup '%s'\n", name);
@@ -189,7 +197,7 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- rid = r1.out.rids.ids[0];
+ rid = r1.out.rids->ids[0];
r2.in.domain_handle = domain_handle;
r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
diff --git a/source4/torture/raw/acls.c b/source4/torture/raw/acls.c
index 862b96ac17..48dec6e561 100644
--- a/source4/torture/raw/acls.c
+++ b/source4/torture/raw/acls.c
@@ -1410,7 +1410,9 @@ static bool test_inheritance(struct torture_context *tctx,
if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) {
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
- printf("Expected default sd at %d - got:\n", i);
+ printf("Expected default sd:\n");
+ NDR_PRINT_DEBUG(security_descriptor, sd_def);
+ printf("at %d - got:\n", i);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
}
goto check_dir;
@@ -1455,7 +1457,9 @@ static bool test_inheritance(struct torture_context *tctx,
(!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) ||
(test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) {
if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) {
- printf("Expected default sd for dir at %d - got:\n", i);
+ printf("Expected default sd for dir at %d:\n", i);
+ NDR_PRINT_DEBUG(security_descriptor, sd_def);
+ printf("got:\n");
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
}
continue;
@@ -1469,7 +1473,7 @@ static bool test_inheritance(struct torture_context *tctx,
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
sd_orig->owner_sid) ||
q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
- printf("Bad sd in child dir at %d (parent 0x%x)\n",
+ printf("(CI & NP) Bad sd in child dir at %d (parent 0x%x)\n",
i, test_flags[i].parent_flags);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
ret = false;
@@ -1487,7 +1491,7 @@ static bool test_inheritance(struct torture_context *tctx,
q.query_secdesc.out.sd->dacl->aces[0].flags != 0 ||
q.query_secdesc.out.sd->dacl->aces[1].flags !=
(test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) {
- printf("Bad sd in child dir at %d (parent 0x%x)\n",
+ printf("(CI) Bad sd in child dir at %d (parent 0x%x)\n",
i, test_flags[i].parent_flags);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
ret = false;
@@ -1500,8 +1504,8 @@ static bool test_inheritance(struct torture_context *tctx,
!dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee,
creator_owner) ||
q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) {
- printf("Bad sd in child dir at %d (parent 0x%x)\n",
- i, test_flags[i].parent_flags);
+ printf("(0) Bad sd in child dir at %d (parent 0x%x)\n",
+ i, test_flags[i].parent_flags);
NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd);
ret = false;
continue;
diff --git a/source4/torture/raw/chkpath.c b/source4/torture/raw/chkpath.c
index 68ef8e226d..b66839b997 100644
--- a/source4/torture/raw/chkpath.c
+++ b/source4/torture/raw/chkpath.c
@@ -18,6 +18,7 @@
*/
#include "includes.h"
+#include "system/locale.h"
#include "torture/torture.h"
#include "libcli/raw/libcliraw.h"
#include "libcli/raw/raw_proto.h"
@@ -267,6 +268,85 @@ done:
return ret;
}
+static bool test_chkpath_names(struct smbcli_state *cli, struct torture_context *tctx)
+{
+ union smb_chkpath io;
+ union smb_fileinfo finfo;
+ NTSTATUS status;
+ bool ret = true;
+ uint8_t i;
+
+ /*
+ * we don't test characters >= 0x80 yet,
+ * as somehow our client libraries can't do that
+ */
+ for (i=0x01; i <= 0x7F; i++) {
+ /*
+ * it's important that we test the last character
+ * because of the error code with ':' 0x3A
+ * and servers without stream support
+ */
+ char *path = talloc_asprintf(tctx, "%s\\File0x%02X%c",
+ BASEDIR, i, i);
+ NTSTATUS expected;
+ NTSTATUS expected_dos1;
+ NTSTATUS expected_dos2;
+
+ expected = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
+ expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRbadfile);
+
+ switch (i) {
+ case '"':/*0x22*/
+ case '*':/*0x2A*/
+ case '/':/*0x2F*/
+ case ':':/*0x3A*/
+ case '<':/*0x3C*/
+ case '>':/*0x3E*/
+ case '?':/*0x3F*/
+ case '|':/*0x7C*/
+ if (i == '/' &&
+ torture_setting_bool(tctx, "samba3", true)) {
+ /* samba 3 handles '/' as '\\' */
+ break;
+ }
+ expected = NT_STATUS_OBJECT_NAME_INVALID;
+ expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
+ expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRinvalidname);
+ break;
+ default:
+ if (i <= 0x1F) {
+ expected = NT_STATUS_OBJECT_NAME_INVALID;
+ expected_dos1 = NT_STATUS_DOS(ERRDOS,ERRbadpath);
+ expected_dos2 = NT_STATUS_DOS(ERRDOS,ERRinvalidname);
+ }
+ break;
+ }
+
+ printf("Checking File0x%02X%c%s expected[%s|%s|%s]\n",
+ i, isprint(i)?(char)i:' ',
+ isprint(i)?"":"(not printable)",
+ nt_errstr(expected),
+ nt_errstr(expected_dos1),
+ nt_errstr(expected_dos2));
+
+ io.chkpath.in.path = path;
+ status = smb_raw_chkpath(cli->tree, &io);
+ CHECK_STATUS(status, expected, expected_dos1);
+
+ ZERO_STRUCT(finfo);
+ finfo.generic.level = RAW_FILEINFO_NAME_INFO;
+ finfo.generic.in.file.path = path;
+ status = smb_raw_pathinfo(cli->tree, cli, &finfo);
+ CHECK_STATUS(status, expected, expected_dos2);
+
+ talloc_free(path);
+ }
+
+done:
+ return ret;
+}
+
/*
basic testing of chkpath calls
*/
@@ -303,6 +383,7 @@ bool torture_raw_chkpath(struct torture_context *torture,
}
ret &= test_chkpath(cli, torture);
+ ret &= test_chkpath_names(cli, torture);
done:
diff --git a/source4/torture/raw/streams.c b/source4/torture/raw/streams.c
index 8b2d327653..501da2335e 100644
--- a/source4/torture/raw/streams.c
+++ b/source4/torture/raw/streams.c
@@ -20,6 +20,7 @@
*/
#include "includes.h"
+#include "system/locale.h"
#include "torture/torture.h"
#include "libcli/raw/libcliraw.h"
#include "system/filesys.h"
@@ -43,6 +44,34 @@
ret = false; \
}} while (0)
+#define CHECK_NTTIME(v, correct) do { \
+ if ((v) != (correct)) { \
+ printf("(%s) Incorrect value %s=%llu - should be %llu\n", \
+ __location__, #v, (unsigned long long)v, \
+ (unsigned long long)correct); \
+ ret = false; \
+ }} while (0)
+
+#define CHECK_STR(v, correct) do { \
+ bool ok; \
+ if ((v) && !(correct)) { \
+ ok = false; \
+ } else if (!(v) && (correct)) { \
+ ok = false; \
+ } else if (!(v) && !(correct)) { \
+ ok = true; \
+ } else if (strcmp((v), (correct)) == 0) { \
+ ok = true; \
+ } else { \
+ ok = false; \
+ } \
+ if (!ok) { \
+ printf("(%s) Incorrect value %s='%s' - should be '%s'\n", \
+ __location__, #v, (v)?(v):"NULL", \
+ (correct)?(correct):"NULL"); \
+ ret = false; \
+ }} while (0)
+
/*
check that a stream has the right contents
*/
@@ -236,11 +265,7 @@ static bool test_stream_dir(struct torture_context *tctx,
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = basedir_data;
status = smb_raw_open(cli->tree, mem_ctx, &io);
- if (torture_setting_bool(tctx, "samba3", false)) {
- CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND);
- } else {
- CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
- }
+ CHECK_STATUS(status, NT_STATUS_FILE_IS_A_DIRECTORY);
printf("(%s) list the streams on the basedir\n", __location__);
ret &= check_stream_list(cli, BASEDIR, 0, NULL);
@@ -565,16 +590,12 @@ static bool test_stream_delete(struct torture_context *tctx,
status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_DELETE_PENDING);
- if (!torture_setting_bool(tctx, "samba3", false)) {
-
- /*
- * S3 doesn't do this yet
- */
-
- finfo.generic.in.file.path = sname1;
- status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
- CHECK_STATUS(status, NT_STATUS_DELETE_PENDING);
- }
+ /*
+ * older S3 doesn't do this
+ */
+ finfo.generic.in.file.path = sname1;
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_DELETE_PENDING);
/*
* fd-based qfileinfo on the stream still works, the stream does not
@@ -587,7 +608,9 @@ static bool test_stream_delete(struct torture_context *tctx,
status = smb_raw_fileinfo(cli->tree, mem_ctx, &finfo);
CHECK_STATUS(status, NT_STATUS_OK);
+ /* w2k and w2k3 return 0 and w2k8 returns 1
CHECK_VALUE(finfo.all_info.out.delete_pending, 0);
+ */
smbcli_close(cli->tree, fnum);
@@ -620,6 +643,378 @@ done:
return ret;
}
+/*
+ test stream names
+*/
+static bool test_stream_names(struct torture_context *tctx,
+ struct smbcli_state *cli,
+ TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ union smb_open io;
+ union smb_fileinfo finfo;
+ union smb_fileinfo stinfo;
+ union smb_setfileinfo sinfo;
+ const char *fname = BASEDIR "\\stream_names.txt";
+ const char *sname1, *sname1b, *sname1c, *sname1d;
+ const char *sname2, *snamew, *snamew2;
+ const char *snamer1, *snamer2;
+ bool ret = true;
+ int fnum1 = -1;
+ int fnum2 = -1;
+ int fnum3 = -1;
+ int i;
+ const char *four[4] = {
+ "::$DATA",
+ ":\x05Stream\n One:$DATA",
+ ":MStream Two:$DATA",
+ ":?Stream*:$DATA"
+ };
+ const char *five1[5] = {
+ "::$DATA",
+ ":\x05Stream\n One:$DATA",
+ ":BeforeRename:$DATA",
+ ":MStream Two:$DATA",
+ ":?Stream*:$DATA"
+ };
+ const char *five2[5] = {
+ "::$DATA",
+ ":\x05Stream\n One:$DATA",
+ ":AfterRename:$DATA",
+ ":MStream Two:$DATA",
+ ":?Stream*:$DATA"
+ };
+
+ sname1 = talloc_asprintf(mem_ctx, "%s:%s", fname, "\x05Stream\n One");
+ sname1b = talloc_asprintf(mem_ctx, "%s:", sname1);
+ sname1c = talloc_asprintf(mem_ctx, "%s:$FOO", sname1);
+ sname1d = talloc_asprintf(mem_ctx, "%s:?D*a", sname1);
+ sname2 = talloc_asprintf(mem_ctx, "%s:%s:$DaTa", fname, "MStream Two");
+ snamew = talloc_asprintf(mem_ctx, "%s:%s:$DATA", fname, "?Stream*");
+ snamew2 = talloc_asprintf(mem_ctx, "%s\\stream*:%s:$DATA", BASEDIR, "?Stream*");
+ snamer1 = talloc_asprintf(mem_ctx, "%s:%s:$DATA", fname, "BeforeRename");
+ snamer2 = talloc_asprintf(mem_ctx, "%s:%s:$DATA", fname, "AfterRename");
+
+ printf("(%s) testing stream names\n", __location__);
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.flags = 0;
+ io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = 0;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = sname1;
+
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ /*
+ * A different stream does not give a sharing violation
+ */
+
+ io.ntcreatex.in.fname = sname2;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum2 = io.ntcreatex.out.file.fnum;
+
+ /*
+ * ... whereas the same stream does with unchanged access/share_access
+ * flags
+ */
+
+ io.ntcreatex.in.fname = sname1;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_SUPERSEDE;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
+
+ io.ntcreatex.in.fname = sname1b;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+
+ io.ntcreatex.in.fname = sname1c;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ /* w2k returns INVALID_PARAMETER */
+ CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+ } else {
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+ }
+
+ io.ntcreatex.in.fname = sname1d;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) {
+ /* w2k returns INVALID_PARAMETER */
+ CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+ } else {
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+ }
+
+ io.ntcreatex.in.fname = sname2;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_SHARING_VIOLATION);
+
+ io.ntcreatex.in.fname = snamew;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum3 = io.ntcreatex.out.file.fnum;
+
+ io.ntcreatex.in.fname = snamew2;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID);
+
+ ret &= check_stream_list(cli, fname, 4, four);
+
+ smbcli_close(cli->tree, fnum1);
+ smbcli_close(cli->tree, fnum2);
+ smbcli_close(cli->tree, fnum3);
+
+ if (torture_setting_bool(tctx, "samba4", true)) {
+ goto done;
+ }
+
+ finfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ finfo.generic.in.file.path = fname;
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ ret &= check_stream_list(cli, fname, 4, four);
+
+ for (i=0; i < 4; i++) {
+ NTTIME write_time;
+ uint64_t stream_size;
+ char *path = talloc_asprintf(tctx, "%s%s",
+ fname, four[i]);
+
+ char *rpath = talloc_strdup(path, path);
+ char *p = strrchr(rpath, ':');
+ /* eat :$DATA */
+ *p = 0;
+ p--;
+ if (*p == ':') {
+ /* eat ::$DATA */
+ *p = 0;
+ }
+ printf("(%s): i[%u][%s]\n", __location__, i, path);
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE |
+ SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.fname = path;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ finfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ finfo.generic.in.file.path = fname;
+ status = smb_raw_pathinfo(cli->tree, mem_ctx, &finfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ stinfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ stinfo.generic.in.file.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &stinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ CHECK_NTTIME(stinfo.all_info.out.create_time,
+ finfo.all_info.out.create_time);
+ CHECK_NTTIME(stinfo.all_info.out.access_time,
+ finfo.all_info.out.access_time);
+ CHECK_NTTIME(stinfo.all_info.out.write_time,
+ finfo.all_info.out.write_time);
+ CHECK_NTTIME(stinfo.all_info.out.change_time,
+ finfo.all_info.out.change_time);
+ }
+ CHECK_VALUE(stinfo.all_info.out.attrib,
+ finfo.all_info.out.attrib);
+ CHECK_VALUE(stinfo.all_info.out.size,
+ finfo.all_info.out.size);
+ CHECK_VALUE(stinfo.all_info.out.delete_pending,
+ finfo.all_info.out.delete_pending);
+ CHECK_VALUE(stinfo.all_info.out.directory,
+ finfo.all_info.out.directory);
+ CHECK_VALUE(stinfo.all_info.out.ea_size,
+ finfo.all_info.out.ea_size);
+
+ stinfo.generic.level = RAW_FILEINFO_NAME_INFO;
+ stinfo.generic.in.file.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &stinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ CHECK_STR(rpath, stinfo.name_info.out.fname.s);
+ }
+
+ write_time = finfo.all_info.out.write_time;
+ write_time += i*1000000;
+ write_time /= 1000000;
+ write_time *= 1000000;
+
+ ZERO_STRUCT(sinfo);
+ sinfo.basic_info.level = RAW_SFILEINFO_BASIC_INFO;
+ sinfo.basic_info.in.file.fnum = fnum1;
+ sinfo.basic_info.in.write_time = write_time;
+ sinfo.basic_info.in.attrib = stinfo.all_info.out.attrib;
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ stream_size = i*8192;
+
+ ZERO_STRUCT(sinfo);
+ sinfo.end_of_file_info.level = RAW_SFILEINFO_END_OF_FILE_INFO;
+ sinfo.end_of_file_info.in.file.fnum = fnum1;
+ sinfo.end_of_file_info.in.size = stream_size;
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ stinfo.generic.level = RAW_FILEINFO_ALL_INFO;
+ stinfo.generic.in.file.fnum = fnum1;
+ status = smb_raw_fileinfo(cli->tree, mem_ctx, &stinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ if (!torture_setting_bool(tctx, "samba3", false)) {
+ CHECK_NTTIME(stinfo.all_info.out.write_time,
+ write_time);
+ CHECK_VALUE(stinfo.all_info.out.attrib,
+ finfo.all_info.out.attrib);
+ }
+ CHECK_VALUE(stinfo.all_info.out.size,
+ stream_size);
+ CHECK_VALUE(stinfo.all_info.out.delete_pending,
+ finfo.all_info.out.delete_pending);
+ CHECK_VALUE(stinfo.all_info.out.directory,
+ finfo.all_info.out.directory);
+ CHECK_VALUE(stinfo.all_info.out.ea_size,
+ finfo.all_info.out.ea_size);
+
+ ret &= check_stream_list(cli, fname, 4, four);
+
+ smbcli_close(cli->tree, fnum1);
+ talloc_free(path);
+ }
+
+ printf("(%s): testing stream renames\n", __location__);
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.access_mask = SEC_FILE_READ_ATTRIBUTE |
+ SEC_FILE_WRITE_ATTRIBUTE |
+ SEC_RIGHTS_FILE_ALL;
+ io.ntcreatex.in.fname = snamer1;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ ret &= check_stream_list(cli, fname, 5, five1);
+
+ ZERO_STRUCT(sinfo);
+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sinfo.rename_information.in.file.fnum = fnum1;
+ sinfo.rename_information.in.overwrite = true;
+ sinfo.rename_information.in.root_fid = 0;
+ sinfo.rename_information.in.new_name = ":AfterRename:$DATA";
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OK);
+
+ ret &= check_stream_list(cli, fname, 5, five2);
+
+ ZERO_STRUCT(sinfo);
+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sinfo.rename_information.in.file.fnum = fnum1;
+ sinfo.rename_information.in.overwrite = false;
+ sinfo.rename_information.in.root_fid = 0;
+ sinfo.rename_information.in.new_name = ":MStream Two:$DATA";
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_COLLISION);
+
+ ret &= check_stream_list(cli, fname, 5, five2);
+
+ ZERO_STRUCT(sinfo);
+ sinfo.rename_information.level = RAW_SFILEINFO_RENAME_INFORMATION;
+ sinfo.rename_information.in.file.fnum = fnum1;
+ sinfo.rename_information.in.overwrite = true;
+ sinfo.rename_information.in.root_fid = 0;
+ sinfo.rename_information.in.new_name = ":MStream Two:$DATA";
+ status = smb_raw_setfileinfo(cli->tree, &sinfo);
+ CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER);
+
+ ret &= check_stream_list(cli, fname, 5, five2);
+
+ /* TODO: we need to test more rename combinations */
+
+done:
+ if (fnum1 != -1) smbcli_close(cli->tree, fnum1);
+ if (fnum2 != -1) smbcli_close(cli->tree, fnum2);
+ if (fnum3 != -1) smbcli_close(cli->tree, fnum3);
+ status = smbcli_unlink(cli->tree, fname);
+ return ret;
+}
+
+/*
+ test stream names
+*/
+static bool test_stream_names2(struct torture_context *tctx,
+ struct smbcli_state *cli,
+ TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ union smb_open io;
+ const char *fname = BASEDIR "\\stream_names2.txt";
+ bool ret = true;
+ int fnum1 = -1;
+ uint8_t i;
+
+ printf("(%s) testing stream names\n", __location__);
+ io.generic.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.flags = 0;
+ io.ntcreatex.in.access_mask = SEC_FILE_WRITE_DATA;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL;
+ io.ntcreatex.in.share_access = 0;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_CREATE;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_ANONYMOUS;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = fname;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, NT_STATUS_OK);
+ fnum1 = io.ntcreatex.out.file.fnum;
+
+ for (i=0x01; i < 0x7F; i++) {
+ char *path = talloc_asprintf(tctx, "%s:Stream%c0x%02X:$DATA",
+ fname, i, i);
+ NTSTATUS expected;
+
+ switch (i) {
+ case '/':/*0x2F*/
+ case ':':/*0x3A*/
+ case '\\':/*0x5C*/
+ expected = NT_STATUS_OBJECT_NAME_INVALID;
+ break;
+ default:
+ expected = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ break;
+ }
+
+ printf("(%s) %s:Stream%c0x%02X:$DATA%s => expected[%s]\n",
+ __location__, fname, isprint(i)?(char)i:' ', i,
+ isprint(i)?"":" (not printable)",
+ nt_errstr(expected));
+
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ io.ntcreatex.in.fname = path;
+ status = smb_raw_open(cli->tree, mem_ctx, &io);
+ CHECK_STATUS(status, expected);
+
+ talloc_free(path);
+ }
+
+done:
+ if (fnum1 != -1) smbcli_close(cli->tree, fnum1);
+ status = smbcli_unlink(cli->tree, fname);
+ return ret;
+}
+
/*
basic testing of streams calls
*/
@@ -638,6 +1033,10 @@ bool torture_raw_streams(struct torture_context *torture,
smb_raw_exit(cli->session);
ret &= test_stream_sharemodes(torture, cli, torture);
smb_raw_exit(cli->session);
+ ret &= test_stream_names(torture, cli, torture);
+ smb_raw_exit(cli->session);
+ ret &= test_stream_names2(torture, cli, torture);
+ smb_raw_exit(cli->session);
if (!torture_setting_bool(torture, "samba4", false)) {
ret &= test_stream_delete(torture, cli, torture);
}
diff --git a/source4/torture/rpc/eventlog.c b/source4/torture/rpc/eventlog.c
index d5665ad07d..e89cdd3ea9 100644
--- a/source4/torture/rpc/eventlog.c
+++ b/source4/torture/rpc/eventlog.c
@@ -46,12 +46,12 @@ static bool get_policy_handle(struct torture_context *tctx,
unknown0.unknown1 = 0x0001;
r.in.unknown0 = &unknown0;
- init_lsa_String(r.in.logname, "dns server");
- init_lsa_String(r.in.servername, NULL);
+ init_lsa_String(&logname, "dns server");
+ init_lsa_String(&servername, NULL);
r.in.logname = &logname;
r.in.servername = &servername;
- r.in.unknown2 = 0x00000001;
- r.in.unknown3 = 0x00000001;
+ r.in.major_version = 0x00000001;
+ r.in.minor_version = 0x00000001;
r.out.handle = handle;
torture_assert_ntstatus_ok(tctx,
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index 96cab0bf02..953f9d126d 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -32,8 +32,10 @@
#include "../lib/crypto/crypto.h"
#include "libcli/auth/libcli_auth.h"
#include "librpc/gen_ndr/ndr_netlogon_c.h"
+#include "librpc/gen_ndr/ndr_netlogon.h"
#include "librpc/gen_ndr/ndr_lsa_c.h"
#include "param/param.h"
+#include "libcli/security/security.h"
#define TEST_MACHINE_NAME "torturetest"
@@ -831,6 +833,538 @@ static bool test_DatabaseDeltas(struct torture_context *tctx,
return true;
}
+static bool test_DatabaseRedo(struct torture_context *tctx,
+ struct dcerpc_pipe *p,
+ struct cli_credentials *machine_credentials)
+{
+ NTSTATUS status;
+ struct netr_DatabaseRedo r;
+ struct creds_CredentialState *creds;
+ struct netr_Authenticator credential;
+ struct netr_Authenticator return_authenticator;
+ struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL;
+ struct netr_ChangeLogEntry e;
+ struct dom_sid null_sid, *sid;
+ int i,d;
+
+ ZERO_STRUCT(null_sid);
+
+ sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500");
+
+ {
+
+ struct {
+ uint32_t rid;
+ uint16_t flags;
+ uint8_t db_index;
+ uint8_t delta_type;
+ struct dom_sid sid;
+ const char *name;
+ NTSTATUS expected_error;
+ uint32_t expected_num_results;
+ uint8_t expected_delta_type_1;
+ uint8_t expected_delta_type_2;
+ const char *comment;
+ } changes[] = {
+
+ /* SAM_DATABASE_DOMAIN */
+
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_MODIFY_COUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_MODIFY_COUNT"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = 0,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NULL DELTA"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_DOMAIN,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NETR_DELTA_DOMAIN"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_USER,
+ .comment = "NETR_DELTA_USER by rid 500"
+ },
+ {
+ .rid = DOMAIN_RID_GUEST,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_USER,
+ .comment = "NETR_DELTA_USER by rid 501"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = *sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by null_sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = "administrator",
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by name 'administrator'"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINS,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_GROUP,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_GROUP,
+ .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
+ .comment = "NETR_DELTA_GROUP by rid 512"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINS,
+ .flags = 0,
+ .db_index = SAM_DATABASE_DOMAIN,
+ .delta_type = NETR_DELTA_GROUP_MEMBER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_GROUP,
+ .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER,
+ .comment = "NETR_DELTA_GROUP_MEMBER by rid 512"
+ },
+
+
+ /* SAM_DATABASE_BUILTIN */
+
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_MODIFY_COUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_MODIFY_COUNT"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_DOMAIN,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NETR_DELTA_DOMAIN"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER by rid 500"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_USER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_USER,
+ .comment = "NETR_DELTA_USER"
+ },
+ {
+ .rid = 544,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_ALIAS,
+ .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
+ .comment = "NETR_DELTA_ALIAS by rid 544"
+ },
+ {
+ .rid = 544,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS_MEMBER,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_ALIAS,
+ .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
+ .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544"
+ },
+ {
+ .rid = 544,
+ .flags = 0,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = 0,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NULL DELTA by rid 544"
+ },
+ {
+ .rid = 544,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = 0,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DOMAIN,
+ .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags"
+ },
+ {
+ .rid = 544,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 2,
+ .expected_delta_type_1 = NETR_DELTA_ALIAS,
+ .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER,
+ .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_BUILTIN,
+ .delta_type = NETR_DELTA_ALIAS,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS,
+ .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags"
+ },
+
+ /* SAM_DATABASE_PRIVS */
+
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = 0,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_ACCESS_DENIED,
+ .expected_num_results = 0,
+ .comment = "NULL DELTA"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_MODIFY_COUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_MODIFY_COUNT"
+ },
+ {
+ .rid = 0,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_POLICY,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_POLICY,
+ .comment = "NETR_DELTA_POLICY"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_POLICY,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_POLICY,
+ .comment = "NETR_DELTA_POLICY by null sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_POLICY,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_POLICY,
+ .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = 0,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = null_sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_ACCOUNT by rid 500"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
+ .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED |
+ NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_ACCOUNT,
+ .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_SID_INCLUDED |
+ NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"),
+ .name = NULL,
+ .expected_error = NT_STATUS_INVALID_PARAMETER,
+ .expected_num_results = 0,
+ .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags"
+ },
+ {
+ .rid = DOMAIN_RID_ADMINISTRATOR,
+ .flags = NETR_CHANGELOG_SID_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_ACCOUNT,
+ .sid = *sid,
+ .name = NULL,
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT,
+ .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_SECRET,
+ .sid = null_sid,
+ .name = "IsurelydontexistIhope",
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET,
+ .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags"
+ },
+ {
+ .rid = 0,
+ .flags = NETR_CHANGELOG_NAME_INCLUDED,
+ .db_index = SAM_DATABASE_PRIVS,
+ .delta_type = NETR_DELTA_SECRET,
+ .sid = null_sid,
+ .name = "G$BCKUPKEY_P",
+ .expected_error = NT_STATUS_OK,
+ .expected_num_results = 1,
+ .expected_delta_type_1 = NETR_DELTA_SECRET,
+ .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags"
+ }
+ };
+
+ ZERO_STRUCT(return_authenticator);
+
+ r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.computername = TEST_MACHINE_NAME;
+ r.in.return_authenticator = &return_authenticator;
+ r.out.return_authenticator = &return_authenticator;
+ r.out.delta_enum_array = &delta_enum_array;
+
+ for (d=0; d<3; d++) {
+
+ const char *database;
+
+ switch (d) {
+ case 0:
+ database = "SAM";
+ break;
+ case 1:
+ database = "BUILTIN";
+ break;
+ case 2:
+ database = "LSA";
+ break;
+ default:
+ break;
+ }
+
+ torture_comment(tctx, "Testing DatabaseRedo\n");
+
+ if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
+ return false;
+ }
+
+ for (i=0;i<ARRAY_SIZE(changes);i++) {
+
+ if (d != changes[i].db_index) {
+ continue;
+ }
+
+ creds_client_authenticator(creds, &credential);
+
+ r.in.credential = &credential;
+
+ e.serial_number1 = 0;
+ e.serial_number2 = 0;
+ e.object_rid = changes[i].rid;
+ e.flags = changes[i].flags;
+ e.db_index = changes[i].db_index;
+ e.delta_type = changes[i].delta_type;
+
+ switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) {
+ case NETR_CHANGELOG_SID_INCLUDED:
+ e.object.object_sid = changes[i].sid;
+ break;
+ case NETR_CHANGELOG_NAME_INCLUDED:
+ e.object.object_name = changes[i].name;
+ break;
+ default:
+ break;
+ }
+
+ r.in.change_log_entry = e;
+
+ torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n",
+ database, changes[i].comment);
+
+ status = dcerpc_netr_DatabaseRedo(p, tctx, &r);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+ return true;
+ }
+
+ torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment);
+ if (delta_enum_array) {
+ torture_assert_int_equal(tctx,
+ delta_enum_array->num_deltas,
+ changes[i].expected_num_results,
+ changes[i].comment);
+ if (delta_enum_array->num_deltas > 0) {
+ torture_assert_int_equal(tctx,
+ delta_enum_array->delta_enum[0].delta_type,
+ changes[i].expected_delta_type_1,
+ changes[i].comment);
+ }
+ if (delta_enum_array->num_deltas > 1) {
+ torture_assert_int_equal(tctx,
+ delta_enum_array->delta_enum[1].delta_type,
+ changes[i].expected_delta_type_2,
+ changes[i].comment);
+ }
+ }
+
+ if (!creds_client_check(creds, &return_authenticator.cred)) {
+ torture_comment(tctx, "Credential chaining failed\n");
+ if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
/*
try a netlogon AccountDeltas
@@ -1761,6 +2295,7 @@ struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx)
torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo);
torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync);
torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas);
+ torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo);
torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas);
torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync);
torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName);
diff --git a/source4/torture/rpc/ntsvcs.c b/source4/torture/rpc/ntsvcs.c
new file mode 100644
index 0000000000..5453102039
--- /dev/null
+++ b/source4/torture/rpc/ntsvcs.c
@@ -0,0 +1,169 @@
+/*
+ Unix SMB/CIFS implementation.
+ test suite for rpc ntsvcs operations
+
+ Copyright (C) Guenther Deschner 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "lib/torture/torture.h"
+#include "torture/rpc/rpc.h"
+#include "librpc/gen_ndr/ndr_ntsvcs_c.h"
+#include "torture/util.h"
+#include "param/param.h"
+
+static bool test_PNP_GetVersion(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetVersion r;
+ uint16_t version = 0;
+
+ r.out.version = &version;
+
+ status = dcerpc_PNP_GetVersion(p, tctx, &r);
+
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetVersion");
+ torture_assert_werr_ok(tctx, r.out.result, "PNP_GetVersion");
+ torture_assert_int_equal(tctx, version, 0x400, "invalid version");
+
+ return true;
+}
+
+static bool test_PNP_GetDeviceListSize(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetDeviceListSize r;
+ uint32_t size = 0;
+
+ r.in.devicename = NULL;
+ r.in.flags = 0;
+ r.out.size = &size;
+
+ status = dcerpc_PNP_GetDeviceListSize(p, tctx, &r);
+
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceListSize");
+ torture_assert_werr_ok(tctx, r.out.result, "PNP_GetDeviceListSize");
+
+ return true;
+}
+
+static bool test_PNP_GetDeviceList(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetDeviceList r;
+ uint16_t *buffer = NULL;
+ uint32_t length = 0;
+
+ buffer = talloc_array(tctx, uint16_t, 0);
+
+ r.in.filter = NULL;
+ r.in.flags = 0;
+ r.in.length = &length;
+ r.out.length = &length;
+ r.out.buffer = buffer;
+
+ status = dcerpc_PNP_GetDeviceList(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceList");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_CM_BUFFER_SMALL)) {
+ struct PNP_GetDeviceListSize s;
+
+ s.in.devicename = NULL;
+ s.in.flags = 0;
+ s.out.size = &length;
+
+ status = dcerpc_PNP_GetDeviceListSize(p, tctx, &s);
+
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceListSize");
+ torture_assert_werr_ok(tctx, s.out.result, "PNP_GetDeviceListSize");
+ }
+
+ buffer = talloc_array(tctx, uint16_t, length);
+
+ r.in.length = &length;
+ r.out.length = &length;
+ r.out.buffer = buffer;
+
+ status = dcerpc_PNP_GetDeviceList(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceList");
+ torture_assert_werr_ok(tctx, r.out.result, "PNP_GetDeviceList");
+
+ return true;
+}
+
+static bool test_PNP_GetDeviceRegProp(struct torture_context *tctx,
+ struct dcerpc_pipe *p)
+{
+ NTSTATUS status;
+ struct PNP_GetDeviceRegProp r;
+
+ enum winreg_Type reg_data_type = REG_NONE;
+ uint32_t buffer_size = 0;
+ uint32_t needed = 0;
+ uint8_t *buffer;
+
+ buffer = talloc(tctx, uint8_t);
+
+ r.in.devicepath = "ACPI\\ACPI0003\\1";
+ r.in.property = DEV_REGPROP_DESC;
+ r.in.flags = 0;
+ r.in.reg_data_type = &reg_data_type;
+ r.in.buffer_size = &buffer_size;
+ r.in.needed = &needed;
+ r.out.buffer = buffer;
+ r.out.reg_data_type = &reg_data_type;
+ r.out.buffer_size = &buffer_size;
+ r.out.needed = &needed;
+
+ status = dcerpc_PNP_GetDeviceRegProp(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceRegProp");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_CM_BUFFER_SMALL)) {
+
+ buffer = talloc_array(tctx, uint8_t, needed);
+ r.in.buffer_size = &needed;
+
+ status = dcerpc_PNP_GetDeviceRegProp(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "PNP_GetDeviceRegProp");
+ }
+
+ return true;
+}
+
+struct torture_suite *torture_rpc_ntsvcs(TALLOC_CTX *mem_ctx)
+{
+ struct torture_rpc_tcase *tcase;
+ struct torture_suite *suite = torture_suite_create(mem_ctx, "NTSVCS");
+ struct torture_test *test;
+
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "ntsvcs",
+ &ndr_table_ntsvcs);
+
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceRegProp",
+ test_PNP_GetDeviceRegProp);
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceList",
+ test_PNP_GetDeviceList);
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetDeviceListSize",
+ test_PNP_GetDeviceListSize);
+ test = torture_rpc_tcase_add_test(tcase, "PNP_GetVersion",
+ test_PNP_GetVersion);
+
+ return suite;
+}
diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c
index 2fcf700c36..7f6b06d000 100644
--- a/source4/torture/rpc/rpc.c
+++ b/source4/torture/rpc/rpc.c
@@ -395,6 +395,7 @@ NTSTATUS torture_rpc_init(void)
torture_suite_add_simple_test(suite, "SAMR", torture_rpc_samr);
torture_suite_add_simple_test(suite, "SAMR-USERS", torture_rpc_samr_users);
torture_suite_add_simple_test(suite, "SAMR-PASSWORDS", torture_rpc_samr_passwords);
+ torture_suite_add_simple_test(suite, "SAMR-PASSWORDS-PWDLASTSET", torture_rpc_samr_passwords_pwdlastset);
torture_suite_add_suite(suite, torture_rpc_netlogon(suite));
torture_suite_add_suite(suite, torture_rpc_remote_pac(suite));
torture_suite_add_simple_test(suite, "SAMLOGON", torture_rpc_samlogon);
@@ -438,6 +439,7 @@ NTSTATUS torture_rpc_init(void)
torture_suite_add_simple_test(suite, "DSSYNC", torture_rpc_dssync);
torture_suite_add_simple_test(suite, "BENCH-RPC", torture_bench_rpc);
torture_suite_add_simple_test(suite, "ASYNCBIND", torture_async_bind);
+ torture_suite_add_suite(suite, torture_rpc_ntsvcs(suite));
suite->description = talloc_strdup(suite, "DCE/RPC protocol and interface tests");
diff --git a/source4/torture/rpc/rpc.h b/source4/torture/rpc/rpc.h
index 29b1ebee54..9fd64f18b5 100644
--- a/source4/torture/rpc/rpc.h
+++ b/source4/torture/rpc/rpc.h
@@ -21,14 +21,13 @@
#ifndef __TORTURE_RPC_H__
#define __TORTURE_RPC_H__
-#include "torture/torture.h"
+#include "lib/torture/torture.h"
#include "auth/credentials/credentials.h"
#include "torture/rpc/drsuapi.h"
#include "libnet/libnet_join.h"
#include "librpc/rpc/dcerpc.h"
#include "libcli/raw/libcliraw.h"
#include "torture/rpc/proto.h"
-#include "torture/torture.h"
struct torture_rpc_tcase {
struct torture_tcase tcase;
diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c
index c2b849127f..f1e7e5a367 100644
--- a/source4/torture/rpc/samba3rpc.c
+++ b/source4/torture/rpc/samba3rpc.c
@@ -355,7 +355,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
char **domain,
struct dcerpc_pipe **result_pipe,
struct policy_handle **result_handle,
- struct dom_sid **sid)
+ struct dom_sid **sid_p)
{
struct dcerpc_pipe *samr_pipe;
NTSTATUS status;
@@ -365,7 +365,10 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
struct samr_Connect2 conn;
struct samr_EnumDomains enumdom;
uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ struct samr_SamArray *sam = NULL;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
int dom_idx;
struct lsa_String domain_name;
struct lsa_String user_name;
@@ -423,6 +426,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
enumdom.in.resume_handle = &resume_handle;
enumdom.in.buf_size = (uint32_t)-1;
enumdom.out.resume_handle = &resume_handle;
+ enumdom.out.num_entries = &num_entries;
+ enumdom.out.sam = &sam;
status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom);
if (!NT_STATUS_IS_OK(status)) {
@@ -430,20 +435,21 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
goto fail;
}
- if (enumdom.out.num_entries != 2) {
+ if (*enumdom.out.num_entries != 2) {
d_printf("samr_EnumDomains returned %d entries, expected 2\n",
- enumdom.out.num_entries);
+ *enumdom.out.num_entries);
status = NT_STATUS_UNSUCCESSFUL;
goto fail;
}
- dom_idx = strequal(enumdom.out.sam->entries[0].name.string,
+ dom_idx = strequal(sam->entries[0].name.string,
"builtin") ? 1:0;
l.in.connect_handle = &conn_handle;
- domain_name.string = enumdom.out.sam->entries[dom_idx].name.string;
+ domain_name.string = sam->entries[dom_idx].name.string;
*domain = talloc_strdup(mem_ctx, domain_name.string);
l.in.domain_name = &domain_name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -453,7 +459,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
o.in.connect_handle = &conn_handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = &domain_handle;
status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o);
@@ -477,10 +483,13 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
struct samr_LookupNames ln;
struct samr_OpenUser ou;
+ struct samr_Ids rids, types;
ln.in.domain_handle = &domain_handle;
ln.in.num_names = 1;
ln.in.names = &user_name;
+ ln.out.rids = &rids;
+ ln.out.types = &types;
status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln);
if (!NT_STATUS_IS_OK(status)) {
@@ -491,7 +500,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
ou.in.domain_handle = &domain_handle;
ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- user_rid = ou.in.rid = ln.out.rids.ids[0];
+ user_rid = ou.in.rid = ln.out.rids->ids[0];
ou.out.user_handle = user_handle;
status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou);
@@ -509,8 +518,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli,
*result_pipe = samr_pipe;
*result_handle = user_handle;
- if (sid != NULL) {
- *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid);
+ if (sid_p != NULL) {
+ *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid);
}
return NT_STATUS_OK;
@@ -555,6 +564,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
struct samr_SetUserInfo sui;
struct samr_QueryUserInfo qui;
union samr_UserInfo u_info;
+ union samr_UserInfo *info;
DATA_BLOB session_key;
@@ -597,6 +607,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
qui.in.user_handle = wks_handle;
qui.in.level = 21;
+ qui.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui);
if (!NT_STATUS_IS_OK(status)) {
@@ -604,14 +615,14 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli,
goto done;
}
- qui.out.info->info21.allow_password_change = 0;
- qui.out.info->info21.force_password_change = 0;
- qui.out.info->info21.account_name.string = NULL;
- qui.out.info->info21.rid = 0;
- qui.out.info->info21.acct_expiry = 0;
- qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
+ info->info21.allow_password_change = 0;
+ info->info21.force_password_change = 0;
+ info->info21.account_name.string = NULL;
+ info->info21.rid = 0;
+ info->info21.acct_expiry = 0;
+ info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */
- u_info.info21 = qui.out.info->info21;
+ u_info.info21 = info->info21;
sui.in.user_handle = wks_handle;
sui.in.info = &u_info;
sui.in.level = 21;
@@ -721,9 +732,11 @@ static bool join3(struct smbcli_state *cli,
{
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
q.in.user_handle = wks_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -732,7 +745,7 @@ static bool join3(struct smbcli_state *cli,
goto done;
}
- last_password_change = q.out.info->info21.last_password_change;
+ last_password_change = info->info21.last_password_change;
}
cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED);
@@ -755,6 +768,10 @@ static bool join3(struct smbcli_state *cli,
i21->acct_flags = ACB_WSTRUST;
i21->fields_present = SAMR_FIELD_FULL_NAME |
SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_PASSWORD;
+ /* this would break the test result expectations
+ i21->fields_present |= SAMR_FIELD_EXPIRED_FLAG;
+ i21->password_expired = 1;
+ */
encode_pw_buffer(u_info.info25.password.data,
cli_credentials_get_password(wks_creds),
@@ -795,8 +812,8 @@ static bool join3(struct smbcli_state *cli,
encode_pw_buffer(u_info.info24.password.data,
cli_credentials_get_password(wks_creds),
STR_UNICODE);
- u_info.info24.pw_len =
- strlen_m(cli_credentials_get_password(wks_creds))*2;
+ /* just to make this test pass */
+ u_info.info24.password_expired = 1;
status = dcerpc_fetch_session_key(samr_pipe, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -830,9 +847,11 @@ static bool join3(struct smbcli_state *cli,
{
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
q.in.user_handle = wks_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -843,7 +862,7 @@ static bool join3(struct smbcli_state *cli,
if (use_level25) {
if (last_password_change
- == q.out.info->info21.last_password_change) {
+ == info->info21.last_password_change) {
d_printf("(%s) last_password_change unchanged "
"during join, level25 must change "
"it\n", __location__);
@@ -852,7 +871,7 @@ static bool join3(struct smbcli_state *cli,
}
else {
if (last_password_change
- != q.out.info->info21.last_password_change) {
+ != info->info21.last_password_change) {
d_printf("(%s) last_password_change changed "
"during join, level24 doesn't "
"change it\n", __location__);
diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c
index 23c288bfcc..01ff01674c 100644
--- a/source4/torture/rpc/samr.c
+++ b/source4/torture/rpc/samr.c
@@ -29,6 +29,8 @@
#include "libcli/security/security.h"
#include "torture/rpc/rpc.h"
+#include <unistd.h>
+
#define TEST_ACCOUNT_NAME "samrtorturetest"
#define TEST_ALIASNAME "samrtorturetestalias"
#define TEST_GROUPNAME "samrtorturetestgroup"
@@ -37,6 +39,7 @@
enum torture_samr_choice {
TORTURE_SAMR_PASSWORDS,
+ TORTURE_SAMR_PASSWORDS_PWDLASTSET,
TORTURE_SAMR_USER_ATTRIBUTES,
TORTURE_SAMR_OTHER
};
@@ -59,6 +62,13 @@ static void init_lsa_String(struct lsa_String *string, const char *s)
string->string = s;
}
+static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length)
+{
+ string->length = length;
+ string->size = length;
+ string->array = (uint16_t *)discard_const(s);
+}
+
bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle)
{
@@ -131,18 +141,20 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p,
NTSTATUS status;
struct samr_QuerySecurity r;
struct samr_SetSecurity s;
+ struct sec_desc_buf *sdbuf = NULL;
r.in.handle = handle;
r.in.sec_info = 7;
+ r.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "QuerySecurity");
- torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL");
+ torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL");
s.in.handle = handle;
s.in.sec_info = 7;
- s.in.sdbuf = r.out.sdbuf;
+ s.in.sdbuf = sdbuf;
if (torture_setting_bool(tctx, "samba4", false)) {
torture_skip(tctx, "skipping SetSecurity test against Samba4\n");
@@ -168,6 +180,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
struct samr_QueryUserInfo q;
struct samr_QueryUserInfo q0;
union samr_UserInfo u;
+ union samr_UserInfo *info;
bool ret = true;
const char *test_account_name;
@@ -184,7 +197,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
s2.in.info = &u;
q.in.user_handle = handle;
- q.out.info = &u;
+ q.out.info = &info;
q0 = q;
#define TESTCALL(call, r) \
@@ -204,6 +217,14 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
break; \
}
+#define MEM_EQUAL(s1, s2, length, field) \
+ if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \
+ torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \
+ #field, (const char *)s2, __location__); \
+ ret = false; \
+ break; \
+ }
+
#define INT_EQUAL(i1, i2, field) \
if (i1 != i2) { \
torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \
@@ -218,7 +239,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(QueryUserInfo, q) \
s.in.level = lvl1; \
s2.in.level = lvl1; \
- u = *q.out.info; \
+ u = *info; \
if (lvl1 == 21) { \
ZERO_STRUCT(u.info21); \
u.info21.fields_present = fpval; \
@@ -228,21 +249,45 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(SetUserInfo2, s2) \
init_lsa_String(&u.info ## lvl1.field1, ""); \
TESTCALL(QueryUserInfo, q); \
- u = *q.out.info; \
+ u = *info; \
STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \
q.in.level = lvl2; \
TESTCALL(QueryUserInfo, q) \
- u = *q.out.info; \
+ u = *info; \
STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \
} while (0)
+#define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \
+ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
+ q.in.level = lvl1; \
+ TESTCALL(QueryUserInfo, q) \
+ s.in.level = lvl1; \
+ s2.in.level = lvl1; \
+ u = *info; \
+ if (lvl1 == 21) { \
+ ZERO_STRUCT(u.info21); \
+ u.info21.fields_present = fpval; \
+ } \
+ init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \
+ TESTCALL(SetUserInfo, s) \
+ TESTCALL(SetUserInfo2, s2) \
+ init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \
+ TESTCALL(QueryUserInfo, q); \
+ u = *info; \
+ MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \
+ q.in.level = lvl2; \
+ TESTCALL(QueryUserInfo, q) \
+ u = *info; \
+ MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \
+ } while (0)
+
#define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \
torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \
q.in.level = lvl1; \
TESTCALL(QueryUserInfo, q) \
s.in.level = lvl1; \
s2.in.level = lvl1; \
- u = *q.out.info; \
+ u = *info; \
if (lvl1 == 21) { \
uint8_t *bits = u.info21.logon_hours.bits; \
ZERO_STRUCT(u.info21); \
@@ -257,11 +302,11 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TESTCALL(SetUserInfo2, s2) \
u.info ## lvl1.field1 = 0; \
TESTCALL(QueryUserInfo, q); \
- u = *q.out.info; \
+ u = *info; \
INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \
q.in.level = lvl2; \
TESTCALL(QueryUserInfo, q) \
- u = *q.out.info; \
+ u = *info; \
INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \
} while (0)
@@ -359,10 +404,10 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14",
SAMR_FIELD_WORKSTATIONS);
- TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
- TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters",
+ TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0);
+ TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters",
SAMR_FIELD_PARAMETERS);
- TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters",
+ TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters",
SAMR_FIELD_PARAMETERS);
TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0);
@@ -466,12 +511,19 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx
/*
generate a random password for password change tests
*/
-static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
+static char *samr_rand_pass_silent(TALLOC_CTX *mem_ctx, int min_len)
{
size_t len = MAX(8, min_len) + (random() % 6);
char *s = generate_random_str(mem_ctx, len);
+ return s;
+}
+
+static char *samr_rand_pass(TALLOC_CTX *mem_ctx, int min_len)
+{
+ char *s = samr_rand_pass_silent(mem_ctx, min_len);
printf("Generated password '%s'\n", s);
return s;
+
}
/*
@@ -512,12 +564,14 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx
DATA_BLOB session_key;
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -526,8 +580,7 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx
s.in.level = 24;
encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
- /* w2k3 ignores this length */
- u.info24.pw_len = strlen_m(newpass) * 2;
+ u.info24.password_expired = 0;
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -564,12 +617,14 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t
DATA_BLOB session_key;
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -643,12 +698,14 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc
char *newpass;
struct MD5Context ctx;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
if (makeshort && policy_min_pw_len) {
newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1);
@@ -661,7 +718,7 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc
s.in.level = 26;
encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
- u.info26.pw_len = strlen(newpass);
+ u.info26.password_expired = 0;
status = dcerpc_fetch_session_key(p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
@@ -725,12 +782,14 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t
uint8_t confounder[16];
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
pwp.in.user_handle = handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -790,12 +849,161 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t
return ret;
}
+static bool test_SetUserPass_level_ex(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *handle,
+ uint16_t level,
+ uint32_t fields_present,
+ char **password, uint8_t password_expired,
+ bool use_setinfo2, NTSTATUS expected_error)
+{
+ NTSTATUS status;
+ struct samr_SetUserInfo s;
+ struct samr_SetUserInfo2 s2;
+ union samr_UserInfo u;
+ bool ret = true;
+ DATA_BLOB session_key;
+ DATA_BLOB confounded_session_key = data_blob_talloc(tctx, NULL, 16);
+ struct MD5Context ctx;
+ uint8_t confounder[16];
+ char *newpass;
+ struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
+ int policy_min_pw_len = 0;
+ const char *comment = NULL;
+
+ pwp.in.user_handle = handle;
+ pwp.out.info = &info;
+
+ status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
+ if (NT_STATUS_IS_OK(status)) {
+ policy_min_pw_len = pwp.out.info->min_password_length;
+ }
+ newpass = samr_rand_pass_silent(tctx, policy_min_pw_len);
+
+ if (use_setinfo2) {
+ s2.in.user_handle = handle;
+ s2.in.info = &u;
+ s2.in.level = level;
+ } else {
+ s.in.user_handle = handle;
+ s.in.info = &u;
+ s.in.level = level;
+ }
+
+ if (fields_present & SAMR_FIELD_COMMENT) {
+ comment = talloc_asprintf(tctx, "comment: %d\n", time(NULL));
+ }
+
+ ZERO_STRUCT(u);
+
+ switch (level) {
+ case 21:
+ u.info21.fields_present = fields_present;
+ u.info21.password_expired = password_expired;
+ u.info21.comment.string = comment;
+
+ break;
+ case 23:
+ u.info23.info.fields_present = fields_present;
+ u.info23.info.password_expired = password_expired;
+ u.info23.info.comment.string = comment;
+
+ encode_pw_buffer(u.info23.password.data, newpass, STR_UNICODE);
+
+ break;
+ case 24:
+ u.info24.password_expired = password_expired;
+
+ encode_pw_buffer(u.info24.password.data, newpass, STR_UNICODE);
+
+ break;
+ case 25:
+ u.info25.info.fields_present = fields_present;
+ u.info25.info.password_expired = password_expired;
+ u.info25.info.comment.string = comment;
+
+ encode_pw_buffer(u.info25.password.data, newpass, STR_UNICODE);
+
+ break;
+ case 26:
+ u.info26.password_expired = password_expired;
+
+ encode_pw_buffer(u.info26.password.data, newpass, STR_UNICODE);
+
+ break;
+ }
+
+ status = dcerpc_fetch_session_key(p, &session_key);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetUserInfo level %u - no session key - %s\n",
+ s.in.level, nt_errstr(status));
+ return false;
+ }
+
+ generate_random_buffer((uint8_t *)confounder, 16);
+
+ MD5Init(&ctx);
+ MD5Update(&ctx, confounder, 16);
+ MD5Update(&ctx, session_key.data, session_key.length);
+ MD5Final(confounded_session_key.data, &ctx);
+
+ switch (level) {
+ case 23:
+ arcfour_crypt_blob(u.info23.password.data, 516, &session_key);
+ break;
+ case 24:
+ arcfour_crypt_blob(u.info24.password.data, 516, &session_key);
+ break;
+ case 25:
+ arcfour_crypt_blob(u.info25.password.data, 516, &confounded_session_key);
+ memcpy(&u.info25.password.data[516], confounder, 16);
+ break;
+ case 26:
+ arcfour_crypt_blob(u.info26.password.data, 516, &confounded_session_key);
+ memcpy(&u.info26.password.data[516], confounder, 16);
+ break;
+ }
+
+ if (use_setinfo2) {
+ status = dcerpc_samr_SetUserInfo2(p, tctx, &s2);
+ } else {
+ status = dcerpc_samr_SetUserInfo(p, tctx, &s);
+ }
+
+ if (!NT_STATUS_IS_OK(expected_error)) {
+ if (use_setinfo2) {
+ torture_assert_ntstatus_equal(tctx,
+ s2.out.result,
+ expected_error, "SetUserInfo2 failed");
+ } else {
+ torture_assert_ntstatus_equal(tctx,
+ s.out.result,
+ expected_error, "SetUserInfo failed");
+ }
+ return true;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("SetUserInfo%s level %u failed - %s\n",
+ use_setinfo2 ? "2":"", level, nt_errstr(status));
+ ret = false;
+ } else {
+ if (level != 21) {
+ *password = newpass;
+ }
+ }
+
+ return ret;
+}
+
static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle)
{
NTSTATUS status;
struct samr_SetAliasInfo r;
struct samr_QueryAliasInfo q;
+ union samr_AliasInfo *info;
uint16_t levels[] = {2, 3};
int i;
bool ret = true;
@@ -826,6 +1034,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct
q.in.alias_handle = handle;
q.in.level = levels[i];
+ q.out.info = &info;
status = dcerpc_samr_QueryAliasInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -842,11 +1051,13 @@ static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context
struct policy_handle *user_handle)
{
struct samr_GetGroupsForUser r;
+ struct samr_RidWithAttributeArray *rids = NULL;
NTSTATUS status;
torture_comment(tctx, "testing GetGroupsForUser\n");
r.in.user_handle = user_handle;
+ r.out.rids = &rids;
status = dcerpc_samr_GetGroupsForUser(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser");
@@ -860,8 +1071,11 @@ static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tct
{
NTSTATUS status;
struct samr_GetDomPwInfo r;
+ struct samr_PwInfo info;
r.in.domain_name = domain_name;
+ r.out.info = &info;
+
torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string);
status = dcerpc_samr_GetDomPwInfo(p, tctx, &r);
@@ -893,10 +1107,12 @@ static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tc
{
NTSTATUS status;
struct samr_GetUserPwInfo r;
+ struct samr_PwInfo info;
torture_comment(tctx, "Testing GetUserPwInfo\n");
r.in.user_handle = handle;
+ r.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo");
@@ -911,15 +1127,18 @@ static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *t
NTSTATUS status;
struct samr_LookupNames n;
struct lsa_String sname[2];
+ struct samr_Ids rids, types;
init_lsa_String(&sname[0], name);
n.in.domain_handle = domain_handle;
n.in.num_names = 1;
n.in.names = sname;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, tctx, &n);
if (NT_STATUS_IS_OK(status)) {
- *rid = n.out.rids.ids[0];
+ *rid = n.out.rids->ids[0];
} else {
return status;
}
@@ -1071,6 +1290,7 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
char *newpass;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle);
@@ -1078,10 +1298,11 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex
return false;
}
pwp.in.user_handle = &user_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1346,12 +1567,14 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
uint8_t old_lm_hash[16], new_lm_hash[16];
struct samr_GetDomPwInfo dom_pw_info;
+ struct samr_PwInfo info;
int policy_min_pw_len = 0;
struct lsa_String domain_name;
domain_name.string = "";
dom_pw_info.in.domain_name = &domain_name;
+ dom_pw_info.out.info = &info;
torture_comment(tctx, "Testing OemChangePasswordUser2\n");
@@ -1362,7 +1585,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co
status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+ policy_min_pw_len = dom_pw_info.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1515,11 +1738,13 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
uint8_t old_lm_hash[16], new_lm_hash[16];
struct samr_GetDomPwInfo dom_pw_info;
+ struct samr_PwInfo info;
struct lsa_String domain_name;
domain_name.string = "";
dom_pw_info.in.domain_name = &domain_name;
+ dom_pw_info.out.info = &info;
torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name);
@@ -1531,7 +1756,7 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte
int policy_min_pw_len = 0;
status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = dom_pw_info.out.info.min_password_length;
+ policy_min_pw_len = dom_pw_info.out.info->min_password_length;
}
newpass = samr_rand_pass(tctx, policy_min_pw_len);
@@ -1594,6 +1819,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
uint8_t old_nt_hash[16], new_nt_hash[16];
uint8_t old_lm_hash[16], new_lm_hash[16];
NTTIME t;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
torture_comment(tctx, "Testing ChangePasswordUser3\n");
@@ -1641,6 +1868,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1670,6 +1899,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) &&
@@ -1712,21 +1943,23 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
r.in.lm_password = &lm_pass;
r.in.lm_verifier = &lm_verifier;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)
- && r.out.dominfo
- && r.out.reject
+ && dominfo
+ && reject
&& handle_reject_reason
- && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) {
- if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
+ && (!null_nttime(last_password_change) || !dominfo->min_password_age)) {
+ if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) {
- if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) {
+ if (reject && (reject->reason != SAMR_REJECT_OTHER)) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
}
@@ -1740,54 +1973,54 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct
Guenther */
- if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
- (last_password_change + r.out.dominfo->min_password_age > t)) {
+ if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) &&
+ (last_password_change + dominfo->min_password_age > t)) {
- if (r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
- } else if ((r.out.dominfo->min_password_length > 0) &&
- (strlen(newpass) < r.out.dominfo->min_password_length)) {
+ } else if ((dominfo->min_password_length > 0) &&
+ (strlen(newpass) < dominfo->min_password_length)) {
- if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) {
+ if (reject->reason != SAMR_REJECT_TOO_SHORT) {
printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n",
- SAMR_REJECT_TOO_SHORT, r.out.reject->reason);
+ SAMR_REJECT_TOO_SHORT, reject->reason);
return false;
}
- } else if ((r.out.dominfo->password_history_length > 0) &&
+ } else if ((dominfo->password_history_length > 0) &&
strequal(oldpass, newpass)) {
- if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) {
+ if (reject->reason != SAMR_REJECT_IN_HISTORY) {
printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n",
- SAMR_REJECT_IN_HISTORY, r.out.reject->reason);
+ SAMR_REJECT_IN_HISTORY, reject->reason);
return false;
}
- } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
+ } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) {
- if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) {
+ if (reject->reason != SAMR_REJECT_COMPLEXITY) {
printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n",
- SAMR_REJECT_COMPLEXITY, r.out.reject->reason);
+ SAMR_REJECT_COMPLEXITY, reject->reason);
return false;
}
}
- if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) {
+ if (reject->reason == SAMR_REJECT_TOO_SHORT) {
/* retry with adjusted size */
return test_ChangePasswordUser3(p, tctx, account_string,
- r.out.dominfo->min_password_length,
+ dominfo->min_password_length,
password, NULL, 0, false);
}
} else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -1823,6 +2056,8 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
char *oldpass;
uint8_t old_nt_hash[16], new_nt_hash[16];
NTTIME t;
+ struct samr_DomInfo1 *dominfo = NULL;
+ struct samr_ChangeReject *reject = NULL;
new_random_pass = samr_very_rand_pass(tctx, 128);
@@ -1889,15 +2124,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
r.in.lm_password = NULL;
r.in.lm_verifier = NULL;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -1925,15 +2162,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex
r.in.lm_password = NULL;
r.in.lm_verifier = NULL;
r.in.password3 = NULL;
+ r.out.dominfo = &dominfo;
+ r.out.reject = &reject;
unix_to_nt_time(&t, time(NULL));
status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r);
if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) {
- if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) {
+ if (reject && reject->reason != SAMR_REJECT_OTHER) {
printf("expected SAMR_REJECT_OTHER (%d), got %d\n",
- SAMR_REJECT_OTHER, r.out.reject->reason);
+ SAMR_REJECT_OTHER, reject->reason);
return false;
}
/* Perhaps the server has a 'min password age' set? */
@@ -2051,6 +2290,486 @@ static bool test_TestPrivateFunctionsUser(struct dcerpc_pipe *p, struct torture_
return true;
}
+static bool test_QueryUserInfo_pwdlastset(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *handle,
+ bool use_info2,
+ NTTIME *pwdlastset)
+{
+ NTSTATUS status;
+ uint16_t levels[] = { /* 3, */ 5, 21 };
+ int i;
+ NTTIME pwdlastset3 = 0;
+ NTTIME pwdlastset5 = 0;
+ NTTIME pwdlastset21 = 0;
+
+ torture_comment(tctx, "Testing QueryUserInfo%s level 5 and 21 call ",
+ use_info2 ? "2":"");
+
+ for (i=0; i<ARRAY_SIZE(levels); i++) {
+
+ struct samr_QueryUserInfo r;
+ struct samr_QueryUserInfo2 r2;
+ union samr_UserInfo *info;
+
+ if (use_info2) {
+ r2.in.user_handle = handle;
+ r2.in.level = levels[i];
+ r2.out.info = &info;
+ status = dcerpc_samr_QueryUserInfo2(p, tctx, &r2);
+
+ } else {
+ r.in.user_handle = handle;
+ r.in.level = levels[i];
+ r.out.info = &info;
+ status = dcerpc_samr_QueryUserInfo(p, tctx, &r);
+ }
+
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_INFO_CLASS)) {
+ printf("QueryUserInfo%s level %u failed - %s\n",
+ use_info2 ? "2":"", levels[i], nt_errstr(status));
+ return false;
+ }
+
+ switch (levels[i]) {
+ case 3:
+ pwdlastset3 = info->info3.last_password_change;
+ break;
+ case 5:
+ pwdlastset5 = info->info5.last_password_change;
+ break;
+ case 21:
+ pwdlastset21 = info->info21.last_password_change;
+ break;
+ default:
+ return false;
+ }
+ }
+ /* torture_assert_int_equal(tctx, pwdlastset3, pwdlastset5,
+ "pwdlastset mixup"); */
+ torture_assert_int_equal(tctx, pwdlastset5, pwdlastset21,
+ "pwdlastset mixup");
+
+ *pwdlastset = pwdlastset21;
+
+ torture_comment(tctx, "(pwdlastset: %lld)\n", *pwdlastset);
+
+ return true;
+}
+
+static bool test_SetPassword_level(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ struct policy_handle *handle,
+ uint16_t level,
+ uint32_t fields_present,
+ uint8_t password_expired,
+ NTSTATUS expected_error,
+ bool use_setinfo2,
+ char **password,
+ bool use_queryinfo2,
+ NTTIME *pwdlastset)
+{
+ const char *fields = NULL;
+ bool ret = true;
+
+ switch (level) {
+ case 21:
+ case 23:
+ case 25:
+ fields = talloc_asprintf(tctx, "(fields_present: 0x%08x)",
+ fields_present);
+ break;
+ default:
+ break;
+ }
+
+ torture_comment(tctx, "Testing SetUserInfo%s level %d call "
+ "(password_expired: %d) %s\n",
+ use_setinfo2 ? "2":"", level, password_expired,
+ fields ? fields : "");
+
+ switch (level) {
+ case 21:
+ case 23:
+ case 24:
+ case 25:
+ case 26:
+ if (!test_SetUserPass_level_ex(p, tctx, handle, level,
+ fields_present,
+ password,
+ password_expired,
+ use_setinfo2,
+ expected_error)) {
+ ret = false;
+ }
+ break;
+ default:
+ return false;
+ }
+
+ if (!test_QueryUserInfo_pwdlastset(p, tctx, handle,
+ use_queryinfo2,
+ pwdlastset)) {
+ ret = false;
+ }
+
+ return ret;
+}
+
+static bool test_SetPassword_pwdlastset(struct dcerpc_pipe *p,
+ struct torture_context *tctx,
+ uint32_t acct_flags,
+ struct policy_handle *handle,
+ char **password)
+{
+ int i, s = 0, q = 0;
+ bool ret = true;
+ int delay = 500000;
+ bool set_levels[] = { false, true };
+ bool query_levels[] = { false, true };
+
+ struct {
+ uint16_t level;
+ uint8_t password_expired_nonzero;
+ uint32_t fields_present;
+ bool query_info2;
+ bool set_info2;
+ NTSTATUS set_error;
+ } pwd_tests[] = {
+
+ /* level 21 */
+ {
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = 0,
+ .set_error = NT_STATUS_INVALID_PARAMETER
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_COMMENT,
+
+#if 0
+ /* FIXME */
+ },{
+ .level = 21,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_LAST_PWD_CHANGE,
+ .query_info2 = false,
+ .set_error = NT_STATUS_ACCESS_DENIED
+#endif
+
+ /* level 23 */
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
+ SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE |
+ SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_EXPIRED_FLAG,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2,
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_COMMENT,
+ },{
+ .level = 23,
+ .password_expired_nonzero = 1,
+ .fields_present = 0,
+ .set_error = NT_STATUS_INVALID_PARAMETER
+ },{
+
+ /* level 24 */
+
+ .level = 24,
+ .password_expired_nonzero = 1
+ },{
+ .level = 24,
+ .password_expired_nonzero = 24
+ },{
+
+ /* level 25 */
+
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_LAST_PWD_CHANGE,
+ .set_error = NT_STATUS_ACCESS_DENIED
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_EXPIRED_FLAG,
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2 |
+ SAMR_FIELD_EXPIRED_FLAG
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_PASSWORD |
+ SAMR_FIELD_PASSWORD2,
+ },{
+ .level = 25,
+ .password_expired_nonzero = 1,
+ .fields_present = SAMR_FIELD_COMMENT,
+ },{
+
+ /* level 26 */
+
+ .level = 26,
+ .password_expired_nonzero = 1
+ },{
+ .level = 26,
+ .password_expired_nonzero = 24
+ }
+ };
+
+ if (torture_setting_bool(tctx, "samba3", false)) {
+ delay = 1000000;
+ printf("Samba3 has second granularity, setting delay to: %d\n",
+ delay);
+ }
+
+ /* set to 1 to enable testing for all possible opcode
+ (SetUserInfo, SetUserInfo2, QueryUserInfo, QueryUserInfo2)
+ combinations */
+#if 0
+#define TEST_SET_LEVELS 1
+#define TEST_QUERY_LEVELS 1
+#endif
+ for (i=0; i<ARRAY_SIZE(pwd_tests); i++) {
+#ifdef TEST_SET_LEVELS
+ for (s=0; s<ARRAY_SIZE(set_levels); s++) {
+#endif
+#ifdef TEST_QUERY_LEVELS
+ for (q=0; q<ARRAY_SIZE(query_levels); q++) {
+#endif
+ NTTIME pwdlastset_old = 0;
+ NTTIME pwdlastset_new = 0;
+
+ torture_comment(tctx, "------------------------------\n"
+ "Testing pwdLastSet attribute for flags: 0x%08x "
+ "(s: %d (l: %d), q: %d)\n",
+ acct_flags, s, pwd_tests[i].level, q);
+
+ /* set #1 */
+
+ /* set a password and force password change (pwdlastset 0) by
+ * setting the password expired flag to a non-0 value */
+
+ if (!test_SetPassword_level(p, tctx, handle,
+ pwd_tests[i].level,
+ pwd_tests[i].fields_present,
+ pwd_tests[i].password_expired_nonzero,
+ pwd_tests[i].set_error,
+ set_levels[s],
+ password,
+ query_levels[q],
+ &pwdlastset_old)) {
+ ret = false;
+ }
+
+ if (!NT_STATUS_IS_OK(pwd_tests[i].set_error)) {
+ /* skipping on expected failure */
+ continue;
+ }
+
+ /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
+ * set without the SAMR_FIELD_EXPIRED_FLAG */
+
+ switch (pwd_tests[i].level) {
+ case 21:
+ case 23:
+ case 25:
+ if ((pwdlastset_new != 0) &&
+ !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
+ torture_comment(tctx, "not considering a non-0 "
+ "pwdLastSet as a an error as the "
+ "SAMR_FIELD_EXPIRED_FLAG has not "
+ "been set\n");
+ break;
+ }
+ default:
+ if (pwdlastset_new != 0) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected pwdLastSet 0 but got %lld\n",
+ pwdlastset_old);
+ ret = false;
+ }
+ break;
+ }
+
+ usleep(delay);
+
+ /* set #2 */
+
+ /* set a password, pwdlastset needs to get updated (increased
+ * value), password_expired value used here is 0 */
+
+ if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
+ pwd_tests[i].fields_present,
+ 0,
+ pwd_tests[i].set_error,
+ set_levels[s],
+ password,
+ query_levels[q],
+ &pwdlastset_new)) {
+
+ ret = false;
+ }
+
+ /* when a password has been changed, pwdlastset must not be 0 afterwards
+ * and must be larger then the old value */
+
+ switch (pwd_tests[i].level) {
+ case 21:
+ case 23:
+ case 25:
+
+ /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
+ * password has been changed, old and new pwdlastset
+ * need to be the same value */
+
+ if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
+ !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
+ (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
+ {
+ torture_assert_int_equal(tctx, pwdlastset_old,
+ pwdlastset_new, "pwdlastset must be equal");
+ break;
+ }
+ default:
+ if (pwdlastset_old >= pwdlastset_new) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected last pwdlastset (%lld) < new pwdlastset (%lld)\n",
+ pwdlastset_old, pwdlastset_new);
+ ret = false;
+ }
+ if (pwdlastset_new == 0) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected non-0 pwdlastset, got: %lld\n",
+ pwdlastset_new);
+ ret = false;
+ }
+ }
+
+ pwdlastset_old = pwdlastset_new;
+
+ usleep(delay);
+
+ /* set #3 */
+
+ /* set a password and force password change (pwdlastset 0) by
+ * setting the password expired flag to a non-0 value */
+
+ if (!test_SetPassword_level(p, tctx, handle, pwd_tests[i].level,
+ pwd_tests[i].fields_present,
+ pwd_tests[i].password_expired_nonzero,
+ pwd_tests[i].set_error,
+ set_levels[s],
+ password,
+ query_levels[q],
+ &pwdlastset_new)) {
+ ret = false;
+ }
+
+ /* pwdlastset must be 0 afterwards, except for a level 21, 23 and 25
+ * set without the SAMR_FIELD_EXPIRED_FLAG */
+
+ switch (pwd_tests[i].level) {
+ case 21:
+ case 23:
+ case 25:
+ if ((pwdlastset_new != 0) &&
+ !(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG)) {
+ torture_comment(tctx, "not considering a non-0 "
+ "pwdLastSet as a an error as the "
+ "SAMR_FIELD_EXPIRED_FLAG has not "
+ "been set\n");
+ break;
+ }
+
+ /* SAMR_FIELD_EXPIRED_FLAG has not been set and no
+ * password has been changed, old and new pwdlastset
+ * need to be the same value */
+
+ if (!(pwd_tests[i].fields_present & SAMR_FIELD_EXPIRED_FLAG) &&
+ !((pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD) ||
+ (pwd_tests[i].fields_present & SAMR_FIELD_PASSWORD2)))
+ {
+ torture_assert_int_equal(tctx, pwdlastset_old,
+ pwdlastset_new, "pwdlastset must be equal");
+ break;
+ }
+ default:
+
+ if (pwdlastset_old == pwdlastset_new) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected last pwdlastset (%lld) != new pwdlastset (%lld)\n",
+ pwdlastset_old, pwdlastset_new);
+ ret = false;
+ }
+
+ if (pwdlastset_new != 0) {
+ torture_warning(tctx, "pwdLastSet test failed: "
+ "expected pwdLastSet 0, got %lld\n",
+ pwdlastset_old);
+ ret = false;
+ }
+ break;
+ }
+#ifdef TEST_QUERY_LEVELS
+ }
+#endif
+#ifdef TEST_SET_LEVELS
+ }
+#endif
+ }
+
+#undef TEST_SET_LEVELS
+#undef TEST_QUERY_LEVELS
+
+ return ret;
+}
static bool test_user_ops(struct dcerpc_pipe *p,
struct torture_context *tctx,
@@ -2061,6 +2780,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
{
char *password = NULL;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
NTSTATUS status;
bool ret = true;
@@ -2143,7 +2863,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
ret = false;
}
}
-
+
for (i = 0; password_fields[i]; i++) {
if (!test_SetUserPass_23(p, tctx, user_handle, password_fields[i], &password)) {
ret = false;
@@ -2176,6 +2896,7 @@ static bool test_user_ops(struct dcerpc_pipe *p,
q.in.user_handle = user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2184,20 +2905,37 @@ static bool test_user_ops(struct dcerpc_pipe *p,
ret = false;
} else {
uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED);
- if ((q.out.info->info5.acct_flags) != expected_flags) {
+ if ((info->info5.acct_flags) != expected_flags) {
printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info5.acct_flags,
+ info->info5.acct_flags,
expected_flags);
ret = false;
}
- if (q.out.info->info5.rid != rid) {
+ if (info->info5.rid != rid) {
printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n",
- q.out.info->info5.rid, rid);
+ info->info5.rid, rid);
}
}
break;
+
+ case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
+
+ /* test last password change timestamp behaviour */
+ if (!test_SetPassword_pwdlastset(p, tctx, base_acct_flags,
+ user_handle, &password)) {
+ ret = false;
+ }
+
+ if (ret == true) {
+ torture_comment(tctx, "pwdLastSet test succeeded\n");
+ } else {
+ torture_warning(tctx, "pwdLastSet test failed\n");
+ }
+
+ break;
+
case TORTURE_SAMR_OTHER:
/* We just need the account to exist */
break;
@@ -2481,6 +3219,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
/* set samr_SetDomainInfo level 1 with min_length 5 */
{
struct samr_QueryDomainInfo r;
+ union samr_DomainInfo *info = NULL;
struct samr_SetDomainInfo s;
uint16_t len_old, len;
uint32_t pwd_prop_old;
@@ -2491,6 +3230,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = domain_handle;
r.in.level = 1;
+ r.out.info = &info;
printf("testing samr_QueryDomainInfo level 1\n");
status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r);
@@ -2500,7 +3240,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
s.in.domain_handle = domain_handle;
s.in.level = 1;
- s.in.info = r.out.info;
+ s.in.info = info;
/* remember the old min length, so we can reset it */
len_old = s.in.info->info1.min_password_length;
@@ -2540,13 +3280,17 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_LookupNames n;
struct policy_handle user_handle;
+ struct samr_Ids rids, types;
n.in.domain_handle = domain_handle;
n.in.num_names = 1;
n.in.names = talloc_array(mem_ctx, struct lsa_String, 1);
n.in.names[0].string = acct_name;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
if (!NT_STATUS_IS_OK(status)) {
@@ -2556,17 +3300,18 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = domain_handle;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r.in.rid = n.out.rids.ids[0];
+ r.in.rid = n.out.rids->ids[0];
r.out.user_handle = &user_handle;
status = dcerpc_samr_OpenUser(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
- printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status));
+ printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status));
return false;
}
q.in.user_handle = &user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2577,7 +3322,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("calling test_ChangePasswordUser3 with too early password change\n");
if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL,
- q.out.info->info5.last_password_change, true)) {
+ info->info5.last_password_change, true)) {
ret = false;
}
}
@@ -2607,6 +3352,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
NTSTATUS status;
struct samr_CreateUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_DeleteUser d;
uint32_t rid;
@@ -2654,6 +3400,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
} else {
q.in.user_handle = &user_handle;
q.in.level = 16;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2661,9 +3408,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx,
q.in.level, nt_errstr(status));
ret = false;
} else {
- if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) {
+ if ((info->info16.acct_flags & acct_flags) != acct_flags) {
printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info16.acct_flags,
+ info->info16.acct_flags,
acct_flags);
ret = false;
}
@@ -2705,6 +3452,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
NTSTATUS status;
struct samr_CreateUser2 r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct samr_DeleteUser d;
struct policy_handle user_handle;
uint32_t rid;
@@ -2783,6 +3531,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
if (NT_STATUS_IS_OK(status)) {
q.in.user_handle = &user_handle;
q.in.level = 5;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -2794,31 +3543,31 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx
if (acct_flags == ACB_NORMAL) {
expected_flags |= ACB_PW_EXPIRED;
}
- if ((q.out.info->info5.acct_flags) != expected_flags) {
+ if ((info->info5.acct_flags) != expected_flags) {
printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n",
- q.out.info->info5.acct_flags,
+ info->info5.acct_flags,
expected_flags);
ret = false;
}
switch (acct_flags) {
case ACB_SVRTRUST:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) {
+ if (info->info5.primary_gid != DOMAIN_RID_DCS) {
printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n",
- DOMAIN_RID_DCS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_DCS, info->info5.primary_gid);
ret = false;
}
break;
case ACB_WSTRUST:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
+ if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) {
printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n",
- DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid);
ret = false;
}
break;
case ACB_NORMAL:
- if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) {
+ if (info->info5.primary_gid != DOMAIN_RID_USERS) {
printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n",
- DOMAIN_RID_USERS, q.out.info->info5.primary_gid);
+ DOMAIN_RID_USERS, info->info5.primary_gid);
ret = false;
}
break;
@@ -2852,6 +3601,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryAliasInfo r;
+ union samr_AliasInfo *info;
uint16_t levels[] = {1, 2, 3};
int i;
bool ret = true;
@@ -2861,6 +3611,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.alias_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2878,6 +3629,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupInfo r;
+ union samr_GroupInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
bool ret = true;
@@ -2887,6 +3639,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.group_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2904,11 +3657,13 @@ static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupMember r;
+ struct samr_RidTypeArray *rids = NULL;
bool ret = true;
printf("Testing QueryGroupMember\n");
r.in.group_handle = handle;
+ r.out.rids = &rids;
status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2925,6 +3680,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryGroupInfo r;
+ union samr_GroupInfo *info;
struct samr_SetGroupInfo s;
uint16_t levels[] = {1, 2, 3, 4};
uint16_t set_ok[] = {0, 1, 1, 1};
@@ -2936,6 +3692,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.group_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -2948,7 +3705,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
s.in.group_handle = handle;
s.in.level = levels[i];
- s.in.info = r.out.info;
+ s.in.info = *r.out.info;
#if 0
/* disabled this, as it changes the name only from the point of view of samr,
@@ -2990,6 +3747,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryUserInfo r;
+ union samr_UserInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 16, 17, 20, 21};
int i;
@@ -3000,6 +3758,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.user_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3017,6 +3776,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
{
NTSTATUS status;
struct samr_QueryUserInfo2 r;
+ union samr_UserInfo *info;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 16, 17, 20, 21};
int i;
@@ -3027,6 +3787,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.user_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3174,6 +3935,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
NTSTATUS status;
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
bool ret = true;
@@ -3192,6 +3954,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
q.in.user_handle = &user_handle;
q.in.level = 16;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, tctx, &q);
if (!NT_STATUS_IS_OK(status)) {
@@ -3199,9 +3962,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx,
nt_errstr(status));
ret = false;
} else {
- if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) {
+ if ((acct_flag_mask & info->info16.acct_flags) == 0) {
printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n",
- acct_flag_mask, q.out.info->info16.acct_flags, rid);
+ acct_flag_mask, info->info16.acct_flags, rid);
ret = false;
}
}
@@ -3223,6 +3986,11 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
bool ret = true;
struct samr_LookupNames n;
struct samr_LookupRids lr ;
+ struct lsa_Strings names;
+ struct samr_Ids rids, types;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
+
uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST,
ACB_DISABLED, ACB_NORMAL | ACB_DISABLED,
ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST,
@@ -3236,6 +4004,8 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
r.in.acct_flags = mask = masks[mask_idx];
r.in.max_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomainUsers(p, tctx, &r);
if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) &&
@@ -3244,18 +4014,18 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
return false;
}
- torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
+ torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL");
- if (r.out.sam->count == 0) {
+ if (sam->count == 0) {
continue;
}
- for (i=0;i<r.out.sam->count;i++) {
+ for (i=0;i<sam->count;i++) {
if (mask) {
- if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) {
+ if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) {
ret = false;
}
- } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) {
+ } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3263,10 +4033,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
printf("Testing LookupNames\n");
n.in.domain_handle = handle;
- n.in.num_names = r.out.sam->count;
- n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count);
- for (i=0;i<r.out.sam->count;i++) {
- n.in.names[i].string = r.out.sam->entries[i].name.string;
+ n.in.num_names = sam->count;
+ n.in.names = talloc_array(tctx, struct lsa_String, sam->count);
+ n.out.rids = &rids;
+ n.out.types = &types;
+ for (i=0;i<sam->count;i++) {
+ n.in.names[i].string = sam->entries[i].name.string;
}
status = dcerpc_samr_LookupNames(p, tctx, &n);
if (!NT_STATUS_IS_OK(status)) {
@@ -3277,10 +4049,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context *
printf("Testing LookupRids\n");
lr.in.domain_handle = handle;
- lr.in.num_rids = r.out.sam->count;
- lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count);
- for (i=0;i<r.out.sam->count;i++) {
- lr.in.rids[i] = r.out.sam->entries[i].idx;
+ lr.in.num_rids = sam->count;
+ lr.in.rids = talloc_array(tctx, uint32_t, sam->count);
+ lr.out.names = &names;
+ lr.out.types = &types;
+ for (i=0;i<sam->count;i++) {
+ lr.in.rids[i] = sam->entries[i].idx;
}
status = dcerpc_samr_LookupRids(p, tctx, &lr);
torture_assert_ntstatus_ok(tctx, status, "LookupRids");
@@ -3337,6 +4111,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_EnumDomainGroups r;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
@@ -3346,6 +4122,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.resume_handle = &resume_handle;
r.in.max_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3353,12 +4131,12 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- if (!r.out.sam) {
+ if (!sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
- if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+ for (i=0;i<sam->count;i++) {
+ if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3372,6 +4150,8 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_EnumDomainAliases r;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
@@ -3379,7 +4159,9 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.domain_handle = handle;
r.in.resume_handle = &resume_handle;
- r.in.acct_flags = (uint32_t)-1;
+ r.in.max_size = (uint32_t)-1;
+ r.out.sam = &sam;
+ r.out.num_entries = &num_entries;
r.out.resume_handle = &resume_handle;
status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r);
@@ -3388,12 +4170,12 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return false;
}
- if (!r.out.sam) {
+ if (!sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
- if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) {
+ for (i=0;i<sam->count;i++) {
+ if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) {
ret = false;
}
}
@@ -3409,14 +4191,19 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+ struct lsa_String name;
+ uint32_t idx = 0;
int i;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]);
+ init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
r.in.domain_handle = handle;
r.in.level = levels[i];
- init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+ r.in.name = &name;
+ r.out.idx = &idx;
status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
@@ -3428,7 +4215,7 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m
ret = false;
}
- init_lsa_String(&r.in.name, "zzzzzzzz");
+ init_lsa_String(&name, "zzzzzzzz");
status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r);
@@ -3450,14 +4237,19 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
uint16_t ok_lvl[] = {1, 1, 1, 0, 0};
+ struct lsa_String name;
+ uint32_t idx = 0;
int i;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]);
+ init_lsa_String(&name, TEST_ACCOUNT_NAME);
+
r.in.domain_handle = handle;
r.in.level = levels[i];
- init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME);
+ r.in.name = &name;
+ r.out.idx = &idx;
status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
if (ok_lvl[i] &&
@@ -3468,7 +4260,7 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX *
ret = false;
}
- init_lsa_String(&r.in.name, "zzzzzzzz");
+ init_lsa_String(&name, "zzzzzzzz");
status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r);
if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) {
@@ -3502,6 +4294,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
{
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
int i, ret = true;
NTSTATUS status;
@@ -3510,16 +4303,16 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
for (i = 0; ; i++) {
switch (querydisplayinfo->in.level) {
case 1:
- if (i >= querydisplayinfo->out.info.info1.count) {
+ if (i >= querydisplayinfo->out.info->info1.count) {
return ret;
}
- r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid;
+ r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid;
break;
case 2:
- if (i >= querydisplayinfo->out.info.info2.count) {
+ if (i >= querydisplayinfo->out.info->info2.count) {
return ret;
}
- r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid;
+ r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid;
break;
case 3:
/* Groups */
@@ -3543,6 +4336,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
q.in.user_handle = &user_handle;
q.in.level = 21;
+ q.out.info = &info;
status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q);
if (!NT_STATUS_IS_OK(status)) {
printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status));
@@ -3551,41 +4345,41 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
switch (querydisplayinfo->in.level) {
case 1:
- if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
+ if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) {
*seen_testuser = true;
}
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name,
- q.out.info->info21.full_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name,
- q.out.info->info21.account_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description,
- q.out.info->info21.description, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid,
- q.out.info->info21.rid, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags,
- q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name,
+ info->info21.full_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name,
+ info->info21.account_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description,
+ info->info21.description, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid,
+ info->info21.rid, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags,
+ info->info21.acct_flags, info->info21.account_name);
break;
case 2:
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name,
- q.out.info->info21.account_name, q.out.info->info21.account_name);
- STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description,
- q.out.info->info21.description, q.out.info->info21.account_name);
- INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid,
- q.out.info->info21.rid, q.out.info->info21.account_name);
- INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL),
- q.out.info->info21.acct_flags, q.out.info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name,
+ info->info21.account_name, info->info21.account_name);
+ STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description,
+ info->info21.description, info->info21.account_name);
+ INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid,
+ info->info21.rid, info->info21.account_name);
+ INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL),
+ info->info21.acct_flags, info->info21.account_name);
- if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) {
+ if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) {
printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n",
- q.out.info->info21.account_name.string);
+ info->info21.account_name.string);
}
- if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
+ if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) {
printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n",
- q.out.info->info21.account_name.string,
- querydisplayinfo->out.info.info2.entries[i].acct_flags,
- q.out.info->info21.acct_flags);
+ info->info21.account_name.string,
+ querydisplayinfo->out.info->info2.entries[i].acct_flags,
+ info->info21.acct_flags);
return false;
}
@@ -3605,10 +4399,15 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
NTSTATUS status;
struct samr_QueryDisplayInfo r;
struct samr_QueryDomainInfo dom_info;
+ union samr_DomainInfo *info = NULL;
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
bool seen_testuser = false;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo disp_info;
+
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing QueryDisplayInfo level %u\n", levels[i]);
@@ -3620,6 +4419,9 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.level = levels[i];
r.in.max_entries = 2;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &disp_info;
status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) {
@@ -3632,27 +4434,29 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) {
ret = false;
}
- r.in.start_idx += r.out.info.info1.count;
+ r.in.start_idx += r.out.info->info1.count;
break;
case 2:
if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) {
ret = false;
}
- r.in.start_idx += r.out.info.info2.count;
+ r.in.start_idx += r.out.info->info2.count;
break;
case 3:
- r.in.start_idx += r.out.info.info3.count;
+ r.in.start_idx += r.out.info->info3.count;
break;
case 4:
- r.in.start_idx += r.out.info.info4.count;
+ r.in.start_idx += r.out.info->info4.count;
break;
case 5:
- r.in.start_idx += r.out.info.info5.count;
+ r.in.start_idx += r.out.info->info5.count;
break;
}
}
dom_info.in.domain_handle = handle;
dom_info.in.level = 2;
+ dom_info.out.info = &info;
+
/* Check number of users returned is correct */
status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info);
if (!NT_STATUS_IS_OK(status)) {
@@ -3664,17 +4468,17 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
switch (r.in.level) {
case 1:
case 4:
- if (dom_info.out.info->general.num_users < r.in.start_idx) {
+ if (info->general.num_users < r.in.start_idx) {
printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n",
- r.in.start_idx, dom_info.out.info->general.num_groups,
- dom_info.out.info->general.domain_name.string);
+ r.in.start_idx, info->general.num_groups,
+ info->general.domain_name.string);
ret = false;
}
if (!seen_testuser) {
struct policy_handle user_handle;
if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) {
printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n",
- dom_info.out.info->general.domain_name.string);
+ info->general.domain_name.string);
ret = false;
test_samr_handle_Close(p, mem_ctx, &user_handle);
}
@@ -3682,10 +4486,10 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
break;
case 3:
case 5:
- if (dom_info.out.info->general.num_groups != r.in.start_idx) {
+ if (info->general.num_groups != r.in.start_idx) {
printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n",
- r.in.start_idx, dom_info.out.info->general.num_groups,
- dom_info.out.info->general.domain_name.string);
+ r.in.start_idx, info->general.num_groups,
+ info->general.domain_name.string);
ret = false;
}
@@ -3705,6 +4509,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
for (i=0;i<ARRAY_SIZE(levels);i++) {
printf("Testing QueryDisplayInfo2 level %u\n", levels[i]);
@@ -3714,6 +4521,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.start_idx = 0;
r.in.max_entries = 1000;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3734,6 +4544,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
bool ret = true;
uint16_t levels[] = {1, 2, 3, 4, 5};
int i;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
for (i=0;i<ARRAY_SIZE(levels);i++) {
torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]);
@@ -3743,6 +4556,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context
r.in.start_idx = 0;
r.in.max_entries = 1000;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3762,6 +4578,9 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
NTSTATUS status;
struct samr_QueryDisplayInfo r;
bool ret = true;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
printf("Testing QueryDisplayInfo continuation\n");
@@ -3770,14 +4589,17 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
r.in.start_idx = 0;
r.in.max_entries = 1;
r.in.buf_size = (uint32_t)-1;
+ r.out.total_size = &total_size;
+ r.out.returned_size = &returned_size;
+ r.out.info = &info;
do {
status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r);
- if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) {
- if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) {
+ if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) {
+ if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) {
printf("expected idx %d but got %d\n",
r.in.start_idx + 1,
- r.out.info.info1.entries[0].idx);
+ r.out.info->info1.entries[0].idx);
break;
}
}
@@ -3791,7 +4613,7 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me
r.in.start_idx++;
} while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) ||
NT_STATUS_IS_OK(status)) &&
- r.out.returned_size != 0);
+ *r.out.returned_size != 0);
return ret;
}
@@ -3801,6 +4623,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
{
NTSTATUS status;
struct samr_QueryDomainInfo r;
+ union samr_DomainInfo *info = NULL;
struct samr_SetDomainInfo s;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0};
@@ -3827,6 +4650,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
r.in.domain_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryDomainInfo(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3838,40 +4662,40 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
switch (levels[i]) {
case 2:
- if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
- levels[i], r.out.info->general.oem_information.string, domain_comment);
+ levels[i], info->general.oem_information.string, domain_comment);
ret = false;
}
- if (!r.out.info->general.primary.string) {
+ if (!info->general.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = false;
- } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) {
- if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) {
+ } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) {
+ if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) {
printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n",
- levels[i], r.out.info->general.primary.string, dcerpc_server_name(p));
+ levels[i], info->general.primary.string, dcerpc_server_name(p));
}
}
break;
case 4:
- if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->oem.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n",
- levels[i], r.out.info->oem.oem_information.string, domain_comment);
+ levels[i], info->oem.oem_information.string, domain_comment);
ret = false;
}
break;
case 6:
- if (!r.out.info->info6.primary.string) {
+ if (!info->info6.primary.string) {
printf("QueryDomainInfo level %u returned no PDC name\n",
levels[i]);
ret = false;
}
break;
case 11:
- if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) {
+ if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) {
printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n",
- levels[i], r.out.info->general2.general.oem_information.string, domain_comment);
+ levels[i], info->general2.general.oem_information.string, domain_comment);
ret = false;
}
break;
@@ -3881,7 +4705,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context *
s.in.domain_handle = handle;
s.in.level = levels[i];
- s.in.info = r.out.info;
+ s.in.info = info;
status = dcerpc_samr_SetDomainInfo(p, tctx, &s);
if (set_ok[i]) {
@@ -3918,6 +4742,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
{
NTSTATUS status;
struct samr_QueryDomainInfo2 r;
+ union samr_DomainInfo *info = NULL;
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
int i;
bool ret = true;
@@ -3927,6 +4752,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context
r.in.domain_handle = handle;
r.in.level = levels[i];
+ r.out.info = &info;
status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -3949,8 +4775,13 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_QueryDisplayInfo q2;
NTSTATUS status;
uint32_t resume_handle=0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
int i;
bool ret = true;
+ uint32_t total_size;
+ uint32_t returned_size;
+ union samr_DispInfo info;
int num_names = 0;
const char **names = NULL;
@@ -3961,6 +4792,8 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
q1.in.resume_handle = &resume_handle;
q1.in.max_size = 5;
q1.out.resume_handle = &resume_handle;
+ q1.out.num_entries = &num_entries;
+ q1.out.sam = &sam;
status = STATUS_MORE_ENTRIES;
while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3970,22 +4803,25 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
break;
- for (i=0; i<q1.out.num_entries; i++) {
+ for (i=0; i<*q1.out.num_entries; i++) {
add_string_to_array(tctx,
- q1.out.sam->entries[i].name.string,
+ sam->entries[i].name.string,
&names, &num_names);
}
}
torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups");
- torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam");
+ torture_assert(tctx, sam, "EnumDomainGroups failed to return sam");
q2.in.domain_handle = handle;
q2.in.level = 5;
q2.in.start_idx = 0;
q2.in.max_entries = 5;
q2.in.buf_size = (uint32_t)-1;
+ q2.out.total_size = &total_size;
+ q2.out.returned_size = &returned_size;
+ q2.out.info = &info;
status = STATUS_MORE_ENTRIES;
while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
@@ -3995,9 +4831,9 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES))
break;
- for (i=0; i<q2.out.info.info5.count; i++) {
+ for (i=0; i<q2.out.info->info5.count; i++) {
int j;
- const char *name = q2.out.info.info5.entries[i].account_name.string;
+ const char *name = q2.out.info->info5.entries[i].account_name.string;
bool found = false;
for (j=0; j<num_names; j++) {
if (names[j] == NULL)
@@ -4015,7 +4851,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx,
ret = false;
}
}
- q2.in.start_idx += q2.out.info.info5.count;
+ q2.in.start_idx += q2.out.info->info5.count;
}
if (!NT_STATUS_IS_OK(status)) {
@@ -4076,7 +4912,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_RidToSid r;
NTSTATUS status;
bool ret = true;
- struct dom_sid *calc_sid;
+ struct dom_sid *calc_sid, *out_sid;
int rids[] = { 0, 42, 512, 10200 };
int i;
@@ -4086,6 +4922,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
calc_sid = dom_sid_dup(tctx, domain_sid);
r.in.domain_handle = domain_handle;
r.in.rid = rids[i];
+ r.out.sid = &out_sid;
status = dcerpc_samr_RidToSid(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -4094,9 +4931,9 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx,
} else {
calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]);
- if (!dom_sid_equal(calc_sid, r.out.sid)) {
+ if (!dom_sid_equal(calc_sid, out_sid)) {
printf("RidToSid for %d failed - got %s, expected %s\n", rids[i],
- dom_sid_string(tctx, r.out.sid),
+ dom_sid_string(tctx, out_sid),
dom_sid_string(tctx, calc_sid));
ret = false;
}
@@ -4112,10 +4949,12 @@ static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_con
struct samr_GetBootKeyInformation r;
NTSTATUS status;
bool ret = true;
+ uint32_t unknown = 0;
torture_comment(tctx, "Testing GetBootKeyInformation\n");
r.in.domain_handle = domain_handle;
+ r.out.unknown = &unknown;
status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -4134,6 +4973,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
struct samr_AddGroupMember r;
struct samr_DeleteGroupMember d;
struct samr_QueryGroupMember q;
+ struct samr_RidTypeArray *rids = NULL;
struct samr_SetMemberAttributesOfGroup s;
uint32_t rid;
@@ -4173,6 +5013,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t
}
q.in.group_handle = group_handle;
+ q.out.rids = &rids;
status = dcerpc_samr_QueryGroupMember(p, tctx, &q);
torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember");
@@ -4312,6 +5153,7 @@ static bool test_OpenDomain(struct dcerpc_pipe *p, struct torture_context *tctx,
switch (which_ops) {
case TORTURE_SAMR_USER_ATTRIBUTES:
case TORTURE_SAMR_PASSWORDS:
+ case TORTURE_SAMR_PASSWORDS_PWDLASTSET:
ret &= test_CreateUser2(p, tctx, &domain_handle, sid, which_ops);
ret &= test_CreateUser(p, tctx, &domain_handle, &user_handle, sid, which_ops);
/* This test needs 'complex' users to validate */
@@ -4388,6 +5230,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
{
NTSTATUS status;
struct samr_LookupDomain r;
+ struct dom_sid2 *sid = NULL;
struct lsa_String n1;
struct lsa_String n2;
bool ret = true;
@@ -4397,6 +5240,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
/* check for correct error codes */
r.in.connect_handle = handle;
r.in.domain_name = &n2;
+ r.out.sid = &sid;
n2.string = NULL;
status = dcerpc_samr_LookupDomain(p, tctx, &r);
@@ -4419,7 +5263,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct
ret = false;
}
- if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) {
+ if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) {
ret = false;
}
@@ -4433,6 +5277,8 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
NTSTATUS status;
struct samr_EnumDomains r;
uint32_t resume_handle = 0;
+ uint32_t num_entries = 0;
+ struct samr_SamArray *sam = NULL;
int i;
bool ret = true;
@@ -4440,17 +5286,19 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx
r.in.resume_handle = &resume_handle;
r.in.buf_size = (uint32_t)-1;
r.out.resume_handle = &resume_handle;
+ r.out.num_entries = &num_entries;
+ r.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumDomains");
- if (!r.out.sam) {
+ if (!*r.out.sam) {
return false;
}
- for (i=0;i<r.out.sam->count;i++) {
+ for (i=0;i<sam->count;i++) {
if (!test_LookupDomain(p, tctx, handle,
- r.out.sam->entries[i].name.string, which_ops)) {
+ sam->entries[i].name.string, which_ops)) {
ret = false;
}
}
@@ -4473,6 +5321,7 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
struct samr_Connect5 r5;
union samr_ConnectInfo info;
struct policy_handle h;
+ uint32_t level_out = 0;
bool ret = true, got_handle = false;
torture_comment(tctx, "testing samr_Connect\n");
@@ -4553,9 +5402,10 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx,
r5.in.system_name = "";
r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- r5.in.level = 1;
- r5.in.info = &info;
- r5.out.info = &info;
+ r5.in.level_in = 1;
+ r5.out.level_out = &level_out;
+ r5.in.info_in = &info;
+ r5.out.info_out = &info;
r5.out.connect_handle = &h;
status = dcerpc_samr_Connect5(p, tctx, &r5);
@@ -4651,3 +5501,25 @@ bool torture_rpc_samr_passwords(struct torture_context *torture)
return ret;
}
+bool torture_rpc_samr_passwords_pwdlastset(struct torture_context *torture)
+{
+ NTSTATUS status;
+ struct dcerpc_pipe *p;
+ bool ret = true;
+ struct policy_handle handle;
+
+ status = torture_rpc_connection(torture, &p, &ndr_table_samr);
+ if (!NT_STATUS_IS_OK(status)) {
+ return false;
+ }
+
+ ret &= test_Connect(p, torture, &handle);
+
+ ret &= test_EnumDomains(p, torture, &handle,
+ TORTURE_SAMR_PASSWORDS_PWDLASTSET);
+
+ ret &= test_samr_handle_Close(p, torture, &handle);
+
+ return ret;
+}
+
diff --git a/source4/torture/rpc/samr_accessmask.c b/source4/torture/rpc/samr_accessmask.c
index bfff8c9267..9a8e442019 100644
--- a/source4/torture/rpc/samr_accessmask.c
+++ b/source4/torture/rpc/samr_accessmask.c
@@ -52,13 +52,15 @@ static NTSTATUS torture_samr_Connect5(struct torture_context *tctx,
NTSTATUS status;
struct samr_Connect5 r5;
union samr_ConnectInfo info;
+ uint32_t level_out = 0;
info.info1.client_version = 0;
info.info1.unknown2 = 0;
r5.in.system_name = "";
- r5.in.level = 1;
- r5.in.info = &info;
- r5.out.info = &info;
+ r5.in.level_in = 1;
+ r5.in.info_in = &info;
+ r5.out.info_out = &info;
+ r5.out.level_out = &level_out;
r5.out.connect_handle = h;
r5.in.access_mask = mask;
@@ -147,6 +149,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
int i;
uint32_t mask;
uint32_t resume_handle = 0;
+ struct samr_SamArray *sam = NULL;
+ uint32_t num_entries = 0;
printf("testing which bits in Connect5 accessmask allows us to EnumDomains\n");
mask = 1;
@@ -170,6 +174,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
ed.in.resume_handle = &resume_handle;
ed.in.buf_size = (uint32_t)-1;
ed.out.resume_handle = &resume_handle;
+ ed.out.num_entries = &num_entries;
+ ed.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
if (!NT_STATUS_IS_OK(status)) {
@@ -195,6 +201,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx,
ed.in.resume_handle = &resume_handle;
ed.in.buf_size = (uint32_t)-1;
ed.out.resume_handle = &resume_handle;
+ ed.out.num_entries = &num_entries;
+ ed.out.sam = &sam;
status = dcerpc_samr_EnumDomains(p, tctx, &ed);
if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) {
@@ -236,7 +244,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
struct samr_SetSecurity ss;
struct security_ace ace;
struct security_descriptor *sd;
- struct sec_desc_buf sdb;
+ struct sec_desc_buf sdb, *sdbuf = NULL;
bool ret = true;
int sd_size;
struct dcerpc_pipe *test_p;
@@ -255,6 +263,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
/* get the current ACL for the SAMR policy handle */
qs.in.handle = &ch;
qs.in.sec_info = SECINFO_DACL;
+ qs.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(p, tctx, &qs);
if (!NT_STATUS_IS_OK(status)) {
printf("QuerySecurity failed - %s\n", nt_errstr(status));
@@ -262,13 +271,13 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
}
/* how big is the security descriptor? */
- sd_size = qs.out.sdbuf->sd_size;
+ sd_size = sdbuf->sd_size;
/* add an ACE to the security descriptor to deny the user the
* 'connect to server' right
*/
- sd = qs.out.sdbuf->sd;
+ sd = sdbuf->sd;
ace.type = SEC_ACE_TYPE_ACCESS_DENIED;
ace.flags = 0;
ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER;
@@ -314,7 +323,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx,
printf("QuerySecurity failed - %s\n", nt_errstr(status));
ret = false;
}
- if (sd_size != qs.out.sdbuf->sd_size) {
+ if (sd_size != sdbuf->sd_size) {
printf("security descriptor changed\n");
ret = false;
}
@@ -387,6 +396,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct policy_handle ch;
struct lsa_String dn;
int i;
@@ -412,6 +422,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx,
ld.in.connect_handle = &ch;
ld.in.domain_name = &dn;
+ ld.out.sid = &sid;
dn.string = lp_workgroup(tctx->lp_ctx);
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
@@ -471,6 +482,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_LookupDomain ld;
+ struct dom_sid2 *sid = NULL;
struct samr_OpenDomain od;
struct policy_handle ch;
struct policy_handle dh;
@@ -488,6 +500,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
ld.in.connect_handle = &ch;
ld.in.domain_name = &dn;
+ ld.out.sid = &sid;
dn.string = lp_workgroup(tctx->lp_ctx);
status = dcerpc_samr_LookupDomain(p, tctx, &ld);
if (!NT_STATUS_IS_OK(status)) {
@@ -517,7 +530,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx,
od.in.connect_handle = &ch;
od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- od.in.sid = ld.out.sid;
+ od.in.sid = *ld.out.sid;
od.out.domain_handle = &dh;
status = dcerpc_samr_OpenDomain(p, tctx, &od);
diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c
index 12ddc934c9..a3fc6f740f 100644
--- a/source4/torture/rpc/samsync.c
+++ b/source4/torture/rpc/samsync.c
@@ -151,17 +151,19 @@ struct samsync_trusted_domain {
static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
struct samsync_state *samsync_state,
const char *domain,
- struct dom_sid **sid)
+ struct dom_sid **sid_p)
{
struct lsa_String name;
struct samr_OpenDomain o;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
struct policy_handle *domain_handle = talloc(mem_ctx, struct policy_handle);
NTSTATUS nt_status;
name.string = domain;
l.in.connect_handle = samsync_state->connect_handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
nt_status = dcerpc_samr_LookupDomain(samsync_state->p_samr, mem_ctx, &l);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -171,11 +173,11 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx,
o.in.connect_handle = samsync_state->connect_handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = domain_handle;
if (sid) {
- *sid = l.out.sid;
+ *sid_p = *l.out.sid;
}
nt_status = dcerpc_samr_OpenDomain(samsync_state->p_samr, mem_ctx, &o);
@@ -192,10 +194,12 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
struct policy_handle *handle)
{
struct samr_QuerySecurity r;
+ struct sec_desc_buf *sdbuf = NULL;
NTSTATUS status;
r.in.handle = handle;
r.in.sec_info = 0x7;
+ r.out.sdbuf = &sdbuf;
status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@@ -203,7 +207,7 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx,
return NULL;
}
- return r.out.sdbuf;
+ return sdbuf;
}
static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx,
@@ -260,6 +264,15 @@ static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx,
} \
} while (0)
+#define TEST_BINARY_STRING_EQUAL(s1, s2) do {\
+ if (!((!s1.array || s1.array[0]=='\0') && (!s2.array || s2.array[0]=='\0')) \
+ && memcmp(s1.array, s2.array, s1.length * 2) != 0) {\
+ printf("%s: string mismatch: " #s1 ":%s != " #s2 ": %s\n", \
+ __location__, (const char *)s1.array, (const char *)s2.array);\
+ ret = false;\
+ } \
+} while (0)
+
#define TEST_SID_EQUAL(s1, s2) do {\
if (!dom_sid_equal(s1, s2)) {\
printf("%s: dom_sid mismatch: " #s1 ":%s != " #s2 ": %s\n", \
@@ -294,6 +307,7 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
struct netr_DELTA_DOMAIN *domain = delta->delta_union.domain;
struct dom_sid *dom_sid;
struct samr_QueryDomainInfo q[14]; /* q[0] will be unused simple for clarity */
+ union samr_DomainInfo *info[14];
uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13};
NTSTATUS nt_status;
int i;
@@ -341,8 +355,10 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
(long long)samsync_state->seq_num[database_id]);
for (i=0;i<ARRAY_SIZE(levels);i++) {
+
q[levels[i]].in.domain_handle = samsync_state->domain_handle[database_id];
q[levels[i]].in.level = levels[i];
+ q[levels[i]].out.info = &info[levels[i]];
nt_status = dcerpc_samr_QueryDomainInfo(samsync_state->p_samr, mem_ctx, &q[levels[i]]);
@@ -353,23 +369,23 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam
}
}
- TEST_STRING_EQUAL(q[5].out.info->info5.domain_name, domain->domain_name);
+ TEST_STRING_EQUAL(info[5]->info5.domain_name, domain->domain_name);
- TEST_STRING_EQUAL(q[2].out.info->general.oem_information, domain->oem_information);
- TEST_STRING_EQUAL(q[4].out.info->oem.oem_information, domain->oem_information);
- TEST_TIME_EQUAL(q[2].out.info->general.force_logoff_time, domain->force_logoff_time);
- TEST_TIME_EQUAL(q[3].out.info->info3.force_logoff_time, domain->force_logoff_time);
+ TEST_STRING_EQUAL(info[2]->general.oem_information, domain->oem_information);
+ TEST_STRING_EQUAL(info[4]->oem.oem_information, domain->oem_information);
+ TEST_TIME_EQUAL(info[2]->general.force_logoff_time, domain->force_logoff_time);
+ TEST_TIME_EQUAL(info[3]->info3.force_logoff_time, domain->force_logoff_time);
- TEST_TIME_EQUAL(q[1].out.info->info1.min_password_length, domain->min_password_length);
- TEST_TIME_EQUAL(q[1].out.info->info1.password_history_length, domain->password_history_length);
- TEST_TIME_EQUAL(q[1].out.info->info1.max_password_age, domain->max_password_age);
- TEST_TIME_EQUAL(q[1].out.info->info1.min_password_age, domain->min_password_age);
+ TEST_TIME_EQUAL(info[1]->info1.min_password_length, domain->min_password_length);
+ TEST_TIME_EQUAL(info[1]->info1.password_history_length, domain->password_history_length);
+ TEST_TIME_EQUAL(info[1]->info1.max_password_age, domain->max_password_age);
+ TEST_TIME_EQUAL(info[1]->info1.min_password_age, domain->min_password_age);
- TEST_UINT64_EQUAL(q[8].out.info->info8.sequence_num,
+ TEST_UINT64_EQUAL(info[8]->info8.sequence_num,
domain->sequence_num);
- TEST_TIME_EQUAL(q[8].out.info->info8.domain_create_time,
+ TEST_TIME_EQUAL(info[8]->info8.domain_create_time,
domain->domain_create_time);
- TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time,
+ TEST_TIME_EQUAL(info[13]->info13.domain_create_time,
domain->domain_create_time);
TEST_SEC_DESC_EQUAL(domain->sdbuf, samr, samsync_state->domain_handle[database_id]);
@@ -425,9 +441,12 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
struct samr_OpenUser r;
struct samr_QueryUserInfo q;
+ union samr_UserInfo *info;
struct policy_handle user_handle;
struct samr_GetGroupsForUser getgroups;
+ struct samr_RidWithAttributeArray *rids;
+
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
printf("SamSync needs domain information before the users\n");
return false;
@@ -446,6 +465,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
q.in.user_handle = &user_handle;
q.in.level = 21;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(user->sdbuf, samr, &user_handle);
@@ -457,6 +477,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
}
getgroups.in.user_handle = &user_handle;
+ getgroups.out.rids = &rids;
nt_status = dcerpc_samr_GetGroupsForUser(samsync_state->p_samr, mem_ctx, &getgroups);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -480,67 +501,67 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
return false;
}
- TEST_STRING_EQUAL(q.out.info->info21.account_name, user->account_name);
- TEST_STRING_EQUAL(q.out.info->info21.full_name, user->full_name);
- TEST_INT_EQUAL(q.out.info->info21.rid, user->rid);
- TEST_INT_EQUAL(q.out.info->info21.primary_gid, user->primary_gid);
- TEST_STRING_EQUAL(q.out.info->info21.home_directory, user->home_directory);
- TEST_STRING_EQUAL(q.out.info->info21.home_drive, user->home_drive);
- TEST_STRING_EQUAL(q.out.info->info21.logon_script, user->logon_script);
- TEST_STRING_EQUAL(q.out.info->info21.description, user->description);
- TEST_STRING_EQUAL(q.out.info->info21.workstations, user->workstations);
+ TEST_STRING_EQUAL(info->info21.account_name, user->account_name);
+ TEST_STRING_EQUAL(info->info21.full_name, user->full_name);
+ TEST_INT_EQUAL(info->info21.rid, user->rid);
+ TEST_INT_EQUAL(info->info21.primary_gid, user->primary_gid);
+ TEST_STRING_EQUAL(info->info21.home_directory, user->home_directory);
+ TEST_STRING_EQUAL(info->info21.home_drive, user->home_drive);
+ TEST_STRING_EQUAL(info->info21.logon_script, user->logon_script);
+ TEST_STRING_EQUAL(info->info21.description, user->description);
+ TEST_STRING_EQUAL(info->info21.workstations, user->workstations);
- TEST_TIME_EQUAL(q.out.info->info21.last_logon, user->last_logon);
- TEST_TIME_EQUAL(q.out.info->info21.last_logoff, user->last_logoff);
+ TEST_TIME_EQUAL(info->info21.last_logon, user->last_logon);
+ TEST_TIME_EQUAL(info->info21.last_logoff, user->last_logoff);
- TEST_INT_EQUAL(q.out.info->info21.logon_hours.units_per_week,
+ TEST_INT_EQUAL(info->info21.logon_hours.units_per_week,
user->logon_hours.units_per_week);
if (ret) {
- if (memcmp(q.out.info->info21.logon_hours.bits, user->logon_hours.bits,
- q.out.info->info21.logon_hours.units_per_week/8) != 0) {
+ if (memcmp(info->info21.logon_hours.bits, user->logon_hours.bits,
+ info->info21.logon_hours.units_per_week/8) != 0) {
printf("Logon hours mismatch\n");
ret = false;
}
}
- TEST_INT_EQUAL(q.out.info->info21.bad_password_count,
+ TEST_INT_EQUAL(info->info21.bad_password_count,
user->bad_password_count);
- TEST_INT_EQUAL(q.out.info->info21.logon_count,
+ TEST_INT_EQUAL(info->info21.logon_count,
user->logon_count);
- TEST_TIME_EQUAL(q.out.info->info21.last_password_change,
+ TEST_TIME_EQUAL(info->info21.last_password_change,
user->last_password_change);
- TEST_TIME_EQUAL(q.out.info->info21.acct_expiry,
+ TEST_TIME_EQUAL(info->info21.acct_expiry,
user->acct_expiry);
- TEST_INT_EQUAL((q.out.info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags);
+ TEST_INT_EQUAL((info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags);
if (user->acct_flags & ACB_PWNOEXP) {
- if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) {
+ if (info->info21.acct_flags & ACB_PW_EXPIRED) {
printf("ACB flags mismatch: both expired and no expiry!\n");
ret = false;
}
- if (q.out.info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) {
+ if (info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) {
printf("ACB flags mismatch: no password expiry, but force password change 0x%016llx (%lld) != 0x%016llx (%lld)\n",
- (unsigned long long)q.out.info->info21.force_password_change,
- (unsigned long long)q.out.info->info21.force_password_change,
+ (unsigned long long)info->info21.force_password_change,
+ (unsigned long long)info->info21.force_password_change,
(unsigned long long)0x7FFFFFFFFFFFFFFFULL, (unsigned long long)0x7FFFFFFFFFFFFFFFULL
);
ret = false;
}
}
- TEST_INT_EQUAL(q.out.info->info21.nt_password_set, user->nt_password_present);
- TEST_INT_EQUAL(q.out.info->info21.lm_password_set, user->lm_password_present);
- TEST_INT_EQUAL(q.out.info->info21.password_expired, user->password_expired);
+ TEST_INT_EQUAL(info->info21.nt_password_set, user->nt_password_present);
+ TEST_INT_EQUAL(info->info21.lm_password_set, user->lm_password_present);
+ TEST_INT_EQUAL(info->info21.password_expired, user->password_expired);
- TEST_STRING_EQUAL(q.out.info->info21.comment, user->comment);
- TEST_STRING_EQUAL(q.out.info->info21.parameters, user->parameters);
+ TEST_STRING_EQUAL(info->info21.comment, user->comment);
+ TEST_BINARY_STRING_EQUAL(info->info21.parameters, user->parameters);
- TEST_INT_EQUAL(q.out.info->info21.country_code, user->country_code);
- TEST_INT_EQUAL(q.out.info->info21.code_page, user->code_page);
+ TEST_INT_EQUAL(info->info21.country_code, user->country_code);
+ TEST_INT_EQUAL(info->info21.code_page, user->code_page);
- TEST_STRING_EQUAL(q.out.info->info21.profile_path, user->profile_path);
+ TEST_STRING_EQUAL(info->info21.profile_path, user->profile_path);
if (user->lm_password_present) {
sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0);
@@ -619,7 +640,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
return true;
}
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED)) {
- if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) {
+ if (info->info21.acct_flags & ACB_PW_EXPIRED) {
return true;
}
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) {
@@ -654,7 +675,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
TEST_TIME_EQUAL(user->last_logon, info3->base.last_logon);
TEST_TIME_EQUAL(user->acct_expiry, info3->base.acct_expiry);
TEST_TIME_EQUAL(user->last_password_change, info3->base.last_password_change);
- TEST_TIME_EQUAL(q.out.info->info21.force_password_change, info3->base.force_password_change);
+ TEST_TIME_EQUAL(info->info21.force_password_change, info3->base.force_password_change);
/* Does the concept of a logoff time ever really
* exist? (not in any sensible way, according to the
@@ -667,28 +688,28 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct
TEST_TIME_EQUAL(user->last_logoff, info3->base.last_logoff);
}
- TEST_INT_EQUAL(getgroups.out.rids->count, info3->base.groups.count);
- if (getgroups.out.rids->count == info3->base.groups.count) {
+ TEST_INT_EQUAL(rids->count, info3->base.groups.count);
+ if (rids->count == info3->base.groups.count) {
int i, j;
- int count = getgroups.out.rids->count;
- bool *matched = talloc_zero_array(mem_ctx, bool, getgroups.out.rids->count);
+ int count = rids->count;
+ bool *matched = talloc_zero_array(mem_ctx, bool, rids->count);
for (i = 0; i < count; i++) {
for (j = 0; j < count; j++) {
- if ((getgroups.out.rids->rids[i].rid ==
+ if ((rids->rids[i].rid ==
info3->base.groups.rids[j].rid)
- && (getgroups.out.rids->rids[i].attributes ==
+ && (rids->rids[i].attributes ==
info3->base.groups.rids[j].attributes)) {
matched[i] = true;
}
}
}
- for (i = 0; i < getgroups.out.rids->count; i++) {
+ for (i = 0; i < rids->count; i++) {
if (matched[i] == false) {
ret = false;
printf("Could not find group RID %u found in getgroups in NETLOGON reply\n",
- getgroups.out.rids->rids[i].rid);
+ rids->rids[i].rid);
}
}
}
@@ -711,6 +732,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
struct samr_OpenAlias r;
struct samr_QueryAliasInfo q;
+ union samr_AliasInfo *info;
struct policy_handle alias_handle;
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
@@ -731,6 +753,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
q.in.alias_handle = &alias_handle;
q.in.level = 1;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(alias->sdbuf, samr, &alias_handle);
@@ -745,8 +768,8 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams
return false;
}
- TEST_STRING_EQUAL(q.out.info->all.name, alias->alias_name);
- TEST_STRING_EQUAL(q.out.info->all.description, alias->description);
+ TEST_STRING_EQUAL(info->all.name, alias->alias_name);
+ TEST_STRING_EQUAL(info->all.description, alias->description);
return ret;
}
@@ -760,6 +783,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
struct samr_OpenGroup r;
struct samr_QueryGroupInfo q;
+ union samr_GroupInfo *info;
struct policy_handle group_handle;
if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) {
@@ -780,6 +804,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
q.in.group_handle = &group_handle;
q.in.level = 1;
+ q.out.info = &info;
TEST_SEC_DESC_EQUAL(group->sdbuf, samr, &group_handle);
@@ -794,9 +819,9 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams
return false;
}
- TEST_STRING_EQUAL(q.out.info->all.name, group->group_name);
- TEST_INT_EQUAL(q.out.info->all.attributes, group->attributes);
- TEST_STRING_EQUAL(q.out.info->all.description, group->description);
+ TEST_STRING_EQUAL(info->all.name, group->group_name);
+ TEST_INT_EQUAL(info->all.attributes, group->attributes);
+ TEST_STRING_EQUAL(info->all.description, group->description);
return ret;
}
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index ca1655729b..451990a71b 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -128,6 +128,7 @@ static bool test_samr_ops(struct torture_context *tctx,
{
NTSTATUS status;
struct samr_GetDomPwInfo r;
+ struct samr_PwInfo info;
struct samr_Connect connect;
struct samr_OpenDomain opendom;
int i;
@@ -137,6 +138,7 @@ static bool test_samr_ops(struct torture_context *tctx,
name.string = lp_workgroup(tctx->lp_ctx);
r.in.domain_name = &name;
+ r.out.info = &info;
connect.in.system_name = 0;
connect.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
diff --git a/source4/torture/rpc/svcctl.c b/source4/torture/rpc/svcctl.c
index c9006baaf5..8d8f43a0cf 100644
--- a/source4/torture/rpc/svcctl.c
+++ b/source4/torture/rpc/svcctl.c
@@ -1,19 +1,19 @@
-/*
+/*
Unix SMB/CIFS implementation.
test suite for srvsvc rpc operations
Copyright (C) Jelmer Vernooij 2004
-
+
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/>.
*/
@@ -26,28 +26,141 @@
static bool test_OpenSCManager(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h)
{
struct svcctl_OpenSCManagerW r;
-
+
r.in.MachineName = NULL;
r.in.DatabaseName = NULL;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.handle = h;
-
- torture_assert_ntstatus_ok(tctx,
- dcerpc_svcctl_OpenSCManagerW(p, tctx, &r),
- "OpenSCManager failed!");
-
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_svcctl_OpenSCManagerW(p, tctx, &r),
+ "OpenSCManager failed!");
+
return true;
}
static bool test_CloseServiceHandle(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *h)
{
- struct svcctl_CloseServiceHandle r;
+ struct svcctl_CloseServiceHandle r;
r.in.handle = h;
r.out.handle = h;
- torture_assert_ntstatus_ok(tctx,
- dcerpc_svcctl_CloseServiceHandle(p, tctx, &r),
- "CloseServiceHandle failed");
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_svcctl_CloseServiceHandle(p, tctx, &r),
+ "CloseServiceHandle failed");
+
+ return true;
+}
+
+static bool test_OpenService(struct dcerpc_pipe *p, struct torture_context *tctx,
+ struct policy_handle *h, const char *name, struct policy_handle *s)
+{
+ struct svcctl_OpenServiceW r;
+
+ r.in.scmanager_handle = h;
+ r.in.ServiceName = name;
+ r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
+ r.out.handle = s;
+
+ torture_assert_ntstatus_ok(tctx,
+ dcerpc_svcctl_OpenServiceW(p, tctx, &r),
+ "OpenServiceW failed!");
+ torture_assert_werr_ok(tctx, r.out.result, "OpenServiceW failed!");
+
+ return true;
+
+}
+
+static bool test_QueryServiceStatusEx(struct torture_context *tctx, struct dcerpc_pipe *p)
+{
+ struct svcctl_QueryServiceStatusEx r;
+ struct policy_handle h, s;
+ NTSTATUS status;
+
+ uint32_t info_level = 0;
+ uint8_t *buffer;
+ uint32_t buf_size = 0;
+ uint32_t bytes_needed = 0;
+
+ if (!test_OpenSCManager(p, tctx, &h))
+ return false;
+
+ if (!test_OpenService(p, tctx, &h, "Netlogon", &s))
+ return false;
+
+ buffer = talloc(tctx, uint8_t);
+
+ r.in.handle = &s;
+ r.in.info_level = info_level;
+ r.in.buf_size = buf_size;
+ r.out.buffer = buffer;
+ r.out.bytes_needed = &bytes_needed;
+
+ status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ r.in.buf_size = bytes_needed;
+ buffer = talloc_array(tctx, uint8_t, bytes_needed);
+ r.out.buffer = buffer;
+
+ status = dcerpc_svcctl_QueryServiceStatusEx(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceStatusEx failed!");
+ torture_assert_werr_ok(tctx, r.out.result, "QueryServiceStatusEx failed!");
+ }
+
+ if (!test_CloseServiceHandle(p, tctx, &s))
+ return false;
+
+ if (!test_CloseServiceHandle(p, tctx, &h))
+ return false;
+
+ return true;
+}
+
+static bool test_QueryServiceConfig2W(struct torture_context *tctx, struct dcerpc_pipe *p)
+{
+ struct svcctl_QueryServiceConfig2W r;
+ struct policy_handle h, s;
+ NTSTATUS status;
+
+ uint32_t info_level = 1;
+ uint8_t *buffer;
+ uint32_t buf_size = 0;
+ uint32_t bytes_needed = 0;
+
+ if (!test_OpenSCManager(p, tctx, &h))
+ return false;
+
+ if (!test_OpenService(p, tctx, &h, "Netlogon", &s))
+ return false;
+
+ buffer = talloc(tctx, uint8_t);
+
+ r.in.handle = &s;
+ r.in.info_level = info_level;
+ r.in.buf_size = buf_size;
+ r.out.buffer = buffer;
+ r.out.bytes_needed = &bytes_needed;
+
+ status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
+
+ if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
+ r.in.buf_size = bytes_needed;
+ buffer = talloc_array(tctx, uint8_t, bytes_needed);
+ r.out.buffer = buffer;
+
+ status = dcerpc_svcctl_QueryServiceConfig2W(p, tctx, &r);
+ torture_assert_ntstatus_ok(tctx, status, "QueryServiceConfig2W failed!");
+ torture_assert_werr_ok(tctx, r.out.result, "QueryServiceConfig2W failed!");
+ }
+
+ if (!test_CloseServiceHandle(p, tctx, &s))
+ return false;
+
+ if (!test_CloseServiceHandle(p, tctx, &h))
+ return false;
return true;
}
@@ -59,7 +172,9 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_
int i;
NTSTATUS status;
uint32_t resume_handle = 0;
- struct ENUM_SERVICE_STATUS *service = NULL;
+ struct ENUM_SERVICE_STATUS *service = NULL;
+ uint32_t bytes_needed = 0;
+ uint32_t services_returned = 0;
if (!test_OpenSCManager(p, tctx, &h))
return false;
@@ -71,17 +186,17 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_
r.in.resume_handle = &resume_handle;
r.out.service = NULL;
r.out.resume_handle = &resume_handle;
- r.out.services_returned = 0;
- r.out.bytes_needed = 0;
+ r.out.services_returned = &services_returned;
+ r.out.bytes_needed = &bytes_needed;
status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) {
- r.in.buf_size = *r.out.bytes_needed;
- r.out.service = talloc_array(tctx, uint8_t, *r.out.bytes_needed);
-
+ r.in.buf_size = bytes_needed;
+ r.out.service = talloc_array(tctx, uint8_t, bytes_needed);
+
status = dcerpc_svcctl_EnumServicesStatusW(p, tctx, &r);
torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!");
@@ -90,17 +205,17 @@ static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_
service = (struct ENUM_SERVICE_STATUS *)r.out.service;
}
- for(i = 0; i < *r.out.services_returned; i++) {
+ for(i = 0; i < services_returned; i++) {
printf("Type: %d, State: %d\n", service[i].status.type, service[i].status.state);
}
-
+
if (!test_CloseServiceHandle(p, tctx, &h))
return false;
return true;
}
-static bool test_SCManager(struct torture_context *tctx,
+static bool test_SCManager(struct torture_context *tctx,
struct dcerpc_pipe *p)
{
struct policy_handle h;
@@ -119,13 +234,16 @@ struct torture_suite *torture_rpc_svcctl(TALLOC_CTX *mem_ctx)
struct torture_suite *suite = torture_suite_create(mem_ctx, "SVCCTL");
struct torture_rpc_tcase *tcase;
- tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl",
- &ndr_table_svcctl);
-
- torture_rpc_tcase_add_test(tcase, "SCManager",
- test_SCManager);
- torture_rpc_tcase_add_test(tcase, "EnumServicesStatus",
- test_EnumServicesStatus);
+ tcase = torture_suite_add_rpc_iface_tcase(suite, "svcctl", &ndr_table_svcctl);
+
+ torture_rpc_tcase_add_test(tcase, "SCManager",
+ test_SCManager);
+ torture_rpc_tcase_add_test(tcase, "EnumServicesStatus",
+ test_EnumServicesStatus);
+ torture_rpc_tcase_add_test(tcase, "QueryServiceStatusEx",
+ test_QueryServiceStatusEx);
+ torture_rpc_tcase_add_test(tcase, "QueryServiceConfig2W",
+ test_QueryServiceConfig2W);
return suite;
}
diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c
index 3408a1924c..c93358015c 100644
--- a/source4/torture/rpc/testjoin.c
+++ b/source4/torture/rpc/testjoin.c
@@ -59,6 +59,7 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle user_handle;
uint32_t rid;
struct samr_LookupNames n;
+ struct samr_Ids rids, types;
struct lsa_String sname;
struct samr_OpenUser r;
@@ -67,10 +68,12 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
n.in.domain_handle = handle;
n.in.num_names = 1;
n.in.names = &sname;
+ n.out.rids = &rids;
+ n.out.types = &types;
status = dcerpc_samr_LookupNames(p, mem_ctx, &n);
if (NT_STATUS_IS_OK(status)) {
- rid = n.out.rids.ids[0];
+ rid = n.out.rids->ids[0];
} else {
return status;
}
@@ -113,7 +116,9 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
struct samr_CreateUser2 r;
struct samr_OpenDomain o;
struct samr_LookupDomain l;
+ struct dom_sid2 *sid = NULL;
struct samr_GetUserPwInfo pwp;
+ struct samr_PwInfo info;
struct samr_SetUserInfo s;
union samr_UserInfo u;
struct policy_handle handle;
@@ -172,6 +177,7 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
name.string = domain;
l.in.connect_handle = &handle;
l.in.domain_name = &name;
+ l.out.sid = &sid;
status = dcerpc_samr_LookupDomain(join->p, join, &l);
if (!NT_STATUS_IS_OK(status)) {
@@ -179,14 +185,14 @@ struct test_join *torture_create_testuser(struct torture_context *torture,
goto failed;
}
- talloc_steal(join, l.out.sid);
- join->dom_sid = l.out.sid;
+ talloc_steal(join, *l.out.sid);
+ join->dom_sid = *l.out.sid;
join->dom_netbios_name = talloc_strdup(join, domain);
if (!join->dom_netbios_name) goto failed;
o.in.connect_handle = &handle;
o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
- o.in.sid = l.out.sid;
+ o.in.sid = *l.out.sid;
o.out.domain_handle = &domain_handle;
status = dcerpc_samr_OpenDomain(join->p, join, &o);
@@ -224,10 +230,11 @@ again:
join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid);
pwp.in.user_handle = &join->user_handle;
+ pwp.out.info = &info;
status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp);
if (NT_STATUS_IS_OK(status)) {
- policy_min_pw_len = pwp.out.info.min_password_length;
+ policy_min_pw_len = pwp.out.info->min_password_length;
}
random_pw = generate_random_str(join, MAX(8, policy_min_pw_len));
@@ -240,7 +247,7 @@ again:
s.in.level = 24;
encode_pw_buffer(u.info24.password.data, random_pw, STR_UNICODE);
- u.info24.pw_len = strlen(random_pw);
+ u.info24.password_expired = 0;
status = dcerpc_fetch_session_key(join->p, &session_key);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source4/torture/smb2/config.mk b/source4/torture/smb2/config.mk
index 9785303629..3a1ac5e06c 100644
--- a/source4/torture/smb2/config.mk
+++ b/source4/torture/smb2/config.mk
@@ -5,7 +5,7 @@
SUBSYSTEM = smbtorture
INIT_FUNCTION = torture_smb2_init
PRIVATE_DEPENDENCIES = \
- LIBCLI_SMB2 POPT_CREDENTIALS
+ LIBCLI_SMB2 POPT_CREDENTIALS torture
# End SUBSYSTEM TORTURE_SMB2
#################################
diff --git a/source4/torture/smbtorture.h b/source4/torture/smbtorture.h
index 3b5a573d83..c1363fd4c1 100644
--- a/source4/torture/smbtorture.h
+++ b/source4/torture/smbtorture.h
@@ -21,7 +21,7 @@
#ifndef __SMBTORTURE_H__
#define __SMBTORTURE_H__
-#include "torture/torture.h"
+#include "../lib/torture/torture.h"
struct smbcli_state;
diff --git a/source4/torture/util.h b/source4/torture/util.h
index f36d54233d..3609cca7d9 100644
--- a/source4/torture/util.h
+++ b/source4/torture/util.h
@@ -20,7 +20,7 @@
#ifndef _TORTURE_UTIL_H_
#define _TORTURE_UTIL_H_
-#include "torture/torture.h"
+#include "lib/torture/torture.h"
struct smbcli_state;
struct smbcli_tree;
diff --git a/source4/torture/winbind/config.mk b/source4/torture/winbind/config.mk
index 15bc51daba..9648a7472b 100644
--- a/source4/torture/winbind/config.mk
+++ b/source4/torture/winbind/config.mk
@@ -5,7 +5,7 @@
SUBSYSTEM = smbtorture
INIT_FUNCTION = torture_winbind_init
PRIVATE_DEPENDENCIES = \
- LIBWINBIND-CLIENT
+ LIBWINBIND-CLIENT torture
# End SUBSYSTEM TORTURE_WINBIND
#################################
diff --git a/source4/utils/ad2oLschema.c b/source4/utils/ad2oLschema.c
index c579112b45..2e3139d9c7 100644
--- a/source4/utils/ad2oLschema.c
+++ b/source4/utils/ad2oLschema.c
@@ -226,7 +226,6 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
const char *equality = NULL, *substring = NULL;
bool single_value = attribute->isSingleValued;
- const struct dsdb_syntax *map = find_syntax_map_by_ad_syntax(attribute->oMSyntax);
char *schema_entry = NULL;
int j;
@@ -244,11 +243,11 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
}
}
- if (map) {
+ if (attribute->syntax) {
/* We might have been asked to remap this oid,
* due to a conflict, or lack of
* implementation */
- syntax = map->ldap_oid;
+ syntax = attribute->syntax->ldap_oid;
/* We might have been asked to remap this oid, due to a conflict */
for (j=0; syntax && oid_map && oid_map[j].old_oid; j++) {
if (strcasecmp(syntax, oid_map[j].old_oid) == 0) {
@@ -257,8 +256,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
}
}
- equality = map->equality;
- substring = map->substring;
+ equality = attribute->syntax->equality;
+ substring = attribute->syntax->substring;
}
/* We might have been asked to remap this name, due to a conflict */
@@ -278,7 +277,10 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
substring,
syntax,
single_value,
- false);
+ false,
+ NULL, NULL,
+ NULL, NULL,
+ false, false);
if (schema_entry == NULL) {
ret.failures++;
@@ -366,7 +368,8 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum dsdb_sch
subClassOf,
objectClassCategory,
must,
- may);
+ may,
+ NULL);
if (schema_entry == NULL) {
ret.failures++;
return ret;
diff --git a/source4/utils/net/config.mk b/source4/utils/net/config.mk
index 93b51e1e28..b2f0fcf6b1 100644
--- a/source4/utils/net/config.mk
+++ b/source4/utils/net/config.mk
@@ -16,6 +16,7 @@ PRIVATE_DEPENDENCIES = \
net_OBJ_FILES = $(addprefix $(utilssrcdir)/net/, \
net.o \
+ net_machinepw.o \
net_password.o \
net_time.o \
net_join.o \
diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c
index 81584e4398..4d1b202ccb 100644
--- a/source4/utils/net/net.c
+++ b/source4/utils/net/net.c
@@ -107,6 +107,8 @@ static const struct net_functable net_functable[] = {
{"vampire", "join and syncronise an AD domain onto the local server\n", net_vampire, net_vampire_usage},
{"samsync", "synchronise into the local ldb the sam of an NT4 domain\n", net_samsync_ldb, net_samsync_ldb_usage},
{"user", "manage user accounts\n", net_user, net_user_usage},
+ {"machinepw", "Get a machine password out of our SAM", net_machinepw,
+ net_machinepw_usage},
{NULL, NULL, NULL, NULL}
};
diff --git a/source4/utils/net/net_machinepw.c b/source4/utils/net/net_machinepw.c
new file mode 100644
index 0000000000..710d889c19
--- /dev/null
+++ b/source4/utils/net/net_machinepw.c
@@ -0,0 +1,91 @@
+/*
+ Samba Unix/Linux SMB client library
+ Distributed SMB/CIFS Server Management Utility
+
+ Copyright (C) 2008 Volker Lendecke
+
+ 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 "utils/net/net.h"
+#include "libnet/libnet.h"
+#include "libcli/security/security.h"
+#include "param/secrets.h"
+#include "param/param.h"
+#include "lib/events/events.h"
+#include "lib/util/util_ldb.h"
+
+int net_machinepw_usage(struct net_context *ctx, int argc, const char **argv)
+{
+ d_printf("net machinepw <accountname>\n");
+ return -1;
+}
+
+int net_machinepw(struct net_context *ctx, int argc, const char **argv)
+{
+ struct ldb_context *secrets;
+ TALLOC_CTX *mem_ctx;
+ struct event_context *ev;
+ struct ldb_message **msgs;
+ int num_records;
+ const char *attrs[] = { "secret", NULL };
+ const char *secret;
+
+ if (argc != 1) {
+ net_machinepw_usage(ctx, argc, argv);
+ return -1;
+ }
+
+ mem_ctx = talloc_new(ctx);
+ if (mem_ctx == NULL) {
+ d_fprintf(stderr, "talloc_new failed\n");
+ return -1;
+ }
+
+ ev = event_context_init(mem_ctx);
+ if (ev == NULL) {
+ d_fprintf(stderr, "event_context_init failed\n");
+ goto fail;
+ }
+
+ secrets = secrets_db_connect(mem_ctx, ev, ctx->lp_ctx);
+ if (secrets == NULL) {
+ d_fprintf(stderr, "secrets_db_connect failed\n");
+ goto fail;
+ }
+
+ num_records = gendb_search(secrets, mem_ctx, NULL, &msgs, attrs,
+ "(&(objectclass=primaryDomain)"
+ "(samaccountname=%s))", argv[0]);
+ if (num_records != 1) {
+ d_fprintf(stderr, "gendb_search returned %d records, "
+ "expected 1\n", num_records);
+ goto fail;
+ }
+
+ secret = ldb_msg_find_attr_as_string(msgs[0], "secret", NULL);
+ if (secret == NULL) {
+ d_fprintf(stderr, "machine account contains no secret\n");
+ goto fail;
+ }
+
+ printf("%s\n", secret);
+ talloc_free(mem_ctx);
+ return 0;
+
+ fail:
+ talloc_free(mem_ctx);
+ return -1;
+}
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index 48a2a4d882..a50a0fe473 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -325,6 +325,8 @@ struct samr_getuserdomgroups_state {
int num_rids;
uint32_t *rids;
+ struct samr_RidWithAttributeArray *rid_array;
+
struct policy_handle *user_handle;
struct samr_OpenUser o;
struct samr_GetGroupsForUser g;
@@ -386,6 +388,7 @@ static void samr_usergroups_recv_open(struct rpc_request *req)
if (!composite_is_ok(state->ctx)) return;
state->g.in.user_handle = state->user_handle;
+ state->g.out.rids = &state->rid_array;
req = dcerpc_samr_GetGroupsForUser_send(state->samr_pipe, state,
&state->g);
@@ -438,7 +441,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx,
NTSTATUS status = composite_wait(ctx);
if (!NT_STATUS_IS_OK(status)) goto done;
- *num_rids = state->g.out.rids->count;
+ *num_rids = state->rid_array->count;
*rids = talloc_array(mem_ctx, uint32_t, *num_rids);
if (*rids == NULL) {
status = NT_STATUS_NO_MEMORY;
@@ -446,7 +449,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx,
}
for (i=0; i<*num_rids; i++) {
- (*rids)[i] = state->g.out.rids->rids[i].rid;
+ (*rids)[i] = state->rid_array->rids[i].rid;
}
done: