diff options
author | Andrew Tridgell <tridge@samba.org> | 2008-12-03 17:47:39 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2008-12-03 17:47:39 +1100 |
commit | a226d86dcec393b2cd657d5441c3041dfdf5cd8f (patch) | |
tree | 03ef7f3207607a4e5351bf50892b0a39dcf6f219 /source3/smbd/reply.c | |
parent | 30eff4f31b497ac94d8ee02ee2ec24bc8865ce0d (diff) | |
parent | 85b8cccab072bab263061654b677bc84826646c9 (diff) | |
download | samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.gz samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.tar.bz2 samba-a226d86dcec393b2cd657d5441c3041dfdf5cd8f.zip |
Merge branch 'master' of ssh://git.samba.org/data/git/samba
Diffstat (limited to 'source3/smbd/reply.c')
-rw-r--r-- | source3/smbd/reply.c | 74 |
1 files changed, 64 insertions, 10 deletions
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 377ba4e530..11c713ab4a 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -52,11 +52,45 @@ static NTSTATUS check_path_syntax_internal(char *path, const char *s = path; NTSTATUS ret = NT_STATUS_OK; bool start_of_name_component = True; + bool stream_started = false; *p_last_component_contains_wcard = False; while (*s) { - if (IS_PATH_SEP(*s,posix_path)) { + if (stream_started) { + switch (*s) { + case '/': + case '\\': + return NT_STATUS_OBJECT_NAME_INVALID; + case ':': + if (s[1] == '\0') { + return NT_STATUS_OBJECT_NAME_INVALID; + } + if (strchr_m(&s[1], ':')) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + if (StrCaseCmp(s, ":$DATA") != 0) { + return NT_STATUS_INVALID_PARAMETER; + } + break; + } + } + + if (!stream_started && *s == ':') { + if (*p_last_component_contains_wcard) { + return NT_STATUS_OBJECT_NAME_INVALID; + } + /* stream names allow more characters than file names */ + stream_started = true; + start_of_name_component = false; + posix_path = true; + + if (s[1] == '\0') { + return NT_STATUS_OBJECT_NAME_INVALID; + } + } + + if (!stream_started && IS_PATH_SEP(*s,posix_path)) { /* * Safe to assume is not the second part of a mb char * as this is handled below. @@ -119,7 +153,7 @@ static NTSTATUS check_path_syntax_internal(char *path, if (!(*s & 0x80)) { if (!posix_path) { - if (*s <= 0x1f) { + if (*s <= 0x1f || *s == '|') { return NT_STATUS_OBJECT_NAME_INVALID; } switch (*s) { @@ -2894,7 +2928,7 @@ void reply_lockread(struct smb_request *req) return; } - if (!CHECK_READ(fsp,req->inbuf)) { + if (!CHECK_READ(fsp,req)) { reply_doserror(req, ERRDOS, ERRbadaccess); END_PROFILE(SMBlockread); return; @@ -3002,7 +3036,7 @@ void reply_read(struct smb_request *req) return; } - if (!CHECK_READ(fsp,req->inbuf)) { + if (!CHECK_READ(fsp,req)) { reply_doserror(req, ERRDOS, ERRbadaccess); END_PROFILE(SMBread); return; @@ -3255,7 +3289,7 @@ void reply_read_and_X(struct smb_request *req) return; } - if (!CHECK_READ(fsp,req->inbuf)) { + if (!CHECK_READ(fsp,req)) { reply_doserror(req, ERRDOS,ERRbadaccess); END_PROFILE(SMBreadX); return; @@ -4558,8 +4592,15 @@ void reply_printopen(struct smb_request *req) return; } + status = file_new(req, conn, &fsp); + if(!NT_STATUS_IS_OK(status)) { + reply_nterror(req, status); + END_PROFILE(SMBsplopen); + return; + } + /* Open for exclusive use, write only. */ - status = print_fsp_open(req, conn, NULL, req->vuid, &fsp); + status = print_fsp_open(req, conn, NULL, req->vuid, fsp); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -4989,8 +5030,16 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, } } - /* We only have veto files/directories. Recursive delete. */ + /* We only have veto files/directories. + * Are we allowed to delete them ? */ + if(!lp_recursive_veto_delete(SNUM(conn))) { + TALLOC_FREE(dir_hnd); + errno = ENOTEMPTY; + goto err; + } + + /* Do a recursive delete. */ RewindDir(dir_hnd,&dirpos); while ((dname = ReadDirName(dir_hnd,&dirpos))) { char *fullname = NULL; @@ -5016,9 +5065,8 @@ NTSTATUS rmdir_internals(TALLOC_CTX *ctx, break; } if(st.st_mode & S_IFDIR) { - if(lp_recursive_veto_delete(SNUM(conn))) { - if(!recursive_rmdir(ctx, conn, fullname)) - break; + if(!recursive_rmdir(ctx, conn, fullname)) { + break; } if(SMB_VFS_RMDIR(conn,fullname) != 0) { break; @@ -5448,6 +5496,12 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, return NT_STATUS_OBJECT_NAME_COLLISION; } + if(replace_if_exists && dst_exists) { + if (is_ntfs_stream_name(newname)) { + return NT_STATUS_INVALID_PARAMETER; + } + } + if (dst_exists) { struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf1); files_struct *dst_fsp = file_find_di_first(fileid); |