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 2 of the License, or
+ 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,
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.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "libnet/libnet.h"
#include "librpc/gen_ndr/ndr_samr_c.h"
#include "librpc/gen_ndr/ndr_lsa_c.h"
-#include "torture/torture.h"
#include "torture/rpc/rpc.h"
#include "torture/libnet/usertest.h"
+#include "param/param.h"
-static BOOL test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *domain_handle, const char *username)
{
NTSTATUS status;
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);
status = dcerpc_samr_LookupNames(p, mem_ctx, &r1);
if (!NT_STATUS_IS_OK(status)) {
printf("LookupNames failed - %s\n", nt_errstr(status));
- return False;
+ 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;
status = dcerpc_samr_OpenUser(p, mem_ctx, &r2);
if (!NT_STATUS_IS_OK(status)) {
printf("OpenUser failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
r3.in.user_handle = &user_handle;
status = dcerpc_samr_DeleteUser(p, mem_ctx, &r3);
if (!NT_STATUS_IS_OK(status)) {
printf("DeleteUser failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
- return True;
+ return true;
}
-static BOOL test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, struct lsa_String *domname)
{
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");
status = dcerpc_samr_Connect(p, mem_ctx, &r1);
if (!NT_STATUS_IS_OK(status)) {
printf("Connect failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
r2.in.connect_handle = &h;
r2.in.domain_name = domname;
+ r2.out.sid = &sid;
printf("domain lookup on %s\n", domname->string);
status = dcerpc_samr_LookupDomain(p, mem_ctx, &r2);
if (!NT_STATUS_IS_OK(status)) {
printf("LookupDomain failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
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");
status = dcerpc_samr_OpenDomain(p, mem_ctx, &r3);
if (!NT_STATUS_IS_OK(status)) {
printf("OpenDomain failed - %s\n", nt_errstr(status));
- return False;
+ return false;
} else {
*handle = domain_handle;
}
- return True;
+ return true;
}
-static BOOL test_samr_close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+static bool test_samr_close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *domain_handle)
{
NTSTATUS status;
status = dcerpc_samr_Close(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("Close samr domain failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
- return True;
+ return true;
}
-static BOOL test_lsa_close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+static bool test_lsa_close(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *domain_handle)
{
NTSTATUS status;
status = dcerpc_lsa_Close(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("Close lsa domain failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
- return True;
+ return true;
}
-static BOOL test_createuser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+static bool test_createuser(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct policy_handle *handle, const char* user)
{
NTSTATUS status;
if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) {
printf("User (%s) already exists - attempting to delete and recreate account again\n", user);
if (!test_cleanup(p, mem_ctx, handle, TEST_USERNAME)) {
- return False;
+ return false;
}
printf("creating user account\n");
status = dcerpc_samr_CreateUser(p, mem_ctx, &r1);
if (!NT_STATUS_IS_OK(status)) {
printf("CreateUser failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
- return True;
+ return true;
}
- return False;
+ return false;
}
r2.in.handle = &user_handle;
status = dcerpc_samr_Close(p, mem_ctx, &r2);
if (!NT_STATUS_IS_OK(status)) {
printf("Close failed - %s\n", nt_errstr(status));
- return False;
+ return false;
}
- return True;
+ return true;
}
-BOOL torture_createuser(struct torture_context *torture)
+bool torture_createuser(struct torture_context *torture)
{
NTSTATUS status;
- const char *binding;
TALLOC_CTX *mem_ctx;
struct libnet_context *ctx;
struct libnet_CreateUser req;
- BOOL ret = True;
+ bool ret = true;
mem_ctx = talloc_init("test_createuser");
- binding = torture_setting_string(torture, "binding", NULL);
- ctx = libnet_context_init(NULL);
+ ctx = libnet_context_init(torture->ev, torture->lp_ctx);
ctx->cred = cmdline_credentials;
req.in.user_name = TEST_USERNAME;
- req.in.domain_name = lp_workgroup();
+ req.in.domain_name = lp_workgroup(torture->lp_ctx);
req.out.error_string = NULL;
status = libnet_CreateUser(ctx, mem_ctx, &req);
if (!NT_STATUS_IS_OK(status)) {
printf("libnet_CreateUser call failed: %s\n", nt_errstr(status));
- ret = False;
+ ret = false;
goto done;
}
if (!test_cleanup(ctx->samr.pipe, mem_ctx, &ctx->samr.handle, TEST_USERNAME)) {
printf("cleanup failed\n");
- ret = False;
+ ret = false;
goto done;
}
if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
printf("domain close failed\n");
- ret = False;
+ ret = false;
}
done:
}
-BOOL torture_deleteuser(struct torture_context *torture)
+bool torture_deleteuser(struct torture_context *torture)
{
NTSTATUS status;
- const char *binding;
struct dcerpc_pipe *p;
TALLOC_CTX *prep_mem_ctx, *mem_ctx;
struct policy_handle h;
const char *name = TEST_USERNAME;
struct libnet_context *ctx;
struct libnet_DeleteUser req;
- BOOL ret = True;
+ bool ret = true;
prep_mem_ctx = talloc_init("prepare test_deleteuser");
- binding = torture_setting_string(torture, "binding", NULL);
- ctx = libnet_context_init(NULL);
+ ctx = libnet_context_init(torture->ev, torture->lp_ctx);
ctx->cred = cmdline_credentials;
req.in.user_name = TEST_USERNAME;
- req.in.domain_name = lp_workgroup();
+ req.in.domain_name = lp_workgroup(torture->lp_ctx);
- status = torture_rpc_connection(prep_mem_ctx,
+ status = torture_rpc_connection(torture,
&p,
- &dcerpc_table_samr);
+ &ndr_table_samr);
if (!NT_STATUS_IS_OK(status)) {
- ret = False;
+ ret = false;
goto done;
}
- domain_name.string = lp_workgroup();
+ domain_name.string = lp_workgroup(torture->lp_ctx);
if (!test_opendomain(p, prep_mem_ctx, &h, &domain_name)) {
- ret = False;
+ ret = false;
goto done;
}
if (!test_createuser(p, prep_mem_ctx, &h, name)) {
- ret = False;
+ ret = false;
goto done;
}
status = libnet_DeleteUser(ctx, mem_ctx, &req);
if (!NT_STATUS_IS_OK(status)) {
printf("libnet_DeleteUser call failed: %s\n", nt_errstr(status));
- ret = False;
+ ret = false;
}
talloc_free(mem_ctx);
const char* logon_scripts[] = { "start_login.cmd", "login.bat", "start.cmd" };
const char* home_dirs[] = { "\\\\srv\\home", "\\\\homesrv\\home\\user", "\\\\pdcsrv\\domain" };
const char* home_drives[] = { "H:", "z:", "I:", "J:", "n:" };
+ const uint32_t flags[] = { (ACB_DISABLED | ACB_NORMAL | ACB_PW_EXPIRED),
+ (ACB_NORMAL | ACB_PWNOEXP),
+ (ACB_NORMAL | ACB_PW_EXPIRED) };
const char *homedir, *homedrive, *logonscript;
struct timeval now;
int i, testfld;
- srandom((unsigned)time(NULL));
-
printf("Fields to change: [");
for (i = 0; i < num_changes && i < FIELDS_NUM; i++) {
case home_directory:
continue_if_field_set(r->in.home_directory);
- homedir = home_dirs[random() % (sizeof(home_dirs)/sizeof(char*))];
+ homedir = home_dirs[random() % ARRAY_SIZE(home_dirs)];
r->in.home_directory = talloc_strdup(mem_ctx, homedir);
fldname = "home_dir";
break;
case home_drive:
continue_if_field_set(r->in.home_drive);
- homedrive = home_drives[random() % (sizeof(home_drives)/sizeof(char*))];
+ homedrive = home_drives[random() % ARRAY_SIZE(home_drives)];
r->in.home_drive = talloc_strdup(mem_ctx, homedrive);
fldname = "home_drive";
break;
case logon_script:
continue_if_field_set(r->in.logon_script);
- logonscript = logon_scripts[random() % (sizeof(logon_scripts)/sizeof(char*))];
+ logonscript = logon_scripts[random() % ARRAY_SIZE(logon_scripts)];
r->in.logon_script = talloc_strdup(mem_ctx, logonscript);
fldname = "logon_script";
break;
case acct_expiry:
continue_if_field_set(r->in.acct_expiry);
now = timeval_add(&now, (random() % (31*24*60*60)), 0);
- r->in.acct_expiry = talloc_memdup(mem_ctx, &now, sizeof(now));
+ r->in.acct_expiry = (struct timeval *)talloc_memdup(mem_ctx, &now, sizeof(now));
fldname = "acct_expiry";
break;
+ case acct_flags:
+ continue_if_field_set(r->in.acct_flags);
+ r->in.acct_flags = flags[random() % ARRAY_SIZE(flags)];
+ fldname = "acct_flags";
+ break;
+
default:
fldname = "unknown_field";
}
#define TEST_STR_FLD(fld) \
if (!strequal(req.in.fld, user_req.out.fld)) { \
printf("failed to change '%s'\n", #fld); \
- ret = False; \
+ ret = false; \
goto cleanup; \
}
#define TEST_TIME_FLD(fld) \
if (timeval_compare(req.in.fld, user_req.out.fld)) { \
printf("failed to change '%s'\n", #fld); \
- ret = False; \
+ ret = false; \
goto cleanup; \
}
#define TEST_NUM_FLD(fld) \
if (req.in.fld != user_req.out.fld) { \
printf("failed to change '%s'\n", #fld); \
- ret = False; \
+ ret = false; \
goto cleanup; \
}
-BOOL torture_modifyuser(struct torture_context *torture)
+bool torture_modifyuser(struct torture_context *torture)
{
NTSTATUS status;
- const char *binding;
- struct dcerpc_binding *bind;
+ struct dcerpc_binding *binding;
struct dcerpc_pipe *p;
- TALLOC_CTX *prep_mem_ctx, *mem_ctx;
+ TALLOC_CTX *prep_mem_ctx;
struct policy_handle h;
struct lsa_String domain_name;
char *name;
struct libnet_ModifyUser req;
struct libnet_UserInfo user_req;
int fld;
- BOOL ret = True;
+ bool ret = true;
prep_mem_ctx = talloc_init("prepare test_deleteuser");
- binding = torture_setting_string(torture, "binding", NULL);
- ctx = libnet_context_init(NULL);
+ ctx = libnet_context_init(torture->ev, torture->lp_ctx);
ctx->cred = cmdline_credentials;
- status = torture_rpc_connection(prep_mem_ctx,
+ status = torture_rpc_connection(torture,
&p,
- &dcerpc_table_samr);
+ &ndr_table_samr);
if (!NT_STATUS_IS_OK(status)) {
- ret = False;
+ ret = false;
goto done;
}
name = talloc_strdup(prep_mem_ctx, TEST_USERNAME);
- domain_name.string = lp_workgroup();
+ domain_name.string = lp_workgroup(torture->lp_ctx);
if (!test_opendomain(p, prep_mem_ctx, &h, &domain_name)) {
- ret = False;
+ ret = false;
goto done;
}
if (!test_createuser(p, prep_mem_ctx, &h, name)) {
- ret = False;
+ ret = false;
goto done;
}
- mem_ctx = talloc_init("test_modifyuser");
-
- status = dcerpc_parse_binding(mem_ctx, binding, &bind);
+ status = torture_rpc_binding(torture, &binding);
if (!NT_STATUS_IS_OK(status)) {
- ret = False;
+ ret = false;
goto done;
}
for (fld = 1; fld < FIELDS_NUM - 1; fld++) {
ZERO_STRUCT(req);
- req.in.domain_name = lp_workgroup();
+ req.in.domain_name = lp_workgroup(torture->lp_ctx);
req.in.user_name = name;
- set_test_changes(mem_ctx, &req, 1, &name, fld);
+ set_test_changes(torture, &req, 1, &name, fld);
- status = libnet_ModifyUser(ctx, mem_ctx, &req);
+ status = libnet_ModifyUser(ctx, torture, &req);
if (!NT_STATUS_IS_OK(status)) {
printf("libnet_ModifyUser call failed: %s\n", nt_errstr(status));
- ret = False;
+ ret = false;
continue;
}
ZERO_STRUCT(user_req);
- user_req.in.domain_name = lp_workgroup();
- user_req.in.user_name = name;
+ user_req.in.domain_name = lp_workgroup(torture->lp_ctx);
+ user_req.in.data.user_name = name;
+ user_req.in.level = USER_INFO_BY_NAME;
- status = libnet_UserInfo(ctx, mem_ctx, &user_req);
+ status = libnet_UserInfo(ctx, torture, &user_req);
if (!NT_STATUS_IS_OK(status)) {
printf("libnet_UserInfo call failed: %s\n", nt_errstr(status));
+ ret = false;
continue;
}
/* restore original testing username - it's useful when test fails
because it prevents from problems with recreating account */
ZERO_STRUCT(req);
- req.in.domain_name = lp_workgroup();
+ req.in.domain_name = lp_workgroup(torture->lp_ctx);
req.in.user_name = name;
req.in.account_name = TEST_USERNAME;
- status = libnet_ModifyUser(ctx, mem_ctx, &req);
+ status = libnet_ModifyUser(ctx, torture, &req);
if (!NT_STATUS_IS_OK(status)) {
printf("libnet_ModifyUser call failed: %s\n", nt_errstr(status));
- talloc_free(mem_ctx);
- ret = False;
+ ret = false;
goto done;
}
- name = talloc_strdup(mem_ctx, TEST_USERNAME);
+ name = talloc_strdup(torture, TEST_USERNAME);
}
}
cleanup:
- if (!test_cleanup(ctx->samr.pipe, mem_ctx, &ctx->samr.handle, name)) {
+ if (!test_cleanup(ctx->samr.pipe, torture, &ctx->samr.handle, name)) {
printf("cleanup failed\n");
- ret = False;
+ ret = false;
goto done;
}
- if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
+ if (!test_samr_close(ctx->samr.pipe, torture, &ctx->samr.handle)) {
printf("domain close failed\n");
- ret = False;
+ ret = false;
}
- talloc_free(mem_ctx);
-
done:
talloc_free(ctx);
talloc_free(prep_mem_ctx);
}
-BOOL torture_userinfo_api(struct torture_context *torture)
+bool torture_userinfo_api(struct torture_context *torture)
{
const char *name = TEST_USERNAME;
- const char *binding;
- BOOL ret = True;
+ bool ret = true;
NTSTATUS status;
TALLOC_CTX *mem_ctx = NULL, *prep_mem_ctx;
struct libnet_context *ctx;
struct libnet_UserInfo req;
prep_mem_ctx = talloc_init("prepare torture user info");
- binding = torture_setting_string(torture, "binding", NULL);
- ctx = libnet_context_init(NULL);
+ ctx = libnet_context_init(torture->ev, torture->lp_ctx);
ctx->cred = cmdline_credentials;
- status = torture_rpc_connection(prep_mem_ctx,
+ status = torture_rpc_connection(torture,
&p,
- &dcerpc_table_samr);
+ &ndr_table_samr);
if (!NT_STATUS_IS_OK(status)) {
- return False;
+ return false;
}
- domain_name.string = lp_workgroup();
+ domain_name.string = lp_workgroup(torture->lp_ctx);
if (!test_opendomain(p, prep_mem_ctx, &h, &domain_name)) {
- ret = False;
+ ret = false;
goto done;
}
if (!test_createuser(p, prep_mem_ctx, &h, name)) {
- ret = False;
+ ret = false;
goto done;
}
ZERO_STRUCT(req);
req.in.domain_name = domain_name.string;
- req.in.user_name = name;
+ req.in.data.user_name = name;
+ req.in.level = USER_INFO_BY_NAME;
status = libnet_UserInfo(ctx, mem_ctx, &req);
if (!NT_STATUS_IS_OK(status)) {
printf("libnet_UserInfo call failed: %s\n", nt_errstr(status));
- ret = False;
+ ret = false;
talloc_free(mem_ctx);
goto done;
}
if (!test_cleanup(ctx->samr.pipe, mem_ctx, &ctx->samr.handle, TEST_USERNAME)) {
printf("cleanup failed\n");
- ret = False;
+ ret = false;
goto done;
}
if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
printf("domain close failed\n");
- ret = False;
+ ret = false;
}
talloc_free(ctx);
}
-BOOL torture_userlist(struct torture_context *torture)
+bool torture_userlist(struct torture_context *torture)
{
- const char *binding;
- BOOL ret = True;
+ bool ret = true;
NTSTATUS status;
TALLOC_CTX *mem_ctx = NULL;
struct libnet_context *ctx;
struct lsa_String domain_name;
struct libnet_UserList req;
+ int i;
- binding = torture_setting_string(torture, "binding", NULL);
-
- ctx = libnet_context_init(NULL);
+ ctx = libnet_context_init(torture->ev, torture->lp_ctx);
ctx->cred = cmdline_credentials;
- domain_name.string = lp_workgroup();
+ domain_name.string = lp_workgroup(torture->lp_ctx);
mem_ctx = talloc_init("torture user list");
ZERO_STRUCT(req);
+
+ printf("listing user accounts:\n");
- req.in.domain_name = domain_name.string;
- req.in.page_size = 30;
- req.in.restore_index = 0;
+ do {
- status = libnet_UserList(ctx, mem_ctx, &req);
- if (!NT_STATUS_IS_OK(status)) {
+ req.in.domain_name = domain_name.string;
+ req.in.page_size = 128;
+ req.in.resume_index = req.out.resume_index;
+
+ status = libnet_UserList(ctx, mem_ctx, &req);
+ if (!NT_STATUS_IS_OK(status) &&
+ !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) break;
+
+ for (i = 0; i < req.out.count; i++) {
+ printf("\tuser: %s, sid=%s\n",
+ req.out.users[i].username, req.out.users[i].sid);
+ }
+
+ } while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
+
+ if (!(NT_STATUS_IS_OK(status) ||
+ NT_STATUS_EQUAL(status, NT_STATUS_NO_MORE_ENTRIES))) {
printf("libnet_UserList call failed: %s\n", nt_errstr(status));
- ret = False;
- talloc_free(mem_ctx);
+ ret = false;
+ goto done;
+ }
+
+ if (!test_samr_close(ctx->samr.pipe, mem_ctx, &ctx->samr.handle)) {
+ printf("samr domain close failed\n");
+ ret = false;
goto done;
}
if (!test_lsa_close(ctx->lsa.pipe, mem_ctx, &ctx->lsa.handle)) {
- printf("domain close failed\n");
- ret = False;
+ printf("lsa domain close failed\n");
+ ret = false;
}
talloc_free(ctx);