static int AddOffsetToMapUnlessExists(StringMap ** tree, uint64_t offset, int64_t bucket_index) { char *tmp; xasprintf(&tmp, "%" PRIu64, offset); char *val; if (StringMapHasKey(*tree, tmp) == false) { xasprintf(&val, "%" PRIu64, bucket_index); StringMapInsert(*tree, tmp, val); } else { Log(LOG_LEVEL_ERR, "Duplicate offset for value %" PRIu64 " at index %" PRId64 ", other value %" PRIu64 ", other index '%s'", offset, bucket_index, offset, (char *) StringMapGet(*tree, tmp)); free(tmp); } return 0; }
/** * Add access rules to the given ACL #acl according to the constraints in the * particular access promise. * * For legacy reasons (non-TLS connections), build also the #ap (access Auth) * and #dp (deny Auth). */ static void AccessPromise_AddAccessConstraints(const EvalContext *ctx, const Promise *pp, struct resource_acl *racl, Auth *ap, Auth *dp) { for (size_t i = 0; i < SeqLength(pp->conlist); i++) { const Constraint *cp = SeqAt(pp->conlist, i); size_t ret = -2; if (!IsDefinedClass(ctx, cp->classes)) { continue; } switch (cp->rval.type) { #define IsAccessBody(e) (strcmp(cp->lval, CF_REMACCESS_BODIES[e].lval) == 0) case RVAL_TYPE_SCALAR: if (IsAccessBody(REMOTE_ACCESS_IFENCRYPTED)) { ap->encrypt = BooleanFromString(cp->rval.item); } else if (IsAccessBody(REMOTE_ACCESS_SHORTCUT)) { const char *shortcut = cp->rval.item; if (strchr(shortcut, FILE_SEPARATOR) != NULL) { Log(LOG_LEVEL_ERR, "slashes are forbidden in ACL shortcut: %s", shortcut); } else if (StringMapHasKey(SV.path_shortcuts, shortcut)) { Log(LOG_LEVEL_WARNING, "Already existing shortcut for path '%s' was replaced", pp->promiser); } else { StringMapInsert(SV.path_shortcuts, xstrdup(shortcut), xstrdup(pp->promiser)); Log(LOG_LEVEL_DEBUG, "Added shortcut '%s' for path: %s", shortcut, pp->promiser); } } break; case RVAL_TYPE_LIST: for (const Rlist *rp = (const Rlist *) cp->rval.item; rp != NULL; rp = rp->next) { /* TODO keys, ips, hostnames are valid such strings. */ if (IsAccessBody(REMOTE_ACCESS_ADMITIPS)) { ret = StrList_Append(&racl->admit.ips, RlistScalarValue(rp)); PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL); } else if (IsAccessBody(REMOTE_ACCESS_DENYIPS)) { ret = StrList_Append(&racl->deny.ips, RlistScalarValue(rp)); PrependItem(&(dp->accesslist), RlistScalarValue(rp), NULL); } else if (IsAccessBody(REMOTE_ACCESS_ADMITHOSTNAMES)) { ret = StrList_Append(&racl->admit.hostnames, RlistScalarValue(rp)); /* If any hostname rule got added, * turn on reverse DNS lookup in the new protocol. */ if (ret != (size_t) -1) { TurnOnReverseLookups(); } NewHostToOldACL(ap, RlistScalarValue(rp)); } else if (IsAccessBody(REMOTE_ACCESS_DENYHOSTNAMES)) { ret = StrList_Append(&racl->deny.hostnames, RlistScalarValue(rp)); /* If any hostname rule got added, * turn on reverse DNS lookup in the new protocol. */ if (ret != (size_t) -1) { TurnOnReverseLookups(); } NewHostToOldACL(dp, RlistScalarValue(rp)); } else if (IsAccessBody(REMOTE_ACCESS_ADMITKEYS)) { ret = StrList_Append(&racl->admit.keys, RlistScalarValue(rp)); } else if (IsAccessBody(REMOTE_ACCESS_DENYKEYS)) { ret = StrList_Append(&racl->deny.keys, RlistScalarValue(rp)); } /* Legacy stuff */ else if (IsAccessBody(REMOTE_ACCESS_ADMIT)) { ret = racl_SmartAppend(&racl->admit, RlistScalarValue(rp)); PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL); } else if (IsAccessBody(REMOTE_ACCESS_DENY)) { ret = racl_SmartAppend(&racl->deny, RlistScalarValue(rp)); PrependItem(&(dp->accesslist), RlistScalarValue(rp), NULL); } else if (IsAccessBody(REMOTE_ACCESS_MAPROOT)) { PrependItem(&(ap->maproot), RlistScalarValue(rp), NULL); } } if (ret == (size_t) -1) { /* Should never happen, besides when allocation fails. */ Log(LOG_LEVEL_CRIT, "StrList_Append: %s", GetErrorStr()); exit(255); } break; default: UnexpectedError("Unknown constraint type!"); break; #undef IsAccessBody } } StrList_Finalise(&racl->admit.ips); StrList_Sort(racl->admit.ips, string_Compare); StrList_Finalise(&racl->admit.hostnames); StrList_Sort(racl->admit.hostnames, string_CompareFromEnd); StrList_Finalise(&racl->admit.keys); StrList_Sort(racl->admit.keys, string_Compare); StrList_Finalise(&racl->deny.ips); StrList_Sort(racl->deny.ips, string_Compare); StrList_Finalise(&racl->deny.hostnames); StrList_Sort(racl->deny.hostnames, string_CompareFromEnd); StrList_Finalise(&racl->deny.keys); StrList_Sort(racl->deny.keys, string_Compare); }
static void ReadFromUcbPsPipe(FILE *cmd) { char *names[CF_PROCCOLS]; memset(names, 0, sizeof(names)); int start[CF_PROCCOLS]; int end[CF_PROCCOLS]; char *line = NULL; size_t linesize = 0; bool header = true; time_t pstime = time(NULL); int pidcol = -1; int cmdcol = -1; while (CfReadLine(&line, &linesize, cmd) > 0) { if (header) { GetProcessColumnNames(line, names, start, end); for (int i = 0; names[i]; i++) { if (strcmp(names[i], "PID") == 0) { pidcol = i; } else if (strcmp(names[i], "COMMAND") == 0 || strcmp(names[i], "CMD") == 0) { cmdcol = i; } } if (pidcol < 0 || cmdcol < 0) { Log(LOG_LEVEL_ERR, "Could not find PID and/or CMD/COMMAND column in " "ps output: \"%s\"", line); break; } header = false; continue; } char *columns[CF_PROCCOLS]; memset(columns, 0, sizeof(columns)); if (!SplitProcLine(line, pstime, names, start, end, UCB_STYLE_PS_COLUMN_ALGORITHM, columns)) { Log(LOG_LEVEL_WARNING, "Not able to parse ps output: \"%s\"", line); } StringMapInsert(UCB_PS_MAP, columns[pidcol], columns[cmdcol]); // We avoid strdup'ing these strings by claiming ownership here. columns[pidcol] = NULL; columns[cmdcol] = NULL; for (int i = 0; i < CF_PROCCOLS; i++) { // There may be some null entries here, but since we "steal" // strings in the section above, we may have set some of them to // NULL and there may be following non-NULL fields. free(columns[i]); } } if (!feof(cmd) && ferror(cmd)) { Log(LOG_LEVEL_ERR, "Error while reading output from ps: %s", GetErrorStr()); } for (int i = 0; names[i] && i < CF_PROCCOLS; i++) { free(names[i]); } free(line); }
static int DBMetaPopulateRecordMap(DBMeta * dbmeta) { off_t offset; uint64_t data_blocks = 0; uint64_t free_blocks = 0; struct stat st; offset = dbmeta->record_offset; if (fstat(dbmeta->fd, &st) == -1) { Log(LOG_LEVEL_ERR, "Error getting file stats. (fstat: %s)", GetErrorStr()); return 1; } while (offset < st.st_size) { TokyoCabinetRecord new_rec; memset(&new_rec, 0, sizeof(TokyoCabinetRecord)); new_rec.offset = offset; // read a variable-length record if (!DBMetaReadOneRecord(dbmeta, &new_rec)) { Log(LOG_LEVEL_ERR, "Unable to fetch a new record from DB file"); return 2; } else { offset = new_rec.offset + new_rec.length; } // if it is a data record then: // for the record, its left and right do: // look up that record in the offset tree // 1) remove it if it exists // 2) add it to the record_tree if it doesn't if (MAGIC_DATA_BLOCK == new_rec.magic) { if (new_rec.offset > 0) { char *key; xasprintf(&key, "%" PRIu64, new_rec.offset); if (StringMapHasKey(dbmeta->offset_map, key) == true) { if (key) { free(key); } } else { StringMapInsert(dbmeta->record_map, key, xstrdup("0")); } } else { Log(LOG_LEVEL_ERR, "new_rec.offset cannot be <= 0 ???"); } if (new_rec.left > 0) { Log(LOG_LEVEL_VERBOSE, "handle left %" PRIu64, new_rec.left); if (AddOffsetToMapUnlessExists (&(dbmeta->offset_map), new_rec.left, -1)) { return 4; } } if (new_rec.right > 0) { Log(LOG_LEVEL_VERBOSE, "handle right %" PRIu64, new_rec.right); if (AddOffsetToMapUnlessExists (&(dbmeta->offset_map), new_rec.right, -1)) { return 4; } } data_blocks++; } else if (MAGIC_FREE_BLOCK == new_rec.magic) { // if it is a fragment record, then skip it free_blocks++; } else { Log(LOG_LEVEL_ERR, "NO record found at offset %" PRIu64, new_rec.offset); } } // if we are not at the end of the file, output the current file offset // with an appropriate message and return Log(LOG_LEVEL_VERBOSE, "Found %" PRIu64 " data records and " "%" PRIu64 " free block records", data_blocks, free_blocks); return 0; }