Duplicating Pluggable Databases with sysbackup

According to Backup and Recovery User’s Guide, duplicating of a pluggable database in the existing CDB should work with both sysdba and sysbackup privileges:
“Connect AS TARGET to the root of the source CDB as a common user with the SYSDBA or SYSBACKUP privilege.
Connect AS AUXILIARY to the root of the destination CDB as a common user with the SYSDBA or SYSBACKUP privilege”.
sysbackup is more secure because of the principle of least privilege.
But duplicate fails with sysbackup, because of “insufficient privileges”:

connect target 'sysbackup/password@SRCCDB as sysbackup'
connect auxiliary 'sysbackup/password@DESTCDB as sysbackup'
duplicate pluggable database SRCPDB as DESTPDB to DESTCDB from active database;

...
Starting Duplicate PDB at 20-NOV-20
using target database control file instead of recovery catalog
allocated channel: ORA_AUX_DISK_1
channel ORA_AUX_DISK_1: SID=226 device type=DISK
current log archived
duplicating Online logs to Oracle Managed File (OMF) location
duplicating Datafiles to Oracle Managed File (OMF) location
RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: failure of Duplicate PDB command at 11/20/2020 15:20:29
RMAN-05501: aborting duplication of target database
RMAN-06136: Oracle error from auxiliary database: ORA-17628: Oracle error 1031 returned by remote Oracle server
ORA-01031: insufficient privileges

It’s not clear what privilege is missing.

RMAN debug trace gives more information:

begin sys.dbms_backup_restore.describeRemotePdb( service     => :service_in, pdbname     => :pdbname_in, descxmlfile => :descxmlfile_in); end;
DBGSQL:             sqlcode = 17628
DBGSQL:              B :service_in = SRCCDB
DBGSQL:              B :pdbname_in = SRCPDB
DBGSQL:              B :descxmlfile_in = /u00/oracle/orabase/product/19.8.0.0.200714_a/dbs/_rm_pdb_pitr_2_DESTCDB.xml
DBGSQL:          error: ORA-17628: Oracle error 1031 returned by remote Oracle server (krmkosqlerr)
DBGSQL:          ORA-06512: at "SYS.DBMS_BACKUP_RESTORE", line 10817 (krmkosqlerr)
DBGSQL:          ORA-01031: insufficient privileges (krmkosqlerr)
DBGSQL:          ORA-06512: at "SYS.DBMS_BACKUP_RESTORE", line 10811 (krmkosqlerr)
DBGSQL:          ORA-06512: at line 1 (krmkosqlerr)

Still not sure what the problem is, but I’ve got the idea where to look. The error ORA-17628 came from the auxiliary database, because of the ORA-01031 on the remote database. “Remote database” is the target database from the auxiliary perspective. In other words, the problem is on the target.

There weren’t any ORA-01031 recorded in the target’s audit trail (even with audit_sys_operations=TRUE). This usually indicates that the operation bypassed the shared pool, as many Oracle C functions running under sysdba do.

The error was registered in the alert log, though, without any details.

ORA-01031: insufficient privileges

I captured the call stack for getting the context:

alter system set events '1031 trace name errorstack level 3';
kgeade()+392         call     dbkePostKGE_kgsf()   7F18758C19A0 7F1870ACFA38
                                                   000000407 000000000 ?
                                                   7FFF0BDC9228 ? 000000082 ?
kgeselv()+89         call     kgeade()             7F18758C19A0 ? 7F18758C1BE8 ?
                                                   7F1870ACFA38 ? 000000407 ?
                                                   000000000 000000000
ksesecl0()+189       call     kgeselv()            7F18758C19A0 ? 7F1870ACFA38 ?
                                                   000000407 ? 013666718
                                                   013666728 F9FF4D0000000000
kpdbcBeginClone()+5  call     ksesecl0()           7F18758C19A0 ? 7F1870ACFA38 ?
17                                                 000000407 ? 0774C3388
                                                   7F18759123C0 0C0040000
kpdbksrpcswCbk()+28  call     kpdbcBeginClone()    7FFF0BDCBF62 7FFF00000009
57                                                 7F1800000002 000000007
                                                   000000000 000000000
kpdbksrpcCbk()+204   call     kpdbksrpcswCbk()     7FFF0BDCBF50 7FFF00000009 ?
                                                   7FFF0BDCBF60 7FFF0BDCD270
                                                   000000000 ? 000000000 ?
ksrpc_sgfun()+3055   call     kpdbksrpcCbk()       000000014 7FFF0BDCD270
                                                   7F1870C18660 7FFF0BDCD270 ?
                                                   000000000 ? 000000000 ?
ksrpcsexec()+1315    call     ksrpc_sgfun()        000000014 7FFF0BDCFB40
                                                   7F1870C18660 ? 7FFF0BDCD270 ?
                                                   7F18758C1BE8 7FFF00000000
opiodr()+1202        call     ksrpcsexec()         00000009E 000000004
                                                   7FFF0BDCFB40 7FFF0BDCD270 ?
                                                   7F18758C1BE8 7FFF0BDC0000
ttcpip()+1222        call     opiodr()             00000009E 000000004
                                                   7FFF0BDCFB40 ? 000000000
                                                   7F18758C1BE8 ? 7FFF0BDC0000 ?

The shared pool was bypassed. We know this, because there aren’t any parsing functions on the stack.

ksesecl0() generated ORA-01031 due to a failed security check in kpdbcBeginClone(). I assume it’s hardcoded in kpdbcBeginClone() that it can’t be called in a sysbackup session.

A little benefit of this analysis: we can deduce some unknown meanings in the Oracle C function naming convention:

  • “rpc” in ksrpcsexec() and its children might mean remote procedure call, as ksrpcsexec() was called on behalf of sys.dbms_backup_restore.describeRemotePdb() in the auxiliary database.
  • “sgfun” in ksrpc_sgfun() means “single function”.
  • “sec” in ksesecl0 is “security”.

In conclusion, “duplicate pluggable database” doesn’t work with sysbackup, probably because the rule is hardcoded in an Oracle C function. Since this works with non-multitenant databases, and according to the documentation it should work for pluggable databases too, it must be a bug. The only workaround I’m aware of is connecting as sysdba.

I did this analysis on a 19.8.0.0.200714 database.

Thanks for sharing

Nenad Noveljic

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.