The branch, master has been updated via d7c8fb2... s3: async cli_list via 77761d9... s3: Add cli_flush from 71dfa62... s3-ads: cleanup ads_keytab_list()
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit d7c8fb21bb0a29bb7227d4b242aba2f1524f6c48 Author: Volker Lendecke <v...@samba.org> Date: Tue Aug 10 07:44:15 2010 +0200 s3: async cli_list commit 77761d9adcf34a9d1cd4567422c98efac101b3f6 Author: Volker Lendecke <v...@samba.org> Date: Fri Aug 13 14:01:03 2010 +0200 s3: Add cli_flush ----------------------------------------------------------------------- Summary of changes: source3/include/proto.h | 31 +- source3/libsmb/clifile.c | 103 +++++ source3/libsmb/clilist.c | 1043 +++++++++++++++++++++++++++----------------- source3/torture/masktest.c | 47 ++- source3/torture/torture.c | 9 +- 5 files changed, 811 insertions(+), 422 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/proto.h b/source3/include/proto.h index 5c664eb..4f63a77 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2070,6 +2070,8 @@ NTSTATUS cli_ntcreate(struct cli_state *cli, uint16_t *pfid); uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str, size_t str_len, size_t *pconverted_size); +uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, + const uint8_t *bytes, size_t num_bytes); struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx, struct event_context *ev, struct cli_state *cli, const char *fname, @@ -2334,12 +2336,22 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ /* The following definitions come from libsmb/clilist.c */ -int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(const char *, struct file_info *, const char *, - void *), void *state); -int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(const char *, struct file_info *, const char *, - void *), void *state); +NTSTATUS cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(const char *, struct file_info *, + const char *, void *), void *state); +NTSTATUS cli_list_trans(struct cli_state *cli, const char *mask, + uint16_t attribute, int info_level, + void (*fn)(const char *mnt, struct file_info *finfo, + const char *mask, void *private_data), + void *private_data); +struct tevent_req *cli_list_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *mask, + uint16_t attribute, + uint16_t info_level); +NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct file_info **finfo, size_t *num_finfo); NTSTATUS cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, struct file_info *, const char *, void *), void *state); @@ -2483,6 +2495,13 @@ NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint32_t max_rdata, uint8_t **rdata, uint32_t *num_rdata); +struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum); +NTSTATUS cli_flush_recv(struct tevent_req *req); +NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum); + /* The following definitions come from libsmb/clirap2.c */ struct rap_group_info_1; struct rap_user_info_1; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 48af0cc..d6b2e31 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -91,6 +91,26 @@ uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, true, pconverted_size); } +uint8_t *smb_bytes_push_bytes(uint8_t *buf, uint8_t prefix, + const uint8_t *bytes, size_t num_bytes) +{ + size_t buflen; + + if (buf == NULL) { + return NULL; + } + buflen = talloc_get_size(buf); + + buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, + buflen + 1 + num_bytes); + if (buf == NULL) { + return NULL; + } + buf[buflen] = prefix; + memcpy(&buf[buflen+1], bytes, num_bytes); + return buf; +} + /*********************************************************** Same as smb_bytes_push_str(), but without the odd byte align for ucs2 (we're pushing into a param or data block). @@ -5243,3 +5263,86 @@ NTSTATUS cli_qpathinfo(TALLOC_CTX *mem_ctx, struct cli_state *cli, } return status; } + +struct cli_flush_state { + uint16_t vwv[1]; +}; + +static void cli_flush_done(struct tevent_req *subreq); + +struct tevent_req *cli_flush_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint16_t fnum) +{ + struct tevent_req *req, *subreq; + struct cli_flush_state *state; + + req = tevent_req_create(mem_ctx, &state, struct cli_flush_state); + if (req == NULL) { + return NULL; + } + SSVAL(state->vwv + 0, 0, fnum); + + subreq = cli_smb_send(state, ev, cli, SMBflush, 0, 1, state->vwv, + 0, NULL); + if (tevent_req_nomem(subreq, req)) { + return tevent_req_post(req, ev); + } + tevent_req_set_callback(subreq, cli_flush_done, req); + return req; +} + +static void cli_flush_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + NTSTATUS status; + + status = cli_smb_recv(subreq, NULL, NULL, 0, NULL, NULL, NULL, NULL); + TALLOC_FREE(subreq); + if (!NT_STATUS_IS_OK(status)) { + tevent_req_nterror(req, status); + return; + } + tevent_req_done(req); +} + +NTSTATUS cli_flush_recv(struct tevent_req *req) +{ + return tevent_req_simple_recv_ntstatus(req); +} + +NTSTATUS cli_flush(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct tevent_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli_has_async_calls(cli)) { + /* + * Can't use sync call while an async call is in flight + */ + status = NT_STATUS_INVALID_PARAMETER; + goto fail; + } + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + req = cli_flush_send(frame, ev, cli, fnum); + if (req == NULL) { + goto fail; + } + if (!tevent_req_poll_ntstatus(req, ev, &status)) { + goto fail; + } + status = cli_flush_recv(req); + fail: + TALLOC_FREE(frame); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + } + return status; +} diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 1a8b79b..29b16cb 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -227,289 +227,6 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, } /**************************************************************************** - Do a directory listing, calling fn on each file found. -****************************************************************************/ - -int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(const char *, struct 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, *rdata_end; - char *mask = NULL; - struct 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; - char *param; - uint32 resume_key = 0; - TALLOC_CTX *frame = talloc_stackframe(); - DATA_BLOB last_name_raw = data_blob_null; - - /* NT uses SMB_FIND_FILE_BOTH_DIRECTORY_INFO, - OS/2 uses SMB_FIND_EA_SIZE. Both accept SMB_FIND_INFO_STANDARD. */ - info_level = (cli->capabilities&CAP_NT_SMBS)? - SMB_FIND_FILE_BOTH_DIRECTORY_INFO : SMB_FIND_INFO_STANDARD; - - mask = SMB_STRDUP(Mask); - if (!mask) { - TALLOC_FREE(frame); - return -1; - } - - ZERO_STRUCT(finfo); - - while (ff_eos == 0) { - size_t nlen = 2*(strlen(mask)+1); - - loop_count++; - if (loop_count > 200) { - DEBUG(0,("Error: Looping in FIND_NEXT??\n")); - break; - } - - param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2); - if (!param) { - 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, - nlen, 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.length) { - memcpy(p, last_name_raw.data, last_name_raw.length); - p += last_name_raw.length; - } else { - p += clistr_push(cli, param+12, mask, - nlen, 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 - )) { - SAFE_FREE(param); - TALLOC_FREE(frame); - break; - } - - SAFE_FREE(param); - - 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 <li...@kukkukk.com> - */ - - 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; - rdata_end = rdata + data_len; - - /* we might need the lastname for continuations */ - for (p2=p,i=0;i<ff_searchcount && p2 < rdata_end;i++) { - if ((info_level == SMB_FIND_FILE_BOTH_DIRECTORY_INFO) && - (i == ff_searchcount-1)) { - /* Last entry - fixup the last offset length. */ - SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); - } - p2 += interpret_long_filename(frame, - cli, - info_level, - cli->inbuf, - SVAL(cli->inbuf, smb_flg2), - p2, - rdata_end, - &finfo, - &resume_key, - &last_name_raw); - - if (!finfo.name) { - DEBUG(0,("cli_list_new: Error: unable to parse name from info level %d\n", - info_level)); - ff_eos = 1; - break; - } - 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; - } - } - - SAFE_FREE(mask); - if (ff_searchcount > 0 && ff_eos == 0 && finfo.name) { - mask = SMB_STRDUP(finfo.name); - } else { - mask = SMB_STRDUP(""); - } - if (!mask) { - SAFE_FREE(rdata); - SAFE_FREE(rparam); - break; - } - - /* 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; - } - - /* 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 */ - rdata_end = dirlist + dirlist_len; - for (p=dirlist,i=0;i<total_received;i++) { - p += interpret_long_filename(frame, - cli, - info_level, - cli->inbuf, - SVAL(cli->inbuf, smb_flg2), - p, - rdata_end, - &finfo, - NULL, - NULL); - if (!finfo.name) { - DEBUG(0,("cli_list_new: unable to parse name from info level %d\n", - info_level)); - break; - } - fn(cli->dfs_mountpoint, &finfo, Mask, state); - } - } - - /* free up the dirlist buffer and last name raw blob */ - SAFE_FREE(dirlist); - data_blob_free(&last_name_raw); - SAFE_FREE(mask); - TALLOC_FREE(frame); - return(total_received); -} - -/**************************************************************************** Interpret a short filename structure. The length of the structure is returned. ****************************************************************************/ @@ -549,163 +266,697 @@ static bool interpret_short_filename(TALLOC_CTX *ctx, return true; } -/**************************************************************************** - Do a directory listing, calling fn on each file found. - this uses the old SMBsearch interface. It is needed for testing Samba, - but should otherwise not be used. -****************************************************************************/ +struct cli_list_old_state { + struct tevent_context *ev; + struct cli_state *cli; + uint16_t vwv[2]; + char *mask; + int num_asked; + uint16_t attribute; + uint8_t search_status[23]; + bool first; + bool done; + uint8_t *dirlist; +}; + +static void cli_list_old_done(struct tevent_req *subreq); + +static struct tevent_req *cli_list_old_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct cli_state *cli, + const char *mask, + uint16_t attribute) +{ + struct tevent_req *req, *subreq; + struct cli_list_old_state *state; -- Samba Shared Repository