1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-13 13:18:06 +03:00

Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into v4-0-gmake3

Conflicts:

	source/Makefile
	source/build/smb_build/makefile.pm
	source/librpc/config.mk
This commit is contained in:
Jelmer Vernooij 2008-03-03 10:50:53 +01:00
commit 3e02fcfd3f
26 changed files with 910 additions and 415 deletions

View File

@ -22,6 +22,13 @@ HOSTLD_FLAGS = $(LDFLAGS) $(SYS_LDFLAGS)
$(srcdir)/version.h: $(srcdir)/VERSION
@$(SHELL) script/mkversion.sh VERSION $(srcdir)/version.h $(srcdir)/
.DEFAULT_GOAL := all
ifneq ($(automatic_deps),yes)
ALL_PREDEP = proto
.NOTPARALLEL:
endif
regen_version::
@$(SHELL) script/mkversion.sh VERSION $(srcdir)/version.h $(srcdir)/

View File

@ -350,8 +350,7 @@ sub CFlags($$)
my $cflags = join(' ', @cflags);
my $ext = "o";
$self->output("\$($key->{NAME}_OBJ_LIST) \$(patsubst %.ho,%.d,\$($key->{NAME}_OBJ_LIST:.o=.d)): CFLAGS+=$cflags\n");
$self->output("\$(patsubst %.ho,%.d,\$(key->{NAME}_OBJ_LIST:.o=.d)) \$($key->{NAME}_OBJ_LIST): CFLAGS+= $cflags\n");
}
1;

View File

@ -542,6 +542,25 @@ static NTSTATUS odb_ctdb_rename(struct odb_lock *lck, const char *path)
return odb_push_record(lck, &file);
}
/*
get the path of an open file
*/
static NTSTATUS odb_ctdb_get_path(struct odb_lock *lck, const char **path)
{
struct opendb_file file;
NTSTATUS status;
*path = NULL;
status = odb_pull_record(lck, &file);
/* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */
NT_STATUS_NOT_OK_RETURN(status);
*path = file.path;
return NT_STATUS_OK;
}
/*
update delete on close flag on an open file
*/
@ -653,6 +672,7 @@ static const struct opendb_ops opendb_ctdb_ops = {
.odb_close_file = odb_ctdb_close_file,
.odb_remove_pending = odb_ctdb_remove_pending,
.odb_rename = odb_ctdb_rename,
.odb_get_path = odb_ctdb_get_path,
.odb_set_delete_on_close = odb_ctdb_set_delete_on_close,
.odb_get_delete_on_close = odb_ctdb_get_delete_on_close,
.odb_can_open = odb_ctdb_can_open,

View File

@ -290,7 +290,7 @@ char *ldb_filter_from_tree(TALLOC_CTX *mem_ctx, struct ldb_parse_tree *tree);
2254 (Section 4). This function also escapes any non-printable
characters.
\param ctx the memory context to allocate the return string in.
\param mem_ctx the memory context to allocate the return string in.
\param val the (potentially) binary data to be encoded
\return the encoded data as a null terminated string
@ -886,7 +886,7 @@ int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct l
\param attrs the search attributes for the query (pass NULL if none required)
\param controls an array of controls
\param context the callback function context
\param the callback function to handle the async replies
\param callback the callback function to handle the async replies
\return result code (LDB_SUCCESS on success, or a failure code)
*/
@ -911,7 +911,7 @@ int ldb_build_search_req(struct ldb_request **ret_req,
\param message contains the entry to be added
\param controls an array of controls
\param context the callback function context
\param the callback function to handle the async replies
\param callback the callback function to handle the async replies
\return result code (LDB_SUCCESS on success, or a failure code)
*/
@ -933,7 +933,7 @@ int ldb_build_add_req(struct ldb_request **ret_req,
\param message contains the entry to be modified
\param controls an array of controls
\param context the callback function context
\param the callback function to handle the async replies
\param callback the callback function to handle the async replies
\return result code (LDB_SUCCESS on success, or a failure code)
*/
@ -955,7 +955,7 @@ int ldb_build_mod_req(struct ldb_request **ret_req,
\param dn the DN to be deleted
\param controls an array of controls
\param context the callback function context
\param the callback function to handle the async replies
\param callback the callback function to handle the async replies
\return result code (LDB_SUCCESS on success, or a failure code)
*/
@ -978,7 +978,7 @@ int ldb_build_del_req(struct ldb_request **ret_req,
\param newdn the new DN
\param controls an array of controls
\param context the callback function context
\param the callback function to handle the async replies
\param callback the callback function to handle the async replies
\return result code (LDB_SUCCESS on success, or a failure code)
*/
@ -997,7 +997,7 @@ int ldb_build_rename_req(struct ldb_request **ret_req,
\param req the request struct where to add the control
\param oid the object identifier of the control as string
\param ciritical whether the control should be critical or not
\param critical whether the control should be critical or not
\param data a talloc pointer to the control specific data
\return result code (LDB_SUCCESS on success, or a failure code)
@ -1137,7 +1137,7 @@ int ldb_extended_default_callback(struct ldb_context *ldb, void *context, struct
it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it
\param controls an array of controls
\param context the callback function context
\param the callback function to handle the async replies
\param callback the callback function to handle the async replies
\return result code (LDB_SUCCESS on success, or a failure code)
*/
@ -1226,6 +1226,7 @@ int ldb_valid_attr_name(const char *s);
/*
ldif manipulation functions
*/
/**
Write an LDIF message
@ -1418,8 +1419,8 @@ bool ldb_dn_is_null(struct ldb_dn *dn);
This function compares to attribute names. Note that this is a
case-insensitive comparison.
\param attr1 the first attribute name to compare
\param attr2 the second attribute name to compare
\param a the first attribute name to compare
\param b the second attribute name to compare
\return 0 if the attribute names are the same, or only differ in
case; non-zero if there are any differences
@ -1562,6 +1563,7 @@ int ldb_msg_check_string_attribute(const struct ldb_message *msg,
This function performs basic sanity / integrity checks on an
ldb_message.
\param ldb context in which to perform the checks
\param msg the message to check
\return LDB_SUCCESS if the message is OK, or a non-zero error code

View File

@ -547,6 +547,43 @@ PyObject *PyExc_LdbError;
talloc_free($1);
};
%typemap(in,numinputs=1) ldb_msg *add_msg {
int dict_pos, msg_pos;
PyObject *key, *value;
ldb_msg_element *msgel;
if (PyDict_Check($input)) {
$1 = ldb_msg_new(NULL);
$1->elements = talloc_zero_array($1, struct ldb_message_element, PyDict_Size($input));
msg_pos = dict_pos = 0;
while (PyDict_Next($input, &dict_pos, &key, &value)) {
if (!strcmp(PyString_AsString(key), "dn")) {
/* using argp0 (magic SWIG value) here is a hack */
if (ldb_dn_from_pyobject($1, value, argp1, &$1->dn) != 0) {
SWIG_exception(SWIG_TypeError, "unable to import dn object");
}
} else {
msgel = ldb_msg_element_from_pyobject($1->elements, value, 0, PyString_AsString(key));
if (msgel == NULL) {
SWIG_exception(SWIG_TypeError, "unable to import element");
}
memcpy(&$1->elements[msg_pos], msgel, sizeof(*msgel));
msg_pos++;
}
}
if ($1->dn == NULL) {
SWIG_exception(SWIG_TypeError, "no dn set");
}
$1->num_elements = msg_pos;
} else {
if (SWIG_ConvertPtr($input, (void **)&$1, SWIGTYPE_p_ldb_message, 0) != 0) {
SWIG_exception(SWIG_TypeError, "unable to convert ldb message");
}
}
}
/* Top-level ldb operations */
typedef struct ldb_context {
%extend {
@ -604,53 +641,6 @@ typedef struct ldb_context {
struct ldb_control **parse_control_strings(TALLOC_CTX *mem_ctx,
const char * const*control_strings);
ldb_error add(ldb_msg *add_msg);
ldb_error add(PyObject *py_msg)
{
ldb_error ret;
int dict_pos, msg_pos;
PyObject *key, *value;
ldb_msg_element *msgel;
ldb_msg *msg = NULL;
if (PyDict_Check(py_msg)) {
msg = ldb_msg_new(NULL);
msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
msg_pos = dict_pos = 0;
while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
if (!strcmp(PyString_AsString(key), "dn")) {
if (ldb_dn_from_pyobject(msg, value, $self, &msg->dn) != 0) {
return LDB_ERR_OTHER;
}
} else {
msgel = ldb_msg_element_from_pyobject(msg->elements, value, 0, PyString_AsString(key));
if (msgel == NULL) {
SWIG_exception(SWIG_TypeError, "unable to import element");
return LDB_ERR_OTHER;
}
memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
msg_pos++;
}
}
if (msg->dn == NULL) {
SWIG_exception(SWIG_TypeError, "no dn set");
return LDB_ERR_OTHER;
}
msg->num_elements = msg_pos;
} else {
if (SWIG_ConvertPtr(py_msg, (void **)&msg, SWIGTYPE_p_ldb_message, 0) != 0)
return LDB_ERR_OTHER;
}
ret = ldb_add($self, msg);
talloc_free(msg);
return ret;
fail:
return LDB_ERR_OTHER;
}
ldb_error modify(ldb_msg *message);
ldb_dn *get_config_basedn();
ldb_dn *get_root_basedn();

View File

@ -3113,52 +3113,6 @@ SWIGINTERN ldb_error ldb_search_ex(ldb *self,TALLOC_CTX *mem_ctx,ldb_dn *base,en
*OUT = res;
return ret;
}
SWIGINTERN ldb_error ldb_add__SWIG_1(ldb *self,PyObject *py_msg){
ldb_error ret;
int dict_pos, msg_pos;
PyObject *key, *value;
ldb_msg_element *msgel;
ldb_msg *msg = NULL;
if (PyDict_Check(py_msg)) {
msg = ldb_msg_new(NULL);
msg->elements = talloc_zero_array(msg, struct ldb_message_element, PyDict_Size(py_msg));
msg_pos = dict_pos = 0;
while (PyDict_Next(py_msg, &dict_pos, &key, &value)) {
if (!strcmp(PyString_AsString(key), "dn")) {
if (ldb_dn_from_pyobject(msg, value, self, &msg->dn) != 0) {
return 80;
}
} else {
msgel = ldb_msg_element_from_pyobject(msg->elements, value, 0, PyString_AsString(key));
if (msgel == NULL) {
SWIG_exception(SWIG_TypeError, "unable to import element");
return 80;
}
memcpy(&msg->elements[msg_pos], msgel, sizeof(*msgel));
msg_pos++;
}
}
if (msg->dn == NULL) {
SWIG_exception(SWIG_TypeError, "no dn set");
return 80;
}
msg->num_elements = msg_pos;
} else {
if (SWIG_ConvertPtr(py_msg, (void **)&msg, SWIGTYPE_p_ldb_message, 0) != 0)
return 80;
}
ret = ldb_add(self, msg);
talloc_free(msg);
return ret;
fail:
return 80;
}
SWIGINTERN PyObject *ldb_schema_format_value(ldb *self,char const *element_name,PyObject *val){
const struct ldb_schema_attribute *a;
struct ldb_val old_val;
@ -4733,27 +4687,61 @@ fail:
}
SWIGINTERN PyObject *_wrap_Ldb_add__SWIG_0(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) {
SWIGINTERN PyObject *_wrap_Ldb_add(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
ldb_msg *arg2 = (ldb_msg *) 0 ;
ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
PyObject * obj0 = 0 ;
PyObject * obj1 = 0 ;
char * kwnames[] = {
(char *) "self",(char *) "add_msg", NULL
};
if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OO:Ldb_add",kwnames,&obj0,&obj1)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb_add" "', argument " "1"" of type '" "ldb *""'");
}
arg1 = (ldb *)(argp1);
res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_ldb_message, 0 | 0 );
if (!SWIG_IsOK(res2)) {
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Ldb_add" "', argument " "2"" of type '" "ldb_msg *""'");
{
int dict_pos, msg_pos;
PyObject *key, *value;
ldb_msg_element *msgel;
if (PyDict_Check(obj1)) {
arg2 = ldb_msg_new(NULL);
arg2->elements = talloc_zero_array(arg2, struct ldb_message_element, PyDict_Size(obj1));
msg_pos = dict_pos = 0;
while (PyDict_Next(obj1, &dict_pos, &key, &value)) {
if (!strcmp(PyString_AsString(key), "dn")) {
/* using argp0 (magic SWIG value) here is a hack */
if (ldb_dn_from_pyobject(arg2, value, argp1, &arg2->dn) != 0) {
SWIG_exception(SWIG_TypeError, "unable to import dn object");
}
} else {
msgel = ldb_msg_element_from_pyobject(arg2->elements, value, 0, PyString_AsString(key));
if (msgel == NULL) {
SWIG_exception(SWIG_TypeError, "unable to import element");
}
memcpy(&arg2->elements[msg_pos], msgel, sizeof(*msgel));
msg_pos++;
}
}
if (arg2->dn == NULL) {
SWIG_exception(SWIG_TypeError, "no dn set");
}
arg2->num_elements = msg_pos;
} else {
if (SWIG_ConvertPtr(obj1, (void **)&arg2, SWIGTYPE_p_ldb_message, 0) != 0) {
SWIG_exception(SWIG_TypeError, "unable to convert ldb message");
}
}
}
arg2 = (ldb_msg *)(argp2);
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
@ -4772,64 +4760,6 @@ fail:
}
SWIGINTERN PyObject *_wrap_Ldb_add__SWIG_1(PyObject *SWIGUNUSEDPARM(self), int nobjs, PyObject **swig_obj) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
PyObject *arg2 = (PyObject *) 0 ;
ldb_error result;
void *argp1 = 0 ;
int res1 = 0 ;
if ((nobjs < 2) || (nobjs > 2)) SWIG_fail;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ldb_context, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Ldb_add" "', argument " "1"" of type '" "ldb *""'");
}
arg1 = (ldb *)(argp1);
arg2 = swig_obj[1];
if (arg1 == NULL)
SWIG_exception(SWIG_ValueError,
"ldb context must be non-NULL");
result = ldb_add__SWIG_1(arg1,arg2);
if (result != 0) {
PyErr_SetObject(PyExc_LdbError, Py_BuildValue((char *)"(i,s)", result, ldb_strerror(result)));
SWIG_fail;
}
resultobj = Py_None;
return resultobj;
fail:
return NULL;
}
SWIGINTERN PyObject *_wrap_Ldb_add(PyObject *self, PyObject *args) {
int argc;
PyObject *argv[3];
if (!(argc = SWIG_Python_UnpackTuple(args,"Ldb_add",0,2,argv))) SWIG_fail;
--argc;
if (argc == 2) {
int _v = 0;
{
void *vptr = 0;
int res = SWIG_ConvertPtr(argv[1], &vptr, SWIGTYPE_p_ldb_message, 0);
_v = SWIG_CheckState(res);
}
if (!_v) goto check_1;
return _wrap_Ldb_add__SWIG_0(self, argc, argv);
}
check_1:
if (argc == 2) {
return _wrap_Ldb_add__SWIG_1(self, argc, argv);
}
fail:
SWIG_SetErrorMsg(PyExc_NotImplementedError,"Wrong number of arguments for overloaded function 'Ldb_add'.\n Possible C/C++ prototypes are:\n"" add(ldb *,ldb_msg *)\n"" add(ldb *,PyObject *)\n");
return NULL;
}
SWIGINTERN PyObject *_wrap_Ldb_modify(PyObject *SWIGUNUSEDPARM(self), PyObject *args, PyObject *kwargs) {
PyObject *resultobj = 0;
ldb *arg1 = (ldb *) 0 ;
@ -5729,7 +5659,7 @@ static PyMethodDef SwigMethods[] = {
{ (char *)"Ldb_delete", (PyCFunction) _wrap_Ldb_delete, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_rename", (PyCFunction) _wrap_Ldb_rename, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_parse_control_strings", (PyCFunction) _wrap_Ldb_parse_control_strings, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_add", _wrap_Ldb_add, METH_VARARGS, NULL},
{ (char *)"Ldb_add", (PyCFunction) _wrap_Ldb_add, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_modify", (PyCFunction) _wrap_Ldb_modify, METH_VARARGS | METH_KEYWORDS, NULL},
{ (char *)"Ldb_get_config_basedn", (PyCFunction)_wrap_Ldb_get_config_basedn, METH_O, NULL},
{ (char *)"Ldb_get_root_basedn", (PyCFunction)_wrap_Ldb_get_root_basedn, METH_O, NULL},

View File

@ -55,18 +55,66 @@ static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx,
return WERR_GENERAL_FAILURE;
}
static WERROR reg_dir_delete_recursive(const char *name)
{
DIR *d;
struct dirent *e;
WERROR werr;
d = opendir(name);
if (d == NULL) {
DEBUG(3,("Unable to open '%s': %s\n", name,
strerror(errno)));
return WERR_BADFILE;
}
while((e = readdir(d))) {
char *path;
struct stat stbuf;
if (ISDOT(e->d_name) || ISDOTDOT(e->d_name))
continue;
path = talloc_asprintf(name, "%s/%s", name, e->d_name);
if (!path)
return WERR_NOMEM;
stat(path, &stbuf);
if (!S_ISDIR(stbuf.st_mode)) {
if (unlink(path) < 0) {
talloc_free(path);
closedir(d);
return WERR_GENERAL_FAILURE;
}
} else {
werr = reg_dir_delete_recursive(path);
if (!W_ERROR_IS_OK(werr)) {
talloc_free(path);
closedir(d);
return werr;
}
}
talloc_free(path);
}
closedir(d);
if (rmdir(name) == 0)
return WERR_OK;
else if (errno == ENOENT)
return WERR_BADFILE;
else
return WERR_GENERAL_FAILURE;
}
static WERROR reg_dir_del_key(const struct hive_key *k, const char *name)
{
struct dir_key *dk = talloc_get_type(k, struct dir_key);
char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name);
WERROR ret;
if (rmdir(child) == 0)
ret = WERR_OK;
else if (errno == ENOENT)
ret = WERR_BADFILE;
else
ret = WERR_GENERAL_FAILURE;
ret = reg_dir_delete_recursive(child);
talloc_free(child);

View File

@ -442,33 +442,6 @@ static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent,
return WERR_OK;
}
static WERROR ldb_del_key(const struct hive_key *key, const char *name)
{
int ret;
struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data);
struct ldb_dn *ldap_path;
TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key");
ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
ret = ldb_delete(parentkd->ldb, ldap_path);
talloc_free(mem_ctx);
if (ret == LDB_ERR_NO_SUCH_OBJECT) {
return WERR_BADFILE;
} else if (ret != LDB_SUCCESS) {
DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(parentkd->ldb)));
return WERR_FOOBAR;
}
/* reset cache */
talloc_free(parentkd->subkeys);
parentkd->subkeys = NULL;
return WERR_OK;
}
static WERROR ldb_del_value (struct hive_key *key, const char *child)
{
int ret;
@ -501,6 +474,122 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child)
return WERR_OK;
}
static WERROR ldb_del_key(const struct hive_key *key, const char *name)
{
int i, ret;
struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data);
struct ldb_dn *ldap_path;
TALLOC_CTX *mem_ctx = talloc_init("ldb_del_key");
struct ldb_context *c = parentkd->ldb;
struct ldb_result *res_keys;
struct ldb_result *res_vals;
WERROR werr;
struct hive_key *hk;
/* Verify key exists by opening it */
werr = ldb_open_key(mem_ctx, key, name, &hk);
if (!W_ERROR_IS_OK(werr)) {
talloc_free(mem_ctx);
return werr;
}
ldap_path = reg_path_to_ldb(mem_ctx, key, name, NULL);
if (!ldap_path) {
talloc_free(mem_ctx);
return WERR_FOOBAR;
}
/* Search for subkeys */
ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL,
"(key=*)", NULL, &res_keys);
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Error getting subkeys for '%s': %s\n",
ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
talloc_free(mem_ctx);
return WERR_FOOBAR;
}
/* Search for values */
ret = ldb_search(c, ldap_path, LDB_SCOPE_ONELEVEL,
"(value=*)", NULL, &res_vals);
if (ret != LDB_SUCCESS) {
DEBUG(0, ("Error getting values for '%s': %s\n",
ldb_dn_get_linearized(ldap_path), ldb_errstring(c)));
talloc_free(mem_ctx);
return WERR_FOOBAR;
}
/* Start an explicit transaction */
ret = ldb_transaction_start(c);
if (ret != LDB_SUCCESS) {
DEBUG(0, ("ldb_transaction_start: %s\n", ldb_errstring(c)));
talloc_free(mem_ctx);
return WERR_FOOBAR;
}
if (res_keys->count || res_vals->count)
{
/* Delete any subkeys */
for (i = 0; i < res_keys->count; i++)
{
werr = ldb_del_key(hk, ldb_msg_find_attr_as_string(
res_keys->msgs[i],
"key", NULL));
if (!W_ERROR_IS_OK(werr)) {
ret = ldb_transaction_cancel(c);
talloc_free(mem_ctx);
return werr;
}
}
/* Delete any values */
for (i = 0; i < res_vals->count; i++)
{
werr = ldb_del_value(hk, ldb_msg_find_attr_as_string(
res_vals->msgs[i],
"value", NULL));
if (!W_ERROR_IS_OK(werr)) {
ret = ldb_transaction_cancel(c);
talloc_free(mem_ctx);
return werr;
}
}
}
/* Delete the key itself */
ret = ldb_delete(c, ldap_path);
if (ret != LDB_SUCCESS)
{
DEBUG(1, ("ldb_del_key: %s\n", ldb_errstring(c)));
ret = ldb_transaction_cancel(c);
talloc_free(mem_ctx);
return WERR_FOOBAR;
}
/* Commit the transaction */
ret = ldb_transaction_commit(c);
if (ret != LDB_SUCCESS)
{
DEBUG(0, ("ldb_transaction_commit: %s\n", ldb_errstring(c)));
ret = ldb_transaction_cancel(c);
talloc_free(mem_ctx);
return WERR_FOOBAR;
}
talloc_free(mem_ctx);
/* reset cache */
talloc_free(parentkd->subkeys);
parentkd->subkeys = NULL;
return WERR_OK;
}
static WERROR ldb_set_value(struct hive_key *parent,
const char *name, uint32_t type,
const DATA_BLOB data)

View File

@ -1618,10 +1618,55 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name)
return WERR_BADFILE;
}
if (key->nk->subkeys_offset != -1 ||
key->nk->values_offset != -1) {
DEBUG(0, ("Key '%s' is not empty.\n", name));
return WERR_FILE_EXISTS;
if (key->nk->subkeys_offset != -1) {
char *sk_name;
struct hive_key *sk = (struct hive_key *)key;
int i = key->nk->num_subkeys;
while (i--) {
/* Get subkey information. */
error = regf_get_subkey_by_index(parent_nk, sk, 0,
(const char **)&sk_name,
NULL, NULL);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Can't retrieve subkey by index.\n"));
return error;
}
/* Delete subkey. */
error = regf_del_key(sk, sk_name);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Can't delete key '%s'.\n", sk_name));
return error;
}
talloc_free(sk_name);
}
}
if (key->nk->values_offset != -1) {
char *val_name;
struct hive_key *sk = (struct hive_key *)key;
DATA_BLOB data;
int i = key->nk->num_values;
while (i--) {
/* Get value information. */
error = regf_get_value(parent_nk, sk, 0,
(const char **)&val_name,
NULL, &data);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Can't retrieve value by index.\n"));
return error;
}
/* Delete value. */
error = regf_del_value(sk, val_name);
if (!W_ERROR_IS_OK(error)) {
DEBUG(0, ("Can't delete value '%s'.\n", val_name));
return error;
}
talloc_free(val_name);
}
}
/* Delete it from the subkey list. */

View File

@ -111,6 +111,38 @@ static bool test_add_subkey(struct torture_context *tctx,
return true;
}
static bool test_del_recursive(struct torture_context *tctx,
const void *test_data)
{
WERROR error;
struct hive_key *subkey;
struct hive_key *subkey2;
const struct hive_key *root = (const struct hive_key *)test_data;
TALLOC_CTX *mem_ctx = tctx;
uint32_t data = 42;
/* Create a new key under the root */
error = hive_key_add_name(mem_ctx, root, "Parent Key", NULL,
NULL, &subkey);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
/* Create a new key under "Parent Key" */
error = hive_key_add_name(mem_ctx, subkey, "Child Key", NULL,
NULL, &subkey2);
torture_assert_werr_ok(tctx, error, "hive_key_add_name");
/* Create a new value under "Child Key" */
error = hive_key_set_value(subkey2, "Answer Recursive", REG_DWORD,
data_blob_talloc(mem_ctx, &data, sizeof(data)));
torture_assert_werr_ok(tctx, error, "hive_key_set_value");
/* Deleting "Parent Key" will also delete "Child Key" and the value. */
error = hive_key_del(root, "Parent Key");
torture_assert_werr_ok(tctx, error, "hive_key_del");
return true;
}
static bool test_flush_key(struct torture_context *tctx, void *test_data)
{
struct hive_key *root = (struct hive_key *)test_data;
@ -273,6 +305,11 @@ static void tcase_add_tests(struct torture_tcase *tcase)
test_add_subkey);
torture_tcase_add_simple_test(tcase, "flush_key",
test_flush_key);
/* test_del_recursive() test must run before test_keyinfo_root().
test_keyinfo_root() checks the number of subkeys, which verifies
the recursive delete worked properly. */
torture_tcase_add_simple_test_const(tcase, "del_recursive",
test_del_recursive);
torture_tcase_add_simple_test_const(tcase, "get_info",
test_keyinfo_root);
torture_tcase_add_simple_test(tcase, "get_info_nums",

View File

@ -298,8 +298,8 @@ include librpc/idl-deps
librpc/gen_ndr/tables.c: $(IDL_NDR_PARSE_H_FILES)
@echo Generating $@
@$(PERL) $(srcdir)/librpc/tables.pl --output=$@ $(IDL_NDR_PARSE_H_FILES) > librpc/gen_ndr/tables.x
mv librpc/gen_ndr/tables.x $@
@$(PERL) $(srcdir)/librpc/tables.pl --output=$@ $^ > librpc/gen_ndr/tables.x
@mv librpc/gen_ndr/tables.x $@
[SUBSYSTEM::NDR_TABLE]
OBJ_FILES = ndr/ndr_table.o gen_ndr/tables.o

View File

@ -142,6 +142,14 @@ _PUBLIC_ NTSTATUS odb_rename(struct odb_lock *lck, const char *path)
return ops->odb_rename(lck, path);
}
/*
get back the path of an open file
*/
_PUBLIC_ NTSTATUS odb_get_path(struct odb_lock *lck, const char **path)
{
return ops->odb_get_path(lck, path);
}
/*
update delete on close flag on an open file
*/

View File

@ -36,6 +36,7 @@ struct opendb_ops {
const char **delete_path);
NTSTATUS (*odb_remove_pending)(struct odb_lock *lck, void *private);
NTSTATUS (*odb_rename)(struct odb_lock *lck, const char *path);
NTSTATUS (*odb_get_path)(struct odb_lock *lck, const char **path);
NTSTATUS (*odb_set_delete_on_close)(struct odb_lock *lck, bool del_on_close);
NTSTATUS (*odb_get_delete_on_close)(struct odb_context *odb,
DATA_BLOB *key, bool *del_on_close);

View File

@ -713,6 +713,25 @@ static NTSTATUS odb_tdb_rename(struct odb_lock *lck, const char *path)
return odb_push_record(lck, &file);
}
/*
get the path of an open file
*/
static NTSTATUS odb_tdb_get_path(struct odb_lock *lck, const char **path)
{
struct opendb_file file;
NTSTATUS status;
*path = NULL;
status = odb_pull_record(lck, &file);
/* we don't ignore NT_STATUS_OBJECT_NAME_NOT_FOUND here */
NT_STATUS_NOT_OK_RETURN(status);
*path = file.path;
return NT_STATUS_OK;
}
/*
update delete on close flag on an open file
*/
@ -802,6 +821,7 @@ static const struct opendb_ops opendb_tdb_ops = {
.odb_close_file = odb_tdb_close_file,
.odb_remove_pending = odb_tdb_remove_pending,
.odb_rename = odb_tdb_rename,
.odb_get_path = odb_tdb_get_path,
.odb_set_delete_on_close = odb_tdb_set_delete_on_close,
.odb_get_delete_on_close = odb_tdb_get_delete_on_close,
.odb_can_open = odb_tdb_can_open,

View File

@ -144,8 +144,8 @@ static NTSTATUS pvfs_open_setup_eas_acl(struct pvfs_state *pvfs,
form the lock context used for opendb locking. Note that we must
zero here to take account of possible padding on some architectures
*/
static NTSTATUS pvfs_locking_key(struct pvfs_filename *name,
TALLOC_CTX *mem_ctx, DATA_BLOB *key)
NTSTATUS pvfs_locking_key(struct pvfs_filename *name,
TALLOC_CTX *mem_ctx, DATA_BLOB *key)
{
struct {
dev_t device;

View File

@ -368,7 +368,7 @@ NTSTATUS pvfs_qfileinfo(struct ntvfs_module_context *ntvfs,
}
/* update the file information */
status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
status = pvfs_resolve_name_handle(pvfs, h);
if (!NT_STATUS_IS_OK(status)) {
return status;
}

View File

@ -28,16 +28,22 @@
/*
do a file rename, and send any notify triggers
*/
NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs, const struct pvfs_filename *name1,
NTSTATUS pvfs_do_rename(struct pvfs_state *pvfs,
struct odb_lock *lck,
const struct pvfs_filename *name1,
const char *name2)
{
const char *r1, *r2;
uint32_t mask;
NTSTATUS status;
if (rename(name1->full_name, name2) == -1) {
return pvfs_map_errno(pvfs, errno);
}
status = odb_rename(lck, name2);
NT_STATUS_NOT_OK_RETURN(status);
if (name1->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
mask = FILE_NOTIFY_CHANGE_DIR_NAME;
} else {
@ -315,11 +321,7 @@ static NTSTATUS pvfs_rename_one(struct pvfs_state *pvfs,
return NT_STATUS_NO_MEMORY;
}
status = pvfs_do_rename(pvfs, name1, fname2);
if (NT_STATUS_IS_OK(status)) {
status = odb_rename(lck, fname2);
}
status = pvfs_do_rename(pvfs, lck, name1, fname2);
failed:
talloc_free(mem_ctx);
@ -448,9 +450,9 @@ static NTSTATUS pvfs_rename_mv(struct ntvfs_module_context *ntvfs,
return status;
}
status = pvfs_do_rename(pvfs, name1, name2->full_name);
if (NT_STATUS_IS_OK(status)) {
status = odb_rename(lck, name2->full_name);
status = pvfs_do_rename(pvfs, lck, name1, name2->full_name);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
return NT_STATUS_OK;
@ -532,10 +534,7 @@ static NTSTATUS pvfs_rename_nt(struct ntvfs_module_context *ntvfs,
case RENAME_FLAG_RENAME:
status = pvfs_access_check_parent(pvfs, req, name2, SEC_DIR_ADD_FILE);
NT_STATUS_NOT_OK_RETURN(status);
status = pvfs_do_rename(pvfs, name1, name2->full_name);
if (NT_STATUS_IS_OK(status)) {
status = odb_rename(lck, name2->full_name);
}
status = pvfs_do_rename(pvfs, lck, name1, name2->full_name);
NT_STATUS_NOT_OK_RETURN(status);
break;

View File

@ -265,8 +265,15 @@ static NTSTATUS pvfs_unix_path(struct pvfs_state *pvfs, const char *cifs_name,
of a name */
return NT_STATUS_ILLEGAL_CHARACTER;
}
if (p > p_start && p[1] == 0) {
*p = 0;
if (p > p_start && (p[1] == '\\' || p[1] == '\0')) {
/* see if it is definately a "\\" or
* a trailing "\". If it is then fail here,
* and let the next layer up try again after
* pvfs_reduce_name() if it wants to. This is
* much more efficient on average than always
* scanning for these separately
*/
return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
} else {
*p = '/';
}
@ -399,7 +406,7 @@ static NTSTATUS pvfs_reduce_name(TALLOC_CTX *mem_ctx,
if (ISDOTDOT(components[i])) {
if (i < 1) return NT_STATUS_OBJECT_PATH_SYNTAX_BAD;
memmove(&components[i-1], &components[i+1],
sizeof(char *)*(num_components-(i+1)));
sizeof(char *)*(num_components-i));
i -= 2;
continue;
}
@ -616,6 +623,86 @@ NTSTATUS pvfs_resolve_name_fd(struct pvfs_state *pvfs, int fd,
return pvfs_fill_dos_info(pvfs, name, fd);
}
/*
fill in the pvfs_filename info for an open file, given the current
info for a (possibly) non-open file. This is used by places that need
to update the pvfs_filename stat information, and the path
after a possible rename on a different handle.
*/
NTSTATUS pvfs_resolve_name_handle(struct pvfs_state *pvfs,
struct pvfs_file_handle *h)
{
NTSTATUS status;
if (h->have_opendb_entry) {
struct odb_lock *lck;
const char *name = NULL;
lck = odb_lock(h, h->pvfs->odb_context, &h->odb_locking_key);
if (lck == NULL) {
DEBUG(0,("%s: failed to lock file '%s' in opendb\n",
__FUNCTION__, h->name->full_name));
/* we were supposed to do a blocking lock, so something
is badly wrong! */
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
status = odb_get_path(lck, &name);
if (NT_STATUS_IS_OK(status)) {
/*
* This relies an the fact that
* renames of open files are only
* allowed by setpathinfo() and setfileinfo()
* and there're only renames within the same
* directory supported
*/
if (strcmp(h->name->full_name, name) != 0) {
const char *orig_dir;
const char *new_file;
const char *new_orig;
char *delim;
delim = strrchr(name, '/');
if (!delim) {
talloc_free(lck);
return NT_STATUS_INTERNAL_ERROR;
}
new_file = delim + 1;
delim = strrchr(h->name->original_name, '\\');
if (delim) {
delim[0] = '\0';
orig_dir = h->name->original_name;
new_orig = talloc_asprintf(h->name, "%s\\%s",
orig_dir, new_file);
if (!new_orig) {
talloc_free(lck);
return NT_STATUS_NO_MEMORY;
}
} else {
new_orig = talloc_strdup(h->name, new_file);
if (!new_orig) {
talloc_free(lck);
return NT_STATUS_NO_MEMORY;
}
}
talloc_free(h->name->original_name);
talloc_free(h->name->full_name);
h->name->full_name = talloc_steal(h->name, name);
h->name->original_name = new_orig;
}
}
talloc_free(lck);
}
status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
NT_STATUS_NOT_OK_RETURN(status);
return NT_STATUS_OK;
}
/*
resolve the parent of a given name

View File

@ -82,11 +82,13 @@ static uint32_t pvfs_setfileinfo_access(union smb_setfileinfo *info)
static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
struct ntvfs_request *req,
struct pvfs_filename *name,
DATA_BLOB *odb_locking_key,
union smb_setfileinfo *info)
{
NTSTATUS status;
struct pvfs_filename *name2;
char *new_name, *p;
struct odb_lock *lck = NULL;
/* renames are only allowed within a directory */
if (strchr_m(info->rename_information.in.new_name, '\\') &&
@ -94,11 +96,6 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
return NT_STATUS_NOT_SUPPORTED;
}
if (name->dos.attrib & FILE_ATTRIBUTE_DIRECTORY) {
/* don't allow this for now */
return NT_STATUS_FILE_IS_A_DIRECTORY;
}
/* don't allow stream renames for now */
if (name->stream_name) {
return NT_STATUS_INVALID_PARAMETER;
@ -168,7 +165,15 @@ static NTSTATUS pvfs_setfileinfo_rename(struct pvfs_state *pvfs,
return status;
}
status = pvfs_do_rename(pvfs, name, name2->full_name);
lck = odb_lock(req, pvfs->odb_context, odb_locking_key);
if (lck == NULL) {
DEBUG(0,("Unable to lock opendb for can_stat\n"));
return NT_STATUS_INTERNAL_DB_CORRUPTION;
}
status = pvfs_do_rename(pvfs, lck, name, name2->full_name);
talloc_free(lck);
NT_STATUS_NOT_OK_RETURN(status);
if (NT_STATUS_IS_OK(status)) {
name->full_name = talloc_steal(name, name2->full_name);
name->original_name = talloc_steal(name, name2->original_name);
@ -289,7 +294,7 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
}
/* update the file information */
status = pvfs_resolve_name_fd(pvfs, h->fd, h->name);
status = pvfs_resolve_name_handle(pvfs, h);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@ -391,7 +396,8 @@ NTSTATUS pvfs_setfileinfo(struct ntvfs_module_context *ntvfs,
case RAW_SFILEINFO_RENAME_INFORMATION:
case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
return pvfs_setfileinfo_rename(pvfs, req, h->name,
return pvfs_setfileinfo_rename(pvfs, req, h->name,
&h->odb_locking_key,
info);
case RAW_SFILEINFO_SEC_DESC:
@ -565,6 +571,7 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
uint32_t access_needed;
uint32_t change_mask = 0;
struct odb_lock *lck = NULL;
DATA_BLOB odb_locking_key;
/* resolve the cifs name to a posix name */
status = pvfs_resolve_name(pvfs, req, info->generic.in.file.path,
@ -696,8 +703,12 @@ NTSTATUS pvfs_setpathinfo(struct ntvfs_module_context *ntvfs,
case RAW_SFILEINFO_RENAME_INFORMATION:
case RAW_SFILEINFO_RENAME_INFORMATION_SMB2:
return pvfs_setfileinfo_rename(pvfs, req, name,
info);
status = pvfs_locking_key(name, name, &odb_locking_key);
NT_STATUS_NOT_OK_RETURN(status);
status = pvfs_setfileinfo_rename(pvfs, req, name,
&odb_locking_key, info);
NT_STATUS_NOT_OK_RETURN(status);
return NT_STATUS_OK;
case RAW_SFILEINFO_DISPOSITION_INFO:
case RAW_SFILEINFO_DISPOSITION_INFORMATION:

View File

@ -3,9 +3,7 @@ local.iconv.*.next_codepoint()
base.delaywrite.finfo update on close
base.delete.*.deltest20a
base.delete.*.deltest20b
raw.oplock.*BATCH19
raw.oplock.*BATCH20
rpc.winreg
rpc.winreg.*security
local.registry.*.security # Not implemented yet
rpc.wkssvc
rpc.handles.*.lsarpc-shared
@ -35,5 +33,4 @@ rpc.netlogon.*.GetTrustPasswords
base.charset.*.Testing partial surrogate
.*net.api.delshare.* # DelShare isn't implemented yet
rap.*netservergetinfo
samba4.blackbox.provision.py.reprovision # Fails with entry already exists
local.torture.provision

View File

@ -127,7 +127,7 @@ class Ldb(ldb.Ldb):
try:
self.delete(msg.dn)
except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _):
# Ignor eno such object errors
# Ignore no such object errors
pass
res = self.search(basedn, ldb.SCOPE_SUBTREE, "(&(|(objectclass=*)(distinguishedName=*))(!(distinguishedName=@BASEINFO)))", ["distinguishedName"])
@ -151,7 +151,14 @@ class Ldb(ldb.Ldb):
previous_remaining = current_remaining
current_remaining = len(res2)
for msg in res2:
self.delete(msg.dn)
try:
self.delete(msg.dn)
# Ignore no such object errors
except ldb.LdbError, (LDB_ERR_NO_SUCH_OBJECT, _):
pass
# Ignore not allowed on non leaf errors
except ldb.LdbError, (LDB_ERR_NOT_ALLOWED_ON_NON_LEAF, _):
pass
def load_ldif_file_add(self, ldif_path):
"""Load a LDIF file.

View File

@ -279,8 +279,6 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
Alternatively, provision() may call this, and then populate the database.
:param erase: Remove the existing data present in the database.
:note: This will wipe the Sam Database!
:note: This function always removes the local SAM LDB file. The erase
@ -289,10 +287,15 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info,
"""
assert session_info is not None
if os.path.exists(samdb_path):
samdb = SamDB(samdb_path, session_info=session_info,
credentials=credentials, lp=lp)
# Wipes the database
try:
samdb.erase()
except:
os.unlink(samdb_path)
# Also wipes the database
samdb = SamDB(samdb_path, session_info=session_info,
credentials=credentials, lp=lp)
@ -547,7 +550,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn,
def setup_samdb(path, setup_path, session_info, credentials, lp,
schemadn, configdn, domaindn, dnsdomain, realm,
netbiosname, message, hostname, rootdn, erase,
netbiosname, message, hostname, rootdn,
domainsid, aci, domainguid, policyguid,
domainname, fill, adminpass, krbtgtpass,
machinepass, hostguid, invocationid, dnspass,
@ -560,6 +563,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp,
assert serverrole in ("domain controller", "member server")
erase = (fill != FILL_DRS)
# Also wipes the database
setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn,
domaindn=domaindn, message=message, lp=lp,
@ -726,7 +731,7 @@ def provision(lp, setup_dir, message, paths, session_info,
hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None,
policyguid=None, invocationid=None, machinepass=None,
dnspass=None, root=None, nobody=None, nogroup=None, users=None,
wheel=None, backup=None, aci=None, serverrole=None, erase=False,
wheel=None, backup=None, aci=None, serverrole=None,
ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE):
"""Provision samba4
@ -830,7 +835,7 @@ def provision(lp, setup_dir, message, paths, session_info,
message("Setting up smb.conf")
if serverrole == "domain controller":
smbconfsuffix = "dc"
elif serverrole == "member":
elif serverrole == "member server":
smbconfsuffix = "member"
setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix),
paths.smbconf, {
@ -873,7 +878,7 @@ def provision(lp, setup_dir, message, paths, session_info,
configdn=configdn, domaindn=domaindn,
dnsdomain=dnsdomain, netbiosname=netbiosname,
realm=realm, message=message, hostname=hostname,
rootdn=rootdn, erase=erase, domainsid=domainsid,
rootdn=rootdn, domainsid=domainsid,
aci=aci, domainguid=domainguid, policyguid=policyguid,
domainname=domain, fill=samdb_fill,
adminpass=adminpass, krbtgtpass=krbtgtpass,

View File

@ -389,25 +389,26 @@ yoZeAErTALjyZYZEPcECQQDlUi0N8DFxQ/lOwWyR3Hailft+mPqoPCa8QHlQZnlG
EOF
#generated with
#hxtool issue-certificate --self-signed --issue-ca --ca-private-key=FILE:$KEYFILE \
# --subject="CN=CA,$BASEDN" --certificate="FILE:$CAFILE"
# hxtool issue-certificate --self-signed --issue-ca \
# --ca-private-key="FILE:$KEYFILE" \
# --subject="CN=CA,DC=samba,DC=example,DC=com" \
# --certificate="FILE:$CAFILE" --lifetime="25 years"
open(CAFILE, ">$cafile");
print CAFILE <<EOF;
-----BEGIN CERTIFICATE-----
MIIChTCCAe6gAwIBAgIUFZoF6jt0R+hQBdF7cWPy0tT3fGwwCwYJKoZIhvcNAQEFMFIxEzAR
MIICcTCCAdqgAwIBAgIUaBPmjnPVqyFqR5foICmLmikJTzgwCwYJKoZIhvcNAQEFMFIxEzAR
BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDcwMTIzMDU1MzA5WhgPMjAwODAxMjQw
NTUzMDlaMFIxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTIyMzEyWhgPMjAzMzAyMjQx
MjIzMTJaMFIxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMIGfMA0GCSqGSIb3DQEBAQUA
A4GNADCBiQKBgQDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpcol3+S9/6
I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H6H+pPqVIRLOmrWIm
ai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABo1YwVDAOBgNVHQ8BAf8EBAMC
AqQwEgYDVR0lBAswCQYHKwYBBQIDBTAdBgNVHQ4EFgQUwtm596AMotmzRU7IVdgrUvozyjIw
DwYDVR0TBAgwBgEB/wIBADANBgkqhkiG9w0BAQUFAAOBgQBgzh5uLDmESGYv60iUdEfuk/T9
VCpzb1z3VJVWt3uJoQYbcpR00SKeyMdlfTTLzO6tSPMmlk4hwqfvLkPzGCSObR4DRRYa0BtY
2laBVlg9X59bGpMUvpFQfpvxjvFWNJDL+377ELCVpLNdoR23I9TKXlalj0bY5Ks46CVIrm6W
EA==
ai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
AaYwHQYDVR0OBBYEFMLZufegDKLZs0VOyFXYK1L6M8oyMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
KoZIhvcNAQEFBQADgYEAAZJbCAAkaqgFJ0xgNovn8Ydd0KswQPjicwiODPgw9ZPoD2HiOUVO
yYDRg/dhFF9y656OpcHk4N7qZ2sl3RlHkzDu+dseETW+CnKvQIoXNyeARRJSsSlwrwcoD4JR
HTLk2sGigsWwrJ2N99sG/cqSJLJ1MFwLrs6koweBnYU0f/g=
-----END CERTIFICATE-----
EOF
@ -434,17 +435,23 @@ EOF
close(CERTFILE);
#KDC certificate
# hxtool request-create --subject="CN=krbtgt,cn=users,$basedn" --key=FILE:$KEYFILE $KDCREQ
# hxtool request-create \
# --subject="CN=krbtgt,CN=users,DC=samba,DC=example,DC=com" \
# --key="FILE:$KEYFILE" $KDCREQ
# hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE --type="pkinit-kdc" --pk-init-principal="krbtgt/$RELAM@$REALM" --req="$KDCREQ" --certificate="FILE:$KDCCERTFILE"
# hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
# --type="pkinit-kdc" \
# --pk-init-principal="krbtgt/SAMBA.EXAMPLE.COM@SAMBA.EXAMPLE.COM" \
# --req="PKCS10:$KDCREQ" --certificate="FILE:$KDCCERTFILE" \
# --lifetime="25 years"
open(KDCCERTFILE, ">$kdccertfile");
print KDCCERTFILE <<EOF;
-----BEGIN CERTIFICATE-----
MIIDDDCCAnWgAwIBAgIUDEhjaOT1ZjHjHHEn+l5eYO05oK8wCwYJKoZIhvcNAQEFMFIxEzAR
MIIDDDCCAnWgAwIBAgIUI2Tzj+JnMzMcdeabcNo30rovzFAwCwYJKoZIhvcNAQEFMFIxEzAR
BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDcwMTIzMDcwNzA4WhgPMjAwODAxMjQw
NzA3MDhaMGYxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTMxOTIzWhgPMjAzMzAyMjQx
MzE5MjNaMGYxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMQ8wDQYDVQQDDAZrcmJ0
Z3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMqDqkDAIdQwDUN8cOZaFl934XQL70nF
yq+nD2KL0SfcTW5+WlyiXf5L3/oj+5pOYkdmt74MXd1PNv9Q5mjRl6bw34jPOSCgaQVp+Ne5
@ -453,32 +460,40 @@ AAGjgcgwgcUwDgYDVR0PAQH/BAQDAgWgMBIGA1UdJQQLMAkGBysGAQUCAwUwVAYDVR0RBE0w
S6BJBgYrBgEFAgKgPzA9oBMbEVNBTUJBLkVYQU1QTEUuQ09NoSYwJKADAgEBoR0wGxsGa3Ji
dGd0GxFTQU1CQS5FWEFNUExFLkNPTTAfBgNVHSMEGDAWgBTC2bn3oAyi2bNFTshV2CtS+jPK
MjAdBgNVHQ4EFgQUwtm596AMotmzRU7IVdgrUvozyjIwCQYDVR0TBAIwADANBgkqhkiG9w0B
AQUFAAOBgQCMSgLkIv9RobE0a95H2ECA+5YABBwKXIt4AyN/HpV7iJdRx7B9PE6vM+nboVKY
E7i7ECUc3bu6NgrLu7CKHelNclHWWMiZzSUwhkXyvG/LE9qtr/onNu9NfLt1OV+dwQwyLdEP
n63FxSmsKg3dfi3ryQI/DIKeisvipwDtLqOn9g==
AQUFAAOBgQBmrVD5MCmZjfHp1nEnHqTIh8r7lSmVtDx4s9MMjxm9oNrzbKXynvdhwQYFVarc
ge4yRRDXtSebErOl71zVJI9CVeQQpwcH+tA85oGA7oeFtO/S7ls581RUU6tGgyxV4veD+lJv
KPH5LevUtgD+q9H4LU4Sq5N3iFwBaeryB0g2wg==
-----END CERTIFICATE-----
EOF
#hxtool request-create --subject="CN=Administrator,cn=users,$basedn" --key=FILE:$ADMINKEYFILE $ADMINREQFILE
#hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE --type="pkinit-client" --pk-init-principal="administrator@$REALM" --req="$ADMINREQFILE" --certificate="FILE:$ADMINCERTFILE"
# hxtool request-create \
# --subject="CN=Administrator,CN=users,DC=samba,DC=example,DC=com" \
# --key="FILE:$ADMINKEYFILE" $ADMINREQFILE
# hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
# --type="pkinit-client" \
# --pk-init-principal="administrator@SAMBA.EXAMPLE.COM" \
# --req="PKCS10:$ADMINREQFILE" --certificate="FILE:$ADMINCERTFILE" \
# --lifetime="25 years"
open(ADMINCERTFILE, ">$admincertfile");
print ADMINCERTFILE <<EOF;
-----BEGIN CERTIFICATE-----
MIICwjCCAiugAwIBAgIUXyECoq4im33ByZDWZMGhtpvHYWEwCwYJKoZIhvcNAQEFMFIxEzAR
MIIDHTCCAoagAwIBAgIUC0W5dW/N9kE+NgD0mKK34YgyqQ0wCwYJKoZIhvcNAQEFMFIxEzAR
BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDcwMTIzMDcyMzE2WhgPMjAwODAxMjQw
NzIzMTZaMCgxDjAMBgNVBAMMBXVzZXJzMRYwFAYDVQQDDA1BZG1pbmlzdHJhdG9yMIGfMA0G
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0+OL7TQBj0RejbIH1+g5GeRaWaM9xF43uE5y7jUHE
si5owhZF5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMFxB6esnXhl0Jpip1JkUMM
XLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xdl3JRlwIDAQABo4G8MIG5
MA4GA1UdDwEB/wQEAwIFoDASBgNVHSUECzAJBgcrBgEFAgMEMEgGA1UdEQRBMD+gPQYGKwYB
BQICoDMwMaATGxFTQU1CQS5FWEFNUExFLkNPTaEaMBigAwIBAaERMA8bDWFkbWluaXN0cmF0
b3IwHwYDVR0jBBgwFoAUwtm596AMotmzRU7IVdgrUvozyjIwHQYDVR0OBBYEFCDzVsvJ8IDz
wLYH8EONeUa5oVrGMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQEFBQADgYEAbTCnaPTieVZPV3bH
UmAMbnF9+YN1mCbe2xZJ0xzve+Yw1XO82iv/9kZaZkcRkaQt2qcwsBK/aSPOgfqGx+mJ7hXQ
AGWvAJhnWi25PawNaRysCN8WC6+nWKR4d2O2m5rpj3T9kH5WE7QbG0bCu92dGaS29FvWDCP3
q9pRtDOoAZc=
LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTMyMzAwWhgPMjAzMzAyMjQx
MzIzMDBaMG0xEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMRYwFAYDVQQDDA1BZG1p
bmlzdHJhdG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0+OL7TQBj0RejbIH1+g5G
eRaWaM9xF43uE5y7jUHEsi5owhZF5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMF
xB6esnXhl0Jpip1JkUMMXLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xd
l3JRlwIDAQABo4HSMIHPMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBgcrBgEFAgMEBggr
BgEFBQcDAgYKKwYBBAGCNxQCAjBIBgNVHREEQTA/oD0GBisGAQUCAqAzMDGgExsRU0FNQkEu
RVhBTVBMRS5DT02hGjAYoAMCAQGhETAPGw1hZG1pbmlzdHJhdG9yMB8GA1UdIwQYMBaAFMLZ
ufegDKLZs0VOyFXYK1L6M8oyMB0GA1UdDgQWBBQg81bLyfCA88C2B/BDjXlGuaFaxjAJBgNV
HRMEAjAAMA0GCSqGSIb3DQEBBQUAA4GBAHsqSqul0hZCXn4t8Kfp3v/JLMiUMJihR1XOgzoa
ufLOQ1HNzFUHKuo1JEQ1+i5gHT/arLu/ZBF4BfQol7vW27gKIEt0fkRV8EvoPxXvSokHq0Ku
HCuPOhYNEP3wYiwB3g93NMCinWVlz0mh5aijEU7y/XrjlZxBKFFrTE+BJi1o
-----END CERTIFICATE-----
EOF
close(ADMINCERTFILE);

View File

@ -54,24 +54,68 @@ static NTSTATUS single_search(struct smbcli_state *cli,
return status;
}
static bool test_path(struct smbcli_state *cli, const char *path, NTSTATUS expected, NTSTATUS dos_expected)
static bool test_path_ex(struct smbcli_state *cli, struct torture_context *tctx,
const char *path, const char *path_expected,
NTSTATUS expected, NTSTATUS dos_expected)
{
union smb_chkpath io;
union smb_fileinfo finfo;
NTSTATUS status;
io.chkpath.in.path = path;
status = smb_raw_chkpath(cli->tree, &io);
if (!NT_STATUS_EQUAL(status, expected) && !NT_STATUS_EQUAL(status, dos_expected)) {
printf("%-40s FAILED %s should be %s or %s\n",
printf("FAILED %-30s chkpath %s should be %s or %s\n",
path, nt_errstr(status), nt_errstr(expected), nt_errstr(dos_expected));
return false;
} else {
printf("%-40s correct (%s)\n", path, nt_errstr(status));
printf("%-30s chkpath correct (%s)\n", path, nt_errstr(status));
}
if (NT_STATUS_EQUAL(expected, NT_STATUS_NOT_A_DIRECTORY)) {
expected = NT_STATUS_OK;
}
ZERO_STRUCT(finfo);
finfo.generic.level = RAW_FILEINFO_NAME_INFO;
finfo.generic.in.file.path = path;
status = smb_raw_pathinfo(cli->tree, cli, &finfo);
if (!NT_STATUS_EQUAL(status, expected) && !NT_STATUS_EQUAL(status, dos_expected)) {
printf("FAILED: %-30s pathinfo %s should be %s or %s\n",
path, nt_errstr(status), nt_errstr(expected), nt_errstr(dos_expected));
return false;
}
if (!NT_STATUS_IS_OK(status)) {
printf("%-30s chkpath correct (%s)\n", path, nt_errstr(status));
return true;
}
if (path_expected &&
(!finfo.name_info.out.fname.s ||
strcmp(finfo.name_info.out.fname.s, path_expected) != 0)) {
if (tctx && torture_setting_bool(tctx, "samba4", false)) {
printf("IGNORE: %-30s => %-20s should be %s\n",
path, finfo.name_info.out.fname.s, path_expected);
return true;
}
printf("FAILED: %-30s => %-20s should be %s\n",
path, finfo.name_info.out.fname.s, path_expected);
return false;
}
printf("%-30s => %-20s correct\n",
path, finfo.name_info.out.fname.s);
return true;
}
static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
static bool test_path(struct smbcli_state *cli, const char *path,
NTSTATUS expected, NTSTATUS dos_expected)
{
return test_path_ex(cli, NULL, path, path, expected, dos_expected);
}
static bool test_chkpath(struct smbcli_state *cli, struct torture_context *tctx)
{
union smb_chkpath io;
NTSTATUS status;
@ -86,7 +130,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
ret &= test_path(cli, BASEDIR "\\nodir", NT_STATUS_OBJECT_NAME_NOT_FOUND, NT_STATUS_DOS(ERRDOS,ERRbadpath));
fnum = create_complex_file(cli, mem_ctx, BASEDIR "\\test.txt..");
fnum = create_complex_file(cli, tctx, BASEDIR "\\test.txt..");
if (fnum == -1) {
printf("failed to open test.txt - %s\n", smbcli_errstr(cli->tree));
ret = false;
@ -101,9 +145,20 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
goto done;
}
ret &= test_path(cli, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path(cli, BASEDIR "\\foo\\..\\test.txt..", NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_DOS(ERRDOS,ERRbadpath));
ret &= test_path(cli, "", NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR) + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\foo\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\f\\o\\o\\..\\..\\..") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, ((char *)BASEDIR"\\foo\\\\\..\\\\") + 1, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, BASEDIR"\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, BASEDIR"\\\\..\\"BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, BASEDIR"\\\\\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, "\\\\\\\\"BASEDIR"\\\\\\\\", BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, "\\\\\\\\"BASEDIR, BASEDIR, NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, BASEDIR "\\foo\\..\\test.txt..", BASEDIR "\\test.txt..",
NT_STATUS_NOT_A_DIRECTORY, NT_STATUS_DOS(ERRDOS,ERRbadpath));
ret &= test_path_ex(cli, tctx, "", "\\", NT_STATUS_OK, NT_STATUS_OK);
ret &= test_path(cli, ".", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
ret &= test_path(cli, ".\\", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
ret &= test_path(cli, "\\\\\\.\\", NT_STATUS_OBJECT_NAME_INVALID, NT_STATUS_DOS(ERRDOS,ERRbadpath));
@ -122,7 +177,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
give different NT status returns for chkpth and findfirst. */
printf("testing findfirst on %s\n", "\\.\\\\\\\\\\\\.");
status = single_search(cli, mem_ctx, "\\.\\\\\\\\\\\\.");
status = single_search(cli, tctx, "\\.\\\\\\\\\\\\.");
CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRinvalidname));
ret &= test_path(cli, "\\.\\\\\\\\\\\\.", NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
@ -164,7 +219,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
ret &= test_path(cli, "\\..\\", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
ret &= test_path(cli, "\\..", NT_STATUS_OBJECT_PATH_SYNTAX_BAD,NT_STATUS_DOS(ERRDOS,ERRinvalidpath));
ret &= test_path(cli, BASEDIR "\\.", NT_STATUS_OBJECT_NAME_INVALID,NT_STATUS_DOS(ERRDOS,ERRbadpath));
ret &= test_path(cli, BASEDIR "\\..", NT_STATUS_OK,NT_STATUS_OK);
ret &= test_path_ex(cli, tctx, BASEDIR "\\..", "\\", NT_STATUS_OK,NT_STATUS_OK);
ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb600", NT_STATUS_OBJECT_NAME_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
ret &= test_path(cli, BASEDIR "\\nt\\V S\\VB98\\vb6.exe", NT_STATUS_NOT_A_DIRECTORY,NT_STATUS_DOS(ERRDOS,ERRbadpath));
@ -183,7 +238,7 @@ static bool test_chkpath(struct smbcli_state *cli, TALLOC_CTX *mem_ctx)
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
printf("testing findfirst on %s\n", BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
status = single_search(cli, mem_ctx, BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
status = single_search(cli, tctx, BASEDIR".\\.\\.\\.\\foo\\..\\.\\");
CHECK_STATUS(status, NT_STATUS_OBJECT_PATH_NOT_FOUND,NT_STATUS_DOS(ERRDOS,ERRbadpath));
/* We expect this open to fail with the same error code as the chkpath below. */

View File

@ -453,6 +453,10 @@ bool torture_raw_sfileinfo_rename(struct torture_context *torture,
char *fnum_fname_new;
char *path_fname;
char *path_fname_new;
char *path_dname;
char *path_dname_new;
char *saved_name;
char *saved_name_new;
union smb_fileinfo finfo1, finfo2;
union smb_setfileinfo sfinfo;
NTSTATUS status, status2;
@ -464,6 +468,8 @@ bool torture_raw_sfileinfo_rename(struct torture_context *torture,
asprintf(&path_fname_new, BASEDIR "\\fname_test_new_%d.txt", n);
asprintf(&fnum_fname, BASEDIR "\\fnum_test_%d.txt", n);
asprintf(&fnum_fname_new, BASEDIR "\\fnum_test_new_%d.txt", n);
asprintf(&path_dname, BASEDIR "\\dname_test_%d", n);
asprintf(&path_dname_new, BASEDIR "\\dname_test_new_%d", n);
if (!torture_setup_dir(cli, BASEDIR)) {
return false;
@ -553,17 +559,112 @@ bool torture_raw_sfileinfo_rename(struct torture_context *torture,
sfinfo.rename_information.in.root_fid = d_fnum;
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_INVALID_PARAMETER);
CHECK_STR(NAME_INFO, name_info, fname.s, fnum_fname);
smbcli_close(cli->tree, d_fnum);
printf("Trying rename directory\n");
if (!torture_setup_dir(cli, path_dname)) {
ret = false;
goto done;
}
saved_name = path_fname;
saved_name_new = path_fname_new;
path_fname = path_dname;
path_fname_new = path_dname_new;
sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
sfinfo.rename_information.in.overwrite = 0;
sfinfo.rename_information.in.root_fid = 0;
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
path_fname = saved_name;
path_fname_new = saved_name_new;
if (torture_setting_bool(torture, "samba3", false)) {
printf("SKIP: Trying rename directory with a handle\n");
printf("SKIP: Trying rename by path while a handle is open\n");
printf("SKIP: Trying rename directory by path while a handle is open\n");
goto done;
}
printf("Trying rename directory with a handle\n");
status = create_directory_handle(cli->tree, path_dname_new, &d_fnum);
fnum_saved = fnum;
fnum = d_fnum;
saved_name = fnum_fname;
saved_name_new = fnum_fname_new;
fnum_fname = path_dname;
fnum_fname_new = path_dname_new;
sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
sfinfo.rename_information.in.overwrite = 0;
sfinfo.rename_information.in.root_fid = 0;
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
smbcli_close(cli->tree, d_fnum);
fnum = fnum_saved;
fnum_fname = saved_name;
fnum_fname_new = saved_name_new;
printf("Trying rename by path while a handle is open\n");
fnum_saved = fnum;
fnum = create_complex_file(cli, torture, path_fname);
sfinfo.rename_information.in.new_name = path_fname_new+strlen(BASEDIR)+1;
sfinfo.rename_information.in.overwrite = 0;
sfinfo.rename_information.in.root_fid = 0;
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
/* check that the handle returns the same name */
check_fnum = true;
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname_new);
/* rename it back on the handle */
sfinfo.rename_information.in.new_name = path_fname+strlen(BASEDIR)+1;
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
check_fnum = false;
CHECK_STR(NAME_INFO, name_info, fname.s, path_fname);
smbcli_close(cli->tree, fnum);
fnum = fnum_saved;
printf("Trying rename directory by path while a handle is open\n");
status = create_directory_handle(cli->tree, path_dname, &d_fnum);
fnum_saved = fnum;
fnum = d_fnum;
saved_name = path_fname;
saved_name_new = path_fname_new;
path_fname = path_dname;
path_fname_new = path_dname_new;
sfinfo.rename_information.in.new_name = path_dname_new+strlen(BASEDIR)+1;
sfinfo.rename_information.in.overwrite = 0;
sfinfo.rename_information.in.root_fid = 0;
CHECK_CALL_PATH(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
path_fname = saved_name;
path_fname_new = saved_name_new;
saved_name = fnum_fname;
saved_name_new = fnum_fname_new;
fnum_fname = path_dname;
fnum_fname_new = path_dname_new;
/* check that the handle returns the same name */
check_fnum = true;
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname_new);
/* rename it back on the handle */
sfinfo.rename_information.in.new_name = path_dname+strlen(BASEDIR)+1;
CHECK_CALL_FNUM(RENAME_INFORMATION, NT_STATUS_OK);
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
fnum_fname = saved_name;
fnum_fname_new = saved_name_new;
saved_name = path_fname;
saved_name_new = path_fname_new;
path_fname = path_dname;
path_fname_new = path_dname_new;
check_fnum = false;
CHECK_STR(NAME_INFO, name_info, fname.s, path_dname);
smbcli_close(cli->tree, d_fnum);
fnum = fnum_saved;
path_fname = saved_name;
path_fname_new = saved_name_new;
done:
smb_raw_exit(cli->session);
smbcli_close(cli->tree, fnum);
if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, fnum_fname))) {
printf("Failed to delete %s - %s\n", fnum_fname, smbcli_errstr(cli->tree));
}
if (NT_STATUS_IS_ERR(smbcli_unlink(cli->tree, path_fname))) {
printf("Failed to delete %s - %s\n", path_fname, smbcli_errstr(cli->tree));
}
smbcli_deltree(cli->tree, BASEDIR);
return ret;
}

View File

@ -848,7 +848,6 @@ static bool test_SecurityDescriptorInheritance(struct dcerpc_pipe *p,
out:
test_CloseKey(p, tctx, &new_handle);
test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD);
test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
test_RestoreSecurity(p, tctx, handle, key, sd_orig);
@ -971,7 +970,6 @@ static bool test_SecurityDescriptorBlockInheritance(struct dcerpc_pipe *p,
out:
test_CloseKey(p, tctx, &new_handle);
test_Cleanup(p, tctx, handle, TEST_SUBSUBKEY_SD);
test_Cleanup(p, tctx, handle, TEST_SUBKEY_SD);
test_RestoreSecurity(p, tctx, handle, key, sd_orig);
@ -1386,27 +1384,6 @@ static bool test_DeleteKey(struct dcerpc_pipe *p, struct torture_context *tctx,
return true;
}
/* DeleteKey on a key with subkey(s) should
* return WERR_ACCESS_DENIED. */
static bool test_DeleteKeyWithSubkey(struct dcerpc_pipe *p,
struct torture_context *tctx,
struct policy_handle *handle,
const char *key)
{
struct winreg_DeleteKey r;
r.in.handle = handle;
init_winreg_String(&r.in.key, key);
torture_assert_ntstatus_ok(tctx, dcerpc_winreg_DeleteKey(p, tctx, &r),
"DeleteKeyWithSubkey failed");
torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
"DeleteKeyWithSubkey failed");
return true;
}
static bool test_QueryInfoKey(struct dcerpc_pipe *p,
struct torture_context *tctx,
struct policy_handle *handle, char *class)
@ -1443,10 +1420,12 @@ static bool test_QueryInfoKey(struct dcerpc_pipe *p,
}
static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle, int depth);
struct policy_handle *handle, int depth,
bool test_security);
static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle, int depth)
struct policy_handle *handle, int depth,
bool test_security)
{
struct winreg_EnumKey r;
struct winreg_StringBuf class, name;
@ -1479,7 +1458,8 @@ static bool test_EnumKey(struct dcerpc_pipe *p, struct torture_context *tctx,
if (!test_OpenKey(p, tctx, handle, r.out.name->name,
&key_handle)) {
} else {
test_key(p, tctx, &key_handle, depth + 1);
test_key(p, tctx, &key_handle,
depth + 1, test_security);
}
}
@ -1676,7 +1656,8 @@ static bool test_InitiateSystemShutdownEx(struct torture_context *tctx,
#define MAX_DEPTH 2 /* Only go this far down the tree */
static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
struct policy_handle *handle, int depth)
struct policy_handle *handle, int depth,
bool test_security)
{
if (depth == MAX_DEPTH)
return true;
@ -1687,10 +1668,10 @@ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
if (!test_NotifyChangeKeyValue(p, tctx, handle)) {
}
if (!test_GetKeySecurity(p, tctx, handle, NULL)) {
if (test_security && !test_GetKeySecurity(p, tctx, handle, NULL)) {
}
if (!test_EnumKey(p, tctx, handle, depth)) {
if (!test_EnumKey(p, tctx, handle, depth, test_security)) {
}
if (!test_EnumValue(p, tctx, handle, 0xFF, 0xFFFF)) {
@ -1703,12 +1684,11 @@ static bool test_key(struct dcerpc_pipe *p, struct torture_context *tctx,
typedef NTSTATUS (*winreg_open_fn)(struct dcerpc_pipe *, TALLOC_CTX *, void *);
static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
void *userdata)
static bool test_Open_Security(struct torture_context *tctx,
struct dcerpc_pipe *p, void *userdata)
{
struct policy_handle handle, newhandle;
bool ret = true, created = false, created2 = false, deleted = false;
bool created3 = false, created_subkey = false;
bool ret = true, created2 = false;
bool created4 = false;
struct winreg_OpenHKLM r;
@ -1721,15 +1701,86 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
"open");
test_Cleanup(p, tctx, &handle, TEST_KEY1);
test_Cleanup(p, tctx, &handle, TEST_SUBSUBKEY_SD);
test_Cleanup(p, tctx, &handle, TEST_SUBKEY_SD);
test_Cleanup(p, tctx, &handle, TEST_KEY4);
test_Cleanup(p, tctx, &handle, TEST_KEY2);
test_Cleanup(p, tctx, &handle, TEST_SUBKEY);
test_Cleanup(p, tctx, &handle, TEST_KEY3);
test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
torture_comment(tctx,
"CreateKey (TEST_KEY_BASE) failed\n");
}
if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
NULL, &newhandle)) {
created2 = true;
}
if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
printf("CloseKey failed\n");
ret = false;
}
if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
created4 = true;
}
if (created4 && !test_CloseKey(p, tctx, &newhandle)) {
printf("CloseKey failed\n");
ret = false;
}
if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
ret = false;
}
if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
printf("DeleteKey failed\n");
ret = false;
}
if (created2 && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
printf("DeleteKey failed\n");
ret = false;
}
/* The HKCR hive has a very large fanout */
if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, true)) {
ret = false;
}
} else {
if (!test_key(p, tctx, &handle, 0, true)) {
ret = false;
}
}
test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
return ret;
}
static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
void *userdata)
{
struct policy_handle handle, newhandle;
bool ret = true, created = false, deleted = false;
bool created3 = false, created_subkey = false;
struct winreg_OpenHKLM r;
winreg_open_fn open_fn = userdata;
r.in.system_name = 0;
r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
r.out.handle = &handle;
torture_assert_ntstatus_ok(tctx, open_fn(p, tctx, &r),
"open");
test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
if (!test_CreateKey(p, tctx, &handle, TEST_KEY_BASE, NULL)) {
torture_comment(tctx,
"CreateKey (TEST_KEY_BASE) failed\n");
}
if (!test_CreateKey(p, tctx, &handle, TEST_KEY1, NULL)) {
torture_comment(tctx,
"CreateKey failed - not considering a failure\n");
@ -1763,9 +1814,12 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
}
if (created && deleted &&
test_OpenKey(p, tctx, &handle, TEST_KEY1, &newhandle)) {
!_test_OpenKey(p, tctx, &handle, TEST_KEY1,
SEC_FLAG_MAXIMUM_ALLOWED, &newhandle,
WERR_BADFILE, NULL)) {
torture_comment(tctx,
"DeleteKey failed (OpenKey after Delete worked)\n");
"DeleteKey failed (OpenKey after Delete "
"did not return WERR_BADFILE)\n");
ret = false;
}
@ -1774,40 +1828,6 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
ret = false;
}
if (created && test_CreateKey_sd(p, tctx, &handle, TEST_KEY2,
NULL, &newhandle)) {
created2 = true;
}
if (created2 && !test_CloseKey(p, tctx, &newhandle)) {
printf("CloseKey failed\n");
ret = false;
}
if (test_CreateKey_sd(p, tctx, &handle, TEST_KEY4, NULL, &newhandle)) {
created4 = true;
}
if (!created4 && !test_CloseKey(p, tctx, &newhandle)) {
printf("CloseKey failed\n");
ret = false;
}
if (created4 && !test_SecurityDescriptors(p, tctx, &handle, TEST_KEY4)) {
ret = false;
}
if (created4 && !test_DeleteKey(p, tctx, &handle, TEST_KEY4)) {
printf("DeleteKey failed\n");
ret = false;
}
if (created && !test_DeleteKey(p, tctx, &handle, TEST_KEY2)) {
printf("DeleteKey failed\n");
ret = false;
}
if (created && test_CreateKey(p, tctx, &handle, TEST_KEY3, NULL)) {
created3 = true;
}
@ -1818,19 +1838,6 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
}
if (created_subkey &&
!test_DeleteKeyWithSubkey(p, tctx, &handle, TEST_KEY3)) {
printf("DeleteKeyWithSubkey failed "
"(DeleteKey didn't return ACCESS_DENIED)\n");
ret = false;
}
if (created_subkey &&
!test_DeleteKey(p, tctx, &handle, TEST_SUBKEY)) {
printf("DeleteKey failed\n");
ret = false;
}
if (created3 &&
!test_DeleteKey(p, tctx, &handle, TEST_KEY3)) {
printf("DeleteKey failed\n");
ret = false;
@ -1838,13 +1845,13 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
/* The HKCR hive has a very large fanout */
if (open_fn == (void *)dcerpc_winreg_OpenHKCR) {
if(!test_key(p, tctx, &handle, MAX_DEPTH - 1)) {
if(!test_key(p, tctx, &handle, MAX_DEPTH - 1, false)) {
ret = false;
}
} else {
if (!test_key(p, tctx, &handle, 0, false)) {
ret = false;
}
}
if (!test_key(p, tctx, &handle, 0)) {
ret = false;
}
test_Cleanup(p, tctx, &handle, TEST_KEY_BASE);
@ -1854,14 +1861,6 @@ static bool test_Open(struct torture_context *tctx, struct dcerpc_pipe *p,
struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
{
struct {
const char *name;
winreg_open_fn fn;
} open_fns[] = {{"OpenHKLM", (winreg_open_fn)dcerpc_winreg_OpenHKLM },
{"OpenHKU", (winreg_open_fn)dcerpc_winreg_OpenHKU },
{"OpenHKCR", (winreg_open_fn)dcerpc_winreg_OpenHKCR },
{"OpenHKCU", (winreg_open_fn)dcerpc_winreg_OpenHKCU }};
int i;
struct torture_rpc_tcase *tcase;
struct torture_suite *suite = torture_suite_create(mem_ctx, "WINREG");
struct torture_test *test;
@ -1877,10 +1876,33 @@ struct torture_suite *torture_rpc_winreg(TALLOC_CTX *mem_ctx)
test_InitiateSystemShutdownEx);
test->dangerous = true;
for (i = 0; i < ARRAY_SIZE(open_fns); i++) {
torture_rpc_tcase_add_test_ex(tcase, open_fns[i].name,
test_Open, open_fns[i].fn);
}
/* Basic tests without security descriptors */
torture_rpc_tcase_add_test_ex(tcase, "HKLM-basic",
test_Open,
(winreg_open_fn)dcerpc_winreg_OpenHKLM);
torture_rpc_tcase_add_test_ex(tcase, "HKU-basic",
test_Open,
(winreg_open_fn)dcerpc_winreg_OpenHKU);
torture_rpc_tcase_add_test_ex(tcase, "HKCR-basic",
test_Open,
(winreg_open_fn)dcerpc_winreg_OpenHKCR);
torture_rpc_tcase_add_test_ex(tcase, "HKCU-basic",
test_Open,
(winreg_open_fn)dcerpc_winreg_OpenHKCU);
/* Security descriptor tests */
torture_rpc_tcase_add_test_ex(tcase, "HKLM-security",
test_Open_Security,
(winreg_open_fn)dcerpc_winreg_OpenHKLM);
torture_rpc_tcase_add_test_ex(tcase, "HKU-security",
test_Open_Security,
(winreg_open_fn)dcerpc_winreg_OpenHKU);
torture_rpc_tcase_add_test_ex(tcase, "HKCR-security",
test_Open_Security,
(winreg_open_fn)dcerpc_winreg_OpenHKCR);
torture_rpc_tcase_add_test_ex(tcase, "HKCU-security",
test_Open_Security,
(winreg_open_fn)dcerpc_winreg_OpenHKCU);
return suite;
}