Skip to content

Commit b533b24

Browse files
fix: no permission check for copy stdin/out (#136)
Fixes #135
1 parent 0a71ff3 commit b533b24

File tree

6 files changed

+45
-36
lines changed

6 files changed

+45
-36
lines changed

src/arrow_parquet/uri_utils.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,13 +269,18 @@ pub(crate) fn parquet_writer_from_uri(
269269
})
270270
}
271271

272-
pub(crate) fn ensure_access_privilege_to_uri(uri: &Url, copy_from: bool) {
272+
pub(crate) fn ensure_access_privilege_to_uri(uri_info: &ParsedUriInfo, copy_from: bool) {
273273
if unsafe { superuser() } {
274274
return;
275275
}
276276

277+
// permission check is not needed for stdin/out
278+
if uri_info.stdio_tmp_fd.is_some() {
279+
return;
280+
}
281+
277282
let user_id = unsafe { GetUserId() };
278-
let is_file = uri.scheme() == "file";
283+
let is_file = uri_info.uri.scheme() == "file";
279284

280285
let required_role_name = if is_file {
281286
if copy_from {

src/parquet_copy_hook/hook.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,8 @@ fn process_copy_to_parquet(
5353
) -> u64 {
5454
let uri_info = copy_stmt_uri(p_stmt).unwrap_or_else(|e| panic!("{}", e));
5555

56-
let uri = uri_info.uri.clone();
57-
5856
let copy_from = false;
59-
ensure_access_privilege_to_uri(&uri, copy_from);
57+
ensure_access_privilege_to_uri(&uri_info, copy_from);
6058

6159
validate_copy_to_options(p_stmt, &uri_info);
6260

@@ -68,7 +66,7 @@ fn process_copy_to_parquet(
6866
let compression_level = copy_to_stmt_compression_level(p_stmt, &uri_info);
6967

7068
let parquet_split_dest = create_copy_to_parquet_split_dest_receiver(
71-
uri_as_string(&uri).as_pg_cstr(),
69+
uri_as_string(&uri_info.uri).as_pg_cstr(),
7270
uri_info.stdio_tmp_fd.is_some(),
7371
&file_size_bytes,
7472
field_ids,
@@ -103,10 +101,8 @@ fn process_copy_from_parquet(
103101
) -> u64 {
104102
let uri_info = copy_stmt_uri(p_stmt).unwrap_or_else(|e| panic!("{}", e));
105103

106-
let uri = uri_info.uri.clone();
107-
108104
let copy_from = true;
109-
ensure_access_privilege_to_uri(&uri, copy_from);
105+
ensure_access_privilege_to_uri(&uri_info, copy_from);
110106

111107
validate_copy_from_options(p_stmt);
112108

src/parquet_udfs/metadata.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ mod parquet {
4545
panic!("{}", e.to_string());
4646
});
4747

48-
ensure_access_privilege_to_uri(&uri_info.uri, true);
48+
ensure_access_privilege_to_uri(&uri_info, true);
4949
let parquet_metadata = parquet_metadata_from_uri(&uri_info);
5050

5151
let mut rows = vec![];
@@ -148,7 +148,7 @@ mod parquet {
148148
panic!("{}", e.to_string());
149149
});
150150

151-
ensure_access_privilege_to_uri(&uri_info.uri, true);
151+
ensure_access_privilege_to_uri(&uri_info, true);
152152
let parquet_metadata = parquet_metadata_from_uri(&uri_info);
153153

154154
let created_by = parquet_metadata
@@ -188,7 +188,7 @@ mod parquet {
188188
panic!("{}", e.to_string());
189189
});
190190

191-
ensure_access_privilege_to_uri(&uri_info.uri, true);
191+
ensure_access_privilege_to_uri(&uri_info, true);
192192
let parquet_metadata = parquet_metadata_from_uri(&uri_info);
193193

194194
let kv_metadata = parquet_metadata.file_metadata().key_value_metadata();

src/parquet_udfs/schema.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ mod parquet {
3636
panic!("{}", e.to_string());
3737
});
3838

39-
ensure_access_privilege_to_uri(&uri_info.uri, true);
39+
ensure_access_privilege_to_uri(&uri_info, true);
4040
let parquet_schema = parquet_schema_from_uri(&uri_info);
4141

4242
let root_type = parquet_schema.root_schema();

src/parquet_udfs/stats.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ mod parquet {
112112
panic!("{}", e.to_string());
113113
});
114114

115-
ensure_access_privilege_to_uri(&uri_info.uri, true);
115+
ensure_access_privilege_to_uri(&uri_info, true);
116116
let parquet_metadata = parquet_metadata_from_uri(&uri_info);
117117

118118
let mut aggregated_column_stats = HashMap::new();

src/pgrx_tests/copy_stdin_out.rs

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,33 @@ mod tests {
7676
"Failed to insert into test_expected table"
7777
);
7878

79-
// copy to stdout
79+
// create a dummy role
80+
let role = "dummy";
81+
let output = Command::new("psql")
82+
.arg("-p")
83+
.arg(test_port.clone())
84+
.arg("-h")
85+
.arg("localhost")
86+
.arg("-d")
87+
.arg("pgrx_tests")
88+
.arg("-c")
89+
.arg(format!(
90+
"CREATE ROLE {role} LOGIN;
91+
GRANT SELECT, INSERT, UPDATE, DELETE ON test_expected TO {role};
92+
GRANT SELECT, INSERT, UPDATE, DELETE ON test_result TO {role};"
93+
))
94+
.output()
95+
.expect("failed to execute process");
96+
assert!(output.status.success(), "Failed to create role {role}");
97+
98+
// copy to stdout with dummy role
8099
let mut copy_to = Command::new("psql")
81100
.arg("-p")
82101
.arg(test_port.clone())
83102
.arg("-h")
84103
.arg("localhost")
104+
.arg("-U")
105+
.arg(role)
85106
.arg("-d")
86107
.arg("pgrx_tests")
87108
.arg("-c")
@@ -101,12 +122,14 @@ mod tests {
101122
assert!(status.success(), "psql COPY TO process did not succeed");
102123
}
103124

104-
// copy from stdin
125+
// copy from stdin with dummy role
105126
let mut copy_from = Command::new("psql")
106127
.arg("-p")
107128
.arg(test_port.clone())
108129
.arg("-h")
109130
.arg("localhost")
131+
.arg("-U")
132+
.arg(role)
110133
.arg("-d")
111134
.arg("pgrx_tests")
112135
.arg("-c")
@@ -178,7 +201,7 @@ mod tests {
178201
]
179202
);
180203

181-
// drop test_expected
204+
// drop tables and role
182205
let output = Command::new("psql")
183206
.arg("-p")
184207
.arg(test_port.clone())
@@ -187,26 +210,11 @@ mod tests {
187210
.arg("-d")
188211
.arg("pgrx_tests")
189212
.arg("-c")
190-
.arg("DROP TABLE test_expected;")
191-
.output()
192-
.expect("failed to execute process");
193-
assert!(
194-
output.status.success(),
195-
"Failed to drop test_expected table"
196-
);
197-
198-
// drop test_result
199-
let output = Command::new("psql")
200-
.arg("-p")
201-
.arg(test_port.clone())
202-
.arg("-h")
203-
.arg("localhost")
204-
.arg("-d")
205-
.arg("pgrx_tests")
206-
.arg("-c")
207-
.arg("DROP TABLE test_result;")
213+
.arg(format!(
214+
"DROP TABLE test_expected, test_result; DROP ROLE {role};"
215+
))
208216
.output()
209217
.expect("failed to execute process");
210-
assert!(output.status.success(), "Failed to drop test_result table");
218+
assert!(output.status.success(), "Failed to clean up");
211219
}
212220
}

0 commit comments

Comments
 (0)