Hi Neelakanta, "where" statement is part of sql query used for finding attributes with unsupported flags. > + 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";
I don't see how "where ((attr_flags | %lu) & ~%lu) != 0 " always returns 0. For example: If we have supported flags 0x01 and 0x02, but attr_flags has value 0x06 (0x04 | 0x02). 0x04 is not supported flag. Then the result of "((attr_flags | %lu) & ~%lu)" is 0x04. [ ((0x06 | 0x03) & 0xfc = 0x04 ] For supported flags "where" statement returns 0 as it should. Only improvement that I see is to change "where ((attr_flags | %lu) & ~%lu) != 0 " ... to ... "where (attr_flags & ~%lu) != 0 " Best regards, Zoran -----Original Message----- From: Neelakanta Reddy [mailto:[email protected]] Sent: Friday, August 21, 2015 10:51 AM To: Zoran Milinkovic Cc: [email protected] Subject: Re: [PATCH 1 of 1] immtools: add new checks for PBE audit [#19] Hi zoran, Reviewed and tested the patch. Ack with the following comment. comment: The below query always result in 0, this needs to be changed. "where ((attr_flags | %lu) & ~%lu) != 0" /Neel. On Wednesday 12 August 2015 06:02 PM, Zoran Milinkovic wrote: > 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
