Страницы

четверг, 13 июня 2019 г.

srvctl config database OSDBA and OSOPER groups not defined

I have recently investigated why there are some databases in my environment which are shown with empty OSDBA or OSOPER groups:
$ srvctl config database -d orcl
Database unique name: orcl
Database name: orcl
Oracle home: /u01/app/oracle/product/db_19
Oracle user: oracle
Spfile: +DATA/ORCL/PARAMETERFILE/spfile.270.1010270597
Password file:
Domain:
Start options: open
Stop options: immediate
Database role: PRIMARY
Management policy: AUTOMATIC
Disk Groups: DATA,FRA
Services:
OSDBA group:
OSOPER group:
Database instance: orcl
srvctl is a usual shell script that calls the following:
# JRE Executable and Class File Variables
JRE=${JREDIR}/bin/java
..skip..
# Run srvctl
${JRE} ${JRE_OPTIONS} -DORACLE_HOME=${ORACLE_HOME} -classpath ${CLASSPATH} ${SRVM_PROPERTY_DEFS} oracle.ops.opsctl.OPSCTLDriver "$@"
That's just a Java class call. We call oracle.ops.opsctl.OPSCTLDriver passing command-line arguments. CLASSPATH is defined as follows:
CLASSPATH=${NETCFGJAR}:${LDAPJAR}:${JREJAR}:${SRVMJAR}:${SRVMHASJAR}:${SRVMASMJAR}:\
${EONSJAR}:${SRVCTLJAR}:${GNSJAR}:${ANTLRJAR}:${CLSCEJAR}:${CHACONFIGJAR}:${JDBCJAR}:\
${MAILJAR}:${ACTIVATIONJAR}:${JWCCREDJAR}
Those jar-variables are set in the script so it's trivial to find out all classes that are used there.
I used to use JAD to decompile them but it appears to be not in vogue and not developed anymore.
Thankfully, there are a bunch of free sites that can be used as a replacement. I personally have used this one.
It is usually advised to identify the entry jar first by looking into the jar files so as to figure out where exactly OPSCTLDriver is coming from.
Not surprisingly, it is coming from ${SRVCTLJAR} which is set to ${ORACLE_HOME}/srvm/jlib/srvctl.jar.
OPSCTLDriver calls oracle.ops.opsctl.ConfigAction that does the following:
for (Database db : dblist) {
..skip..
  if ((isUnixSystem) && (!isMgmtDB)) {
    groups = db.getGroups();
    dbaGrp = groups.get("OSDBA") == null ? "" : (String)groups.get("OSDBA");
    operGrp = groups.get("OSOPER") == null ? "" : (String)groups.get("OSOPER");
  }
Hence, the groups I am interested in are from the Database class which is set in the import section: import oracle.cluster.database.Database;
That's just an interface from srvm.jar:
public abstract interface Database
  extends SoftwareModule
{
The actual implementation is this: oracle.cluster.impl.database.DatabaseImpl.
Here are how those groups are determined:
String oracleBin = getOracleHome() + File.separator + "bin";
      Trace.out("Creating OSDBAGRPUtil with path: " + oracleBin);
      OSDBAGRPUtil grpUtil = new OSDBAGRPUtil(oracleBin);
      Map<String, String> groups = grpUtil.getAdminGroups(version());
      

      ResourcePermissionsImpl perm = (ResourcePermissionsImpl)m_crsResource.getPermissions();
      String acl = perm.getAclString();
      Map<String, List<string>> aclMap = splitACL(acl);
      
      List<String> acl_groups = (List)aclMap.get(ResourceType.ACL.GROUP.toString());
      

      String dba = (String)groups.get("SYSDBA");
      String oper = (String)groups.get("SYSOPER");
      if ((!dba.isEmpty()) && (acl_groups.contains(dba.toLowerCase()))) {
        groupMap.put("OSDBA", dba);
      }
      if ((!oper.isEmpty()) && (acl_groups.contains(oper.toLowerCase()))) {
        groupMap.put("OSOPER", oper);
      }
      return groupMap;
Having applied the same technique, it's easy to find out that OSDBAGRPUtil calls ${ORACLE_HOME}/bin/osdbagrp passing either "-d" or "-o" flags depending on what group we are interested in.
In my case, those commands returned dba and oper for OSDBA and OSOPER respectively:
$ osdbagrp -d
dba
$ osdbagrp -o
oper
Hence, this part of the if statement is true: "(!dba.isEmpty())" and the dba group is not set because of: "(acl_groups.contains(dba.toLowerCase()))".
So that is something related to ACLs which is coming from "ResourcePermissionsImpl perm = (ResourcePermissionsImpl)m_crsResource.getPermissions();".
Let's use the crsctl getperm command passing the database resource to it:
$ crsctl getperm resource ora.orcl.db
Name: ora.orcl.db
owner:oracle:rwx,pgrp:asmdba:r-x,other::r--,group:oinstall:r-x,user:oracle:rwx
That looks promising - neither dba nor oper groups are set. I ran the command below to set dba group:
$ crsctl setperm resource ora.orcl.db -u group:dba:r-x
CRS-4995:  The command 'Setperm  resource' is invalid in crsctl. Use srvctl for this command.
$ crsctl setperm resource ora.orcl.db -u group:dba:r-x -unsupported
Well, that is an Oracle Restart environment, so that I added the unsupported flag.
Once it was done, the OSDBA group was properly coming back:
$ srvctl config database -d orcl
Database unique name: orcl
Database name: orcl
Oracle home: /u01/app/oracle/product/db_19
Oracle user: oracle
Spfile: +DATA/ORCL/PARAMETERFILE/spfile.270.1010270597
Password file:
Domain:
Start options: open
Stop options: immediate
Database role: PRIMARY
Management policy: AUTOMATIC
Disk Groups: DATA,FRA
Services:
OSDBA group: dba
OSOPER group:
Database instance: orcl

Комментариев нет:

Отправка комментария