NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) { unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; int count=8; char *p; BOOL ret; unsigned int len; p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO); p += 6; p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); do { ret = (cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ ) && cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)); if (!ret && cli_is_dos_error(cli)) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); } } while (count-- && ret==False); if (!ret || !rdata || data_len < 4) { return NT_STATUS_UNSUCCESSFUL; } len = IVAL(rdata, 0); if (len > data_len - 4) { return NT_STATUS_INVALID_NETWORK_RESPONSE; } clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, STR_UNICODE); SAFE_FREE(rdata); SAFE_FREE(rparam); return NT_STATUS_OK; }
static void wait_before_sending_break(void) { long wait_time = (long)lp_oplock_break_wait_time(); if (wait_time) { smb_msleep(wait_time); } }
void nbio_time_delay(double targett) { double elapsed = timeval_elapsed(&children[nbio_id].starttime); if (targett > elapsed) { smb_msleep(1000*(targett - elapsed)); } else if (elapsed - targett > children[nbio_id].max_latency) { children[nbio_id].max_latency = MAX(elapsed - targett, children[nbio_id].max_latency); } }
/* basic testing of disconnects */ bool torture_disconnect(struct torture_context *torture) { bool ret = true; TALLOC_CTX *mem_ctx; int i; extern int torture_numops; struct smbcli_state *cli; mem_ctx = talloc_init("torture_raw_mux"); if (!torture_open_connection(&cli, torture, 0)) { return false; } if (!torture_setup_dir(cli, BASEDIR)) { return false; } for (i=0;i<torture_numops;i++) { ret &= test_disconnect_lock(cli, mem_ctx); if (!torture_open_connection(&cli, torture, 0)) { return false; } ret &= test_disconnect_open(cli, mem_ctx); if (!torture_open_connection(&cli, torture, 0)) { return false; } if (torture_setting_bool(torture, "samba3", false)) { /* * In Samba3 it might happen that the old smbd from * test_disconnect_lock is not scheduled before the * new process comes in. Try to get rid of the random * failures in the build farm. */ smb_msleep(200); } } smb_raw_exit(cli->session); smbcli_deltree(cli->tree, BASEDIR); talloc_free(mem_ctx); return ret; }
void nbio_target_rate(double rate) { static double last_bytes; static struct timeval last_time; double tdelay; if (last_bytes == 0) { last_bytes = children[nbio_id].bytes; last_time = timeval_current(); return; } tdelay = (children[nbio_id].bytes - last_bytes)/(1.0e6*rate) - timeval_elapsed(&last_time); if (tdelay > 0) { smb_msleep(tdelay*1000); } else { children[nbio_id].max_latency = MAX(children[nbio_id].max_latency, -tdelay); } last_time = timeval_current(); last_bytes = children[nbio_id].bytes; }
uint32 _echo_TestSleep(struct pipes_struct *p, struct echo_TestSleep *r) { smb_msleep(r->in.seconds * 1000); return 0; }
static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, const char *domain_name, uint32_t flags, struct ip_service_name *dclist, int num_dcs, struct netr_DsRGetDCNameInfo **info) { struct sockaddr_storage ss; struct ip_service ip_list; enum nbt_name_type name_type = NBT_NAME_LOGON; NTSTATUS status; int i; const char *dc_name = NULL; fstring tmp_dc_name; struct netlogon_samlogon_response *r = NULL; bool store_cache = false; uint32_t nt_version = NETLOGON_NT_VERSION_1 | NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX_WITH_IP; if (!msg_ctx) { msg_ctx = msg_context(mem_ctx); } if (flags & DS_PDC_REQUIRED) { name_type = NBT_NAME_PDC; } nt_version |= map_ds_flags_to_nt_version(flags); DEBUG(10,("process_dc_netbios\n")); for (i=0; i<num_dcs; i++) { ip_list.ss = dclist[i].ss; ip_list.port = 0; if (!interpret_string_addr(&ss, dclist[i].hostname, AI_NUMERICHOST)) { return NT_STATUS_UNSUCCESSFUL; } if (send_getdc_request(mem_ctx, msg_ctx, &dclist[i].ss, domain_name, NULL, nt_version)) { int k; smb_msleep(300); for (k=0; k<5; k++) { if (receive_getdc_response(mem_ctx, &dclist[i].ss, domain_name, &nt_version, &dc_name, &r)) { store_cache = true; namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } smb_msleep(1500); } } if (name_status_find(domain_name, name_type, NBT_NAME_SERVER, &dclist[i].ss, tmp_dc_name)) { struct NETLOGON_SAM_LOGON_RESPONSE_NT40 logon1; r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); NT_STATUS_HAVE_NO_MEMORY(r); ZERO_STRUCT(logon1); nt_version = NETLOGON_NT_VERSION_1; logon1.nt_version = nt_version; logon1.server = tmp_dc_name; logon1.domain = talloc_strdup_upper(mem_ctx, domain_name); NT_STATUS_HAVE_NO_MEMORY(logon1.domain); r->data.nt4 = logon1; r->ntver = nt_version; map_netlogon_samlogon_response(r); namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } } return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; make_reply: status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, &r->data.nt5_ex, info); if (NT_STATUS_IS_OK(status) && store_cache) { return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, nt_version, &r->data.nt5_ex); } return status; }
int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { #if 1 int max_matches = 1366; /* Match W2k - was 512. */ #else int max_matches = 512; #endif int info_level; char *p, *p2; pstring mask; file_info finfo; int i; char *dirlist = NULL; int dirlist_len = 0; int total_received = -1; BOOL First = True; int ff_searchcount=0; int ff_eos=0; int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; unsigned int param_len, data_len; uint16 setup; pstring param; const char *mnt; uint32 resume_key = 0; uint32 last_name_raw_len = 0; DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring)); /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; pstrcpy(mask,Mask); while (ff_eos == 0) { loop_count++; if (loop_count > 200) { DEBUG(0,("Error: Looping in FIND_NEXT??\n")); break; } if (First) { setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); /* For W2K servers serving out FAT filesystems we *must* set the resume key. If it's not FAT then it's returned as zero. */ SIVAL(param,6,resume_key); /* ff_resume_key */ /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) { memcpy(p, last_name_raw.data, last_name_raw_len); p += last_name_raw_len; } else { p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } } param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, 0, #if 0 /* w2k value. */ MIN(16384,cli->max_xmit) /* data, length, max. */ #else cli->max_xmit /* data, length, max. */ #endif )) { break; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { /* We need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; SAFE_FREE(rdata); SAFE_FREE(rparam); cli_dos_error(cli, &eclass, &ecode); /* * OS/2 might return "no more files", * which just tells us, that searchcount is zero * in this search. * Guenter Kukkukk <*****@*****.**> */ if (eclass == ERRDOS && ecode == ERRnofiles) { ff_searchcount = 0; cli_reset_error(cli); break; } if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); continue; } if (cli_is_error(cli) || !rdata || !rparam) { SAFE_FREE(rdata); SAFE_FREE(rparam); break; } if (total_received == -1) total_received = 0; /* parse out some important return info */ p = rparam; if (First) { ff_dir_handle = SVAL(p,0); ff_searchcount = SVAL(p,2); ff_eos = SVAL(p,4); } else { ff_searchcount = SVAL(p,0); ff_eos = SVAL(p,2); } if (ff_searchcount == 0) { SAFE_FREE(rdata); SAFE_FREE(rparam); break; } /* point to the data bytes */ p = rdata; /* we might need the lastname for continuations */ for (p2=p,i=0;i<ff_searchcount;i++) { if ((info_level == 260) && (i == ff_searchcount-1)) { /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } p2 += interpret_long_filename(cli,info_level,p2,&finfo, &resume_key,&last_name_raw,&last_name_raw_len); if (!First && *mask && strcsequal(finfo.name, mask)) { DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n", finfo.name)); ff_eos = 1; break; } } if (ff_searchcount > 0) { pstrcpy(mask, finfo.name); } else { pstrcpy(mask,""); } /* grab the data for later use */ /* and add them to the dirlist pool */ dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len); if (!dirlist) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); SAFE_FREE(rdata); SAFE_FREE(rparam); break; } memcpy(dirlist+dirlist_len,p,data_len); dirlist_len += data_len; total_received += ff_searchcount; SAFE_FREE(rdata); SAFE_FREE(rparam); DEBUG(3,("received %d entries (eos=%d)\n", ff_searchcount,ff_eos)); if (ff_searchcount > 0) loop_count = 0; First = False; } mnt = cli_cm_get_mntpoint( cli ); /* see if the server disconnected or the connection otherwise failed */ if (cli_is_error(cli)) { total_received = -1; } else { /* no connection problem. let user function add each entry */ for (p=dirlist,i=0;i<total_received;i++) { p += interpret_long_filename(cli, info_level, p, &finfo,NULL,NULL,NULL); fn( mnt,&finfo, Mask, state ); } } /* free up the dirlist buffer and last name raw blob */ SAFE_FREE(dirlist); data_blob_free(&last_name_raw); return(total_received); }
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; }
int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) { struct sockaddr_in sock_out; int res,ret; int connect_loop = 10; int increment = 10; /* create a socket to write to */ res = socket(PF_INET, type, 0); if (res == -1) { DEBUG(0,("socket error (%s)\n", strerror(errno))); return -1; } if (type != SOCK_STREAM) return(res); memset((char *)&sock_out,'\0',sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)addr); sock_out.sin_port = htons( port ); sock_out.sin_family = PF_INET; /* set it non-blocking */ set_blocking(res,False); DEBUG(3,("Connecting to %s at port %d\n",inet_ntoa(*addr),port)); /* and connect it to the destination */ connect_again: ret = connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out)); /* Some systems return EAGAIN when they mean EINPROGRESS */ if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN) && (connect_loop < timeout) ) { smb_msleep(connect_loop); connect_loop += increment; if (increment < 250) { /* After 8 rounds we end up at a max of 255 msec */ increment *= 1.5; } goto connect_again; } if (ret < 0 && (errno == EINPROGRESS || errno == EALREADY || errno == EAGAIN)) { DEBUG(1,("timeout connecting to %s:%d\n",inet_ntoa(*addr),port)); close(res); return -1; } #ifdef EISCONN if (ret < 0 && errno == EISCONN) { errno = 0; ret = 0; } #endif if (ret < 0) { DEBUG(2,("error connecting to %s:%d (%s)\n", inet_ntoa(*addr),port,strerror(errno))); close(res); return -1; } /* set it blocking again */ set_blocking(res,True); return res; }
bool run_cleanup2(int dummy) { struct cli_state *cli1, *cli2, *cli3; const char *fname = "\\cleanup2"; uint16_t fnum1, fnum2, fnum3; NTSTATUS status; char buf; printf("CLEANUP2: Checking that a conflicting brlock is cleaned up\n"); if (!torture_open_connection(&cli1, 0)) { return false; } status = cli_ntcreate( cli1, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum1, NULL); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } status = cli_lock32(cli1, fnum1, 0, 1, 0, WRITE_LOCK); if (!NT_STATUS_IS_OK(status)) { printf("lock failed (%s)\n", nt_errstr(status)); return false; } if (!torture_open_connection(&cli3, 1)) { return false; } status = cli_ntcreate( cli3, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OVERWRITE_IF, 0, 0, &fnum3, NULL); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } status = cli_lock32(cli3, fnum3, 1, 1, 0, WRITE_LOCK); if (!NT_STATUS_IS_OK(status)) { printf("lock failed (%s)\n", nt_errstr(status)); return false; } status = cli_lock32(cli1, fnum1, 2, 1, 0, WRITE_LOCK); if (!NT_STATUS_IS_OK(status)) { printf("lock failed (%s)\n", nt_errstr(status)); return false; } /* * Check the file is indeed locked */ if (!torture_open_connection(&cli2, 1)) { return false; } status = cli_ntcreate( cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, FILE_OPEN, 0, 0, &fnum2, NULL); if (!NT_STATUS_IS_OK(status)) { printf("open of %s failed (%s)\n", fname, nt_errstr(status)); return false; } buf = 'x'; status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL); if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) { printf("write succeeded\n"); return false; } /* * Kill the lock holder */ status = smbXcli_conn_samba_suicide(cli1->conn, 1); if (!NT_STATUS_IS_OK(status)) { printf("smbXcli_conn_samba_suicide failed: %s\n", nt_errstr(status)); return false; } /* * Give the suicidal smbd a bit of time to really pass away */ smb_msleep(1000); status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL); if (!NT_STATUS_IS_OK(status)) { printf("write failed: %s\n", nt_errstr(status)); return false; } return true; }
static bool test_handles_lsa_shared(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3, *p4, *p5; struct dcerpc_binding_handle *b1, *b2, *b3, *b4; struct policy_handle handle; struct policy_handle handle2; struct lsa_ObjectAttribute attr; struct lsa_QosInfo qos; struct lsa_OpenPolicy r; struct lsa_Close c; struct lsa_QuerySecurity qsec; struct sec_desc_buf *sdbuf = NULL; uint16_t system_name = '\\'; TALLOC_CTX *mem_ctx = talloc_new(torture); enum dcerpc_transport_t transport; uint32_t assoc_group_id; torture_comment(torture, "RPC-HANDLE-LSARPC-SHARED\n"); torture_comment(torture, "connect lsa pipe1\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_lsarpc); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe1"); b1 = p1->binding_handle; transport = p1->conn->transport.transport; assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); torture_comment(torture, "use assoc_group_id[0x%08X] for new connections\n", assoc_group_id); torture_comment(torture, "connect lsa pipe2\n"); status = torture_rpc_connection_transport(torture, &p2, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe2"); b2 = p2->binding_handle; torture_comment(torture, "got assoc_group_id[0x%08X] for p2\n", dcerpc_binding_get_assoc_group_id(p2->binding)); qos.len = 0; qos.impersonation_level = 2; qos.context_mode = 1; qos.effective_only = 0; attr.len = 0; attr.root_dir = NULL; attr.object_name = NULL; attr.attributes = 0; attr.sec_desc = NULL; attr.sec_qos = &qos; r.in.system_name = &system_name; r.in.attr = &attr; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.handle = &handle; torture_comment(torture, "open lsa policy handle\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_OpenPolicy_r(b1, mem_ctx, &r), "OpenPolicy failed"); if (!NT_STATUS_IS_OK(r.out.result)) { torture_comment(torture, "lsa_OpenPolicy not supported - skipping\n"); talloc_free(mem_ctx); return true; } /* * connect p3 after the policy handle is opened */ torture_comment(torture, "connect lsa pipe3 after the policy handle is opened\n"); status = torture_rpc_connection_transport(torture, &p3, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe3"); b3 = p3->binding_handle; qsec.in.handle = &handle; qsec.in.sec_info = 0; qsec.out.sdbuf = &sdbuf; c.in.handle = &handle; c.out.handle = &handle2; /* * use policy handle on all 3 connections */ torture_comment(torture, "use the policy handle on p1,p2,p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b1, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "use policy handle on p1"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b2, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "use policy handle on p2"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b3, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "use policy handle on p3"); /* * close policy handle on connection 2 and the others get a fault */ torture_comment(torture, "close the policy handle on p2 others get a fault\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_Close_r(b2, mem_ctx, &c), "Close failed"); torture_assert_ntstatus_equal(torture, c.out.result, NT_STATUS_OK, "closing policy handle on p2"); status = dcerpc_lsa_Close_r(b1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p1 again"); status = dcerpc_lsa_Close_r(b3, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p3"); status = dcerpc_lsa_Close_r(b2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p2 again"); /* * open a new policy handle on p3 */ torture_comment(torture, "open a new policy handle on p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_OpenPolicy_r(b3, mem_ctx, &r), "OpenPolicy failed"); torture_assert_ntstatus_equal(torture, r.out.result, NT_STATUS_OK, "open policy handle on p3"); /* * use policy handle on all 3 connections */ torture_comment(torture, "use the policy handle on p1,p2,p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b1, mem_ctx, &qsec), "Query Security failed"); torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK, "use policy handle on p1"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b2, mem_ctx, &qsec), "Query Security failed"); torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK, "use policy handle on p2"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b3, mem_ctx, &qsec), "Query Security failed"); torture_assert_ntstatus_equal(torture, status, NT_STATUS_OK, "use policy handle on p3"); /* * close policy handle on connection 2 and the others get a fault */ torture_comment(torture, "close the policy handle on p2 others get a fault\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_Close_r(b2, mem_ctx, &c), "Close failed"); torture_assert_ntstatus_equal(torture, c.out.result, NT_STATUS_OK, "closing policy handle on p2"); status = dcerpc_lsa_Close_r(b1, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p1 again"); status = dcerpc_lsa_Close_r(b3, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p3"); status = dcerpc_lsa_Close_r(b2, mem_ctx, &c); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing policy handle on p2 again"); /* * open a new policy handle */ torture_comment(torture, "open a new policy handle on p1 and use it\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_OpenPolicy_r(b1, mem_ctx, &r), "OpenPolicy failed"); torture_assert_ntstatus_equal(torture, r.out.result, NT_STATUS_OK, "open 2nd policy handle on p1"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b1, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "QuerySecurity handle on p1"); /* close first connection */ torture_comment(torture, "disconnect p1\n"); talloc_free(p1); smb_msleep(5); /* * and it's still available on p2,p3 */ torture_comment(torture, "use policy handle on p2,p3\n"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b2, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "QuerySecurity handle on p2 after p1 was disconnected"); torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b3, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "QuerySecurity handle on p3 after p1 was disconnected"); /* * now open p4 * and use the handle on it */ torture_comment(torture, "connect lsa pipe4 and use policy handle\n"); status = torture_rpc_connection_transport(torture, &p4, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe4"); b4 = p4->binding_handle; torture_assert_ntstatus_ok(torture, dcerpc_lsa_QuerySecurity_r(b4, mem_ctx, &qsec), "QuerySecurity failed"); torture_assert_ntstatus_equal(torture, qsec.out.result, NT_STATUS_OK, "using policy handle on p4"); /* * now close p2,p3,p4 * without closing the policy handle */ torture_comment(torture, "disconnect p2,p3,p4\n"); talloc_free(p2); talloc_free(p3); talloc_free(p4); smb_msleep(10); /* * now open p5 */ torture_comment(torture, "connect lsa pipe5 - should fail\n"); status = torture_rpc_connection_transport(torture, &p5, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening lsa pipe5"); talloc_free(mem_ctx); return true; }
BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *change_time, time_t *access_time, time_t *write_time, SMB_OFF_T *size, uint16 *mode) { unsigned int data_len = 0; unsigned int param_len = 0; unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; int count=8; BOOL ret; time_t (*date_fn)(struct cli_state *, void *); char *p; p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_INFO_STANDARD); p += 6; p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); do { ret = (cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ ) && cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_len, &rdata, &rdata_len)); if (!cli_is_dos_error(cli)) break; if (!ret) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); } } while (count-- && ret==False); if (!ret || !rdata || rdata_len < 22) { return False; } if (cli->win95) { date_fn = cli_make_unix_date; } else { date_fn = cli_make_unix_date2; } if (change_time) { *change_time = date_fn(cli, rdata+0); } if (access_time) { *access_time = date_fn(cli, rdata+4); } if (write_time) { *write_time = date_fn(cli, rdata+8); } if (size) { *size = IVAL(rdata, 12); } if (mode) { *mode = SVAL(rdata,l1_attrFile); } SAFE_FREE(rdata); SAFE_FREE(rparam); return True; }
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; }
/* Start, Creates, Install service if necessary */ NTSTATUS svc_install(struct tevent_context *ev_ctx, const char *hostname, const char *service_name, 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) { 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 s; int need_start = 0; int need_conf = 0; 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); if (NT_STATUS_EQUAL(status, NT_STATUS_SERVICE_DOES_NOT_EXIST)) { status = svc_UploadService(ev_ctx, hostname, service_filename, svc32_exe, svc32_exe_len, svc64_exe, svc64_exe_len, credentials, cllp_ctx, flags); NT_ERR(status, 1, "UploadService failed"); status = svc_CreateService(binding_handle, &scm_handle, service_name, SERVICE_WIN32_OWN_PROCESS | (flags & SVC_INTERACTIVE ? SERVICE_INTERACTIVE_PROCESS : 0), service_filename, &svc_handle); NT_ERR(status, 1, "CreateService failed"); need_start = 1; } else { NT_ERR(status, 1, "OpenService failed"); } status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); if (!(flags & SVC_IGNORE_INTERACTIVE)) need_conf = !(s.type & SERVICE_INTERACTIVE_PROCESS) ^ !(flags & SVC_INTERACTIVE); if (s.state == SVCCTL_STOPPED) { need_start = 1; } else if (need_conf) { status = svc_ControlService(binding_handle, &svc_handle, SERVICE_CONTROL_STOP, &s); NT_ERR(status, 1, "StopService failed"); do { smb_msleep(100); status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_STOP_PENDING); need_start = 1; } if (need_conf) { status = svc_ChangeServiceConfig(binding_handle, &svc_handle, SERVICE_WIN32_OWN_PROCESS | ((flags & SVC_INTERACTIVE) ? SERVICE_INTERACTIVE_PROCESS : 0), NULL); NT_ERR(status, 1, "ChangeServiceConfig failed"); } if (need_start) { status = svc_StartService(binding_handle, &svc_handle); NT_ERR(status, 1, "StartService failed"); do { smb_msleep(100); status = svc_QueryServiceStatus(binding_handle, &svc_handle, &s); NT_ERR(status, 1, "QueryServiceStatus failed"); } while (s.state == SVCCTL_START_PENDING); if (s.state != SVCCTL_RUNNING) { DEBUG(0, ("Service cannot start, status=0x%08X\n", s.state)); return NT_STATUS_UNSUCCESSFUL; } } svc_CloseServiceHandle(binding_handle, &svc_handle); svc_CloseServiceHandle(binding_handle, &scm_handle); talloc_free(svc_pipe); return status; }
static bool test_fsrvp_sc_create(struct torture_context *tctx, struct dcerpc_pipe *p, const char *share, enum test_fsrvp_inject inject, struct fssagent_share_mapping_1 **sc_map) { struct fss_IsPathSupported r_pathsupport_get; struct fss_GetSupportedVersion r_version_get; struct fss_SetContext r_context_set; struct fss_StartShadowCopySet r_scset_start; struct fss_AddToShadowCopySet r_scset_add1; struct fss_AddToShadowCopySet r_scset_add2; struct fss_PrepareShadowCopySet r_scset_prep; struct fss_CommitShadowCopySet r_scset_commit; struct fss_ExposeShadowCopySet r_scset_expose; struct fss_GetShareMapping r_sharemap_get; struct dcerpc_binding_handle *b = p->binding_handle; NTSTATUS status; time_t start_time; TALLOC_CTX *tmp_ctx = talloc_new(tctx); struct fssagent_share_mapping_1 *map = NULL; int sleep_time; /* * PrepareShadowCopySet & CommitShadowCopySet often exceed the default * 60 second dcerpc request timeout against Windows Server "8" Beta. */ dcerpc_binding_handle_set_timeout(b, 240); ZERO_STRUCT(r_pathsupport_get); r_pathsupport_get.in.ShareName = share; status = dcerpc_fss_IsPathSupported_r(b, tmp_ctx, &r_pathsupport_get); torture_assert_ntstatus_ok(tctx, status, "IsPathSupported failed"); torture_assert_int_equal(tctx, r_pathsupport_get.out.result, 0, "failed IsPathSupported response"); torture_assert(tctx, r_pathsupport_get.out.SupportedByThisProvider, "path not supported"); ZERO_STRUCT(r_version_get); status = dcerpc_fss_GetSupportedVersion_r(b, tmp_ctx, &r_version_get); torture_assert_ntstatus_ok(tctx, status, "GetSupportedVersion failed"); torture_assert_int_equal(tctx, r_version_get.out.result, 0, "failed GetSupportedVersion response"); ZERO_STRUCT(r_context_set); r_context_set.in.Context = FSRVP_CTX_BACKUP; status = dcerpc_fss_SetContext_r(b, tmp_ctx, &r_context_set); torture_assert_ntstatus_ok(tctx, status, "SetContext failed"); torture_assert_int_equal(tctx, r_context_set.out.result, 0, "failed SetContext response"); if (inject == TEST_FSRVP_TOUT_SET_CTX) { sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss", "sequence timeout", 180); torture_comment(tctx, "sleeping for %d\n", sleep_time); smb_msleep((sleep_time * 1000) + 500); } ZERO_STRUCT(r_scset_start); r_scset_start.in.ClientShadowCopySetId = GUID_random(); status = dcerpc_fss_StartShadowCopySet_r(b, tmp_ctx, &r_scset_start); torture_assert_ntstatus_ok(tctx, status, "StartShadowCopySet failed"); if (inject == TEST_FSRVP_TOUT_SET_CTX) { /* expect error due to message sequence timeout after set_ctx */ torture_assert_int_equal(tctx, r_scset_start.out.result, FSRVP_E_BAD_STATE, "StartShadowCopySet timeout response"); goto done; } torture_assert_int_equal(tctx, r_scset_start.out.result, 0, "failed StartShadowCopySet response"); torture_comment(tctx, "%s: shadow-copy set created\n", GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId)); if (inject == TEST_FSRVP_TOUT_START_SET) { sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss", "sequence timeout", 180); torture_comment(tctx, "sleeping for %d\n", sleep_time); smb_msleep((sleep_time * 1000) + 500); } ZERO_STRUCT(r_scset_add1); r_scset_add1.in.ClientShadowCopyId = GUID_random(); r_scset_add1.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; r_scset_add1.in.ShareName = share; status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add1); torture_assert_ntstatus_ok(tctx, status, "AddToShadowCopySet failed"); if (inject == TEST_FSRVP_TOUT_START_SET) { torture_assert_int_equal(tctx, r_scset_add1.out.result, HRES_ERROR_V(HRES_E_INVALIDARG), "AddToShadowCopySet timeout response"); goto done; } torture_assert_int_equal(tctx, r_scset_add1.out.result, 0, "failed AddToShadowCopySet response"); torture_comment(tctx, "%s(%s): %s added to shadow-copy set\n", GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId), GUID_string(tmp_ctx, r_scset_add1.out.pShadowCopyId), r_scset_add1.in.ShareName); /* attempts to add the same share twice should fail */ ZERO_STRUCT(r_scset_add2); r_scset_add2.in.ClientShadowCopyId = GUID_random(); r_scset_add2.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; r_scset_add2.in.ShareName = share; status = dcerpc_fss_AddToShadowCopySet_r(b, tmp_ctx, &r_scset_add2); torture_assert_ntstatus_ok(tctx, status, "AddToShadowCopySet failed"); torture_assert_int_equal(tctx, r_scset_add2.out.result, FSRVP_E_OBJECT_ALREADY_EXISTS, "failed AddToShadowCopySet response"); if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) { sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss", "sequence timeout", 1800); torture_comment(tctx, "sleeping for %d\n", sleep_time); smb_msleep((sleep_time * 1000) + 500); } start_time = time_mono(NULL); ZERO_STRUCT(r_scset_prep); r_scset_prep.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; // r_scset_prep.in.TimeOutInMilliseconds = (1800 * 1000); /* win8 */ r_scset_prep.in.TimeOutInMilliseconds = (240 * 1000); status = dcerpc_fss_PrepareShadowCopySet_r(b, tmp_ctx, &r_scset_prep); torture_assert_ntstatus_ok(tctx, status, "PrepareShadowCopySet failed"); if (inject == TEST_FSRVP_TOUT_ADD_TO_SET) { torture_assert_int_equal(tctx, r_scset_prep.out.result, HRES_ERROR_V(HRES_E_INVALIDARG), "PrepareShadowCopySet tout response"); goto done; } torture_assert_int_equal(tctx, r_scset_prep.out.result, 0, "failed PrepareShadowCopySet response"); torture_comment(tctx, "%s: prepare completed in %llu secs\n", GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId), (unsigned long long)(time_mono(NULL) - start_time)); if (inject == TEST_FSRVP_TOUT_PREPARE) { sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss", "sequence timeout", 1800); torture_comment(tctx, "sleeping for %d\n", sleep_time); smb_msleep((sleep_time * 1000) + 500); } start_time = time_mono(NULL); ZERO_STRUCT(r_scset_commit); r_scset_commit.in.ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; r_scset_commit.in.TimeOutInMilliseconds = (180 * 1000); /* win8 */ status = dcerpc_fss_CommitShadowCopySet_r(b, tmp_ctx, &r_scset_commit); torture_assert_ntstatus_ok(tctx, status, "CommitShadowCopySet failed"); if (inject == TEST_FSRVP_TOUT_PREPARE) { torture_assert_int_equal(tctx, r_scset_commit.out.result, HRES_ERROR_V(HRES_E_INVALIDARG), "CommitShadowCopySet tout response"); goto done; } torture_assert_int_equal(tctx, r_scset_commit.out.result, 0, "failed CommitShadowCopySet response"); torture_comment(tctx, "%s: commit completed in %llu secs\n", GUID_string(tmp_ctx, r_scset_start.out.pShadowCopySetId), (unsigned long long)(time_mono(NULL) - start_time)); if (inject == TEST_FSRVP_TOUT_COMMIT) { sleep_time = lpcfg_parm_int(tctx->lp_ctx, NULL, "fss", "sequence timeout", 180); torture_comment(tctx, "sleeping for %d\n", sleep_time); smb_msleep((sleep_time * 1000) + 500); } else if (inject == TEST_FSRVP_STOP_B4_EXPOSE) { /* return partial snapshot information */ map = talloc_zero(tctx, struct fssagent_share_mapping_1); map->ShadowCopySetId = *r_scset_start.out.pShadowCopySetId; map->ShadowCopyId = *r_scset_add1.out.pShadowCopyId; goto done; }
static bool test_lease_multibreak(struct torture_context *tctx, struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io; struct smb2_lease ls; struct smb2_handle h, h2, h3; struct smb2_write w; NTSTATUS status; const char *fname = "lease.dat"; bool ret = true; uint32_t caps; caps = smb2cli_conn_server_capabilities(tree->session->transport->conn); if (!(caps & SMB2_CAP_LEASING)) { torture_skip(tctx, "leases are not supported"); } tree->session->transport->lease.handler = torture_lease_handler; tree->session->transport->lease.private_data = tree; tree->session->transport->oplock.handler = torture_oplock_handler; tree->session->transport->oplock.private_data = tree; smb2_util_unlink(tree, fname); ZERO_STRUCT(break_info); /* Grab lease, upgrade to RHW .. */ smb2_lease_create(&io, &ls, false, fname, LEASE1, smb2_util_lease_state("RH")); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h = io.out.file.handle; CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_LEASE(&io, "RH", true, LEASE1); smb2_lease_create(&io, &ls, false, fname, LEASE1, smb2_util_lease_state("RHW")); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h2 = io.out.file.handle; CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); CHECK_LEASE(&io, "RHW", true, LEASE1); /* Contend with LEASE2. */ smb2_lease_create(&io, &ls, false, fname, LEASE2, smb2_util_lease_state("RHW")); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h3 = io.out.file.handle; CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); CHECK_LEASE(&io, "RH", true, LEASE2); /* Verify that we were only sent one break. */ CHECK_BREAK_INFO("RHW", "RH", LEASE1); /* Drop LEASE1 / LEASE2 */ status = smb2_util_close(tree, h); CHECK_STATUS(status, NT_STATUS_OK); status = smb2_util_close(tree, h2); CHECK_STATUS(status, NT_STATUS_OK); status = smb2_util_close(tree, h3); CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(break_info); /* Grab an R lease. */ smb2_lease_create(&io, &ls, false, fname, LEASE1, smb2_util_lease_state("R")); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h = io.out.file.handle; CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); CHECK_LEASE(&io, "R", true, LEASE1); /* Grab a level-II oplock. */ smb2_oplock_create(&io, fname, smb2_util_oplock_level("s")); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h2 = io.out.file.handle; CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_ARCHIVE); CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("s")); break_info.held_oplock_level = io.out.oplock_level; /* Verify no breaks. */ CHECK_VAL(break_info.count, 0); CHECK_VAL(break_info.failures, 0); /* Open for truncate, force a break. */ smb2_generic_create(&io, NULL, false, fname, NTCREATEX_DISP_OVERWRITE_IF, smb2_util_oplock_level(""), 0, 0); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h3 = io.out.file.handle; CHECK_CREATED(&io, TRUNCATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_VAL(io.out.oplock_level, smb2_util_oplock_level("")); break_info.held_oplock_level = io.out.oplock_level; /* Sleep, use a write to clear the recv queue. */ smb_msleep(250); ZERO_STRUCT(w); w.in.file.handle = h3; w.in.offset = 0; w.in.data = data_blob_talloc(mem_ctx, NULL, 4096); memset(w.in.data.data, 'o', w.in.data.length); status = smb2_write(tree, &w); CHECK_STATUS(status, NT_STATUS_OK); /* Verify one oplock break, one lease break. */ CHECK_VAL(break_info.oplock_count, 1); CHECK_VAL(break_info.oplock_failures, 0); CHECK_VAL(break_info.oplock_level, smb2_util_oplock_level("")); CHECK_BREAK_INFO("R", "", LEASE1); done: smb2_util_close(tree, h); smb2_util_close(tree, h2); smb2_util_close(tree, h3); smb2_util_unlink(tree, fname); talloc_free(mem_ctx); return ret; }
static bool test_lease_v2_request(struct torture_context *tctx, struct smb2_tree *tree) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_create io; struct smb2_lease ls; struct smb2_handle h1, h2, h3, h4, h5; struct smb2_write w; NTSTATUS status; const char *fname = "lease.dat"; const char *dname = "lease.dir"; const char *dnamefname = "lease.dir\\lease.dat"; const char *dnamefname2 = "lease.dir\\lease2.dat"; bool ret = true; smb2_util_unlink(tree, fname); smb2_deltree(tree, dname); tree->session->transport->lease.handler = torture_lease_handler; tree->session->transport->lease.private_data = tree; tree->session->transport->oplock.handler = torture_oplock_handler; tree->session->transport->oplock.private_data = tree; ZERO_STRUCT(break_info); ZERO_STRUCT(io); smb2_lease_v2_create_share(&io, &ls, false, fname, smb2_util_share_access("RWD"), LEASE1, NULL, smb2_util_lease_state("RHW"), 0); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h1 = io.out.file.handle; CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_LEASE_V2(&io, "RHW", true, LEASE1, 0); ZERO_STRUCT(io); smb2_lease_v2_create_share(&io, &ls, true, dname, smb2_util_share_access("RWD"), LEASE2, NULL, smb2_util_lease_state("RHW"), 0); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h2 = io.out.file.handle; CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_DIRECTORY); CHECK_LEASE_V2(&io, "RH", true, LEASE2, 0); ZERO_STRUCT(io); smb2_lease_v2_create_share(&io, &ls, false, dnamefname, smb2_util_share_access("RWD"), LEASE3, &LEASE2, smb2_util_lease_state("RHW"), 0); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h3 = io.out.file.handle; CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_LEASE_V2(&io, "RHW", true, LEASE3, SMB2_LEASE_FLAG_PARENT_LEASE_KEY_SET); torture_wait_for_lease_break(tctx); CHECK_VAL(break_info.count, 0); CHECK_VAL(break_info.failures, 0); ZERO_STRUCT(io); smb2_lease_v2_create_share(&io, &ls, false, dnamefname2, smb2_util_share_access("RWD"), LEASE4, NULL, smb2_util_lease_state("RHW"), 0); status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h4 = io.out.file.handle; CHECK_CREATED(&io, CREATED, FILE_ATTRIBUTE_ARCHIVE); CHECK_LEASE_V2(&io, "RHW", true, LEASE4, 0); torture_wait_for_lease_break(tctx); torture_wait_for_lease_break(tctx); CHECK_BREAK_INFO("RH", "", LEASE2); torture_wait_for_lease_break(tctx); ZERO_STRUCT(break_info); ZERO_STRUCT(io); smb2_lease_v2_create_share(&io, &ls, true, dname, smb2_util_share_access("RWD"), LEASE2, NULL, smb2_util_lease_state("RHW"), 0); io.in.create_disposition = NTCREATEX_DISP_OPEN; status = smb2_create(tree, mem_ctx, &io); CHECK_STATUS(status, NT_STATUS_OK); h5 = io.out.file.handle; CHECK_CREATED(&io, EXISTED, FILE_ATTRIBUTE_DIRECTORY); CHECK_LEASE_V2(&io, "RH", true, LEASE2, 0); smb2_util_close(tree, h5); ZERO_STRUCT(w); w.in.file.handle = h4; w.in.offset = 0; w.in.data = data_blob_talloc(mem_ctx, NULL, 4096); memset(w.in.data.data, 'o', w.in.data.length); status = smb2_write(tree, &w); CHECK_STATUS(status, NT_STATUS_OK); smb_msleep(2000); torture_wait_for_lease_break(tctx); CHECK_VAL(break_info.count, 0); CHECK_VAL(break_info.failures, 0); smb2_util_close(tree, h4); torture_wait_for_lease_break(tctx); torture_wait_for_lease_break(tctx); CHECK_BREAK_INFO("RH", "", LEASE2); torture_wait_for_lease_break(tctx); done: smb2_util_close(tree, h1); smb2_util_close(tree, h2); smb2_util_close(tree, h3); smb2_util_close(tree, h4); smb2_util_close(tree, h5); smb2_util_unlink(tree, fname); smb2_deltree(tree, dname); talloc_free(mem_ctx); return ret; }
BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, time_t create_time, time_t access_time, time_t write_time, time_t change_time, uint16 mode) { unsigned int data_len = 0; unsigned int param_len = 0; unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_SETPATHINFO; pstring param; pstring data; char *rparam=NULL, *rdata=NULL; int count=8; BOOL ret; char *p; memset(param, 0, sizeof(param)); memset(data, 0, sizeof(data)); p = param; /* Add the information level */ SSVAL(p, 0, SMB_FILE_BASIC_INFORMATION); /* Skip reserved */ p += 6; /* Add the file name */ p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); p = data; /* * Add the create, last access, modification, and status change times */ put_long_date(p, create_time); p += 8; put_long_date(p, access_time); p += 8; put_long_date(p, write_time); p += 8; put_long_date(p, change_time); p += 8; /* Add attributes */ SIVAL(p, 0, mode); p += 4; /* Add padding */ SIVAL(p, 0, 0); p += 4; data_len = PTR_DIFF(p, data); do { ret = (cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ data, data_len, cli->max_xmit /* data, length, max */ ) && cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_len, &rdata, &rdata_len)); if (!cli_is_dos_error(cli)) break; if (!ret) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); } } while (count-- && ret==False); if (!ret) { return False; } SAFE_FREE(rdata); SAFE_FREE(rparam); return True; }
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; }
static bool test_handles_mixed_shared(struct torture_context *torture) { NTSTATUS status; struct dcerpc_pipe *p1, *p2, *p3, *p4, *p5, *p6; struct dcerpc_binding_handle *b1, *b2; struct policy_handle handle; struct policy_handle handle2; struct samr_Connect r; struct lsa_Close lc; struct samr_Close sc; TALLOC_CTX *mem_ctx = talloc_new(torture); enum dcerpc_transport_t transport; uint32_t assoc_group_id; torture_comment(torture, "RPC-HANDLE-MIXED-SHARED\n"); torture_comment(torture, "connect samr pipe1\n"); status = torture_rpc_connection(torture, &p1, &ndr_table_samr); torture_assert_ntstatus_ok(torture, status, "opening samr pipe1"); b1 = p1->binding_handle; transport = p1->conn->transport.transport; assoc_group_id = dcerpc_binding_get_assoc_group_id(p1->binding); torture_comment(torture, "use assoc_group_id[0x%08X] for new connections\n", assoc_group_id); torture_comment(torture, "connect lsa pipe2\n"); status = torture_rpc_connection_transport(torture, &p2, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_ok(torture, status, "opening lsa pipe2"); b2 = p2->binding_handle; torture_comment(torture, "got assoc_group_id[0x%08X] for p2\n", dcerpc_binding_get_assoc_group_id(p2->binding)); r.in.system_name = 0; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; r.out.connect_handle = &handle; torture_comment(torture, "samr_Connect to open a policy handle on samr p1\n"); torture_assert_ntstatus_ok(torture, dcerpc_samr_Connect_r(b1, mem_ctx, &r), "Connect failed"); torture_assert_ntstatus_ok(torture, r.out.result, "opening policy handle on p1"); lc.in.handle = &handle; lc.out.handle = &handle2; sc.in.handle = &handle; sc.out.handle = &handle2; torture_comment(torture, "use policy handle on lsa p2 - should fail\n"); status = dcerpc_lsa_Close_r(b2, mem_ctx, &lc); torture_assert_ntstatus_equal(torture, status, NT_STATUS_RPC_SS_CONTEXT_MISMATCH, "closing handle on lsa p2"); torture_comment(torture, "closing policy handle on samr p1\n"); torture_assert_ntstatus_ok(torture, dcerpc_samr_Close_r(b1, mem_ctx, &sc), "Close failed"); torture_assert_ntstatus_ok(torture, sc.out.result, "closing policy handle on p1"); talloc_free(p1); talloc_free(p2); smb_msleep(10); torture_comment(torture, "connect samr pipe3 - should fail\n"); status = torture_rpc_connection_transport(torture, &p3, &ndr_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe3"); torture_comment(torture, "connect lsa pipe4 - should fail\n"); status = torture_rpc_connection_transport(torture, &p4, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening lsa pipe4"); /* * We use ~assoc_group_id instead of p1->assoc_group_id, because * this way we are less likely to use an id which is already in use. */ assoc_group_id = ~assoc_group_id; torture_comment(torture, "connect samr pipe5 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(torture, &p5, &ndr_table_samr, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening samr pipe5"); torture_comment(torture, "connect lsa pipe6 with assoc_group_id[0x%08X]- should fail\n", ++assoc_group_id); status = torture_rpc_connection_transport(torture, &p6, &ndr_table_lsarpc, transport, assoc_group_id); torture_assert_ntstatus_equal(torture, status, NT_STATUS_UNSUCCESSFUL, "opening lsa pipe6"); talloc_free(mem_ctx); return true; }
int main(int argc, char *argv[]) { struct event_context *evt_ctx; struct messaging_context *msg_ctx; pid_t pid; int i, n; char buf[12]; load_case_tables(); setup_logging(argv[0],True); lp_load(get_dyn_CONFIGFILE(),False,False,False,True); if (!(evt_ctx = event_context_init(NULL)) || !(msg_ctx = messaging_init(NULL, server_id_self(), evt_ctx))) { fprintf(stderr, "could not init messaging context\n"); exit(1); } if (argc != 3) { fprintf(stderr, "%s: Usage - %s pid count\n", argv[0], argv[0]); exit(1); } pid = atoi(argv[1]); n = atoi(argv[2]); messaging_register(msg_ctx, NULL, MSG_PONG, pong_message); for (i=0; i<n; i++) { messaging_send(msg_ctx, pid_to_procid(pid), MSG_PING, &data_blob_null); } while (pong_count < i) { message_dispatch(msg_ctx); smb_msleep(1); } /* Now test that the duplicate filtering code works. */ pong_count = 0; safe_strcpy(buf, "1234567890", sizeof(buf)-1); for (i=0; i<n; i++) { messaging_send(msg_ctx, pid_to_procid(getpid()), MSG_PING, &data_blob_null); messaging_send_buf(msg_ctx, pid_to_procid(getpid()), MSG_PING, (uint8 *)buf, 11); } for (i=0; i<n; i++) { message_dispatch(msg_ctx); smb_msleep(1); } if (pong_count != 2) { fprintf(stderr, "Duplicate filter failed (%d).\n", pong_count); } /* Speed testing */ pong_count = 0; { struct timeval tv = timeval_current(); size_t timelimit = n; size_t ping_count = 0; printf("Sending pings for %d seconds\n", (int)timelimit); while (timeval_elapsed(&tv) < timelimit) { if(NT_STATUS_IS_OK(messaging_send_buf( msg_ctx, pid_to_procid(pid), MSG_PING, (uint8 *)buf, 11))) ping_count++; if(NT_STATUS_IS_OK(messaging_send( msg_ctx, pid_to_procid(pid), MSG_PING, &data_blob_null))) ping_count++; while (ping_count > pong_count + 20) { message_dispatch(msg_ctx); } } printf("waiting for %d remaining replies (done %d)\n", (int)(ping_count - pong_count), pong_count); while (timeval_elapsed(&tv) < 30 && pong_count < ping_count) { message_dispatch(msg_ctx); } if (ping_count != pong_count) { fprintf(stderr, "ping test failed! received %d, sent " "%d\n", pong_count, (int)ping_count); } printf("ping rate of %.0f messages/sec\n", (ping_count+pong_count)/timeval_elapsed(&tv)); } return (0); }