通常,PL/Perl 被安装为名为 plperl 的
“受信”编程
语言。在这种设置下,某些 Perl 操作为保安全而被禁用。
一般来说,被限制的操作是那些与环境交互的操作。
这包括文件句柄操作、
require,以及用于外部模块的
use。
PL/Perl 无法访问数据库服务器进程的内部机制,也无法以服务器进程的
权限获得操作系统级访问,而 C 函数可以做到这些。
因此,任何无特权的数据库用户都可以被允许使用这种语言。
受信 PL/Perl 依赖 Perl 的 Opcode 模块来保证
安全。
Perl 的
文档
指出该模块对受信 PL/Perl 用例并不有效。
如果您的安全需求与该警告中的不确定性相冲突,请考虑执行
REVOKE USAGE ON LANGUAGE plperl FROM
PUBLIC。
下面是一个无法工作的函数示例,因为出于安全原因不允许文件系统 操作:
CREATE FUNCTION badfunc() RETURNS integer AS $$
my $tmpfile = "/tmp/badfile";
open my $fh, '>', $tmpfile
or elog(ERROR, qq{could not open the file "$tmpfile": $!});
print $fh "Testing writing to a file\n";
close $fh or elog(ERROR, qq{could not close the file "$tmpfile": $!});
return 1;
$$ LANGUAGE plperl;
创建该函数会失败,因为它对被禁止操作的使用会被验证器捕获。
有时人们希望编写不受限制的 Perl 函数。
例如,可能想要一个发送邮件的 Perl 函数。
为了处理这些情况,PL/Perl 也可以被安装为
“非受信”语言(通常称为
PL/PerlU)。
这种情况下可以使用完整的 Perl 语言。
安装该语言时,语言名 plperlu 会选择
非受信的 PL/Perl 变体。
PL/PerlU 函数的作者必须注意该函数不能被 用来做任何不想要的事情,因为它能够做数据库管理员登录后所能做的 任何事情。 注意,数据库系统只允许数据库超级用户在非受信语言中创建函数。
如果上述函数由超级用户用 plperlu 语言创建,
执行将会成功。
同样,用 Perl 编写的匿名代码块在语言被指定为
plperlu 而非 plperl 时
可以使用被限制的操作,但调用者必须是超级用户。
虽然 PL/Perl 函数为每个 SQL 角色在 一个独立的 Perl 解释器中运行,但在给定会话中执行的所有 PL/PerlU 函数都运行在单个 Perl 解释器中 (它不是用于 PL/Perl 函数的那些解释器 中的任何一个)。 这允许 PL/PerlU 函数自由共享数据, 但 PL/Perl 函数与 PL/PerlU 函数之间不会发生任何 通信。
除非 Perl 构建时带有相应的标志(即
usemultiplicity 或
useithreads),否则它无法在一个进程中支持
多个解释器。
(除非您确实需要使用线程,否则优先选择
usemultiplicity。
更多细节参见
perlembed
手册页。)
如果 PL/Perl 使用的是未以此方式构建的
Perl 副本,那么每个会话只能有一个 Perl 解释器,因此任何一个会话
只能执行
PL/PerlU 函数,或全部由同一个 SQL 角色
调用的 PL/Perl 函数。