osaf/libs/common/immsv/immpbe_dump.cc | 424 +++++++++++++++++++++++++++++++++-
1 files changed, 420 insertions(+), 4 deletions(-)
Add new checks for objects and classes for PBE audit.
diff --git a/osaf/libs/common/immsv/immpbe_dump.cc
b/osaf/libs/common/immsv/immpbe_dump.cc
--- a/osaf/libs/common/immsv/immpbe_dump.cc
+++ b/osaf/libs/common/immsv/immpbe_dump.cc
@@ -3168,7 +3168,7 @@ static int pbeAuditNoDangling(sqlite3 *d
step2:
if(stmt) {
- sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
stmt = NULL;
}
@@ -3206,7 +3206,7 @@ step2:
err = 1;
}
- sqlite3_reset(tblStmt);
+ sqlite3_finalize(tblStmt);
}
if(rc != SQLITE_DONE) {
@@ -3217,14 +3217,430 @@ step2:
end:
if(stmt) {
- sqlite3_reset(stmt);
+ sqlite3_finalize(stmt);
}
return err;
}
+static int pbeAuditAttributeFlags(sqlite3 *dbHandle) {
+ uint64_t allAttributes = SA_IMM_ATTR_MULTI_VALUE
+ | SA_IMM_ATTR_RDN
+ | SA_IMM_ATTR_CONFIG
+ | SA_IMM_ATTR_WRITABLE
+ | SA_IMM_ATTR_INITIALIZED
+ | SA_IMM_ATTR_RUNTIME
+ | SA_IMM_ATTR_PERSISTENT
+ | SA_IMM_ATTR_CACHED
+ | SA_IMM_ATTR_NO_DUPLICATES
+ | SA_IMM_ATTR_NOTIFY
+ | SA_IMM_ATTR_NO_DANGLING
+ | SA_IMM_ATTR_DN;
+ const char *sql = "select class_name, attr_name, attr_flags "
+ "from attr_def, classes "
+ "where ((attr_flags | %lu) & ~%lu) != 0 "
+ "and attr_def.class_id = classes.class_id";
+ char query[1024];
+ sqlite3_stmt *stmt = NULL;
+ int err = 0;
+ int rc;
+
+ sprintf(query, sql, allAttributes, allAttributes);
+
+ rc = sqlite3_prepare_v2(dbHandle, query, -1, &stmt, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement for(%d): %s", rc,
query);
+ err = 1;
+ goto done;
+ }
+
+ while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+ LOG_ER("Invalid attribute value (%s) in attribute '%s' in class
'%s'",
+ sqlite3_column_text(stmt, 2),
+ sqlite3_column_text(stmt, 1),
+ sqlite3_column_text(stmt, 0));
+ err = 1;
+ }
+
+ if(rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed with error code: %d\n",
query, rc);
+ err = 1;
+ }
+
+done:
+ if(stmt) {
+ sqlite3_finalize(stmt);
+ }
+
+ return err;
+}
+
+static int pbeAuditObjectRdnFlag(sqlite3 *dbHandle) {
+ const char *sql = "select class_name, count(attr_name) "
+ "from classes cl "
+ "left outer join attr_def ad "
+ "on cl.class_id = ad.class_id "
+ "and (attr_flags & 2) > 0 "
+ "group by class_name "
+ "having count(attr_name) != 1";
+ sqlite3_stmt *stmt = NULL;
+ int err = 0;
+ int rc;
+
+ rc = sqlite3_prepare_v2(dbHandle, sql, -1, &stmt, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement for(%d): %s", rc, sql);
+ err = 1;
+ goto done;
+ }
+
+ while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+ if(sqlite3_column_int(stmt, 1) == 0) {
+ LOG_ER("Class (%s) definition with no RDN attribute",
+ sqlite3_column_text(stmt, 0));
+ } else {
+ LOG_ER("Class (%s) definition with more RDN attributes",
+ sqlite3_column_text(stmt, 0));
+ }
+ err = 1;
+ }
+
+ if(rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed with error code: %d\n",
sql, rc);
+ err = 1;
+ }
+
+done:
+ if(stmt) {
+ sqlite3_finalize(stmt);
+ }
+
+ return err;
+}
+
+static int pbeAuditObjectDn(sqlite3 *dbHandle) {
+ const char *sql = "select obj.obj_id, obj.dn, cl.class_name,
ad.attr_name "
+ "from objects obj "
+ "inner join classes cl "
+ "on cl.class_id = obj.class_id "
+ "inner join attr_def ad "
+ "on ad.class_id = obj.class_id "
+ "and (ad.attr_flags & 2) = 2";
+ sqlite3_stmt *stmt = NULL;
+ sqlite3_stmt *stmt2 = NULL;
+ int err = 0;
+ int rc;
+ char *dn;
+ char *rdn;
+ char *parent;
+ char *t;
+ std::string query;
+
+ rc = sqlite3_prepare_v2(dbHandle, sql, -1, &stmt, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement for(%d): %s", rc, sql);
+ err = 1;
+ goto done;
+ }
+
+ while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+ parent = NULL;
+
+ // Split DN to RDN and parent
+ dn = (char *)sqlite3_column_text(stmt, 1);
+ t = dn;
+ while(*t) {
+ if(t == dn && *t == ',') {
+ LOG_ER("Invalid DN: '%s'", dn);
+ dn = NULL;
+ err =1;
+ break;
+ }
+ if(*t == ',' && *(t - 1) != '\\') {
+ t++;
+ if(*t) {
+ parent = t;
+ }
+ break;
+ }
+ t++;
+ }
+
+ if(!dn) {
+ continue;
+ }
+
+ // Check that RDN attribute has the right RDN from DN
+ query.clear();
+ query.append("select ").append((char
*)sqlite3_column_text(stmt, 3))
+ .append(" from ").append((char
*)sqlite3_column_text(stmt, 2))
+ .append(" where obj_id = ").append((char
*)sqlite3_column_text(stmt, 0));
+
+ stmt2 = NULL;
+ rc = sqlite3_prepare_v2(dbHandle, query.c_str(), -1, &stmt2,
NULL);
+ if(rc == SQLITE_OK) {
+ if((rc = sqlite3_step(stmt2)) == SQLITE_ROW) {
+ rdn = (char *)sqlite3_column_text(stmt2, 0);
+ if(strstr(dn, rdn) != dn || (parent && *(dn +
strlen(rdn)) != ',')) {
+ LOG_ER("Object RDN ('%s') does not
match RDN in object DN ('%s')",
+ rdn, dn);
+ err = 1;
+ }
+ } else {
+ LOG_ER("Failed to get results from '%s'",
query.c_str());
+ err = 1;
+ }
+ } else {
+ LOG_ER("Failed to prepare SQL statement for(%d): %s",
rc, sql);
+ err = 1;
+ }
+
+ if(stmt2) {
+ sqlite3_finalize(stmt2);
+ }
+
+ // Check if parent of selected object exists
+ if(parent) {
+ query.clear();
+ query.append("select 1 from objects where dn =
'").append(parent).append("'");
+
+ stmt2 = NULL;
+ rc = sqlite3_prepare_v2(dbHandle, query.c_str(), -1,
&stmt2, NULL);
+ if(rc == SQLITE_OK) {
+ if(sqlite3_step(stmt) != SQLITE_ROW) {
+ LOG_ER("Parent is missing for object
'%s'", dn);
+ err = 1;
+ }
+ } else {
+ LOG_ER("Failed to prepare SQL statement
for(%d): %s", rc, sql);
+ err = 1;
+ }
+
+ if(stmt2) {
+ sqlite3_finalize(stmt2);
+ }
+ }
+ }
+
+ if(rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed with error code: %d\n",
sql, rc);
+ err = 1;
+ }
+
+done:
+ if(stmt) {
+ sqlite3_finalize(stmt);
+ }
+
+ return err;
+}
+
+static int pbeAuditClasses(sqlite3 *dbHandle) {
+ const char *sql = "select class_id, class_category, class_name from
classes;";
+ sqlite3_stmt *stmt = NULL;
+ sqlite3_stmt *stmt2;
+ int err = 0;
+ int rc;
+ int attr_type;
+ sqlite3_int64 attr_flags;
+ std::string query;
+
+ rc = sqlite3_prepare_v2(dbHandle, sql, -1, &stmt, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement for(%d): %s", rc, sql);
+ err = 1;
+ goto done;
+ }
+
+ while((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
+ // Config class
+ if(sqlite3_column_int(stmt, 1) == 1) {
+ // Check that table exists for config class
+ query.clear();
+ query.append("select 1 from sqlite_master where type =
'table' and tbl_name = '")
+ .append((char
*)sqlite3_column_text(stmt, 2))
+ .append("'");
+
+ rc = sqlite3_prepare_v2(dbHandle, query.c_str(), -1,
&stmt2, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement
for(%d): %s", rc, query.c_str());
+ err = 1;
+ continue;
+ }
+
+ if(sqlite3_step(stmt2) != SQLITE_ROW) {
+ sqlite3_finalize(stmt2);
+ LOG_ER("Config class '%s' does not have
corresponding table in PBE",
+ (char
*)sqlite3_column_text(stmt, 2));
+ err = 1;
+ continue;
+ }
+
+ sqlite3_finalize(stmt2);
+
+ // Check that RDN attribute is config attribute
+ query.clear();
+ query.append("select attr_type, attr_flags, attr_name
from attr_def where class_id = ")
+ .append((char
*)sqlite3_column_text(stmt, 0))
+ .append(" and (attr_flags & 2) = 2");
+
+ rc = sqlite3_prepare_v2(dbHandle, query.c_str(), -1,
&stmt2, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement
for(%d): %s", rc, query.c_str());
+ err = 1;
+ continue;
+ }
+
+ if(sqlite3_step(stmt2) != SQLITE_ROW) {
+ sqlite3_finalize(stmt2);
+ LOG_ER("Class '%s' does not have RDN attribute",
+ (char
*)sqlite3_column_text(stmt, 2));
+ err = 1;
+ continue;
+ }
+
+ attr_type = sqlite3_column_int(stmt2, 0);
+ if(attr_type != SA_IMM_ATTR_SANAMET && attr_type !=
SA_IMM_ATTR_SASTRINGT) {
+ sqlite3_finalize(stmt2);
+ LOG_ER("RDN attribute '%s' of class '%s' is not
type of SaNameT or SaStringT",
+ (char
*)sqlite3_column_text(stmt2, 2),
+ (char
*)sqlite3_column_text(stmt, 2));
+ err = 1;
+ continue;
+ }
+
+ attr_flags = sqlite3_column_int64(stmt2, 1);
+ if((attr_flags & SA_IMM_ATTR_CONFIG) !=
SA_IMM_ATTR_CONFIG) {
+ sqlite3_finalize(stmt2);
+ LOG_ER("RDN attribute '%s' of class '%s' is not
a config attribute. Flags: %lld",
+ (char
*)sqlite3_column_text(stmt2, 2),
+ (char
*)sqlite3_column_text(stmt, 2),
+ attr_flags);
+ err = 1;
+ continue;
+ }
+
+ if((attr_flags & SA_IMM_ATTR_INITIALIZED) !=
SA_IMM_ATTR_INITIALIZED) {
+ sqlite3_finalize(stmt2);
+ LOG_ER("RDN attribute '%s' of class '%s' does
not have SA_IMM_ATTR_INITIALIZED flag. Flags: %lld",
+ (char
*)sqlite3_column_text(stmt2, 2),
+ (char
*)sqlite3_column_text(stmt, 2),
+ attr_flags);
+ err = 1;
+ continue;
+ }
+
+ sqlite3_finalize(stmt2);
+ } else if(sqlite3_column_int(stmt, 1) == 2) {
+ // Runtime object
+ query.clear();
+ query.append("select attr_type, attr_flags, attr_name
from attr_def where class_id = ")
+ .append((char
*)sqlite3_column_text(stmt, 0));
+
+ rc = sqlite3_prepare_v2(dbHandle, query.c_str(), -1,
&stmt2, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement
for(%d): %s", rc, query.c_str());
+ err = 1;
+ continue;
+ }
+
+ bool isPersistent = false;
+ bool rdnExist = false;
+ while((rc = sqlite3_step(stmt2)) == SQLITE_ROW) {
+ attr_flags = sqlite3_column_int64(stmt2, 1);
+ // Check if the attribute has RDN flag
+ if((attr_flags & SA_IMM_ATTR_RDN) ==
SA_IMM_ATTR_RDN) {
+ if(rdnExist) {
+ LOG_ER("Multiple definition for
RDN attribute in class '%s' for attribute '%s'",
+ (char
*)sqlite3_column_text(stmt, 2),
+ (char
*)sqlite3_column_text(stmt2, 2));
+ err = 1;
+ }
+ rdnExist = true;
+ }
+ if((attr_flags & SA_IMM_ATTR_CONFIG) ==
SA_IMM_ATTR_CONFIG) {
+ LOG_ER("In runtime class '%s' attribute
'%s' is a config attribute",
+ (char
*)sqlite3_column_text(stmt, 2),
+ (char
*)sqlite3_column_text(stmt2, 2));
+ err = 1;
+ }
+ if((attr_flags & SA_IMM_ATTR_RUNTIME) !=
SA_IMM_ATTR_RUNTIME) {
+ LOG_ER("In class '%s' attribute '%s' is
not a runtime attribute",
+ (char
*)sqlite3_column_text(stmt, 2),
+ (char
*)sqlite3_column_text(stmt2, 2));
+ err = 1;
+ }
+ if((attr_flags & SA_IMM_ATTR_PERSISTENT) ==
SA_IMM_ATTR_PERSISTENT) {
+ isPersistent = true;
+ }
+ }
+
+ if(!rdnExist) {
+ LOG_ER("RDN attribute is missing in class '%s'",
+ (char
*)sqlite3_column_text(stmt, 2));
+ err = 1;
+ }
+
+ sqlite3_finalize(stmt2);
+
+ query.clear();
+ query.append("select 1 from sqlite_master where type =
'table' and tbl_name = '")
+ .append((char
*)sqlite3_column_text(stmt, 2))
+ .append("'");
+
+ rc = sqlite3_prepare_v2(dbHandle, query.c_str(), -1,
&stmt2, NULL);
+ if(rc != SQLITE_OK) {
+ LOG_ER("Failed to prepare SQL statement
for(%d): %s", rc, query.c_str());
+ err = 1;
+ continue;
+ }
+
+ rc = sqlite3_step(stmt2);
+ if(rc == SQLITE_ROW && !isPersistent) {
+ LOG_ER("Table of non-perisistent runtime class
'%s' exists in PBE",
+ (char
*)sqlite3_column_text(stmt, 2));
+ err = 1;
+ } else if(rc == SQLITE_DONE && isPersistent) {
+ LOG_ER("Missing table in PBE for persistent
runtime class '%s'",
+ (char
*)sqlite3_column_text(stmt, 2));
+ err = 1;
+ } else if(rc != SQLITE_ROW && rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed with error
code: %d\n", query.c_str(), rc);
+ err = 1;
+ }
+
+ sqlite3_finalize(stmt2);
+ } else {
+ LOG_ER("Unknown class category (%d) for class '%s'",
+ sqlite3_column_int(stmt, 1),
+ (char *)sqlite3_column_text(stmt, 2));
+ err = 1;
+ }
+ }
+
+ if(rc != SQLITE_DONE) {
+ LOG_ER("SQL statement ('%s') failed with error code: %d\n",
sql, rc);
+ err = 1;
+ }
+
+done:
+ if(stmt) {
+ sqlite3_finalize(stmt);
+ }
+
+ return err;
+}
+
int pbeAudit(void *db_handle) {
- return pbeAuditNoDangling((sqlite3 *)db_handle);
+ int rc;
+
+ rc = pbeAuditNoDangling((sqlite3 *)db_handle);
+ rc |= pbeAuditAttributeFlags((sqlite3 *)db_handle);
+ rc |= pbeAuditObjectRdnFlag((sqlite3 *)db_handle);
+ rc |= pbeAuditObjectDn((sqlite3 *)db_handle);
+ rc |= pbeAuditClasses((sqlite3 *)db_handle);
+
+ return rc;
}
int pbeAuditFile(const char *filename) {
------------------------------------------------------------------------------
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel