static void test_inplace_tolower(void) { char abc[] = "abc"; char def[] = "def"; ToLowerStrInplace(abc); ToLowerStrInplace(def); assert_string_equal(abc, "abc"); assert_string_equal(def, "def"); }
static Auth *GetAuthPath(const char *path, Auth *list) { size_t path_len = strlen(path); char unslashed_path[path_len + 1]; memcpy(unslashed_path, path, path_len + 1); #ifdef __MINGW32__ ToLowerStrInplace(unslashed_path); #endif if (path_len != 1) { DeleteSlash(unslashed_path); } for (Auth *ap = list; ap != NULL; ap = ap->next) { if (strcmp(ap->path, unslashed_path) == 0) { return ap; } } return NULL; }
static void test_empty_tolower(void) { char str[] = ""; ToLowerStrInplace(str); assert_string_equal(str, ""); }
static void test_mix_case_tolower(void) { char str[] = "aBcD"; ToLowerStrInplace(str); assert_string_equal(str, "abcd"); }
static void test_hi_alphabet_tolower(void) { char hi_alphabet_lowercased[CF_MAXVARSIZE]; strncpy(hi_alphabet_lowercased, hi_alphabet, CF_MAXVARSIZE); ToLowerStrInplace(hi_alphabet_lowercased); assert_string_equal(hi_alphabet_lowercased, lo_alphabet); }
static void test_weird_chars_tolower(void) { static const char *weirdstuff = "1345\0xff%$#@!"; char weirdstuff_copy_lowercased[CF_MAXVARSIZE]; strncpy(weirdstuff_copy_lowercased, weirdstuff, CF_MAXVARSIZE); ToLowerStrInplace(weirdstuff_copy_lowercased); assert_string_equal(weirdstuff_copy_lowercased, weirdstuff); }
static void SetConnectionData(ServerConnectionState *conn, char *buf) { char ipstring[CF_MAXVARSIZE], fqname[CF_MAXVARSIZE], username[CF_MAXVARSIZE]; Log(LOG_LEVEL_DEBUG, "Connecting host identifies itself as '%s'", buf); memset(ipstring, 0, CF_MAXVARSIZE); memset(fqname, 0, CF_MAXVARSIZE); memset(username, 0, CF_MAXVARSIZE); sscanf(buf, "%255s %255s %255s", ipstring, fqname, username); Log(LOG_LEVEL_DEBUG, "(ipstring=[%s],fqname=[%s],username=[%s],socket=[%s])", ipstring, fqname, username, conn->ipaddr); ToLowerStrInplace(fqname); strlcpy(conn->hostname, fqname, CF_MAXVARSIZE); strlcpy(conn->username, username, CF_MAXVARSIZE); #ifdef __MINGW32__ /* NT uses security identifier instead of uid */ if (!NovaWin_UserNameToSid(username, (SID *) conn->sid, CF_MAXSIDSIZE, false)) { memset(conn->sid, 0, CF_MAXSIDSIZE); /* is invalid sid - discarded */ } #else /* !__MINGW32__ */ struct passwd *pw; if ((pw = getpwnam(username)) == NULL) /* Keep this inside mutex */ { conn->uid = -2; } else { conn->uid = pw->pw_uid; } #endif /* !__MINGW32__ */ }
static int VerifyTablePromise(CfdbConn *cfdb, char *table_path, Rlist *columns, Attributes a, Promise *pp) { char name[CF_MAXVARSIZE], type[CF_MAXVARSIZE], query[CF_MAXVARSIZE], table[CF_MAXVARSIZE], db[CF_MAXVARSIZE]; int i, count, size, no_of_cols, *size_table, *done, identified, retval = true; char **name_table, **type_table; CfOut(cf_verbose, "", " -> Verifying promised table structure for \"%s\"", table_path); if (!ValidateSQLTableName(table_path, db, table)) { CfOut(cf_error, "", " !! The structure of the promiser did not match that for an SQL table, i.e. \"database.table\"\n"); return false; } else { CfOut(cf_verbose, "", " -> Assuming database \"%s\" with table \"%s\"", db, table); } /* Verify the existence of the tables within the database */ if (!TableExists(cfdb, table)) { CfOut(cf_error, "", " !! The database did not contain the promised table \"%s\"\n", table_path); if ((a.database.operation) && (strcmp(a.database.operation, "create") == 0)) { if ((!DONTDO) && ((a.transaction.action) != cfa_warn)) { cfPS(cf_error, CF_CHG, "", pp, a, " -> Database.table %s doesn't seem to exist, creating\n", table_path); return CreateTableColumns(cfdb, table, columns, a, pp); } else { CfOut(cf_error, "", " -> Database.table %s doesn't seem to exist, but only a warning was promised\n", table_path); } } return false; } /* Get a list of the columns in the table */ QueryTableColumns(query, db, table); CfNewQueryDB(cfdb, query); if (cfdb->maxcolumns != 3) { cfPS(cf_error, CF_FAIL, "", pp, a, "Could not make sense of the columns"); CfDeleteQuery(cfdb); return false; } /* Assume that the Rlist has been validated and consists of a,b,c */ count = 0; no_of_cols = RlistLen(columns); if (!NewSQLColumns(table, columns, &name_table, &type_table, &size_table, &done)) { cfPS(cf_error, CF_FAIL, "", pp, a, "Could not make sense of the columns"); return false; } /* Obtain columns from the named table - if any */ while (CfFetchRow(cfdb)) { char *sizestr; name[0] = '\0'; type[0] = '\0'; size = CF_NOINT; strlcpy(name, CfFetchColumn(cfdb, 0), CF_MAXVARSIZE); strlcpy(type, CfFetchColumn(cfdb, 1), CF_MAXVARSIZE); ToLowerStrInplace(type); sizestr = CfFetchColumn(cfdb, 2); if (sizestr) { size = Str2Int(sizestr); } CfOut(cf_verbose, "", " ... discovered column (%s,%s,%d)", name, type, size); if (sizestr && (size == CF_NOINT)) { cfPS(cf_verbose, CF_NOP, "", pp, a, " !! Integer size of SQL datatype could not be determined or was not specified - invalid promise."); DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols); CfDeleteQuery(cfdb); return false; } identified = false; for (i = 0; i < no_of_cols; i++) { if (done[i]) { continue; } if (strcmp(name, name_table[i]) == 0) { CheckSQLDataType(type, type_table[i], pp); if (size != size_table[i]) { cfPS(cf_error, CF_FAIL, "", pp, a, " !! Promised column \"%s\" in database.table \"%s\" has a non-matching array size (%d != %d)", name, table_path, size, size_table[i]); } else { CfOut(cf_verbose, "", " -> Promised column \"%s\" in database.table \"%s\" is as promised", name, table_path); } count++; done[i] = true; identified = true; break; } } if (!identified) { cfPS(cf_error, CF_FAIL, "", pp, a, "Column \"%s\" found in database.table \"%s\" is not part of its promise.", name, table_path); if ((a.database.operation) && (strcmp(a.database.operation, "drop") == 0)) { cfPS(cf_error, CF_FAIL, "", pp, a, "Cfengine will not promise to repair this, as the operation is potentially too destructive."); // Future allow deletion? } retval = false; } } CfDeleteQuery(cfdb); /* Now look for deviations - only if we have promised to create missing */ if ((a.database.operation) && (strcmp(a.database.operation, "drop") == 0)) { return retval; } if (count != no_of_cols) { for (i = 0; i < no_of_cols; i++) { if (!done[i]) { CfOut(cf_error, "", " !! Promised column \"%s\" missing from database table %s", name_table[i], pp->promiser); if ((!DONTDO) && ((a.transaction.action) != cfa_warn)) { if (size_table[i] > 0) { snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s(%d)", table, name_table[i], type_table[i], size_table[i]); } else { snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s", table, name_table[i], type_table[i]); } CfVoidQueryDB(cfdb, query); cfPS(cf_error, CF_CHG, "", pp, a, " !! Adding promised column \"%s\" to database table %s", name_table[i], table); retval = true; } else { cfPS(cf_error, CF_WARN, "", pp, a, " !! Promised column \"%s\" missing from database table %s but only a warning was promised", name_table[i], table); retval = false; } } } } DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols); return retval; }
static int VerifyTablePromise(EvalContext *ctx, CfdbConn *cfdb, char *table_path, Rlist *columns, const Attributes *a, const Promise *pp, PromiseResult *result) { assert(a != NULL); char name[CF_MAXVARSIZE], type[CF_MAXVARSIZE], query[CF_MAXVARSIZE], table[CF_MAXVARSIZE], db[CF_MAXVARSIZE]; int i, count, size, no_of_cols, *size_table, *done, identified, retval = true; char **name_table, **type_table; Log(LOG_LEVEL_VERBOSE, "Verifying promised table structure for '%s'", table_path); if (!ValidateSQLTableName(table_path, db, table)) { Log(LOG_LEVEL_ERR, "The structure of the promiser did not match that for an SQL table, i.e. 'database.table'"); return false; } else { Log(LOG_LEVEL_VERBOSE, "Assuming database '%s' with table '%s'", db, table); } /* Verify the existence of the tables within the database */ if (!TableExists(cfdb, table)) { Log(LOG_LEVEL_ERR, "The database did not contain the promised table '%s'", table_path); if ((a->database.operation) && (strcmp(a->database.operation, "create") == 0)) { if ((!DONTDO) && ((a->transaction.action) != cfa_warn)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, a, "Database.table '%s' doesn't seem to exist, creating", table_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return CreateTableColumns(cfdb, table, columns); } else { Log(LOG_LEVEL_WARNING, "Database.table '%s' doesn't seem to exist, but only a warning was promised", table_path); } } return false; } /* Get a list of the columns in the table */ QueryTableColumns(query, db, table); CfNewQueryDB(cfdb, query); if (cfdb->maxcolumns != 3) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not make sense of the columns"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); CfDeleteQuery(cfdb); return false; } /* Assume that the Rlist has been validated and consists of a,b,c */ count = 0; no_of_cols = RlistLen(columns); if (!NewSQLColumns(table, columns, &name_table, &type_table, &size_table, &done)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Could not make sense of the columns"); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); return false; } /* Obtain columns from the named table - if any */ while (CfFetchRow(cfdb)) { char *sizestr; name[0] = '\0'; type[0] = '\0'; size = CF_NOINT; strlcpy(name, CfFetchColumn(cfdb, 0), CF_MAXVARSIZE); strlcpy(type, CfFetchColumn(cfdb, 1), CF_MAXVARSIZE); ToLowerStrInplace(type); sizestr = CfFetchColumn(cfdb, 2); if (sizestr) { size = IntFromString(sizestr); } Log(LOG_LEVEL_VERBOSE, "Discovered database column (%s,%s,%d)", name, type, size); if (sizestr && (size == CF_NOINT)) { cfPS(ctx, LOG_LEVEL_VERBOSE, PROMISE_RESULT_NOOP, pp, a, "Integer size of SQL datatype could not be determined or was not specified - invalid promise."); DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols); CfDeleteQuery(cfdb); return false; } identified = false; for (i = 0; i < no_of_cols; i++) { if (done[i]) { continue; } if (strcmp(name, name_table[i]) == 0) { CheckSQLDataType(type, type_table[i], pp); if (size != size_table[i]) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Promised column '%s' in database.table '%s' has a non-matching array size (%d != %d)", name, table_path, size, size_table[i]); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } else { Log(LOG_LEVEL_VERBOSE, "Promised column '%s' in database.table '%s' is as promised", name, table_path); } count++; done[i] = true; identified = true; break; } } if (!identified) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Column '%s' found in database.table '%s' is not part of its promise.", name, table_path); *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); if ((a->database.operation) && (strcmp(a->database.operation, "drop") == 0)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "CFEngine will not promise to repair this, as the operation is potentially too destructive."); // Future allow deletion? *result = PromiseResultUpdate(*result, PROMISE_RESULT_FAIL); } retval = false; } } CfDeleteQuery(cfdb); /* Now look for deviations - only if we have promised to create missing */ if ((a->database.operation) && (strcmp(a->database.operation, "drop") == 0)) { return retval; } if (count != no_of_cols) { for (i = 0; i < no_of_cols; i++) { if (!done[i]) { Log(LOG_LEVEL_ERR, "Promised column '%s' missing from database table '%s'", name_table[i], pp->promiser); if ((!DONTDO) && ((a->transaction.action) != cfa_warn)) { if (size_table[i] > 0) { snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s(%d)", table, name_table[i], type_table[i], size_table[i]); } else { snprintf(query, CF_MAXVARSIZE - 1, "ALTER TABLE %s ADD %s %s", table, name_table[i], type_table[i]); } CfVoidQueryDB(cfdb, query); cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_CHANGE, pp, a, "Adding promised column '%s' to database table '%s'", name_table[i], table); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); retval = true; } else { cfPS(ctx, LOG_LEVEL_WARNING, PROMISE_RESULT_WARN, pp, a, "Promised column '%s' missing from database table '%s' but only a warning was promised", name_table[i], table); *result = PromiseResultUpdate(*result, PROMISE_RESULT_WARN); retval = false; } } } } DeleteSQLColumns(name_table, type_table, size_table, done, no_of_cols); return retval; }