diff options
author | Jeremy Allison <jra@samba.org> | 2010-10-29 11:56:51 -0700 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2010-10-29 19:40:16 +0000 |
commit | 14ff2e8de9bd8d0064762234555260f5eea643fe (patch) | |
tree | abd73a321e4f9855c9fcaf729d7a9ef7f91112ab | |
parent | 606a447503defdeddc84ae03e06b392517c840c5 (diff) | |
download | samba-14ff2e8de9bd8d0064762234555260f5eea643fe.tar.gz samba-14ff2e8de9bd8d0064762234555260f5eea643fe.tar.bz2 samba-14ff2e8de9bd8d0064762234555260f5eea643fe.zip |
Fix bug #7700 - Improvement of return code of smbclient
Based on an initial patch from H Hasegawa <hasegawa.hiroyuki@fujixerox.co.jp>.
Convert cli_list and associated functions to take calls that return NTSTATUS.
Jeremy.
Autobuild-User: Jeremy Allison <jra@samba.org>
Autobuild-Date: Fri Oct 29 19:40:16 UTC 2010 on sn-devel-104
-rw-r--r-- | source3/client/client.c | 148 | ||||
-rw-r--r-- | source3/client/client_proto.h | 4 | ||||
-rw-r--r-- | source3/client/clitar.c | 45 | ||||
-rw-r--r-- | source3/include/proto.h | 6 | ||||
-rw-r--r-- | source3/libgpo/gpo_filesync.c | 30 | ||||
-rw-r--r-- | source3/libsmb/clilist.c | 21 | ||||
-rw-r--r-- | source3/libsmb/libsmb_dir.c | 21 | ||||
-rw-r--r-- | source3/torture/masktest.c | 13 | ||||
-rw-r--r-- | source3/torture/nbio.c | 18 | ||||
-rw-r--r-- | source3/torture/torture.c | 26 | ||||
-rw-r--r-- | source3/utils/net_rpc.c | 33 |
11 files changed, 229 insertions, 136 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index d69e55cb50..9c02879938 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -527,14 +527,15 @@ static bool do_this_one(struct file_info *finfo) Display info about a file. ****************************************************************************/ -static void display_finfo(struct cli_state *cli_state, struct file_info *finfo, +static NTSTATUS display_finfo(struct cli_state *cli_state, struct file_info *finfo, const char *dir) { time_t t; TALLOC_CTX *ctx = talloc_tos(); + NTSTATUS status = NT_STATUS_OK; if (!do_this_one(finfo)) { - return; + return NT_STATUS_OK; } t = finfo->mtime_ts.tv_sec; /* the time is assumed to be passed as GMT */ @@ -548,11 +549,10 @@ static void display_finfo(struct cli_state *cli_state, struct file_info *finfo, } else { char *afname = NULL; uint16_t fnum; - NTSTATUS status; /* skip if this is . or .. */ if ( strequal(finfo->name,"..") || strequal(finfo->name,".") ) - return; + return NT_STATUS_OK; /* create absolute filename for cli_ntcreate() FIXME */ afname = talloc_asprintf(ctx, "%s%s%s", @@ -560,7 +560,7 @@ static void display_finfo(struct cli_state *cli_state, struct file_info *finfo, CLI_DIRSEP_STR, finfo->name); if (!afname) { - return; + return NT_STATUS_NO_MEMORY; } /* print file meta date header */ d_printf( "FILENAME:%s\n", finfo->name); @@ -581,6 +581,7 @@ static void display_finfo(struct cli_state *cli_state, struct file_info *finfo, DEBUG( 0, ("display_finfo() failed to " "get security descriptor: %s", cli_errstr(cli_state))); + status = cli_nt_error(cli_state); } else { display_sec_desc(sd); } @@ -588,18 +589,20 @@ static void display_finfo(struct cli_state *cli_state, struct file_info *finfo, } TALLOC_FREE(afname); } + return status; } /**************************************************************************** Accumulate size of a file. ****************************************************************************/ -static void do_du(struct cli_state *cli_state, struct file_info *finfo, +static NTSTATUS do_du(struct cli_state *cli_state, struct file_info *finfo, const char *dir) { if (do_this_one(finfo)) { dir_total += finfo->size; } + return NT_STATUS_OK; } static bool do_list_recurse; @@ -608,7 +611,7 @@ static char *do_list_queue = 0; static long do_list_queue_size = 0; static long do_list_queue_start = 0; static long do_list_queue_end = 0; -static void (*do_list_fn)(struct cli_state *cli_state, struct file_info *, +static NTSTATUS (*do_list_fn)(struct cli_state *cli_state, struct file_info *, const char *dir); /**************************************************************************** @@ -726,18 +729,19 @@ static int do_list_queue_empty(void) A helper for do_list. ****************************************************************************/ -static void do_list_helper(const char *mntpoint, struct file_info *f, +static NTSTATUS do_list_helper(const char *mntpoint, struct file_info *f, const char *mask, void *state) { struct cli_state *cli_state = (struct cli_state *)state; TALLOC_CTX *ctx = talloc_tos(); char *dir = NULL; char *dir_end = NULL; + NTSTATUS status = NT_STATUS_OK; /* Work out the directory. */ dir = talloc_strdup(ctx, mask); if (!dir) { - return; + return NT_STATUS_NO_MEMORY; } if ((dir_end = strrchr(dir, CLI_DIRSEP_CHAR)) != NULL) { *dir_end = '\0'; @@ -745,7 +749,10 @@ static void do_list_helper(const char *mntpoint, struct file_info *f, if (f->mode & aDIR) { if (do_list_dirs && do_this_one(f)) { - do_list_fn(cli_state, f, dir); + status = do_list_fn(cli_state, f, dir); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } if (do_list_recurse && f->name && @@ -757,7 +764,7 @@ static void do_list_helper(const char *mntpoint, struct file_info *f, if (!f->name[0]) { d_printf("Empty dir name returned. Possible server misconfiguration.\n"); TALLOC_FREE(dir); - return; + return NT_STATUS_UNSUCCESSFUL; } mask2 = talloc_asprintf(ctx, @@ -766,7 +773,7 @@ static void do_list_helper(const char *mntpoint, struct file_info *f, mask); if (!mask2) { TALLOC_FREE(dir); - return; + return NT_STATUS_NO_MEMORY; } p = strrchr_m(mask2,CLI_DIRSEP_CHAR); if (p) { @@ -780,28 +787,29 @@ static void do_list_helper(const char *mntpoint, struct file_info *f, CLI_DIRSEP_STR); if (!mask2) { TALLOC_FREE(dir); - return; + return NT_STATUS_NO_MEMORY; } add_to_do_list_queue(mask2); TALLOC_FREE(mask2); } TALLOC_FREE(dir); - return; + return NT_STATUS_OK; } if (do_this_one(f)) { - do_list_fn(cli_state, f, dir); + status = do_list_fn(cli_state, f, dir); } TALLOC_FREE(dir); + return status; } /**************************************************************************** A wrapper around cli_list that adds recursion. ****************************************************************************/ -void do_list(const char *mask, +NTSTATUS do_list(const char *mask, uint16 attribute, - void (*fn)(struct cli_state *cli_state, struct file_info *, + NTSTATUS (*fn)(struct cli_state *cli_state, struct file_info *, const char *dir), bool rec, bool dirs) @@ -810,6 +818,8 @@ void do_list(const char *mask, TALLOC_CTX *ctx = talloc_tos(); struct cli_state *targetcli = NULL; char *targetpath = NULL; + NTSTATUS ret_status = NT_STATUS_OK; + NTSTATUS status = NT_STATUS_OK; if (in_do_list && rec) { fprintf(stderr, "INTERNAL ERROR: do_list called recursively when the recursive flag is true\n"); @@ -837,7 +847,7 @@ void do_list(const char *mask, char *head = talloc_strdup(ctx, do_list_queue_head()); if (!head) { - return; + return NT_STATUS_NO_MEMORY; } /* check for dfs */ @@ -848,8 +858,13 @@ void do_list(const char *mask, continue; } - cli_list(targetcli, targetpath, attribute, + status = cli_list(targetcli, targetpath, attribute, do_list_helper, targetcli); + if (!NT_STATUS_IS_OK(status)) { + d_printf("%s listing %s\n", + nt_errstr(status), targetpath); + ret_status = status; + } remove_do_list_queue_head(); if ((! do_list_queue_empty()) && (fn == display_finfo)) { char *next_file = do_list_queue_head(); @@ -877,22 +892,24 @@ void do_list(const char *mask, } else { /* check for dfs */ if (cli_resolve_path(ctx, "", auth_info, cli, mask, &targetcli, &targetpath)) { - NTSTATUS status; status = cli_list(targetcli, targetpath, attribute, do_list_helper, targetcli); if (!NT_STATUS_IS_OK(status)) { d_printf("%s listing %s\n", nt_errstr(status), targetpath); + ret_status = status; } TALLOC_FREE(targetpath); } else { d_printf("do_list: [%s] %s\n", mask, cli_errstr(cli)); + ret_status = cli_nt_error(cli); } } in_do_list = 0; reset_do_list_queue(); + return ret_status; } /**************************************************************************** @@ -906,6 +923,7 @@ static int cmd_dir(void) char *mask = NULL; char *buf = NULL; int rc = 1; + NTSTATUS status; dir_total = 0; mask = talloc_strdup(ctx, client_get_cur_dir()); @@ -932,7 +950,10 @@ static int cmd_dir(void) client_set_cwd(client_get_cur_dir()); } - do_list(mask, attribute, display_finfo, recurse, true); + status = do_list(mask, attribute, display_finfo, recurse, true); + if (!NT_STATUS_IS_OK(status)) { + return 1; + } rc = do_dskattr(); @@ -951,6 +972,7 @@ static int cmd_du(void) uint16 attribute = aDIR | aSYSTEM | aHIDDEN; char *mask = NULL; char *buf = NULL; + NTSTATUS status; int rc = 1; dir_total = 0; @@ -976,7 +998,10 @@ static int cmd_du(void) mask = talloc_strdup(ctx, "*"); } - do_list(mask, attribute, do_du, recurse, true); + status = do_list(mask, attribute, do_du, recurse, true); + if (!NT_STATUS_IS_OK(status)) { + return 1; + } rc = do_dskattr(); @@ -1178,10 +1203,11 @@ static int cmd_get(void) Do an mget operation on one file. ****************************************************************************/ -static void do_mget(struct cli_state *cli_state, struct file_info *finfo, +static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo, const char *dir) { TALLOC_CTX *ctx = talloc_tos(); + NTSTATUS status = NT_STATUS_OK; char *rname = NULL; char *quest = NULL; char *saved_curdir = NULL; @@ -1189,32 +1215,32 @@ static void do_mget(struct cli_state *cli_state, struct file_info *finfo, char *new_cd = NULL; if (!finfo->name) { - return; + return NT_STATUS_OK; } if (strequal(finfo->name,".") || strequal(finfo->name,"..")) - return; + return NT_STATUS_OK; if (abort_mget) { d_printf("mget aborted\n"); - return; + return NT_STATUS_UNSUCCESSFUL; } if (finfo->mode & aDIR) { if (asprintf(&quest, "Get directory %s? ",finfo->name) < 0) { - return; + return NT_STATUS_NO_MEMORY; } } else { if (asprintf(&quest, "Get file %s? ",finfo->name) < 0) { - return; + return NT_STATUS_NO_MEMORY; } } if (prompt && !yesno(quest)) { SAFE_FREE(quest); - return; + return NT_STATUS_OK; } SAFE_FREE(quest); @@ -1224,17 +1250,17 @@ static void do_mget(struct cli_state *cli_state, struct file_info *finfo, client_get_cur_dir(), finfo->name); if (!rname) { - return; + return NT_STATUS_NO_MEMORY; } do_get(rname, finfo->name, false); TALLOC_FREE(rname); - return; + return NT_STATUS_OK; } /* handle directories */ saved_curdir = talloc_strdup(ctx, client_get_cur_dir()); if (!saved_curdir) { - return; + return NT_STATUS_NO_MEMORY; } new_cd = talloc_asprintf(ctx, @@ -1243,7 +1269,7 @@ static void do_mget(struct cli_state *cli_state, struct file_info *finfo, finfo->name, CLI_DIRSEP_STR); if (!new_cd) { - return; + return NT_STATUS_NO_MEMORY; } client_set_cur_dir(new_cd); @@ -1256,13 +1282,13 @@ static void do_mget(struct cli_state *cli_state, struct file_info *finfo, mkdir(finfo->name,0777) != 0) { d_printf("failed to create directory %s\n",finfo->name); client_set_cur_dir(saved_curdir); - return; + return map_nt_error_from_unix(errno); } if (chdir(finfo->name) != 0) { d_printf("failed to chdir to directory %s\n",finfo->name); client_set_cur_dir(saved_curdir); - return; + return map_nt_error_from_unix(errno); } mget_mask = talloc_asprintf(ctx, @@ -1270,18 +1296,24 @@ static void do_mget(struct cli_state *cli_state, struct file_info *finfo, client_get_cur_dir()); if (!mget_mask) { - return; + return NT_STATUS_NO_MEMORY; + } + + status = do_list(mget_mask, aSYSTEM | aHIDDEN | aDIR,do_mget,false, true); + if (!NT_STATUS_IS_OK(status)) { + return status; } - do_list(mget_mask, aSYSTEM | aHIDDEN | aDIR,do_mget,false, true); if (chdir("..") == -1) { d_printf("do_mget: failed to chdir to .. (error %s)\n", strerror(errno) ); + return map_nt_error_from_unix(errno); } client_set_cur_dir(saved_curdir); TALLOC_FREE(mget_mask); TALLOC_FREE(saved_curdir); TALLOC_FREE(new_cd); + return NT_STATUS_OK; } /**************************************************************************** @@ -1359,6 +1391,7 @@ static int cmd_mget(void) uint16 attribute = aSYSTEM | aHIDDEN; char *mget_mask = NULL; char *buf = NULL; + NTSTATUS status = NT_STATUS_OK; if (recurse) { attribute |= aDIR; @@ -1367,6 +1400,7 @@ static int cmd_mget(void) abort_mget = false; while (next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { + mget_mask = talloc_strdup(ctx, client_get_cur_dir()); if (!mget_mask) { return 1; @@ -1380,7 +1414,10 @@ static int cmd_mget(void) if (!mget_mask) { return 1; } - do_list(mget_mask, attribute, do_mget, false, true); + status = do_list(mget_mask, attribute, do_mget, false, true); + if (!NT_STATUS_IS_OK(status)) { + return 1; + } } if (mget_mask == NULL) { @@ -1395,7 +1432,10 @@ static int cmd_mget(void) if (!mget_mask) { return 1; } - do_list(mget_mask, attribute, do_mget, false, true); + status = do_list(mget_mask, attribute, do_mget, false, true); + if (!NT_STATUS_IS_OK(status)) { + return 1; + } } return 0; @@ -2165,7 +2205,7 @@ static int cmd_queue(void) Delete some files. ****************************************************************************/ -static void do_del(struct cli_state *cli_state, struct file_info *finfo, +static NTSTATUS do_del(struct cli_state *cli_state, struct file_info *finfo, const char *dir) { TALLOC_CTX *ctx = talloc_tos(); @@ -2178,12 +2218,12 @@ static void do_del(struct cli_state *cli_state, struct file_info *finfo, CLI_DIRSEP_CHAR, finfo->name); if (!mask) { - return; + return NT_STATUS_NO_MEMORY; } if (finfo->mode & aDIR) { TALLOC_FREE(mask); - return; + return NT_STATUS_OK; } status = cli_unlink(cli_state, mask, aSYSTEM | aHIDDEN); @@ -2192,6 +2232,7 @@ static void do_del(struct cli_state *cli_state, struct file_info *finfo, nt_errstr(status), mask); } TALLOC_FREE(mask); + return status; } /**************************************************************************** @@ -2203,6 +2244,7 @@ static int cmd_del(void) TALLOC_CTX *ctx = talloc_tos(); char *mask = NULL; char *buf = NULL; + NTSTATUS status = NT_STATUS_OK; uint16 attribute = aSYSTEM | aHIDDEN; if (recurse) { @@ -2222,7 +2264,10 @@ static int cmd_del(void) return 1; } - do_list(mask,attribute,do_del,false,false); + status = do_list(mask,attribute,do_del,false,false); + if (!NT_STATUS_IS_OK(status)) { + return 1; + } return 0; } @@ -4362,7 +4407,7 @@ struct completion_remote { int len; }; -static void completion_remote_filter(const char *mnt, +static NTSTATUS completion_remote_filter(const char *mnt, struct file_info *f, const char *mask, void *state) @@ -4370,13 +4415,13 @@ static void completion_remote_filter(const char *mnt, struct completion_remote *info = (struct completion_remote *)state; if (info->count >= MAX_COMPLETIONS - 1) { - return; + return NT_STATUS_OK; } if (strncmp(info->text, f->name, info->len) != 0) { - return; + return NT_STATUS_OK; } if (ISDOT(f->name) || ISDOTDOT(f->name)) { - return; + return NT_STATUS_OK; } if ((info->dirmask[0] == 0) && !(f->mode & aDIR)) @@ -4388,12 +4433,12 @@ static void completion_remote_filter(const char *mnt, tmp = talloc_strdup(ctx,info->dirmask); if (!tmp) { TALLOC_FREE(ctx); - return; + return NT_STATUS_NO_MEMORY; } tmp = talloc_asprintf_append(tmp, "%s", f->name); if (!tmp) { TALLOC_FREE(ctx); - return; + return NT_STATUS_NO_MEMORY; } if (f->mode & aDIR) { tmp = talloc_asprintf_append(tmp, "%s", @@ -4401,13 +4446,13 @@ static void completion_remote_filter(const char *mnt, } if (!tmp) { TALLOC_FREE(ctx); - return; + return NT_STATUS_NO_MEMORY; } info->matches[info->count] = SMB_STRDUP(tmp); TALLOC_FREE(ctx); } if (info->matches[info->count] == NULL) { - return; + return NT_STATUS_OK; } if (f->mode & aDIR) { smb_readline_ca_char(0); @@ -4422,6 +4467,7 @@ static void completion_remote_filter(const char *mnt, } } info->count++; + return NT_STATUS_OK; } static char **remote_completion(const char *text, int len) diff --git a/source3/client/client_proto.h b/source3/client/client_proto.h index 8623435e24..fa3ca40d6b 100644 --- a/source3/client/client_proto.h +++ b/source3/client/client_proto.h @@ -28,9 +28,9 @@ const char *client_get_cur_dir(void); const char *client_set_cur_dir(const char *newdir); -void do_list(const char *mask, +NTSTATUS do_list(const char *mask, uint16 attribute, - void (*fn)(struct cli_state *cli_state, struct file_info *, + NTSTATUS (*fn)(struct cli_state *cli_state, struct file_info *, const char *dir), bool rec, bool dirs); diff --git a/source3/client/clitar.c b/source3/client/clitar.c index 534b721894..5aa59c8cff 100644 --- a/source3/client/clitar.c +++ b/source3/client/clitar.c @@ -114,9 +114,9 @@ static int tarhandle; static void writetarheader(int f, const char *aname, uint64_t size, time_t mtime, const char *amode, unsigned char ftype); -static void do_atar(const char *rname_in, char *lname, +static NTSTATUS do_atar(const char *rname_in, char *lname, struct file_info *finfo1); -static void do_tar(struct cli_state *cli_state, struct file_info *finfo, +static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo, const char *dir); static void oct_it(uint64_t value, int ndgs, char *p); static void fixtarname(char *tptr, const char *fp, size_t l); @@ -615,7 +615,7 @@ static void do_setrattr(char *name, uint16 attr, int set) append one remote file to the tar file ***************************************************************************/ -static void do_atar(const char *rname_in, char *lname, +static NTSTATUS do_atar(const char *rname_in, char *lname, struct file_info *finfo1) { uint16_t fnum = (uint16_t)-1; @@ -628,7 +628,7 @@ static void do_atar(const char *rname_in, char *lname, int datalen=0; char *rname = NULL; TALLOC_CTX *ctx = talloc_stackframe(); - + NTSTATUS status = NT_STATUS_OK; struct timespec tp_start; clock_gettime_mono(&tp_start); @@ -636,6 +636,7 @@ static void do_atar(const char *rname_in, char *lname, data = SMB_MALLOC_ARRAY(char, read_size); if (!data) { DEBUG(0,("do_atar: out of memory.\n")); + status = NT_STATUS_NO_MEMORY; goto cleanup; } @@ -662,10 +663,12 @@ static void do_atar(const char *rname_in, char *lname, rname = clean_name(ctx, rname_in); if (!rname) { + status = NT_STATUS_NO_MEMORY; goto cleanup; } - if (!NT_STATUS_IS_OK(cli_open(cli, rname, O_RDONLY, DENY_NONE, &fnum))) { + status = cli_open(cli, rname, O_RDONLY, DENY_NONE, &fnum); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("%s opening remote file %s (%s)\n", cli_errstr(cli),rname, client_get_cur_dir())); goto cleanup; @@ -674,6 +677,7 @@ static void do_atar(const char *rname_in, char *lname, finfo.name = string_create_s(strlen(rname)); if (finfo.name == NULL) { DEBUG(0, ("Unable to allocate space for finfo.name in do_atar\n")); + status = NT_STATUS_NO_MEMORY; goto cleanup; } @@ -704,6 +708,7 @@ static void do_atar(const char *rname_in, char *lname, if (datalen == -1) { DEBUG(0,("Error reading file %s : %s\n", rname, cli_errstr(cli))); + status = cli_nt_error(cli); break; } @@ -732,10 +737,12 @@ static void do_atar(const char *rname_in, char *lname, if (dotarbuf(tarhandle,data,datalen) != datalen) { DEBUG(0,("Error writing to tar file - %s\n", strerror(errno))); + status = map_nt_error_from_unix(errno); break; } if ( (datalen == 0) && (finfo.size != 0) ) { + status = NT_STATUS_UNSUCCESSFUL; DEBUG(0,("Error reading file %s. Got 0 bytes\n", rname)); break; } @@ -748,8 +755,10 @@ static void do_atar(const char *rname_in, char *lname, if (nread < finfo.size) { DEBUG(0, ("Didn't get entire file. size=%.0f, nread=%d\n", (double)finfo.size, (int)nread)); - if (padit(data, (uint64_t)sizeof(data), finfo.size - nread)) + if (padit(data, (uint64_t)sizeof(data), finfo.size - nread)) { + status = map_nt_error_from_unix(errno); DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); + } } /* round tar file to nearest block */ @@ -761,6 +770,7 @@ static void do_atar(const char *rname_in, char *lname, } else { DEBUG(4, ("skipping %s - initial read failed (file was locked ?)\n", finfo.name)); shallitime=0; + status = NT_STATUS_UNSUCCESSFUL; } } @@ -800,19 +810,21 @@ static void do_atar(const char *rname_in, char *lname, } TALLOC_FREE(ctx); SAFE_FREE(data); + return status; } /**************************************************************************** Append single file to tar file (or not) ***************************************************************************/ -static void do_tar(struct cli_state *cli_state, struct file_info *finfo, +static NTSTATUS do_tar(struct cli_state *cli_state, struct file_info *finfo, const char *dir) { TALLOC_CTX *ctx = talloc_stackframe(); + NTSTATUS status = NT_STATUS_OK; if (strequal(finfo->name,"..") || strequal(finfo->name,".")) - return; + return NT_STATUS_OK; /* Is it on the exclude list ? */ if (!tar_excl && clipn) { @@ -825,7 +837,7 @@ static void do_tar(struct cli_state *cli_state, struct file_info *finfo, client_get_cur_dir(), finfo->name); if (!exclaim) { - return; + return NT_STATUS_NO_MEMORY; } DEBUG(5, ("...tar_re_search: %d\n", tar_re_search)); @@ -834,7 +846,7 @@ static void do_tar(struct cli_state *cli_state, struct file_info *finfo, (tar_re_search && mask_match_list(exclaim, cliplist, clipn, True))) { DEBUG(3,("Skipping file %s\n", exclaim)); TALLOC_FREE(exclaim); - return; + return NT_STATUS_OK; } TALLOC_FREE(exclaim); } @@ -846,7 +858,7 @@ static void do_tar(struct cli_state *cli_state, struct file_info *finfo, saved_curdir = talloc_strdup(ctx, client_get_cur_dir()); if (!saved_curdir) { - return; + return NT_STATUS_NO_MEMORY; } DEBUG(5, ("strlen(cur_dir)=%d, \ @@ -859,7 +871,7 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", client_get_cur_dir(), finfo->name); if (!new_cd) { - return; + return NT_STATUS_NO_MEMORY; } client_set_cur_dir(new_cd); @@ -878,10 +890,10 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", "%s*", client_get_cur_dir()); if (!mtar_mask) { - return; + return NT_STATUS_NO_MEMORY; } DEBUG(5, ("Doing list with mtar_mask: %s\n", mtar_mask)); - do_list(mtar_mask, attribute, do_tar, False, True); + status = do_list(mtar_mask, attribute, do_tar, False, True); client_set_cur_dir(saved_curdir); TALLOC_FREE(saved_curdir); TALLOC_FREE(new_cd); @@ -892,11 +904,12 @@ strlen(finfo->name)=%d\nname=%s,cur_dir=%s\n", client_get_cur_dir(), finfo->name); if (!rname) { - return; + return NT_STATUS_NO_MEMORY; } - do_atar(rname,finfo->name,finfo); + status = do_atar(rname,finfo->name,finfo); TALLOC_FREE(rname); } + return status; } /**************************************************************************** diff --git a/source3/include/proto.h b/source3/include/proto.h index 97e1923625..5095b1fde4 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2187,11 +2187,11 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ /* The following definitions come from libsmb/clilist.c */ NTSTATUS cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(const char *, struct file_info *, + NTSTATUS (*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, + NTSTATUS (*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, @@ -2203,7 +2203,7 @@ struct tevent_req *cli_list_send(TALLOC_CTX *mem_ctx, 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 *, + NTSTATUS (*fn)(const char *, struct file_info *, const char *, void *), void *state); /* The following definitions come from libsmb/climessage.c */ diff --git a/source3/libgpo/gpo_filesync.c b/source3/libgpo/gpo_filesync.c index d85df1f7e1..4e3b93809e 100644 --- a/source3/libgpo/gpo_filesync.c +++ b/source3/libgpo/gpo_filesync.c @@ -30,7 +30,7 @@ struct sync_context { uint16_t attribute; }; -static void gpo_sync_func(const char *mnt, +static NTSTATUS gpo_sync_func(const char *mnt, struct file_info *info, const char *mask, void *state); @@ -98,7 +98,7 @@ NTSTATUS gpo_copy_file(TALLOC_CTX *mem_ctx, static NTSTATUS gpo_copy_dir(const char *unix_path) { if ((mkdir(unix_path, 0644)) < 0 && errno != EEXIST) { - return NT_STATUS_ACCESS_DENIED; + return map_nt_error_from_unix(errno); } return NT_STATUS_OK; @@ -108,7 +108,7 @@ static NTSTATUS gpo_copy_dir(const char *unix_path) sync files ****************************************************************/ -static bool gpo_sync_files(struct sync_context *ctx) +static NTSTATUS gpo_sync_files(struct sync_context *ctx) { NTSTATUS status; @@ -119,17 +119,17 @@ static bool gpo_sync_files(struct sync_context *ctx) if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("listing [%s] failed with error: %s\n", ctx->mask, nt_errstr(status))); - return false; + return status; } - return true; + return status; } /**************************************************************** syncronisation call back ****************************************************************/ -static void gpo_sync_func(const char *mnt, +static NTSTATUS gpo_sync_func(const char *mnt, struct file_info *info, const char *mask, void *state) @@ -143,7 +143,7 @@ static void gpo_sync_func(const char *mnt, ctx = (struct sync_context *)state; if (strequal(info->name, ".") || strequal(info->name, "..")) { - return; + return NT_STATUS_OK; } DEBUG(5,("gpo_sync_func: got mask: [%s], name: [%s]\n", @@ -165,6 +165,7 @@ static void gpo_sync_func(const char *mnt, if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("failed to copy dir: %s\n", nt_errstr(result))); + return result; } old_nt_dir = ctx->remote_path; @@ -178,15 +179,17 @@ static void gpo_sync_func(const char *mnt, nt_dir); if (!ctx->local_path || !ctx->mask || !ctx->remote_path) { DEBUG(0,("gpo_sync_func: ENOMEM\n")); - return; + return NT_STATUS_NO_MEMORY; } - if (!gpo_sync_files(ctx)) { + result = gpo_sync_files(ctx); + if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("could not sync files\n")); + return result; } ctx->remote_path = old_nt_dir; ctx->local_path = old_unix_dir; - return; + return NT_STATUS_OK; } DEBUG(3,("got file: [%s]\n", info->name)); @@ -205,6 +208,7 @@ static void gpo_sync_func(const char *mnt, DEBUG(1,("failed to copy file: %s\n", nt_errstr(result))); } + return result; } @@ -232,9 +236,5 @@ NTSTATUS gpo_sync_directories(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - if (!gpo_sync_files(&ctx)) { - return NT_STATUS_NO_SUCH_FILE; - } - - return NT_STATUS_OK; + return gpo_sync_files(&ctx); } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 280f876ba7..87c66672e1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -469,7 +469,7 @@ static NTSTATUS cli_list_old_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, NTSTATUS cli_list_old(struct cli_state *cli, const char *mask, uint16 attribute, - void (*fn)(const char *, struct file_info *, + NTSTATUS (*fn)(const char *, struct file_info *, const char *, void *), void *state) { TALLOC_CTX *frame = talloc_stackframe(); @@ -504,7 +504,10 @@ NTSTATUS cli_list_old(struct cli_state *cli, const char *mask, } num_finfo = talloc_array_length(finfo); for (i=0; i<num_finfo; i++) { - fn(cli->dfs_mountpoint, &finfo[i], mask, state); + status = fn(cli->dfs_mountpoint, &finfo[i], mask, state); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } } fail: TALLOC_FREE(frame); @@ -795,7 +798,7 @@ static NTSTATUS cli_list_trans_recv(struct tevent_req *req, 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, + NTSTATUS (*fn)(const char *mnt, struct file_info *finfo, const char *mask, void *private_data), void *private_data) { @@ -830,7 +833,10 @@ NTSTATUS cli_list_trans(struct cli_state *cli, const char *mask, } num_finfo = talloc_array_length(finfo); for (i=0; i<num_finfo; i++) { - fn(cli->dfs_mountpoint, &finfo[i], mask, private_data); + status = fn(cli->dfs_mountpoint, &finfo[i], mask, private_data); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } } fail: TALLOC_FREE(frame); @@ -911,7 +917,7 @@ NTSTATUS cli_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, } NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint16 attribute, - void (*fn)(const char *, struct file_info *, const char *, + NTSTATUS (*fn)(const char *, struct file_info *, const char *, void *), void *state) { TALLOC_CTX *frame = talloc_stackframe(); @@ -952,7 +958,10 @@ NTSTATUS cli_list(struct cli_state *cli, const char *mask, uint16 attribute, } for (i=0; i<num_finfo; i++) { - fn(cli->dfs_mountpoint, &finfo[i], mask, state); + status = fn(cli->dfs_mountpoint, &finfo[i], mask, state); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } } fail: TALLOC_FREE(frame); diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 9398f92612..fdaf949c08 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -147,9 +147,10 @@ list_unique_wg_fn(const char *name, dirent_type = dir->dir_type; if (add_dirent(dir, name, comment, dirent_type) < 0) { - /* An error occurred, what do we do? */ /* FIXME: Add some code here */ + /* Change cli_NetServerEnum to take a fn + returning NTSTATUS... JRA. */ } /* Point to the one just added */ @@ -227,14 +228,14 @@ list_fn(const char *name, } if (add_dirent(dir, name, comment, dirent_type) < 0) { - /* An error occurred, what do we do? */ /* FIXME: Add some code here */ - + /* Change cli_NetServerEnum to take a fn + returning NTSTATUS... JRA. */ } } -static void +static NTSTATUS dir_list_fn(const char *mnt, struct file_info *finfo, const char *mask, @@ -243,13 +244,10 @@ dir_list_fn(const char *mnt, if (add_dirent((SMBCFILE *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { - - /* Handle an error ... */ - - /* FIXME: Add some code ... */ - + SMBCFILE *dir = (SMBCFILE *)state; + return map_nt_error_from_unix(dir->dir_error); } - + return NT_STATUS_OK; } static int @@ -1211,7 +1209,7 @@ SMBC_mkdir_ctx(SMBCCTX *context, * Our list function simply checks to see if a directory is not empty */ -static void +static NTSTATUS rmdir_list_fn(const char *mnt, struct file_info *finfo, const char *mask, @@ -1222,6 +1220,7 @@ rmdir_list_fn(const char *mnt, bool *smbc_rmdir_dirempty = (bool *)state; *smbc_rmdir_dirempty = false; } + return NT_STATUS_OK; } /* diff --git a/source3/torture/masktest.c b/source3/torture/masktest.c index 51de6d9505..82aa6bff36 100644 --- a/source3/torture/masktest.c +++ b/source3/torture/masktest.c @@ -269,7 +269,7 @@ struct rn_state { char *short_name; }; -static void listfn(const char *mnt, struct file_info *f, const char *s, +static NTSTATUS listfn(const char *mnt, struct file_info *f, const char *s, void *private_data) { struct rn_state *state = (struct rn_state *)private_data; @@ -281,17 +281,22 @@ static void listfn(const char *mnt, struct file_info *f, const char *s, resultp[2] = '+'; } - if ((state == NULL) || ISDOT(f->name) || ISDOTDOT(f->name)) { - return; + if (state == NULL) { + return NT_STATUS_INTERNAL_ERROR; + } + + if (ISDOT(f->name) || ISDOTDOT(f->name)) { + return NT_STATUS_OK; } fstrcpy(state->short_name, f->short_name); strlower_m(state->short_name); *state->pp_long_name = SMB_STRDUP(f->name); if (!*state->pp_long_name) { - return; + return NT_STATUS_NO_MEMORY; } strlower_m(*state->pp_long_name); + return NT_STATUS_OK; } static void get_real_name(struct cli_state *cli, diff --git a/source3/torture/nbio.c b/source3/torture/nbio.c index 1e72a6f7e4..f4625ab632 100644 --- a/source3/torture/nbio.c +++ b/source3/torture/nbio.c @@ -264,10 +264,11 @@ void nb_qfsinfo(int level) cli_dskattr(c, &bsize, &total, &avail); } -static void find_fn(const char *mnt, struct file_info *finfo, const char *name, +static NTSTATUS find_fn(const char *mnt, struct file_info *finfo, const char *name, void *state) { /* noop */ + return NT_STATUS_OK; } void nb_findfirst(const char *mask) @@ -284,9 +285,10 @@ void nb_flush(int fnum) static int total_deleted; -static void delete_fn(const char *mnt, struct file_info *finfo, +static NTSTATUS delete_fn(const char *mnt, struct file_info *finfo, const char *name, void *state) { + NTSTATUS status; char *s, *n; if (finfo->name[0] == '.') return; @@ -294,15 +296,20 @@ static void delete_fn(const char *mnt, struct file_info *finfo, n[strlen(n)-1] = 0; if (asprintf(&s, "%s%s", n, finfo->name) == -1) { printf("asprintf failed\n"); - return; + return NT_STATUS_NO_MEMORY; } if (finfo->mode & aDIR) { char *s2; if (asprintf(&s2, "%s\\*", s) == -1) { printf("asprintf failed\n"); - return; + return NT_STATUS_NO_MEMORY; + } + status = cli_list(c, s2, aDIR, delete_fn, NULL); + if (!NT_STATUS_IS_OK(status)) { + free(n); + free(s2); + return status; } - cli_list(c, s2, aDIR, delete_fn, NULL); nb_rmdir(s); } else { total_deleted++; @@ -310,6 +317,7 @@ static void delete_fn(const char *mnt, struct file_info *finfo, } free(s); free(n); + return NT_STATUS_OK; } void nb_deltree(const char *dname) diff --git a/source3/torture/torture.c b/source3/torture/torture.c index c416a161e0..57db3d47b7 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -4923,13 +4923,14 @@ static bool run_openattrtest(int dummy) return correct; } -static void list_fn(const char *mnt, struct file_info *finfo, +static NTSTATUS list_fn(const char *mnt, struct file_info *finfo, const char *name, void *state) { int *matched = (int *)state; if (matched != NULL) { *matched += 1; } + return NT_STATUS_OK; } /* @@ -4995,7 +4996,7 @@ static bool run_dirtest(int dummy) return correct; } -static void del_fn(const char *mnt, struct file_info *finfo, const char *mask, +static NTSTATUS del_fn(const char *mnt, struct file_info *finfo, const char *mask, void *state) { struct cli_state *pcli = (struct cli_state *)state; @@ -5003,7 +5004,7 @@ static void del_fn(const char *mnt, struct file_info *finfo, const char *mask, slprintf(fname, sizeof(fname), "\\LISTDIR\\%s", finfo->name); if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0) - return; + return NT_STATUS_OK; if (finfo->mode & aDIR) { if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname))) @@ -5012,6 +5013,7 @@ static void del_fn(const char *mnt, struct file_info *finfo, const char *mask, if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN))) printf("del_fn: failed to unlink %s\n,", fname ); } + return NT_STATUS_OK; } @@ -6312,23 +6314,30 @@ static bool run_uid_regression_test(int dummy) static const char *illegal_chars = "*\\/?<>|\":"; static char force_shortname_chars[] = " +,.[];=\177"; -static void shortname_del_fn(const char *mnt, struct file_info *finfo, +static NTSTATUS shortname_del_fn(const char *mnt, struct file_info *finfo, const char *mask, void *state) { struct cli_state *pcli = (struct cli_state *)state; fstring fname; + NTSTATUS status = NT_STATUS_OK; + slprintf(fname, sizeof(fname), "\\shortname\\%s", finfo->name); if (strcmp(finfo->name, ".") == 0 || strcmp(finfo->name, "..") == 0) - return; + return NT_STATUS_OK; if (finfo->mode & aDIR) { - if (!NT_STATUS_IS_OK(cli_rmdir(pcli, fname))) + status = cli_rmdir(pcli, fname); + if (!NT_STATUS_IS_OK(status)) { printf("del_fn: failed to rmdir %s\n,", fname ); + } } else { - if (!NT_STATUS_IS_OK(cli_unlink(pcli, fname, aSYSTEM | aHIDDEN))) + status = cli_unlink(pcli, fname, aSYSTEM | aHIDDEN); + if (!NT_STATUS_IS_OK(status)) { printf("del_fn: failed to unlink %s\n,", fname ); + } } + return status; } struct sn_state { @@ -6337,7 +6346,7 @@ struct sn_state { bool val; }; -static void shortname_list_fn(const char *mnt, struct file_info *finfo, +static NTSTATUS shortname_list_fn(const char *mnt, struct file_info *finfo, const char *name, void *state) { struct sn_state *s = (struct sn_state *)state; @@ -6362,6 +6371,7 @@ static void shortname_list_fn(const char *mnt, struct file_info *finfo, s->val = true; } s->matched += 1; + return NT_STATUS_OK; } static bool run_shortname_test(int dummy) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index c60887c319..1b0e469afc 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -39,7 +39,7 @@ #include "../libcli/security/security.h" static int net_mode_share; -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask); +static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask); /** * @file net_rpc.c @@ -3347,7 +3347,7 @@ static int rpc_share_migrate_shares(struct net_context *c, int argc, * @param state arg-pointer * **/ -static void copy_fn(const char *mnt, struct file_info *f, +static NTSTATUS copy_fn(const char *mnt, struct file_info *f, const char *mask, void *state) { static NTSTATUS nt_status; @@ -3363,7 +3363,7 @@ static void copy_fn(const char *mnt, struct file_info *f, c = local_state->c; if (strequal(f->name, ".") || strequal(f->name, "..")) - return; + return NT_STATUS_OK; DEBUG(3,("got mask: %s, name: %s\n", mask, f->name)); @@ -3391,12 +3391,14 @@ static void copy_fn(const char *mnt, struct file_info *f, break; default: d_fprintf(stderr, _("Unsupported mode %d\n"), net_mode_share); - return; + return NT_STATUS_INTERNAL_ERROR; } - if (!NT_STATUS_IS_OK(nt_status)) + if (!NT_STATUS_IS_OK(nt_status)) { printf(_("could not handle dir %s: %s\n"), dir, nt_errstr(nt_status)); + return nt_status; + } /* search below that directory */ fstrcpy(new_mask, dir); @@ -3404,11 +3406,13 @@ static void copy_fn(const char *mnt, struct file_info *f, old_dir = local_state->cwd; local_state->cwd = dir; - if (!sync_files(local_state, new_mask)) + nt_status = sync_files(local_state, new_mask); + if (!NT_STATUS_IS_OK(nt_status)) { printf(_("could not handle files\n")); + } local_state->cwd = old_dir; - return; + return nt_status; } @@ -3434,13 +3438,13 @@ static void copy_fn(const char *mnt, struct file_info *f, default: d_fprintf(stderr, _("Unsupported file mode %d\n"), net_mode_share); - return; + return NT_STATUS_INTERNAL_ERROR; } if (!NT_STATUS_IS_OK(nt_status)) printf(_("could not handle file %s: %s\n"), filename, nt_errstr(nt_status)); - + return nt_status; } /** @@ -3452,7 +3456,7 @@ static void copy_fn(const char *mnt, struct file_info *f, * * @return Boolean result **/ -static bool sync_files(struct copy_clistate *cp_clistate, const char *mask) +static NTSTATUS sync_files(struct copy_clistate *cp_clistate, const char *mask) { struct cli_state *targetcli; char *targetpath = NULL; @@ -3465,7 +3469,7 @@ static bool sync_files(struct copy_clistate *cp_clistate, const char *mask) d_fprintf(stderr, _("cli_resolve_path %s failed with error: " "%s\n"), mask, cli_errstr(cp_clistate->cli_share_src)); - return false; + return cli_nt_error(cp_clistate->cli_share_src); } status = cli_list(targetcli, targetpath, cp_clistate->attribute, @@ -3473,10 +3477,9 @@ static bool sync_files(struct copy_clistate *cp_clistate, const char *mask) if (!NT_STATUS_IS_OK(status)) { d_fprintf(stderr, _("listing %s failed with error: %s\n"), mask, nt_errstr(status)); - return false; } - return true; + return status; } @@ -3633,10 +3636,10 @@ static NTSTATUS rpc_share_migrate_files_internals(struct net_context *c, goto done; } - if (!sync_files(&cp_clistate, mask)) { + nt_status = sync_files(&cp_clistate, mask); + if (!NT_STATUS_IS_OK(nt_status)) { d_fprintf(stderr, _("could not handle files for share: " "%s\n"), info502.name); - nt_status = NT_STATUS_UNSUCCESSFUL; goto done; } } |