static struct smbcli_state * /* O - SMB connection */ smb_connect(const char *workgroup, /* I - Workgroup */ const char *server, /* I - Server */ const char *share, /* I - Printer */ const char *username, /* I - Username */ const char *password) /* I - Password */ { struct smbcli_state *c; /* New connection */ char *myname; /* Client name */ NTSTATUS nt_status; /* * Get the names and addresses of the client and server... */ myname = get_myname(); nt_status = smbcli_full_connection(NULL, &c, myname, server, 0, share, NULL, username, workgroup, password, NULL); free(myname); if (!NT_STATUS_IS_OK(nt_status)) { fprintf(stderr, "ERROR: Connection failed with error %s\n", nt_errstr(nt_status)); return NULL; } /* * Return the new connection... */ return (c); }
static struct smbcli_state *connect_to_server(struct torture_context *tctx) { NTSTATUS status; struct smbcli_state *cli; const char *host = torture_setting_string(tctx, "host", NULL); const char *share = torture_setting_string(tctx, "share", NULL); struct smbcli_options options; struct smbcli_session_options session_options; lpcfg_smbcli_options(tctx->lp_ctx, &options); lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options); status = smbcli_full_connection(tctx, &cli, host, lpcfg_smb_ports(tctx->lp_ctx), share, NULL, lpcfg_socket_options(tctx->lp_ctx), cmdline_credentials, lpcfg_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, lpcfg_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { torture_comment(tctx, "failed to connect to //%s/%s: %s\n", host, share, nt_errstr(status)); torture_fail(tctx, "Failed to connect to server"); return NULL; } return cli; }
static NTSTATUS gp_cli_connect(struct gp_context *gp_ctx) { struct smbcli_options options; struct smbcli_session_options session_options; if (gp_ctx->cli != NULL) return NT_STATUS_OK; gp_ctx->cli = smbcli_state_init(gp_ctx); lpcfg_smbcli_options(gp_ctx->lp_ctx, &options); lpcfg_smbcli_session_options(gp_ctx->lp_ctx, &session_options); return smbcli_full_connection(gp_ctx, &gp_ctx->cli, gp_ctx->active_dc.name, lpcfg_smb_ports(gp_ctx->lp_ctx), "sysvol", NULL, lpcfg_socket_options(gp_ctx->lp_ctx), gp_ctx->credentials, lpcfg_resolve_context(gp_ctx->lp_ctx), gp_ctx->ev_ctx, &options, &session_options, lpcfg_gensec_settings(gp_ctx, gp_ctx->lp_ctx)); }
NTSTATUS svc_UploadService(const char *hostname, struct cli_credentials * credentials, int force) { struct smb_composite_savefile *io; struct smbcli_state *cli; NTSTATUS status; status = smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL, credentials, NULL); NT_ERR(status, 1, "Failed to open ADMIN$ share"); if (!force) { int fd = smbcli_open(cli->tree, "winexesvc.exe", O_RDONLY, DENY_NONE); if (fd >= 0) { smbcli_close(cli->tree, fd); return status; } } else { smbcli_unlink(cli->tree, "winexesvc.exe"); } io = talloc_zero(cli->tree, struct smb_composite_savefile); io->in.fname = "winexesvc.exe"; io->in.data = winexesvc_exe; io->in.size = winexesvc_exe_len; status = smb_composite_savefile(cli->tree, io); NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname); talloc_free(io); smbcli_tdis(cli); return status; }
NTSTATUS svc_uninstall(const char *hostname, struct cli_credentials * credentials) { NTSTATUS status; struct dcerpc_pipe *svc_pipe; struct policy_handle scm_handle; struct policy_handle svc_handle; struct SERVICE_STATUS svc_status; status = svc_pipe_connect(&svc_pipe, hostname, credentials); NT_ERR(status, 1, "Cannot connect to svcctl pipe"); status = svc_OpenSCManager(svc_pipe, hostname, &scm_handle); NT_ERR(status, 1, "OpenSCManager failed"); status = svc_OpenService(svc_pipe, &scm_handle, "winexesvc", &svc_handle); NT_ERR(status, 1, "OpenService failed"); DEBUG(1, ("OpenService - %s\n", nt_errstr(status))); if (NT_STATUS_IS_OK(status)) { status = svc_ControlService(svc_pipe, &svc_handle, SERVICE_CONTROL_STOP, &svc_status); { struct SERVICE_STATUS s; do { msleep(100); status = svc_QueryServiceStatus(svc_pipe, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SERVICE_STOP_PENDING); if (s.state != SERVICE_STOPPED) { DEBUG(0, ("Service cannot stop, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } DEBUG(1, ("StopService - %s\n", nt_errstr(status))); status = svc_DeleteService(svc_pipe, &svc_handle); DEBUG(1, ("DeleteService - %s\n", nt_errstr(status))); status = svc_CloseServiceHandle(svc_pipe, &svc_handle); DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status))); } svc_CloseServiceHandle(svc_pipe, &scm_handle); DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status))); struct smbcli_state *cli; status = smbcli_full_connection(NULL, &cli, hostname, "ADMIN$", NULL, credentials, NULL); NT_ERR(status, 1, "Failed to open ADMIN$ share"); /* Give winexesvc some time to exit */ msleep(300); status = smbcli_unlink(cli->tree, "winexesvc.exe"); DEBUG(1, ("Delete winexesvc.exe - %s\n", nt_errstr(status))); status = smbcli_tdis(cli); DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status))); return status; }
static NTSTATUS svc_UploadService(struct tevent_context *ev_ctx, const char *hostname, const char *service_filename, unsigned char *svc32_exe, unsigned int svc32_exe_len, unsigned char *svc64_exe, unsigned int svc64_exe_len, struct cli_credentials *credentials, struct loadparm_context *cllp_ctx, int flags) { struct smb_composite_savefile *io; struct smbcli_state *cli; NTSTATUS status; struct smbcli_options options; struct smbcli_session_options session_options; lpcfg_smbcli_options(cllp_ctx, &options); lpcfg_smbcli_session_options(cllp_ctx, &session_options); status = smbcli_full_connection(NULL, &cli, hostname, lpcfg_smb_ports(cllp_ctx), "ADMIN$", NULL, lpcfg_socket_options(cllp_ctx), credentials, lpcfg_resolve_context(cllp_ctx), ev_ctx, &options, &session_options, lpcfg_gensec_settings(NULL, cllp_ctx)); NT_ERR(status, 1, "Failed to open ADMIN$ share"); if (flags & SVC_FORCE_UPLOAD) { smbcli_unlink(cli->tree, service_filename); } else { int fd = smbcli_open(cli->tree, service_filename, O_RDONLY, DENY_NONE); if (fd >= 0) { smbcli_close(cli->tree, fd); return status; } } io = talloc_zero(cli->tree, struct smb_composite_savefile); io->in.fname = service_filename; if (flags & SVC_OSCHOOSE) { status = smbcli_chkpath(cli->tree, "SysWoW64"); } if (((flags & SVC_OSCHOOSE) && NT_STATUS_IS_OK(status)) || (flags & SVC_OS64BIT)) { DEBUG(1, ("svc_UploadService: Installing 64bit %s\n", service_filename)); io->in.data = svc64_exe; io->in.size = svc64_exe_len; } else { DEBUG(1, ("svc_UploadService: Installing 32bit %s\n", service_filename)); io->in.data = svc32_exe; io->in.size = svc32_exe_len; } status = smb_composite_savefile(cli->tree, io); NT_ERR(status, 1, "Failed to save ADMIN$/%s", io->in.fname); talloc_free(io); smbcli_tdis(cli); return status; }
static struct smbcli_state *connect_to_server(void *mem_ctx, struct cli_credentials *creds) { NTSTATUS status; struct smbcli_state *cli; const char *host = lp_parm_string(-1, "torture", "host"); const char *share = lp_parm_string(-1, "torture", "share"); status = smbcli_full_connection(mem_ctx, &cli, host, share, NULL, creds, NULL); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", host, share, nt_errstr(status)); return NULL; } return cli; }
/***************************************************** return a connection to a server *******************************************************/ static struct smbcli_state *connect_one(char *share) { struct smbcli_state *c; char *server_n; fstring server; fstring myname; static int count; NTSTATUS nt_status; fstrcpy(server,share+2); share = strchr_m(server,'\\'); if (!share) return NULL; *share = 0; share++; server_n = server; if (!got_pass) { char *pass = getpass("Password: "******"lock-%u-%u", getpid(), count++); nt_status = smbcli_full_connection(NULL, &c, myname, server_n, 0, share, NULL, username, lp_workgroup(), password, NULL); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("smbcli_full_connection failed with error %s\n", nt_errstr(nt_status))); return NULL; } c->use_oplocks = use_oplocks; return c; }
/***************************************************** return a connection to a server *******************************************************/ static struct smbcli_state *connect_one(struct resolve_context *resolve_ctx, struct tevent_context *ev, TALLOC_CTX *mem_ctx, char *share, const char **ports, const char *socket_options, struct smbcli_options *options, struct smbcli_session_options *session_options, struct smb_iconv_convenience *iconv_convenience, struct gensec_settings *gensec_settings) { struct smbcli_state *c; char *server; NTSTATUS status; server = talloc_strdup(mem_ctx, share+2); share = strchr_m(server,'\\'); if (!share) return NULL; *share = 0; share++; cli_credentials_set_workstation(cmdline_credentials, "masktest", CRED_SPECIFIED); status = smbcli_full_connection(NULL, &c, server, ports, share, NULL, socket_options, cmdline_credentials, resolve_ctx, ev, options, session_options, iconv_convenience, gensec_settings); if (!NT_STATUS_IS_OK(status)) { return NULL; } return c; }
static int fork_tcon_client(struct torture_context *tctx, int *tcon_count, unsigned tcon_timelimit, const char *host, const char *share) { pid_t child; struct smbcli_state *cli; struct timeval end; struct timeval now; struct smbcli_options options; struct smbcli_session_options session_options; lpcfg_smbcli_options(tctx->lp_ctx, &options); lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options); child = fork(); if (child == -1) { printf("failed to fork child: %s\n,", strerror(errno)); return -1; } else if (child != 0) { /* Parent, just return. */ return 0; } /* Child. Just make as many connections as possible within the * time limit. Don't bother synchronising the child start times * because it's probably not work the effort, and a bit of startup * jitter is probably a more realistic test. */ end = timeval_current(); now = timeval_current(); end.tv_sec += tcon_timelimit; *tcon_count = 0; while (timeval_compare(&now, &end) == -1) { NTSTATUS status; status = smbcli_full_connection(NULL, &cli, host, lpcfg_smb_ports(tctx->lp_ctx), share, NULL, lpcfg_socket_options(tctx->lp_ctx), cmdline_credentials, lpcfg_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, lpcfg_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", host, share, nt_errstr(status)); goto done; } smbcli_tdis(cli); talloc_free(cli); *tcon_count = *tcon_count + 1; now = timeval_current(); } done: exit(0); }
/***************************************************** return a connection to a server *******************************************************/ static struct smbcli_state *connect_one(struct tevent_context *ev, struct loadparm_context *lp_ctx, TALLOC_CTX *mem_ctx, char *share, int snum, int conn) { struct smbcli_state *c; char *server, *myname; NTSTATUS status; int retries = 10; struct smbcli_options options; struct smbcli_session_options session_options; lp_smbcli_options(lp_ctx, &options); lp_smbcli_session_options(lp_ctx, &session_options); printf("connect_one(%s, %d, %d)\n", share, snum, conn); server = talloc_strdup(mem_ctx, share+2); share = strchr_m(server,'\\'); if (!share) return NULL; *share = 0; share++; if (snum == 0) { char **unc_list = NULL; int num_unc_names; const char *p; p = lp_parm_string(lp_ctx, NULL, "torture", "unclist"); if (p) { char *h, *s; unc_list = file_lines_load(p, &num_unc_names, 0, NULL); if (!unc_list || num_unc_names <= 0) { printf("Failed to load unc names list from '%s'\n", p); exit(1); } if (!smbcli_parse_unc(unc_list[conn % num_unc_names], NULL, &h, &s)) { printf("Failed to parse UNC name %s\n", unc_list[conn % num_unc_names]); exit(1); } server = talloc_strdup(mem_ctx, h); share = talloc_strdup(mem_ctx, s); } } myname = talloc_asprintf(mem_ctx, "lock-%u-%u", getpid(), snum); cli_credentials_set_workstation(servers[snum], myname, CRED_SPECIFIED); do { printf("\\\\%s\\%s\n", server, share); status = smbcli_full_connection(NULL, &c, server, lp_smb_ports(lp_ctx), share, NULL, lp_socket_options(lp_ctx), servers[snum], lp_resolve_context(lp_ctx), ev, &options, &session_options, lp_iconv_convenience(lp_ctx), lp_gensec_settings(mem_ctx, lp_ctx)); if (!NT_STATUS_IS_OK(status)) { sleep(2); } } while (!NT_STATUS_IS_OK(status) && retries--); if (!NT_STATUS_IS_OK(status)) { return NULL; } return c; }
NTSTATUS svc_uninstall(struct tevent_context *ev_ctx, const char *hostname, const char *service_name, const char *service_filename, struct cli_credentials *credentials, struct loadparm_context *cllp_ctx) { NTSTATUS status; struct dcerpc_binding_handle *binding_handle; struct dcerpc_pipe *svc_pipe; struct policy_handle scm_handle; struct policy_handle svc_handle; struct SERVICE_STATUS svc_status; struct smbcli_options options; struct smbcli_session_options session_options; lpcfg_smbcli_options(cllp_ctx, &options); lpcfg_smbcli_session_options(cllp_ctx, &session_options); status = svc_pipe_connect(ev_ctx, &svc_pipe, hostname, credentials, cllp_ctx); NT_ERR(status, 1, "Cannot connect to svcctl pipe"); binding_handle = svc_pipe->binding_handle; status = svc_OpenSCManager(binding_handle, hostname, &scm_handle); NT_ERR(status, 1, "OpenSCManager failed"); status = svc_OpenService(binding_handle, &scm_handle, service_name, &svc_handle); NT_ERR(status, 1, "OpenService failed"); DEBUG(1, ("OpenService - %s\n", nt_errstr(status))); if (NT_STATUS_IS_OK(status)) { status = svc_ControlService(binding_handle, &svc_handle, SERVICE_CONTROL_STOP, &svc_status); { struct SERVICE_STATUS s; do { smb_msleep(100); status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_STOP_PENDING); if (s.state != SVCCTL_STOPPED) { DEBUG(0, ("Service cannot stop, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } DEBUG(1, ("StopService - %s\n", nt_errstr(status))); status = svc_DeleteService(binding_handle, &svc_handle); DEBUG(1, ("DeleteService - %s\n", nt_errstr(status))); status = svc_CloseServiceHandle(binding_handle, &svc_handle); DEBUG(1, ("CloseServiceHandle - %s\n", nt_errstr(status))); } svc_CloseServiceHandle(binding_handle, &scm_handle); DEBUG(1, ("CloseSCMHandle - %s\n", nt_errstr(status))); struct smbcli_state *cli; status = smbcli_full_connection(NULL, &cli, hostname, lpcfg_smb_ports(cllp_ctx), "ADMIN$", NULL, lpcfg_socket_options(cllp_ctx), credentials, lpcfg_resolve_context(cllp_ctx), ev_ctx, &options, &session_options, lpcfg_gensec_settings(NULL, cllp_ctx)); NT_ERR(status, 1, "Failed to open ADMIN$ share"); /* Give svc some time to exit */ smb_msleep(300); status = smbcli_unlink(cli->tree, service_filename); DEBUG(1, ("Delete %s - %s\n", service_filename, nt_errstr(status))); status = smbcli_tdis(cli); DEBUG(1, ("Closing ADMIN$ - %s\n", nt_errstr(status))); talloc_free(svc_pipe); return status; }
static bool test_session_expire1(struct torture_context *tctx) { NTSTATUS status; bool ret = false; struct smbcli_options options; struct smbcli_session_options session_options; const char *host = torture_setting_string(tctx, "host", NULL); const char *share = torture_setting_string(tctx, "share", NULL); struct cli_credentials *credentials = cmdline_credentials; struct smbcli_state *cli = NULL; enum credentials_use_kerberos use_kerberos; char fname[256]; union smb_fileinfo qfinfo; uint16_t vuid; uint16_t fnum = 0; struct smb_composite_sesssetup io_sesssetup; size_t i; use_kerberos = cli_credentials_get_kerberos_state(credentials); if (use_kerberos != CRED_MUST_USE_KERBEROS) { torture_warning(tctx, "smb2.session.expire1 requires -k yes!"); torture_skip(tctx, "smb2.session.expire1 requires -k yes!"); } torture_assert_int_equal(tctx, use_kerberos, CRED_MUST_USE_KERBEROS, "please use -k yes"); lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=4"); lpcfg_smbcli_options(tctx->lp_ctx, &options); lpcfg_smbcli_session_options(tctx->lp_ctx, &session_options); status = smbcli_full_connection(tctx, &cli, host, lpcfg_smb_ports(tctx->lp_ctx), share, NULL, lpcfg_socket_options(tctx->lp_ctx), credentials, lpcfg_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, lpcfg_gensec_settings(tctx, tctx->lp_ctx)); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smbcli_full_connection failed"); vuid = cli->session->vuid; /* Add some random component to the file name. */ snprintf(fname, 256, "session_expire1_%s.dat", generate_random_str(tctx, 8)); smbcli_unlink(cli->tree, fname); fnum = smbcli_nt_create_full(cli->tree, fname, 0, SEC_RIGHTS_FILE_ALL, FILE_ATTRIBUTE_NORMAL, NTCREATEX_SHARE_ACCESS_NONE, NTCREATEX_DISP_OPEN_IF, NTCREATEX_OPTIONS_DELETE_ON_CLOSE, 0); torture_assert_ntstatus_ok_goto(tctx, smbcli_nt_error(cli->tree), ret, done, "create file"); torture_assert_goto(tctx, fnum > 0, ret, done, "create file"); /* get the access information */ ZERO_STRUCT(qfinfo); qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; qfinfo.access_information.in.file.fnum = fnum; for (i=0; i < 2; i++) { torture_comment(tctx, "query info => OK\n"); ZERO_STRUCT(qfinfo.access_information.out); status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "raw_fileinfo failed"); torture_comment(tctx, "sleep 5 seconds\n"); smb_msleep(5*1000); } /* * the krb5 library may not handle expired creds * well, lets start with an empty ccache. */ cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); /* * now with CAP_DYNAMIC_REAUTH * * This should trigger NT_STATUS_NETWORK_SESSION_EXPIRED */ ZERO_STRUCT(io_sesssetup); io_sesssetup.in.sesskey = cli->transport->negotiate.sesskey; io_sesssetup.in.capabilities = cli->transport->negotiate.capabilities; io_sesssetup.in.capabilities |= CAP_DYNAMIC_REAUTH; io_sesssetup.in.credentials = credentials; io_sesssetup.in.workgroup = lpcfg_workgroup(tctx->lp_ctx); io_sesssetup.in.gensec_settings = lpcfg_gensec_settings(tctx, tctx->lp_ctx); torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n"); ZERO_STRUCT(io_sesssetup.out); status = smb_composite_sesssetup(cli->session, &io_sesssetup); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "reauth failed"); torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid, ret, done, "reauth"); for (i=0; i < 2; i++) { torture_comment(tctx, "query info => OK\n"); ZERO_STRUCT(qfinfo.access_information.out); status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "raw_fileinfo failed"); torture_comment(tctx, "sleep 5 seconds\n"); smb_msleep(5*1000); torture_comment(tctx, "query info => EXPIRED\n"); ZERO_STRUCT(qfinfo.access_information.out); status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo); torture_assert_ntstatus_equal_goto(tctx, status, NT_STATUS_NETWORK_SESSION_EXPIRED, ret, done, "raw_fileinfo expired"); /* * the krb5 library may not handle expired creds * well, lets start with an empty ccache. */ cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); torture_comment(tctx, "reauth with CAP_DYNAMIC_REAUTH => OK\n"); ZERO_STRUCT(io_sesssetup.out); status = smb_composite_sesssetup(cli->session, &io_sesssetup); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "reauth failed"); torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid, ret, done, "reauth"); } torture_comment(tctx, "query info => OK\n"); ZERO_STRUCT(qfinfo.access_information.out); status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "raw_fileinfo failed"); /* * the krb5 library may not handle expired creds * well, lets start with an empty ccache. */ cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); /* * now without CAP_DYNAMIC_REAUTH * * This should not trigger NT_STATUS_NETWORK_SESSION_EXPIRED */ torture_comment(tctx, "reauth without CAP_DYNAMIC_REAUTH => OK\n"); io_sesssetup.in.capabilities &= ~CAP_DYNAMIC_REAUTH; ZERO_STRUCT(io_sesssetup.out); status = smb_composite_sesssetup(cli->session, &io_sesssetup); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "reauth failed"); torture_assert_int_equal_goto(tctx, io_sesssetup.out.vuid, vuid, ret, done, "reauth"); for (i=0; i < 2; i++) { torture_comment(tctx, "query info => OK\n"); ZERO_STRUCT(qfinfo.access_information.out); status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "raw_fileinfo failed"); torture_comment(tctx, "sleep 5 seconds\n"); smb_msleep(5*1000); } torture_comment(tctx, "query info => OK\n"); ZERO_STRUCT(qfinfo.access_information.out); status = smb_raw_fileinfo(cli->tree, tctx, &qfinfo); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "raw_fileinfo failed"); ret = true; done: if (fnum > 0) { smbcli_close(cli->tree, fnum); } talloc_free(cli); lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0"); return ret; }