Commit fddef6fc authored by Jeremy Allison's avatar Jeremy Allison Committed by Gerald (Jerry) Carter
Browse files

r1115: Fix for #1427. Catch bad path errors at the right point. Ensure all

our pathname parsing is consistent.
Jeremy.
(This used to be commit 5e8237e306f0bb0e492f10fb6487938132899384)
parent f28e4f38
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -748,11 +748,11 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO
	
	if (!good) {

		DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
		DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n",
					(unsigned int)saved_seq));
		dump_data(5, (const char *)calc_md5_mac, 8);
		
		DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
		DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n",
					(unsigned int)saved_seq));
		dump_data(5, (const char *)server_sent_mac, 8);

+24 −0
Original line number Diff line number Diff line
@@ -1886,6 +1886,18 @@ WERROR _srv_net_file_query_secdesc(pipes_struct *p, SRV_Q_NET_FILE_QUERY_SECDESC

	unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
	unix_convert(filename, conn, NULL, &bad_path, &st);
	if (bad_path) {
		DEBUG(3,("_srv_net_file_query_secdesc: bad pathname %s\n", filename));
		r_u->status = WERR_ACCESS_DENIED;
		goto error_exit;
	}

	if (!check_name(filename,conn)) {
		DEBUG(3,("_srv_net_file_query_secdesc: can't access %s\n", filename));
		r_u->status = WERR_ACCESS_DENIED;
		goto error_exit;
	}

	fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
				(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
				&access_mode, &action);
@@ -1990,6 +2002,18 @@ WERROR _srv_net_file_set_secdesc(pipes_struct *p, SRV_Q_NET_FILE_SET_SECDESC *q_

	unistr2_to_ascii(filename, &q_u->uni_file_name, sizeof(filename));
	unix_convert(filename, conn, NULL, &bad_path, &st);
	if (bad_path) {
		DEBUG(3,("_srv_net_file_set_secdesc: bad pathname %s\n", filename));
		r_u->status = WERR_ACCESS_DENIED;
		goto error_exit;
	}

	if (!check_name(filename,conn)) {
		DEBUG(3,("_srv_net_file_set_secdesc: can't access %s\n", filename));
		r_u->status = WERR_ACCESS_DENIED;
		goto error_exit;
	}


	fsp = open_file_shared(conn, filename, &st, SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDWR),
			(FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN), FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY,
+22 −3
Original line number Diff line number Diff line
@@ -237,6 +237,15 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
				 */
				DEBUG(5,("Not a dir %s\n",start));
				*end = '/';
				/* 
				 * We need to return the fact that the intermediate
				 * name resolution failed. This is used to return an
				 * error of ERRbadpath rather than ERRbadfile. Some
				 * Windows applications depend on the difference between
				 * these two errors.
				 */
				errno = ENOTDIR;
				*bad_path = True;
				return(False);
			}

@@ -265,6 +274,9 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
			if (end)
				pstrcpy(rest,end+1);

			/* Reset errno so we can detect directory open errors. */
			errno = 0;

			/*
			 * Try to find this part of the path in the directory.
			 */
@@ -292,6 +304,11 @@ BOOL unix_convert(pstring name,connection_struct *conn,char *saved_last_componen
					return(False);
				}
	      
				if (errno == ENOTDIR) {
					*bad_path = True;
					return(False);
				}

				/* 
				 * Just the last part of the name doesn't exist.
				 * We may need to strupper() or strlower() it in case
@@ -392,12 +409,11 @@ BOOL check_name(pstring name,connection_struct *conn)
{
	BOOL ret = True;

	errno = 0;

	if (IS_VETO_PATH(conn, name))  {
		/* Is it not dot or dot dot. */
		if (!((name[0] == '.') && (!name[1] || (name[1] == '.' && !name[2])))) {
			DEBUG(5,("file path name %s vetoed\n",name));
			errno = ENOENT;
			return False;
		}
	}
@@ -416,13 +432,15 @@ BOOL check_name(pstring name,connection_struct *conn)
		if ( (SMB_VFS_LSTAT(conn,name,&statbuf) != -1) &&
				(S_ISLNK(statbuf.st_mode)) ) {
			DEBUG(3,("check_name: denied: file path name %s is a symlink\n",name));
			errno = EACCES;
			ret = False; 
		}
	}
#endif

	if (!ret)
	if (!ret) {
		DEBUG(5,("check_name on %s failed\n",name));
	}

	return(ret);
}
@@ -496,5 +514,6 @@ static BOOL scan_directory(const char *path, char *name, size_t maxlength,
	}

	CloseDir(cur_dir);
	errno = ENOENT;
	return(False);
}
+2 −2
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ static BOOL parse_dfs_path(char* pathname, struct dfs_path* pdp)
	DEBUG(10,("parse_dfs_path: servicename: %s\n",pdp->servicename));

	/* rest is reqpath */
	check_path_syntax(pdp->reqpath, p+1);
	check_path_syntax(pdp->reqpath, p+1,True);

	DEBUG(10,("parse_dfs_path: rest of the path: %s\n",pdp->reqpath));
	return True;
@@ -111,7 +111,7 @@ static BOOL parse_processed_dfs_path(char* pathname, struct dfs_path* pdp)
	DEBUG(10,("parse_processed_dfs_path: servicename: %s\n",pdp->servicename));

	/* rest is reqpath */
	check_path_syntax(pdp->reqpath, p+1);
	check_path_syntax(pdp->reqpath, p+1,True);

	DEBUG(10,("parse_processed_dfs_path: rest of the path: %s\n",pdp->reqpath));
	return True;
+31 −11
Original line number Diff line number Diff line
@@ -651,7 +651,7 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib

		if(!dir_fsp->is_directory) {

			srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
			srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status,False);
			if (!NT_STATUS_IS_OK(status)) {
				END_PROFILE(SMBntcreateX);
				return ERROR_NT(status);
@@ -693,14 +693,14 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
			dir_name_len++;
		}

		srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status);
		srvstr_get_path(inbuf, rel_fname, smb_buf(inbuf), sizeof(rel_fname), 0, STR_TERMINATE, &status,False);
		if (!NT_STATUS_IS_OK(status)) {
			END_PROFILE(SMBntcreateX);
			return ERROR_NT(status);
		}
		pstrcat(fname, rel_fname);
	} else {
		srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status);
		srvstr_get_path(inbuf, fname, smb_buf(inbuf), sizeof(fname), 0, STR_TERMINATE, &status,False);
		if (!NT_STATUS_IS_OK(status)) {
			END_PROFILE(SMBntcreateX);
			return ERROR_NT(status);
@@ -762,6 +762,17 @@ create_options = 0x%x root_dir_fid = 0x%x\n", flags, desired_access, file_attrib
	set_posix_case_semantics(conn, file_attributes);
		
	unix_convert(fname,conn,0,&bad_path,&sbuf);
	if (bad_path) {
		restore_case_semantics(conn, file_attributes);
		END_PROFILE(SMBntcreateX);
		return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
	}
	/* All file access must go through check_name() */
	if (!check_name(fname,conn)) {
		restore_case_semantics(conn, file_attributes);
		END_PROFILE(SMBntcreateX);
		return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
	}

	/* 
	 * If it's a request for a directory open, deal with it separately.
@@ -1015,7 +1026,7 @@ static int do_nt_transact_create_pipe( connection_struct *conn, char *inbuf, cha
		return ERROR_DOS(ERRDOS,ERRnoaccess);
	}

	srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
	srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
	if (!NT_STATUS_IS_OK(status)) {
		return ERROR_NT(status);
	}
@@ -1218,7 +1229,7 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
			return ERROR_DOS(ERRDOS,ERRbadfid);

		if(!dir_fsp->is_directory) {
			srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
			srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
			if (!NT_STATUS_IS_OK(status)) {
				return ERROR_NT(status);
			}
@@ -1251,14 +1262,14 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o

		{
			pstring tmpname;
			srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status);
			srvstr_get_path(inbuf, tmpname, params+53, sizeof(tmpname), parameter_count-53, STR_TERMINATE, &status, False);
			if (!NT_STATUS_IS_OK(status)) {
				return ERROR_NT(status);
			}
			pstrcat(fname, tmpname);
		}
	} else {
		srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status);
		srvstr_get_path(inbuf, fname, params+53, sizeof(fname), parameter_count-53, STR_TERMINATE, &status, False);
		if (!NT_STATUS_IS_OK(status)) {
			return ERROR_NT(status);
		}
@@ -1292,6 +1303,15 @@ static int call_nt_transact_create(connection_struct *conn, char *inbuf, char *o
	RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);

	unix_convert(fname,conn,0,&bad_path,&sbuf);
	if (bad_path) {
		restore_case_semantics(conn, file_attributes);
		return ERROR_NT(NT_STATUS_OBJECT_PATH_NOT_FOUND);
	}
	/* All file access must go through check_name() */
	if (!check_name(fname,conn)) {
		restore_case_semantics(conn, file_attributes);
		return set_bad_path_error(errno, bad_path, outbuf, ERRDOS,ERRbadpath);
	}
    
	/*
	 * If it's a request for a directory open, deal with it separately.
@@ -1523,7 +1543,7 @@ int reply_ntrename(connection_struct *conn,
	}

	p = smb_buf(inbuf) + 1;
	p += srvstr_get_path(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status);
	p += srvstr_get_path(inbuf, oldname, p, sizeof(oldname), 0, STR_TERMINATE, &status, True);
	if (!NT_STATUS_IS_OK(status)) {
		END_PROFILE(SMBntrename);
		return ERROR_NT(status);
@@ -1536,7 +1556,7 @@ int reply_ntrename(connection_struct *conn,
	}

	p++;
	p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status);
	p += srvstr_get_path(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, True);
	if (!NT_STATUS_IS_OK(status)) {
		END_PROFILE(SMBntrename);
		return ERROR_NT(status);
@@ -1640,7 +1660,7 @@ static int call_nt_transact_rename(connection_struct *conn, char *inbuf, char *o
	fsp = file_fsp(params, 0);
	replace_if_exists = (SVAL(params,2) & RENAME_REPLACE_IF_EXISTS) ? True : False;
	CHECK_FSP(fsp, conn);
	srvstr_get_path(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status);
	srvstr_get_path(inbuf, new_name, params+4, sizeof(new_name), -1, STR_TERMINATE, &status, True);
	if (!NT_STATUS_IS_OK(status)) {
		return ERROR_NT(status);
	}
Loading