From fba5a722497c1e4577aa463921a0fec5f6d5fe55 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Mar 2004 20:55:59 +0000 Subject: Use a common function to parse all pathnames from the wire. This allows much closer emulation of Win2k3 error return codes. Jeremy. (This used to be commit c9f31fafeda6ad79e590276f36e03ecd2e93f818) --- source3/smbd/trans2.c | 69 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 16 deletions(-) (limited to 'source3/smbd/trans2.c') diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 5fbc5ce6ee..1d580e6f5b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -228,6 +228,7 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i int smb_action = 0; BOOL bad_path = False; files_struct *fsp; + NTSTATUS status; /* * Ensure we have enough parameters to perform the operation. @@ -248,7 +249,10 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i open_size = IVAL(params,14); pname = ¶ms[28]; - srvstr_pull(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, fname, pname, sizeof(fname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } DEBUG(3,("trans2open %s mode=%d attr=%d ofun=%d size=%d\n", fname,open_mode, open_attr, open_ofun, open_size)); @@ -939,6 +943,7 @@ static int call_trans2findfirst(connection_struct *conn, char *inbuf, char *outb int space_remaining; BOOL bad_path = False; SMB_STRUCT_STAT sbuf; + NTSTATUS ntstatus = NT_STATUS_OK; if (total_params < 12) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -968,7 +973,10 @@ close_if_end = %d requires_resume_key = %d level = %d, max_data_bytes = %d\n", return(ERROR_DOS(ERRDOS,ERRunknownlevel)); } - srvstr_pull(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE); + srvstr_get_path(inbuf, directory, params+12, sizeof(directory), -1, STR_TERMINATE, &ntstatus); + if (!NT_STATUS_IS_OK(ntstatus)) { + return ERROR_NT(ntstatus); + } RESOLVE_FINDFIRST_DFSPATH(directory, conn, inbuf, outbuf); @@ -1151,13 +1159,17 @@ static int call_trans2findnext(connection_struct *conn, char *inbuf, char *outbu BOOL dont_descend = False; BOOL out_of_space = False; int space_remaining; + NTSTATUS ntstatus = NT_STATUS_OK; if (total_params < 12) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); *mask = *directory = *resume_name = 0; - srvstr_pull(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE); + srvstr_get_path(inbuf, resume_name, params+12, sizeof(resume_name), -1, STR_TERMINATE, &ntstatus); + if (!NT_STATUS_IS_OK(ntstatus)) { + return ERROR_NT(ntstatus); + } DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \ close_after_request=%d, close_if_end = %d requires_resume_key = %d \ @@ -1909,6 +1921,8 @@ static int call_trans2qfilepathinfo(connection_struct *conn, desired_access = fsp->desired_access; } } else { + NTSTATUS status = NT_STATUS_OK; + /* qpathinfo */ if (total_params < 6) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -1917,7 +1931,10 @@ static int call_trans2qfilepathinfo(connection_struct *conn, DEBUG(3,("call_trans2qfilepathinfo: TRANSACT2_QPATHINFO: level = %d\n", info_level)); - srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } RESOLVE_DFSPATH(fname, conn, inbuf, outbuf); @@ -2483,6 +2500,7 @@ static int call_trans2setfilepathinfo(connection_struct *conn, uid_t set_owner = (uid_t)SMB_UID_NO_CHANGE; gid_t set_grp = (uid_t)SMB_GID_NO_CHANGE; mode_t unixmode = 0; + NTSTATUS status = NT_STATUS_OK; if (!params) return ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -2540,7 +2558,10 @@ static int call_trans2setfilepathinfo(connection_struct *conn, return(ERROR_DOS(ERRDOS,ERRinvalidparam)); info_level = SVAL(params,0); - srvstr_pull(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, fname, ¶ms[6], sizeof(fname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } unix_convert(fname,conn,0,&bad_path,&sbuf); /* @@ -2761,7 +2782,6 @@ static int call_trans2setfilepathinfo(connection_struct *conn, case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */ { BOOL delete_on_close; - NTSTATUS status; if (total_data < 1) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -2948,7 +2968,10 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (VALID_STAT(sbuf)) return(ERROR_DOS(ERRDOS,ERRbadpath)); - srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE); + srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } if (ensure_link_is_safe(conn, link_dest, link_dest) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2973,7 +2996,10 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", if (VALID_STAT(sbuf)) return(ERROR_DOS(ERRDOS,ERRbadpath)); - srvstr_pull(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE); + srvstr_get_path(inbuf, link_dest, pdata, sizeof(link_dest), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } if (ensure_link_is_safe(conn, link_dest, link_dest) != 0) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2996,7 +3022,6 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", pstring newname; pstring base_name; char *p; - NTSTATUS status; if (total_data < 12) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); @@ -3004,10 +3029,13 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", overwrite = (CVAL(pdata,0) ? True : False); root_fid = IVAL(pdata,4); len = IVAL(pdata,8); - srvstr_pull(inbuf, newname, &pdata[12], sizeof(newname), len, 0); + srvstr_get_path(inbuf, newname, &pdata[12], sizeof(newname), len, 0, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } - /* Check the new name has no '\' characters. */ - if (strchr_m(newname, '\\') || strchr_m(newname, '/')) + /* Check the new name has no '/' characters. */ + if (strchr_m(newname, '/')) return ERROR_NT(NT_STATUS_NOT_SUPPORTED); RESOLVE_DFSPATH(newname, conn, inbuf, outbuf); @@ -3028,10 +3056,11 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n", } else { DEBUG(10,("call_trans2setfilepathinfo: SMB_FILE_RENAME_INFORMATION %s -> %s\n", fname, newname )); - status = rename_internals(conn, fname, base_name, overwrite); + status = rename_internals(conn, fname, base_name, 0, overwrite); } - if (!NT_STATUS_IS_OK(status)) + if (!NT_STATUS_IS_OK(status)) { return ERROR_NT(status); + } process_pending_change_notify_queue((time_t)0); SSVAL(params,0,0); send_trans2_replies(outbuf, bufsize, params, 2, *ppdata, 0); @@ -3171,6 +3200,7 @@ static int call_trans2mkdir(connection_struct *conn, int ret = -1; SMB_STRUCT_STAT sbuf; BOOL bad_path = False; + NTSTATUS status = NT_STATUS_OK; if (!CAN_WRITE(conn)) return ERROR_DOS(ERRSRV,ERRaccess); @@ -3178,7 +3208,10 @@ static int call_trans2mkdir(connection_struct *conn, if (total_params < 4) return(ERROR_DOS(ERRDOS,ERRinvalidparam)); - srvstr_pull(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE); + srvstr_get_path(inbuf, directory, ¶ms[4], sizeof(directory), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); @@ -3290,6 +3323,7 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, pstring pathname; int reply_size = 0; int max_referral_level; + NTSTATUS status = NT_STATUS_OK; DEBUG(10,("call_trans2getdfsreferral\n")); @@ -3301,7 +3335,10 @@ static int call_trans2getdfsreferral(connection_struct *conn, char* inbuf, if(!lp_host_msdfs()) return ERROR_DOS(ERRDOS,ERRbadfunc); - srvstr_pull(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE); + srvstr_get_path(inbuf, pathname, ¶ms[2], sizeof(pathname), -1, STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { + return ERROR_NT(status); + } if((reply_size = setup_dfs_referral(conn, pathname,max_referral_level,ppdata)) < 0) return UNIXERROR(ERRDOS,ERRbadfile); -- cgit