/** * SMB2 connect with explicit share **/ static bool torture_smb2_con_share(struct torture_context *tctx, const char *share, struct smb2_tree **tree) { struct smbcli_options options; NTSTATUS status; const char *host = torture_setting_string(tctx, "host", NULL); lpcfg_smbcli_options(tctx->lp_ctx, &options); status = smb2_connect_ext(tctx, host, lpcfg_smb_ports(tctx->lp_ctx), share, lpcfg_resolve_context(tctx->lp_ctx), popt_get_cmdline_credentials(), 0, tree, tctx->ev, &options, lpcfg_socket_options(tctx->lp_ctx), lpcfg_gensec_settings(tctx, tctx->lp_ctx) ); if (!NT_STATUS_IS_OK(status)) { printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n", host, share, nt_errstr(status)); return false; } return true; }
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)); }
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; }
/* setup a listening socket on all the SMB ports for a particular address */ static NTSTATUS samba3_add_socket(struct task_server *task, struct tevent_context *event_context, struct loadparm_context *lp_ctx, const struct model_ops *model_ops, const char *address) { const char **ports = lpcfg_smb_ports(lp_ctx); int i; NTSTATUS status; for (i=0;ports[i];i++) { uint16_t port = atoi(ports[i]); if (port == 0) continue; status = stream_setup_socket(task, event_context, lp_ctx, model_ops, &samba3_smb_stream_ops, "ip", address, &port, lpcfg_socket_options(lp_ctx), NULL); NT_STATUS_NOT_OK_RETURN(status); } return NT_STATUS_OK; }
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); }
static int copy_files(struct tevent_context *ev, struct loadparm_context *lp_ctx) { uint8_t * iobuf; /* IO buffer. */ uint64_t iomax; /* Size of the IO buffer. */ uint64_t data_size; /* Amount of data in the IO buffer. */ uint64_t ibs; uint64_t obs; uint64_t count; struct dd_iohandle * ifile; struct dd_iohandle * ofile; struct smbcli_options options; struct smbcli_session_options session_options; ibs = check_arg_numeric("ibs"); obs = check_arg_numeric("obs"); count = check_arg_numeric("count"); lpcfg_smbcli_options(lp_ctx, &options); lpcfg_smbcli_session_options(lp_ctx, &session_options); /* Allocate IO buffer. We need more than the max IO size because we * could accumulate a remainder if ibs and obs don't match. */ iomax = 2 * MAX(ibs, obs); if ((iobuf = malloc_array_p(uint8_t, iomax)) == NULL) { fprintf(stderr, "%s: failed to allocate IO buffer of %llu bytes\n", PROGNAME, (unsigned long long)iomax); return(EOM_EXIT_CODE); } options.max_xmit = MAX(ibs, obs); DEBUG(4, ("IO buffer size is %llu, max xmit is %d\n", (unsigned long long)iomax, options.max_xmit)); if (!(ifile = open_file(lpcfg_resolve_context(lp_ctx), ev, "if", lpcfg_smb_ports(lp_ctx), &options, lpcfg_socket_options(lp_ctx), &session_options, lpcfg_gensec_settings(lp_ctx, lp_ctx)))) { return(FILESYS_EXIT_CODE); } if (!(ofile = open_file(lpcfg_resolve_context(lp_ctx), ev, "of", lpcfg_smb_ports(lp_ctx), &options, lpcfg_socket_options(lp_ctx), &session_options, lpcfg_gensec_settings(lp_ctx, lp_ctx)))) { return(FILESYS_EXIT_CODE); } /* Seek the files to their respective starting points. */ ifile->io_seek(ifile, check_arg_numeric("skip") * ibs); ofile->io_seek(ofile, check_arg_numeric("seek") * obs); DEBUG(4, ("max xmit was negotiated to be %d\n", options.max_xmit)); for (data_size = 0;;) { /* Handle signals. We are somewhat compatible with GNU dd. * SIGINT makes us stop, but still print transfer statistics. * SIGUSR1 makes us print transfer statistics but we continue * copying. */ if (dd_sigint) { break; } if (dd_sigusr1) { print_transfer_stats(); dd_sigusr1 = 0; } if (ifile->io_flags & DD_END_OF_FILE) { DEBUG(4, ("flushing %llu bytes at EOF\n", (unsigned long long)data_size)); while (data_size > 0) { if (!dd_flush_block(ofile, iobuf, &data_size, obs)) { return(IOERROR_EXIT_CODE); } } goto done; } /* Try and read enough blocks of ibs bytes to be able write * out one of obs bytes. */ if (!dd_fill_block(ifile, iobuf, &data_size, obs, ibs)) { return(IOERROR_EXIT_CODE); } if (data_size == 0) { /* Done. */ SMB_ASSERT(ifile->io_flags & DD_END_OF_FILE); } /* Stop reading when we hit the block count. */ if (dd_stats.in.bytes >= (ibs * count)) { ifile->io_flags |= DD_END_OF_FILE; } /* If we wanted to be a legitimate dd, we would do character * conversions and other shenanigans here. */ /* Flush what we read in units of obs bytes. We want to have * at least obs bytes in the IO buffer but might not if the * file is too small. */ if (data_size && !dd_flush_block(ofile, iobuf, &data_size, obs)) { return(IOERROR_EXIT_CODE); } } done: print_transfer_stats(); return(0); }
/* connect to a share - used when a tree_connect operation comes in. */ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, struct ntvfs_request *req, union smb_tcon *tcon) { NTSTATUS status; struct cvfs_private *p; const char *host, *user, *pass, *domain, *remote_share; struct smb_composite_connect io; struct composite_context *creq; struct share_config *scfg = ntvfs->ctx->config; struct cli_credentials *credentials; bool machine_account; bool s4u2proxy; const char* sharename; switch (tcon->generic.level) { case RAW_TCON_TCON: sharename = tcon->tcon.in.service; break; case RAW_TCON_TCONX: sharename = tcon->tconx.in.path; break; case RAW_TCON_SMB2: sharename = tcon->smb2.in.path; break; default: return NT_STATUS_INVALID_LEVEL; } if (strncmp(sharename, "\\\\", 2) == 0) { char *str = strchr(sharename+2, '\\'); if (str) { sharename = str + 1; } } /* Here we need to determine which server to connect to. * For now we use parametric options, type cifs. * Later we will use security=server and auth_server.c. */ host = share_string_option(scfg, CIFS_SERVER, NULL); user = share_string_option(scfg, CIFS_USER, NULL); pass = share_string_option(scfg, CIFS_PASSWORD, NULL); domain = share_string_option(scfg, CIFS_DOMAIN, NULL); remote_share = share_string_option(scfg, CIFS_SHARE, NULL); if (!remote_share) { remote_share = sharename; } machine_account = share_bool_option(scfg, CIFS_USE_MACHINE_ACCT, CIFS_USE_MACHINE_ACCT_DEFAULT); s4u2proxy = share_bool_option(scfg, CIFS_USE_S4U2PROXY, CIFS_USE_S4U2PROXY_DEFAULT); p = talloc_zero(ntvfs, struct cvfs_private); if (!p) { return NT_STATUS_NO_MEMORY; } ntvfs->private_data = p; if (!host) { DEBUG(1,("CIFS backend: You must supply server\n")); return NT_STATUS_INVALID_PARAMETER; } if (user && pass) { DEBUG(5, ("CIFS backend: Using specified password\n")); credentials = cli_credentials_init(p); if (!credentials) { return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); cli_credentials_set_username(credentials, user, CRED_SPECIFIED); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } cli_credentials_set_password(credentials, pass, CRED_SPECIFIED); } else if (machine_account) { DEBUG(5, ("CIFS backend: Using machine account\n")); credentials = cli_credentials_init(p); cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx); if (!NT_STATUS_IS_OK(status)) { return status; } } else if (req->session_info->credentials) { DEBUG(5, ("CIFS backend: Using delegated credentials\n")); credentials = req->session_info->credentials; } else if (s4u2proxy) { struct ccache_container *ccc = NULL; const char *err_str = NULL; int ret; char *impersonate_principal; char *self_service; char *target_service; impersonate_principal = talloc_asprintf(req, "%s@%s", req->session_info->info->account_name, req->session_info->info->domain_name); self_service = talloc_asprintf(req, "cifs/%s", lpcfg_netbios_name(ntvfs->ctx->lp_ctx)); target_service = talloc_asprintf(req, "cifs/%s", host); DEBUG(5, ("CIFS backend: Using S4U2Proxy credentials\n")); credentials = cli_credentials_init(p); cli_credentials_set_conf(credentials, ntvfs->ctx->lp_ctx); if (domain) { cli_credentials_set_domain(credentials, domain, CRED_SPECIFIED); } status = cli_credentials_set_machine_account(credentials, ntvfs->ctx->lp_ctx); if (!NT_STATUS_IS_OK(status)) { return status; } cli_credentials_invalidate_ccache(credentials, CRED_SPECIFIED); cli_credentials_set_impersonate_principal(credentials, impersonate_principal, self_service); cli_credentials_set_target_service(credentials, target_service); ret = cli_credentials_get_ccache(credentials, ntvfs->ctx->event_ctx, ntvfs->ctx->lp_ctx, &ccc, &err_str); if (ret != 0) { status = NT_STATUS_CROSSREALM_DELEGATION_FAILURE; DEBUG(1,("S4U2Proxy: cli_credentials_get_ccache() gave: ret[%d] str[%s] - %s\n", ret, err_str, nt_errstr(status))); return status; } } else { DEBUG(1,("CIFS backend: NO delegated credentials found: You must supply server, user and password or the client must supply delegated credentials\n")); return NT_STATUS_INTERNAL_ERROR; } /* connect to the server, using the smbd event context */ io.in.dest_host = host; io.in.dest_ports = lpcfg_smb_ports(ntvfs->ctx->lp_ctx); io.in.socket_options = lpcfg_socket_options(ntvfs->ctx->lp_ctx); io.in.called_name = host; io.in.credentials = credentials; io.in.fallback_to_anonymous = false; io.in.workgroup = lpcfg_workgroup(ntvfs->ctx->lp_ctx); io.in.service = remote_share; io.in.service_type = "?????"; io.in.gensec_settings = lpcfg_gensec_settings(p, ntvfs->ctx->lp_ctx); lpcfg_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); lpcfg_smbcli_session_options(ntvfs->ctx->lp_ctx, &io.in.session_options); if (!(ntvfs->ctx->client_caps & NTVFS_CLIENT_CAP_LEVEL_II_OPLOCKS)) { io.in.options.use_level2_oplocks = false; } creq = smb_composite_connect_send(&io, p, lpcfg_resolve_context(ntvfs->ctx->lp_ctx), ntvfs->ctx->event_ctx); status = smb_composite_connect_recv(creq, p); NT_STATUS_NOT_OK_RETURN(status); p->tree = io.out.tree; p->transport = p->tree->session->transport; SETUP_PID; p->ntvfs = ntvfs; ntvfs->ctx->fs_type = talloc_strdup(ntvfs->ctx, "NTFS"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->fs_type); ntvfs->ctx->dev_type = talloc_strdup(ntvfs->ctx, "A:"); NT_STATUS_HAVE_NO_MEMORY(ntvfs->ctx->dev_type); if (tcon->generic.level == RAW_TCON_TCONX) { tcon->tconx.out.fs_type = ntvfs->ctx->fs_type; tcon->tconx.out.dev_type = ntvfs->ctx->dev_type; } /* we need to receive oplock break requests from the server */ smbcli_oplock_handler(p->transport, oplock_handler, p); p->map_generic = share_bool_option(scfg, CIFS_MAP_GENERIC, CIFS_MAP_GENERIC_DEFAULT); p->map_trans2 = share_bool_option(scfg, CIFS_MAP_TRANS2, CIFS_MAP_TRANS2_DEFAULT); return NT_STATUS_OK; }
static bool test_session_expire1(struct torture_context *tctx) { NTSTATUS status; bool ret = false; struct smbcli_options 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 smb2_tree *tree = NULL; enum credentials_use_kerberos use_kerberos; char fname[256]; struct smb2_handle _h1; struct smb2_handle *h1 = NULL; struct smb2_create io1; union smb_fileinfo qfinfo; 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); status = smb2_connect(tctx, host, lpcfg_smb_ports(tctx->lp_ctx), share, lpcfg_resolve_context(tctx->lp_ctx), credentials, &tree, tctx->ev, &options, lpcfg_socket_options(tctx->lp_ctx), lpcfg_gensec_settings(tctx, tctx->lp_ctx) ); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_connect failed"); /* Add some random component to the file name. */ snprintf(fname, 256, "session_expire1_%s.dat", generate_random_str(tctx, 8)); smb2_util_unlink(tree, fname); smb2_oplock_create_share(&io1, fname, smb2_util_share_access(""), smb2_util_oplock_level("b")); io1.in.create_options |= NTCREATEX_OPTIONS_DELETE_ON_CLOSE; status = smb2_create(tree, tctx, &io1); CHECK_STATUS(status, NT_STATUS_OK); _h1 = io1.out.file.handle; h1 = &_h1; CHECK_CREATED(&io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_VAL(io1.out.oplock_level, smb2_util_oplock_level("b")); /* get the security descriptor */ ZERO_STRUCT(qfinfo); qfinfo.access_information.level = RAW_FILEINFO_ACCESS_INFORMATION; qfinfo.access_information.in.file.handle = _h1; for (i=0; i < 2; i++) { torture_comment(tctx, "query info => OK\n"); ZERO_STRUCT(qfinfo.access_information.out); status = smb2_getinfo_file(tree, tctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); 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 = smb2_getinfo_file(tree, tctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_NETWORK_SESSION_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 => OK\n"); status = smb2_session_setup_spnego(tree->session, credentials, 0 /* previous_session_id */); CHECK_STATUS(status, NT_STATUS_OK); } ZERO_STRUCT(qfinfo.access_information.out); status = smb2_getinfo_file(tree, tctx, &qfinfo); CHECK_STATUS(status, NT_STATUS_OK); ret = true; done: if (h1 != NULL) { smb2_util_close(tree, *h1); } talloc_free(tree); lpcfg_set_option(tctx->lp_ctx, "gensec_gssapi:requested_life_time=0"); return ret; }
bool test_session_bind1(struct torture_context *tctx, struct smb2_tree *tree1) { const char *host = torture_setting_string(tctx, "host", NULL); const char *share = torture_setting_string(tctx, "share", NULL); struct cli_credentials *credentials = cmdline_credentials; NTSTATUS status; TALLOC_CTX *mem_ctx = talloc_new(tctx); char fname[256]; struct smb2_handle _h1; struct smb2_handle *h1 = NULL; struct smb2_create io1; union smb_fileinfo qfinfo; bool ret = false; struct smb2_tree *tree2 = NULL; struct smb2_transport *transport1 = tree1->session->transport; struct smb2_transport *transport2 = NULL; struct smb2_session *session1_1 = tree1->session; struct smb2_session *session1_2 = NULL; struct smb2_session *session2_1 = NULL; struct smb2_session *session2_2 = NULL; uint32_t caps; caps = smb2cli_conn_server_capabilities(transport1->conn); if (!(caps & SMB2_CAP_MULTI_CHANNEL)) { torture_skip(tctx, "server doesn't support SMB2_CAP_MULTI_CHANNEL\n"); } /* Add some random component to the file name. */ snprintf(fname, sizeof(fname), "session_bind1_%s.dat", generate_random_str(tctx, 8)); smb2_util_unlink(tree1, fname); smb2_oplock_create_share(&io1, fname, smb2_util_share_access(""), smb2_util_oplock_level("b")); status = smb2_create(tree1, mem_ctx, &io1); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_create failed"); _h1 = io1.out.file.handle; h1 = &_h1; CHECK_CREATED(tctx, &io1, CREATED, FILE_ATTRIBUTE_ARCHIVE); torture_assert_int_equal(tctx, io1.out.oplock_level, smb2_util_oplock_level("b"), "oplock_level incorrect"); status = smb2_connect(tctx, host, lpcfg_smb_ports(tctx->lp_ctx), share, lpcfg_resolve_context(tctx->lp_ctx), credentials, &tree2, tctx->ev, &transport1->options, lpcfg_socket_options(tctx->lp_ctx), lpcfg_gensec_settings(tctx, tctx->lp_ctx) ); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_connect failed"); session2_2 = tree2->session; transport2 = tree2->session->transport; /* * Now bind the 2nd transport connection to the 1st session */ session1_2 = smb2_session_channel(transport2, lpcfg_gensec_settings(tctx, tctx->lp_ctx), tree2, session1_1); torture_assert(tctx, session1_2 != NULL, "smb2_session_channel failed"); status = smb2_session_setup_spnego(session1_2, cmdline_credentials, 0 /* previous_session_id */); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_session_setup_spnego failed"); /* use the 1st connection, 1st session */ ZERO_STRUCT(qfinfo); qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION; qfinfo.generic.in.file.handle = _h1; tree1->session = session1_1; status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed"); /* use the 2nd connection, 1st session */ ZERO_STRUCT(qfinfo); qfinfo.generic.level = RAW_FILEINFO_POSITION_INFORMATION; qfinfo.generic.in.file.handle = _h1; tree1->session = session1_2; status = smb2_getinfo_file(tree1, mem_ctx, &qfinfo); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_getinfo_file failed"); tree1->session = session1_1; status = smb2_util_close(tree1, *h1); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_close failed"); h1 = NULL; /* * Now bind the 1st transport connection to the 2nd session */ session2_1 = smb2_session_channel(transport1, lpcfg_gensec_settings(tctx, tctx->lp_ctx), tree1, session2_2); torture_assert(tctx, session2_1 != NULL, "smb2_session_channel failed"); status = smb2_session_setup_spnego(session2_1, cmdline_credentials, 0 /* previous_session_id */); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_session_setup_spnego failed"); tree2->session = session2_1; status = smb2_util_unlink(tree2, fname); torture_assert_ntstatus_ok_goto(tctx, status, ret, done, "smb2_util_unlink failed"); ret = true; done: talloc_free(tree2); tree1->session = session1_1; if (h1 != NULL) { smb2_util_close(tree1, *h1); } smb2_util_unlink(tree1, fname); talloc_free(tree1); talloc_free(mem_ctx); return ret; }
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; }