Exemple #1
0
Item *SelectProcesses(EvalContext *ctx, const Item *processes, const char *process_name, ProcessSelect a, bool attrselect)
{
    Item *result = NULL;

    if (processes == NULL)
    {
        return result;
    }

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];

    GetProcessColumnNames(processes->name, &names[0], start, end);

    for (Item *ip = processes->next; ip != NULL; ip = ip->next)
    {
        int s, e;

        if (BlockTextMatch(ctx, process_name, ip->name, &s, &e))
        {
            if (NULL_OR_EMPTY(ip->name))
            {
                continue;
            }

            if (attrselect && !SelectProcess(ctx, ip->name, names, start, end, a))
            {
                continue;
            }

            pid_t pid = ExtractPid(ip->name, names, end);

            if (pid == -1)
            {
                Log(LOG_LEVEL_VERBOSE, "Unable to extract pid while looking for %s", process_name);
                continue;
            }

            PrependItem(&result, ip->name, "");
            result->counter = (int)pid;
        }
    }

    for (int i = 0; i < CF_PROCCOLS; i++)
    {
        free(names[i]);
    }

    return result;
}
Exemple #2
0
Item *SelectProcesses(const char *process_name, const ProcessSelect *a, bool attrselect)
{
    assert(a != NULL);
    const Item *processes = PROCESSTABLE;
    Item *result = NULL;

    if (processes == NULL)
    {
        return result;
    }

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];

    GetProcessColumnNames(processes->name, names, start, end);

    /* TODO: use actual time of ps-run, as time(NULL) may be later. */
    time_t pstime = time(NULL);

    for (Item *ip = processes->next; ip != NULL; ip = ip->next)
    {
        if (NULL_OR_EMPTY(ip->name))
        {
            continue;
        }

        if (!SelectProcess(ip->name, pstime, names, start, end, process_name, a, attrselect))
        {
            continue;
        }

        pid_t pid = ExtractPid(ip->name, names, end);

        if (pid == -1)
        {
            Log(LOG_LEVEL_VERBOSE, "Unable to extract pid while looking for %s", process_name);
            continue;
        }

        PrependItem(&result, ip->name, "");
        result->counter = (int)pid;
    }

    for (int i = 0; i < CF_PROCCOLS; i++)
    {
        free(names[i]);
    }

    return result;
}
static void KeepServerRolePromise(struct Promise *pp)

{ struct Constraint *cp;
  struct Rlist *rp;
  struct Auth *ap;

if (!GetAuthPath(pp->promiser,ROLES))
   {
   InstallServerAuthPath(pp->promiser,&ROLES,&ROLESTOP);
   }

ap = GetAuthPath(pp->promiser,ROLES);

for (cp = pp->conlist; cp != NULL; cp = cp->next)
   {
   if (!IsDefinedClass(cp->classes))
      {
      continue;
      }

   switch (cp->type)
      {
      case CF_LIST:
          
          for (rp = (struct Rlist *)cp->rval; rp != NULL; rp=rp->next)
             {
             if (strcmp(cp->lval,CF_REMROLE_BODIES[cfs_authorize].lval) == 0)
                {
                PrependItem(&(ap->accesslist),rp->item,NULL);
                continue;
                }
             }
          break;

      case CF_FNCALL:
          /* Shouldn't happen */
          break;

      default:

          if (strcmp(cp->lval,"comment") == 0 || strcmp(cp->lval,"handle") == 0)
             {
             }
          else
             {
             CfOut(cf_error,"","RHS of authorize promise for %s should be a list\n",pp->promiser);
             }
          break;
      }
   }
}
Exemple #4
0
Item *IdempPrependItemClass(Item **liststart, const char *itemstring, const char *classes)
{
    Item *ip;

    ip = ReturnItemInClass(*liststart, itemstring, classes);

    if (ip)                     // already exists
    {
        return ip;
    }

    PrependItem(liststart, itemstring, classes);
    return *liststart;
}
Exemple #5
0
Item *IdempPrependItem(Item **liststart, const char *itemstring, const char *classes)
{
    Item *ip;

    ip = ReturnItemIn(*liststart, itemstring);

    if (ip)
    {
        return ip;
    }

    PrependItem(liststart, itemstring, classes);
    return *liststart;
}
Exemple #6
0
void IdempItemCount(Item **liststart, const char *itemstring, const char *classes)
{
    Item *ip = ReturnItemIn(*liststart, itemstring);

    if (ip)
    {
        ip->counter++;
    }
    else
    {
        PrependItem(liststart, itemstring, classes);
    }

// counter+1 is the histogram of occurrences
}
Exemple #7
0
static void KeepServerRolePromise(EvalContext *ctx, const Promise *pp)
{
    Rlist *rp;
    Auth *ap;

    ap = GetOrCreateAuth(pp->promiser, &SV.roles, &SV.rolestail);

    for (size_t i = 0; i < SeqLength(pp->conlist); i++)
    {
        Constraint *cp = SeqAt(pp->conlist, i);

        if (!IsDefinedClass(ctx, cp->classes))
        {
            continue;
        }

        switch (cp->rval.type)
        {
        case RVAL_TYPE_LIST:

            for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next)
            {
                /* This is for remote class activation by means of cf-runagent.*/
                if (strcmp(cp->lval, CF_REMROLE_BODIES[REMOTE_ROLE_AUTHORIZE].lval) == 0)
                {
                    PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL);
                    continue;
                }
            }
            break;

        case RVAL_TYPE_FNCALL:
            UnexpectedError("Constraint of type FNCALL is invalid in this context!");
            break;

        default:

            if ((strcmp(cp->lval, "comment") == 0) || (strcmp(cp->lval, "handle") == 0))
            {
            }
            else
            {
                Log(LOG_LEVEL_ERR, "Right-hand side of authorize promise for '%s' should be a list", pp->promiser);
            }
            break;
        }
    }
}
static int Unix_GatherProcessUsers(struct Item **userList, int *userListSz, int *numRootProcs, int *numOtherProcs)
{
FILE *pp;
char pscomm[CF_BUFSIZE];
char user[CF_MAXVARSIZE];
char vbuff[CF_BUFSIZE];

snprintf(pscomm,CF_BUFSIZE,"%s %s",VPSCOMM[VSYSTEMHARDCLASS],VPSOPTS[VSYSTEMHARDCLASS]);

if ((pp = cf_popen(pscomm,"r")) == NULL)
   {
   return false;
   }

CfReadLine(vbuff,CF_BUFSIZE,pp); 

while (!feof(pp))
   {
   CfReadLine(vbuff,CF_BUFSIZE,pp);
   sscanf(vbuff,"%s",user);

   if (strcmp(user,"USER") == 0)
      {
      continue;
      }

   if (!IsItemIn(*userList,user))
      {
      PrependItem(userList,user,NULL);
      (*userListSz)++;
      }

   if (strcmp(user,"root") == 0)
      {
      (*numRootProcs)++;
      }
   else
      {
      (*numOtherProcs)++;
      }
   }

cf_pclose(pp);
return true;
}
void
JXPathHistoryMenu::UpdateMenu()
{
	if (GetFirstIndex() == 1)
		{
		JMountPointList list(JPtrArrayT::kDeleteAll);
		time_t t;
		if (JGetUserMountPointList(&list, &t))
			{
			const JSize count = list.GetElementCount();
			SetFirstIndex(count+1);

			for (JIndex i=count; i>=1; i--)
				{
				const JMountPoint mp = list.GetElement(i);
				PrependItem(*(mp.path));
				if (i == count)
					{
					ShowSeparatorAfter(1);
					}

				if (mp.type == kJHardDisk)
					{
					SetItemImage(1, jx_hard_disk_small);
					}
				else if (mp.type == kJZipDisk)
					{
					SetItemImage(1, jx_zip_disk_small);
					}
				else if (mp.type == kJFloppyDisk)
					{
					SetItemImage(1, jx_floppy_disk_small);
					}
				else if (mp.type == kJCDROM)
					{
					SetItemImage(1, jx_cdrom_disk_small);
					}
				}
			}
		}

	RemoveInvalidPaths();
	JXStringHistoryMenu::UpdateMenu();
}
bool CocaSystemTree::moveUp( const coca::INode& node )
{
    wxTreeItemId id = findId( node );
    if ( !id.IsOk() ) { return false; }

    wxTreeItemId parentId = GetItemParent( id );
    if ( !parentId.IsOk() ) { return false; }

    wxTreeItemId previousId = GetPrevSibling( id );
    if ( !previousId.IsOk() ) { return false; }

    // ready to move
    bool wasSelected = ( id == GetSelection() );

    Delete( id );

    previousId = GetPrevSibling( previousId );

    if ( !previousId.IsOk() )
    {
        id = PrependItem( parentId,
                          EditorTools::getName( node ), EditorTools::getImageIndex( node ),
                          -1, new ItemData( node ) );
    }
    else
    {
        id = InsertItem( parentId, previousId,
                         EditorTools::getName( node ), EditorTools::getImageIndex( node ),
                         -1, new ItemData( node ) );
    }

    COCA_ASSERT( id.IsOk() );

    SetItemTextColour( id, EditorTools::getTextColour( node ) );

    addChildren( node, id );

    if ( wasSelected ) { SelectItem( id ); }

    return true;
}
Exemple #11
0
static void KeepServerRolePromise(EvalContext *ctx, const Promise *pp)
{
    Auth *ap = GetOrCreateAuth(pp->promiser, &SV.roles, &SV.rolestail);
    const char *const authorizer = CF_REMROLE_BODIES[REMOTE_ROLE_AUTHORIZE].lval;
    size_t i = SeqLength(pp->conlist);

    while (i > 0)
    {
        i--;
        Constraint *cp = SeqAt(pp->conlist, i);
        if (strcmp(cp->lval, authorizer) == 0)
        {
            if (cp->rval.type != RVAL_TYPE_LIST)
            {
                Log(LOG_LEVEL_ERR,
                    "Right-hand side of authorize promise for '%s' should be a list",
                    pp->promiser);
            }
            else if (IsDefinedClass(ctx, cp->classes))
            {
                /* This is for remote class activation by means of cf-runagent.*/
                for (const Rlist *rp = cp->rval.item; rp != NULL; rp = rp->next)
                {
                    PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL);
                }
            }
        }
        else if (strcmp(cp->lval, "comment") != 0 &&
                 strcmp(cp->lval, "handle") != 0 &&
                 /* Are there other known list constraints ? if not, skip this: */
                 cp->rval.type != RVAL_TYPE_LIST)
        {
            Log(LOG_LEVEL_WARNING,
                "Unrecognised promise '%s' for %s",
                cp->lval, pp->promiser);
        }
    }
}
Exemple #12
0
Item *SplitStringAsItemList(const char *string, char sep)
 /* Splits a string containing a separator like :
    into a linked list of separate items, */
{
    Item *liststart = NULL;
    char node[256];
    char format[] = "%255[^\0]";

    /* Overwrite format's internal \0 with sep: */
    format[strlen(format)] = sep;
    assert(strlen(format) + 1 == sizeof(format) || sep == '\0');

    for (const char *sp = string; *sp != '\0'; sp++)
    {
        if (sscanf(sp, format, node) == 1 &&
            node[0] != '\0')
        {
            sp += strlen(node) - 1;
            PrependItem(&liststart, node, NULL);
        }
    }

    return ReverseItemList(liststart);
}
Exemple #13
0
static bool GetLMSensors(double *cf_this)
{
    FILE *pp;
    Item *ip, *list = NULL;
    double temp = 0;
    char name[CF_BUFSIZE];
    int count;

    cf_this[ob_temp0] = 0.0;
    cf_this[ob_temp1] = 0.0;
    cf_this[ob_temp2] = 0.0;
    cf_this[ob_temp3] = 0.0;

    if ((pp = cf_popen("/usr/bin/sensors", "r", true)) == NULL)
    {
        LMSENSORS = false;      /* Broken */
        return false;
    }

    {
        size_t vbuff_size = CF_BUFSIZE;
        char *vbuff = xmalloc(vbuff_size);

        ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp);
        if (res <= 0)
        {
            /* FIXME: do we need to log anything here? */
            cf_pclose(pp);
            free(vbuff);
            return false;
        }

        for (;;)
        {
            ssize_t res = CfReadLine(&vbuff, &vbuff_size, pp);
            if (res == -1)
            {
                if (!feof(pp))
                {
                    /* FIXME: Do we need to log anything here? */
                    cf_pclose(pp);
                    free(vbuff);
                    return false;
                }
                else
                {
                    break;
                }
            }

            if (strstr(vbuff, "Temp") || strstr(vbuff, "temp"))
            {
                PrependItem(&list, vbuff, NULL);
            }
        }

        cf_pclose(pp);
        free(vbuff);
    }

    if (ListLen(list) > 0)
    {
        Log(LOG_LEVEL_DEBUG, "LM Sensors seemed to return ok data");
    }
    else
    {
        return false;
    }

/* lmsensor names are hopelessly inconsistent - so try a few things */

    for (ip = list; ip != NULL; ip = ip->next)
    {
        for (count = 0; count < 4; count++)
        {
            snprintf(name, 16, "CPU%d Temp:", count);

            if (strncmp(ip->name, name, strlen(name)) == 0)
            {
                sscanf(ip->name, "%*[^:]: %lf", &temp);

                switch (count)
                {
                case 0:
                    cf_this[ob_temp0] = temp;
                    break;
                case 1:
                    cf_this[ob_temp1] = temp;
                    break;
                case 2:
                    cf_this[ob_temp2] = temp;
                    break;
                case 3:
                    cf_this[ob_temp3] = temp;
                    break;
                }

                Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf from what looks like cpu temperature", count, temp);
            }
        }
    }

    if (cf_this[ob_temp0] != 0)
    {
        /* We got something plausible */
        return true;
    }

/* Alternative name Core x: */

    for (ip = list; ip != NULL; ip = ip->next)
    {
        for (count = 0; count < 4; count++)
        {
            snprintf(name, 16, "Core %d:", count);

            if (strncmp(ip->name, name, strlen(name)) == 0)
            {
                sscanf(ip->name, "%*[^:]: %lf", &temp);

                switch (count)
                {
                case 0:
                    cf_this[ob_temp0] = temp;
                    break;
                case 1:
                    cf_this[ob_temp1] = temp;
                    break;
                case 2:
                    cf_this[ob_temp2] = temp;
                    break;
                case 3:
                    cf_this[ob_temp3] = temp;
                    break;
                }

                Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf from what looks like core temperatures", count, temp);
            }
        }
    }

    if (cf_this[ob_temp0] != 0)
    {
        /* We got something plausible */
        return true;
    }

    for (ip = list; ip != NULL; ip = ip->next)
    {
        if (strncmp(ip->name, "CPU Temp:", strlen("CPU Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to CPU Temp");
            cf_this[ob_temp0] = temp;
        }

        if (strncmp(ip->name, "M/B Temp:", strlen("M/B Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to M/B Temp");
            cf_this[ob_temp1] = temp;
        }

        if (strncmp(ip->name, "Sys Temp:", strlen("Sys Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to Sys Temp");
            cf_this[ob_temp2] = temp;
        }

        if (strncmp(ip->name, "AUX Temp:", strlen("AUX Temp:")) == 0)
        {
            sscanf(ip->name, "%*[^:]: %lf", &temp);
            Log(LOG_LEVEL_DEBUG, "Setting temp0 to AUX Temp");
            cf_this[ob_temp3] = temp;
        }
    }

    if (cf_this[ob_temp0] != 0)
    {
        /* We got something plausible */
        return true;
    }

/* Alternative name Core x: */

    for (ip = list; ip != NULL; ip = ip->next)
    {
        for (count = 0; count < 4; count++)
        {
            snprintf(name, 16, "temp%d:", count);

            if (strncmp(ip->name, name, strlen(name)) == 0)
            {
                sscanf(ip->name, "%*[^:]: %lf", &temp);

                switch (count)
                {
                case 0:
                    cf_this[ob_temp0] = temp;
                    break;
                case 1:
                    cf_this[ob_temp1] = temp;
                    break;
                case 2:
                    cf_this[ob_temp2] = temp;
                    break;
                case 3:
                    cf_this[ob_temp3] = temp;
                    break;
                }

                Log(LOG_LEVEL_DEBUG, "Set temp%d to %lf", count, temp);
            }
        }
    }

/* Give up? */
    DeleteItemList(list);
    return true;
}
Exemple #14
0
void ServerEntryPoint(EvalContext *ctx, char *ipaddr, ConnectionInfo *info)
{
    char intime[64];
    time_t now;

    Log(LOG_LEVEL_VERBOSE,
        "Obtained IP address of '%s' on socket %d from accept",
        ipaddr, ConnectionInfoSocket(info));

    if ((SV.nonattackerlist) && (!IsMatchItemIn(SV.nonattackerlist, MapAddress(ipaddr))))
    {
        Log(LOG_LEVEL_ERR, "Not allowing connection from non-authorized IP '%s'", ipaddr);
        cf_closesocket(ConnectionInfoSocket(info));
        ConnectionInfoDestroy(&info);
        return;
    }

    if (IsMatchItemIn(SV.attackerlist, MapAddress(ipaddr)))
    {
        Log(LOG_LEVEL_ERR, "Denying connection from non-authorized IP '%s'", ipaddr);
        cf_closesocket(ConnectionInfoSocket(info));
        ConnectionInfoDestroy(&info);
        return;
    }

    if ((now = time((time_t *) NULL)) == -1)
       {
       now = 0;
       }

    PurgeOldConnections(&SV.connectionlist, now);

    if (!IsMatchItemIn(SV.multiconnlist, MapAddress(ipaddr)))
    {
        if (!ThreadLock(cft_count))
        {
            return;
        }

        if (IsItemIn(SV.connectionlist, MapAddress(ipaddr)))
        {
            ThreadUnlock(cft_count);
            Log(LOG_LEVEL_ERR, "Denying repeated connection from '%s'", ipaddr);
            cf_closesocket(ConnectionInfoSocket(info));
            ConnectionInfoDestroy(&info);
            return;
        }

        ThreadUnlock(cft_count);
    }

    if (SV.logconns)
    {
        Log(LOG_LEVEL_INFO, "Accepting connection from %s", ipaddr);
    }
    else
    {
        Log(LOG_LEVEL_INFO, "Accepting connection from %s", ipaddr);
    }

    snprintf(intime, 63, "%d", (int) now);

    if (!ThreadLock(cft_count))
    {
        cf_closesocket(ConnectionInfoSocket(info));
        ConnectionInfoDestroy(&info);
        return;
    }

    PrependItem(&SV.connectionlist, MapAddress(ipaddr), intime);

    if (!ThreadUnlock(cft_count))
    {
        cf_closesocket(ConnectionInfoSocket(info));
        ConnectionInfoDestroy(&info);
        return;
    }

    SpawnConnection(ctx, ipaddr, info);

}
Exemple #15
0
void RotateFiles(char *name, int number)
{
    int i, fd;
    struct stat statbuf;
    char from[CF_BUFSIZE], to[CF_BUFSIZE];

    if (IsItemIn(ROTATED, name))
    {
        return;
    }

    PrependItem(&ROTATED, name, NULL);

    if (stat(name, &statbuf) == -1)
    {
        Log(LOG_LEVEL_VERBOSE, "No access to file %s", name);
        return;
    }

    for (i = number - 1; i > 0; i--)
    {
        snprintf(from, CF_BUFSIZE, "%s.%d", name, i);
        snprintf(to, CF_BUFSIZE, "%s.%d", name, i + 1);

        if (rename(from, to) == -1)
        {
            Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from);
        }

        snprintf(from, CF_BUFSIZE, "%s.%d.gz", name, i);
        snprintf(to, CF_BUFSIZE, "%s.%d.gz", name, i + 1);

        if (rename(from, to) == -1)
        {
            Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from);
        }

        snprintf(from, CF_BUFSIZE, "%s.%d.Z", name, i);
        snprintf(to, CF_BUFSIZE, "%s.%d.Z", name, i + 1);

        if (rename(from, to) == -1)
        {
            Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from);
        }

        snprintf(from, CF_BUFSIZE, "%s.%d.bz", name, i);
        snprintf(to, CF_BUFSIZE, "%s.%d.bz", name, i + 1);

        if (rename(from, to) == -1)
        {
            Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from);
        }

        snprintf(from, CF_BUFSIZE, "%s.%d.bz2", name, i);
        snprintf(to, CF_BUFSIZE, "%s.%d.bz2", name, i + 1);

        if (rename(from, to) == -1)
        {
            Log(LOG_LEVEL_DEBUG, "Rename failed in RotateFiles '%s' -> '%s'", name, from);
        }
    }

    snprintf(to, CF_BUFSIZE, "%s.1", name);

    if (CopyRegularFileDisk(name, to) == false)
    {
        Log(LOG_LEVEL_DEBUG, "Copy failed in RotateFiles '%s' -> '%s'", name, to);
        return;
    }

    safe_chmod(to, statbuf.st_mode);
    if (safe_chown(to, statbuf.st_uid, statbuf.st_gid))
    {
        UnexpectedError("Failed to chown %s", to);
    }
    safe_chmod(name, 0600);       /* File must be writable to empty .. */

    if ((fd = safe_creat(name, statbuf.st_mode)) == -1)
    {
        Log(LOG_LEVEL_ERR, "Failed to create new '%s' in disable(rotate). (creat: %s)",
            name, GetErrorStr());
    }
    else
    {
        if (safe_chown(name, statbuf.st_uid, statbuf.st_gid))  /* NT doesn't have fchown */
        {
            UnexpectedError("Failed to chown '%s'", name);
        }
        fchmod(fd, statbuf.st_mode);
        close(fd);
    }
}
Exemple #16
0
void KeepControlPromises(Policy *policy)
{
    Rval retval;
    Rlist *rp;

    Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_AGENT);
    if (constraints)
    {
        for (size_t i = 0; i < SeqLength(constraints); i++)
        {
            Constraint *cp = SeqAt(constraints, i);

            if (IsExcluded(cp->classes, NULL))
            {
                continue;
            }

            if (GetVariable("control_common", cp->lval, &retval) != DATA_TYPE_NONE)
            {
                /* Already handled in generic_agent */
                continue;
            }

            if (GetVariable("control_agent", cp->lval, &retval) == DATA_TYPE_NONE)
            {
                CfOut(cf_error, "", "Unknown lval %s in agent control body", cp->lval);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_maxconnections].lval) == 0)
            {
                CFA_MAXTHREADS = (int) Str2Int(retval.item);
                CfOut(cf_verbose, "", "SET maxconnections = %d\n", CFA_MAXTHREADS);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_checksum_alert_time].lval) == 0)
            {
                CF_PERSISTENCE = (int) Str2Int(retval.item);
                CfOut(cf_verbose, "", "SET checksum_alert_time = %d\n", CF_PERSISTENCE);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_agentfacility].lval) == 0)
            {
                SetFacility(retval.item);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_agentaccess].lval) == 0)
            {
                ACCESSLIST = (Rlist *) retval.item;
                CheckAgentAccess(ACCESSLIST, InputFiles(policy));
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_refresh_processes].lval) == 0)
            {
                Rlist *rp;

                if (VERBOSE)
                {
                    printf("%s> SET refresh_processes when starting: ", VPREFIX);

                    for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next)
                    {
                        printf(" %s", (char *) rp->item);
                        PrependItem(&PROCESSREFRESH, rp->item, NULL);
                    }

                    printf("\n");
                }

                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_abortclasses].lval) == 0)
            {
                Rlist *rp;

                CfOut(cf_verbose, "", "SET Abort classes from ...\n");

                for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next)
                {
                    char name[CF_MAXVARSIZE] = "";

                    strncpy(name, rp->item, CF_MAXVARSIZE - 1);

                    AddAbortClass(name, cp->classes);
                }

                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_abortbundleclasses].lval) == 0)
            {
                Rlist *rp;

                CfOut(cf_verbose, "", "SET Abort bundle classes from ...\n");

                for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next)
                {
                    char name[CF_MAXVARSIZE] = "";

                    strncpy(name, rp->item, CF_MAXVARSIZE - 1);

                    if (!IsItemIn(ABORTBUNDLEHEAP, name))
                    {
                        AppendItem(&ABORTBUNDLEHEAP, name, cp->classes);
                    }
                }

                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_addclasses].lval) == 0)
            {
                Rlist *rp;

                CfOut(cf_verbose, "", "-> Add classes ...\n");

                for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next)
                {
                    CfOut(cf_verbose, "", " -> ... %s\n", ScalarValue(rp));
                    NewClass(rp->item, NULL);
                }

                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_auditing].lval) == 0)
            {
                CfOut(cf_verbose, "", "This option does nothing and is retained for compatibility reasons");
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_alwaysvalidate].lval) == 0)
            {
                ALWAYS_VALIDATE = GetBoolean(retval.item);
                CfOut(cf_verbose, "", "SET alwaysvalidate = %d\n", ALWAYS_VALIDATE);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_allclassesreport].lval) == 0)
            {
                ALLCLASSESREPORT = GetBoolean(retval.item);
                CfOut(cf_verbose, "", "SET allclassesreport = %d\n", ALLCLASSESREPORT);
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_secureinput].lval) == 0)
            {
                CFPARANOID = GetBoolean(retval.item);
                CfOut(cf_verbose, "", "SET secure input = %d\n", CFPARANOID);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_binarypaddingchar].lval) == 0)
            {
                CfOut(cf_verbose, "", "binarypaddingchar is obsolete and does nothing\n");
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_bindtointerface].lval) == 0)
            {
                strncpy(BINDINTERFACE, retval.item, CF_BUFSIZE - 1);
                CfOut(cf_verbose, "", "SET bindtointerface = %s\n", BINDINTERFACE);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_hashupdates].lval) == 0)
            {
                bool enabled = GetBoolean(retval.item);

                SetChecksumUpdates(enabled);
                CfOut(cf_verbose, "", "SET ChecksumUpdates %d\n", enabled);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_exclamation].lval) == 0)
            {
                CfOut(cf_verbose, "", "exclamation control is deprecated and does not do anything\n");
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_childlibpath].lval) == 0)
            {
                char output[CF_BUFSIZE];

                snprintf(output, CF_BUFSIZE, "LD_LIBRARY_PATH=%s", (char *) retval.item);
                if (putenv(xstrdup(output)) == 0)
                {
                    CfOut(cf_verbose, "", "Setting %s\n", output);
                }
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_defaultcopytype].lval) == 0)
            {
                DEFAULT_COPYTYPE = (char *) retval.item;
                CfOut(cf_verbose, "", "SET defaultcopytype = %s\n", DEFAULT_COPYTYPE);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_fsinglecopy].lval) == 0)
            {
                SINGLE_COPY_LIST = (Rlist *) retval.item;
                CfOut(cf_verbose, "", "SET file single copy list\n");
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_fautodefine].lval) == 0)
            {
                SetFileAutoDefineList(ListRvalValue(retval));
                CfOut(cf_verbose, "", "SET file auto define list\n");
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_dryrun].lval) == 0)
            {
                DONTDO = GetBoolean(retval.item);
                CfOut(cf_verbose, "", "SET dryrun = %c\n", DONTDO);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_inform].lval) == 0)
            {
                INFORM = GetBoolean(retval.item);
                CfOut(cf_verbose, "", "SET inform = %c\n", INFORM);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_verbose].lval) == 0)
            {
                VERBOSE = GetBoolean(retval.item);
                CfOut(cf_verbose, "", "SET inform = %c\n", VERBOSE);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_repository].lval) == 0)
            {
                SetRepositoryLocation(retval.item);
                CfOut(cf_verbose, "", "SET repository = %s\n", ScalarRvalValue(retval));
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_skipidentify].lval) == 0)
            {
                bool enabled = GetBoolean(retval.item);

                SetSkipIdentify(enabled);
                CfOut(cf_verbose, "", "SET skipidentify = %d\n", (int) enabled);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_suspiciousnames].lval) == 0)
            {

                for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next)
                {
                    AddFilenameToListOfSuspicious(ScalarValue(rp));
                    CfOut(cf_verbose, "", "-> Considering %s as suspicious file", ScalarValue(rp));
                }

                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_repchar].lval) == 0)
            {
                char c = *(char *) retval.item;

                SetRepositoryChar(c);
                CfOut(cf_verbose, "", "SET repchar = %c\n", c);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_mountfilesystems].lval) == 0)
            {
                CF_MOUNTALL = GetBoolean(retval.item);
                CfOut(cf_verbose, "", "SET mountfilesystems = %d\n", CF_MOUNTALL);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_editfilesize].lval) == 0)
            {
                EDITFILESIZE = Str2Int(retval.item);
                CfOut(cf_verbose, "", "SET EDITFILESIZE = %d\n", EDITFILESIZE);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_ifelapsed].lval) == 0)
            {
                VIFELAPSED = Str2Int(retval.item);
                CfOut(cf_verbose, "", "SET ifelapsed = %d\n", VIFELAPSED);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_expireafter].lval) == 0)
            {
                VEXPIREAFTER = Str2Int(retval.item);
                CfOut(cf_verbose, "", "SET ifelapsed = %d\n", VEXPIREAFTER);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_timeout].lval) == 0)
            {
                CONNTIMEOUT = Str2Int(retval.item);
                CfOut(cf_verbose, "", "SET timeout = %jd\n", (intmax_t) CONNTIMEOUT);
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_max_children].lval) == 0)
            {
                CFA_BACKGROUND_LIMIT = Str2Int(retval.item);
                CfOut(cf_verbose, "", "SET MAX_CHILDREN = %d\n", CFA_BACKGROUND_LIMIT);
                if (CFA_BACKGROUND_LIMIT > 10)
                {
                    CfOut(cf_error, "", "Silly value for max_children in agent control promise (%d > 10)",
                          CFA_BACKGROUND_LIMIT);
                    CFA_BACKGROUND_LIMIT = 1;
                }
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_syslog].lval) == 0)
            {
                CfOut(cf_verbose, "", "SET syslog = %d\n", GetBoolean(retval.item));
                continue;
            }

            if (strcmp(cp->lval, CFA_CONTROLBODY[cfa_environment].lval) == 0)
            {
                Rlist *rp;

                CfOut(cf_verbose, "", "SET environment variables from ...\n");

                for (rp = (Rlist *) retval.item; rp != NULL; rp = rp->next)
                {
                    if (putenv(rp->item) != 0)
                    {
                        CfOut(cf_error, "putenv", "Failed to set environment variable %s", ScalarValue(rp));
                    }
                }

                continue;
            }
        }
    }

    if (GetVariable("control_common", CFG_CONTROLBODY[cfg_lastseenexpireafter].lval, &retval) != DATA_TYPE_NONE)
    {
        LASTSEENEXPIREAFTER = Str2Int(retval.item) * 60;
    }

    if (GetVariable("control_common", CFG_CONTROLBODY[cfg_fips_mode].lval, &retval) != DATA_TYPE_NONE)
    {
        FIPS_MODE = GetBoolean(retval.item);
        CfOut(cf_verbose, "", "SET FIPS_MODE = %d\n", FIPS_MODE);
    }

    if (GetVariable("control_common", CFG_CONTROLBODY[cfg_syslog_port].lval, &retval) != DATA_TYPE_NONE)
    {
        SetSyslogPort(Str2Int(retval.item));
        CfOut(cf_verbose, "", "SET syslog_port to %s", ScalarRvalValue(retval));
    }

    if (GetVariable("control_common", CFG_CONTROLBODY[cfg_syslog_host].lval, &retval) != DATA_TYPE_NONE)
    {
        SetSyslogHost(Hostname2IPString(retval.item));
        CfOut(cf_verbose, "", "SET syslog_host to %s", Hostname2IPString(retval.item));
    }

#ifdef HAVE_NOVA
    Nova_Initialize();
#endif
}
Exemple #17
0
static int FindPidMatches(EvalContext *ctx, Item *procdata, Item **killlist, Attributes a, const char *promiser)
{
    int matches = 0;
    pid_t cfengine_pid = getpid();

    Item *matched = SelectProcesses(ctx, procdata, promiser, a.process_select, a.haveselect);

    for (Item *ip = matched; ip != NULL; ip = ip->next)
    {
        pid_t pid = ip->counter;

        if (pid == 1)
        {
            if ((RlistLen(a.signals) == 1) && (RlistIsStringIn(a.signals, "hup")))
            {
                Log(LOG_LEVEL_VERBOSE, "Okay to send only HUP to init");
            }
            else
            {
                continue;
            }
        }

        if ((pid < 4) && (a.signals))
        {
            Log(LOG_LEVEL_VERBOSE, "Will not signal or restart processes 0,1,2,3 (occurred while looking for %s)",
                  promiser);
            continue;
        }

        bool promised_zero = (a.process_count.min_range == 0) && (a.process_count.max_range == 0);

        if ((a.transaction.action == cfa_warn) && promised_zero)
        {
            Log(LOG_LEVEL_ERR, "Process alert '%s'", procdata->name);     /* legend */
            Log(LOG_LEVEL_ERR, "Process alert '%s'", ip->name);
            continue;
        }

        if ((pid == cfengine_pid) && (a.signals))
        {
            Log(LOG_LEVEL_VERBOSE, "cf-agent will not signal itself!");
            continue;
        }

        if (a.transaction.action == cfa_warn)
        {
            Log(LOG_LEVEL_ERR, "Matched '%s'", ip->name);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "Matched '%s'", ip->name);
        }

        PrependItem(killlist, ip->name, "");
        (*killlist)->counter = pid;
        matches++;
    }

    DeleteItemList(matched);

    return matches;
}
Exemple #18
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);
}
Exemple #19
0
int LoadProcessTable(EvalContext *ctx, Item **procdata)
{
    FILE *prp;
    char pscomm[CF_MAXLINKSIZE], vbuff[CF_BUFSIZE], *sp;
    Item *rootprocs = NULL;
    Item *otherprocs = NULL;

    if (PROCESSTABLE)
    {
        Log(LOG_LEVEL_VERBOSE, "Reusing cached process table");
        return true;
    }

    const char *psopts = GetProcessOptions();

    snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VSYSTEMHARDCLASS], psopts);

    Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm);

    if ((prp = cf_popen(pscomm, "r", false)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr());
        return false;
    }

    for (;;)
    {
        ssize_t res = CfReadLine(vbuff, CF_BUFSIZE, prp);
        if (res == 0)
        {
            break;
        }

        if (res == -1)
        {
            Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr());
            cf_pclose(prp);
            return false;
        }

        for (sp = vbuff + strlen(vbuff) - 1; (sp > vbuff) && (isspace((int)*sp)); sp--)
        {
            *sp = '\0';
        }

        if (ForeignZone(vbuff))
        {
            continue;
        }

        AppendItem(procdata, vbuff, "");
    }

    cf_pclose(prp);

/* Now save the data */

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_procs", CFWORKDIR);
    RawSaveItemList(*procdata, vbuff);

    CopyList(&rootprocs, *procdata);
    CopyList(&otherprocs, *procdata);

    while (DeleteItemNotContaining(ctx, &rootprocs, "root"))
    {
    }

    while (DeleteItemContaining(ctx, &otherprocs, "root"))
    {
    }

    if (otherprocs)
    {
        PrependItem(&rootprocs, otherprocs->name, NULL);
    }

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_rootprocs", CFWORKDIR);
    RawSaveItemList(rootprocs, vbuff);
    DeleteItemList(rootprocs);

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_otherprocs", CFWORKDIR);
    RawSaveItemList(otherprocs, vbuff);
    DeleteItemList(otherprocs);

    return true;
}
Exemple #20
0
void TexinfoManual(const char *source_dir, const char *output_file)
{
    char filename[CF_BUFSIZE];
    const SubTypeSyntax *st;
    Item *done = NULL;
    FILE *fout;
    int i;

    if ((fout = fopen(output_file, "w")) == NULL)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "fopen", "Unable to open %s for writing\n", filename);
        return;
    }

    TexinfoHeader(fout);

/* General background */

    fprintf(fout, "@c *****************************************************\n");
    fprintf(fout, "@c * CHAPTER \n");
    fprintf(fout, "@c *****************************************************\n");

    fprintf(fout, "@node Getting started\n@chapter CFEngine %s -- Getting started\n\n", Version());
    IncludeManualFile(source_dir, fout, "reference_basics.texinfo");

/* Control promises */

    fprintf(fout, "@c *****************************************************\n");
    fprintf(fout, "@c * CHAPTER \n");
    fprintf(fout, "@c *****************************************************\n");

    fprintf(fout, "@node Control Promises\n@chapter Control promises\n\n");
    IncludeManualFile(source_dir, fout, "reference_control_intro.texinfo");

    fprintf(fout, "@menu\n");
    for (i = 0; CF_ALL_BODIES[i].bundle_type != NULL; ++i)
    {
        fprintf(fout, "* control %s::\n", CF_ALL_BODIES[i].bundle_type);
    }
    fprintf(fout, "@end menu\n");

    for (i = 0; CF_ALL_BODIES[i].bundle_type != NULL; i++)
    {
        fprintf(fout, "@node control %s\n@section @code{%s} control promises\n\n", CF_ALL_BODIES[i].bundle_type,
                CF_ALL_BODIES[i].bundle_type);
        snprintf(filename, CF_BUFSIZE - 1, "control/%s_example.texinfo", CF_ALL_BODIES[i].bundle_type);
        IncludeManualFile(source_dir, fout, filename);
        snprintf(filename, CF_BUFSIZE - 1, "control/%s_notes.texinfo", CF_ALL_BODIES[i].bundle_type);
        IncludeManualFile(source_dir, fout, filename);

        TexinfoBodyParts(source_dir, fout, CF_ALL_BODIES[i].bs, CF_ALL_BODIES[i].bundle_type);
    }

/* Components */

    for (i = 0; i < CF3_MODULES; i++)
    {
        st = (CF_ALL_SUBTYPES[i]);

        if ((st == CF_COMMON_SUBTYPES) || (st == CF_EXEC_SUBTYPES) || (st == CF_REMACCESS_SUBTYPES)
            || (st == CF_KNOWLEDGE_SUBTYPES) || (st == CF_MEASUREMENT_SUBTYPES))

        {
            CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type %s\n", st->bundle_type);
            fprintf(fout, "@c *****************************************************\n");
            fprintf(fout, "@c * CHAPTER \n");
            fprintf(fout, "@c *****************************************************\n");

            if (strcmp(st->bundle_type, "*") == 0)
            {
                fprintf(fout, "@node Bundles for common\n@chapter Bundles of @code{common}\n\n");
            }
            else
            {
                fprintf(fout, "@node Bundles for %s\n@chapter Bundles of @code{%s}\n\n", st->bundle_type, st->bundle_type);
            }
        }

        if (!IsItemIn(done, st->bundle_type)) /* Avoid multiple reading if several modules */
        {
            char bundle_filename[CF_BUFSIZE];
            if (strcmp(st->bundle_type, "*") == 0)
            {
                strcpy(bundle_filename, "common");
            }
            else
            {
                strlcpy(bundle_filename, st->bundle_type, CF_BUFSIZE);
            }
            PrependItem(&done, st->bundle_type, NULL);
            snprintf(filename, CF_BUFSIZE - 1, "bundletypes/%s_example.texinfo", bundle_filename);
            IncludeManualFile(source_dir, fout, filename);
            snprintf(filename, CF_BUFSIZE - 1, "bundletypes/%s_notes.texinfo", bundle_filename);
            IncludeManualFile(source_dir, fout, filename);

            fprintf(fout, "@menu\n");
            for (int k = 0; k < CF3_MODULES; ++k)
            {
                for (int j = 0; CF_ALL_SUBTYPES[k][j].bundle_type != NULL; ++j)
                {
                    const char *constraint_type_name;
                    if (strcmp(CF_ALL_SUBTYPES[k][j].subtype, "*") == 0)
                    {
                        constraint_type_name = "Miscellaneous";
                    }
                    else
                    {
                        constraint_type_name = CF_ALL_SUBTYPES[k][j].subtype;
                    }

                    const char *bundle_type_name;
                    if (strcmp(CF_ALL_SUBTYPES[k][j].bundle_type, "*") == 0)
                    {
                        bundle_type_name = "common";
                    }
                    else
                    {
                        bundle_type_name = CF_ALL_SUBTYPES[k][j].bundle_type;
                    }

                    fprintf(fout, "* %s in %s promises: %s in %s promises\n", CF_ALL_SUBTYPES[k][j].subtype,
                            bundle_type_name,
                            constraint_type_name,
                            bundle_type_name);
                }
            }
            fprintf(fout, "@end menu\n");
        }

        TexinfoPromiseTypesFor(source_dir, fout, st);
    }

/* Special functions */

    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type - special functions\n");
    fprintf(fout, "@c *****************************************************\n");
    fprintf(fout, "@c * CHAPTER \n");
    fprintf(fout, "@c *****************************************************\n");

    fprintf(fout, "@node Special functions\n@chapter Special functions\n\n");

    fprintf(fout, "@menu\n");
    fprintf(fout, "* Introduction to functions::\n");

    for (i = 0; CF_FNCALL_TYPES[i].name != NULL; ++i)
    {
        fprintf(fout, "* Function %s::\n", CF_FNCALL_TYPES[i].name);
    }

    fprintf(fout, "@end menu\n");

    fprintf(fout, "@node Introduction to functions\n@section Introduction to functions\n\n");

    IncludeManualFile(source_dir, fout, "functions_intro.texinfo");

    for (i = 0; CF_FNCALL_TYPES[i].name != NULL; i++)
    {
        fprintf(fout, "@node Function %s\n@section Function %s \n\n", CF_FNCALL_TYPES[i].name, CF_FNCALL_TYPES[i].name);
        TexinfoSpecialFunction(source_dir, fout, CF_FNCALL_TYPES[i]);
    }

/* Special variables */

    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type - special variables\n");
    fprintf(fout, "@c *****************************************************\n");
    fprintf(fout, "@c * CHAPTER \n");
    fprintf(fout, "@c *****************************************************\n");

    fprintf(fout, "@node Special Variables\n@chapter Special Variables\n\n");

    static const char *scopes[] =
    {
        "const",
        "edit",
        "match",
        "mon",
        "sys",
        "this",
        NULL,
    };

    fprintf(fout, "@menu\n");
    for (const char **s = scopes; *s != NULL; ++s)
    {
        fprintf(fout, "* Variable context %s::\n", *s);
    }
    fprintf(fout, "@end menu\n");

// scopes const and sys

    NewScope("edit");
    NewScalar("edit", "filename", "x", DATA_TYPE_STRING);

    NewScope("match");
    NewScalar("match", "0", "x", DATA_TYPE_STRING);

    for (const char **s = scopes; *s != NULL; ++s)
    {
        TexinfoVariables(source_dir, fout, (char *) *s);
    }

// Log files

    CfOut(OUTPUT_LEVEL_VERBOSE, "", "Dealing with chapter / bundle type - Logs and records\n");
    fprintf(fout, "@c *****************************************************\n");
    fprintf(fout, "@c * CHAPTER \n");
    fprintf(fout, "@c *****************************************************\n");

    fprintf(fout, "@node Logs and records\n@chapter Logs and records\n\n");
    IncludeManualFile(source_dir, fout, "reference_logs.texinfo");

    TexinfoFooter(fout);

    fclose(fout);
}
Exemple #21
0
void AddFilenameToListOfSuspicious(const char *pattern)
{
    PrependItem(&SUSPICIOUSLIST, pattern, NULL);
}
Exemple #22
0
void KeepQueryAccessPromise(EvalContext *ctx, Promise *pp, char *type)
{
    Rlist *rp;
    Auth *ap, *dp;

    if (!GetAuthPath(pp->promiser, SV.varadmit))
    {
        InstallServerAuthPath(pp->promiser, &SV.varadmit, &SV.varadmittop);
    }

    RegisterLiteralServerData(ctx, pp->promiser, pp);

    if (!GetAuthPath(pp->promiser, SV.vardeny))
    {
        InstallServerAuthPath(pp->promiser, &SV.vardeny, &SV.vardenytop);
    }

    ap = GetAuthPath(pp->promiser, SV.varadmit);
    dp = GetAuthPath(pp->promiser, SV.vardeny);

    if (strcmp(type, "query") == 0)
    {
        ap->literal = true;
    }

    for (size_t i = 0; i < SeqLength(pp->conlist); i++)
    {
        Constraint *cp = SeqAt(pp->conlist, i);

        if (!IsDefinedClass(ctx, cp->classes, PromiseGetNamespace(pp)))
        {
            continue;
        }

        switch (cp->rval.type)
        {
        case RVAL_TYPE_SCALAR:

            if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ENCRYPTED].lval) == 0)
            {
                ap->encrypt = true;
            }

            break;

        case RVAL_TYPE_LIST:

            for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next)
            {
                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ADMIT].lval) == 0)
                {
                    PrependItem(&(ap->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_DENY].lval) == 0)
                {
                    PrependItem(&(dp->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_MAPROOT].lval) == 0)
                {
                    PrependItem(&(ap->maproot), rp->item, NULL);
                    continue;
                }
            }
            break;

        default:
            /* Shouldn't happen */
            break;
        }
    }
}
Exemple #23
0
void KeepLiteralAccessPromise(EvalContext *ctx, Promise *pp, char *type)
{
    Rlist *rp;
    Auth *ap = NULL, *dp = NULL;
    const char *handle = PromiseGetHandle(pp);

    if ((handle == NULL) && (strcmp(type,"literal") == 0))
    {
        Log(LOG_LEVEL_ERR, "Access to literal server data requires you to define a promise handle for reference");
        return;
    }
    
    if (strcmp(type, "literal") == 0)
    {
        Log(LOG_LEVEL_VERBOSE,"Looking at literal access promise '%s', type '%s'", pp->promiser, type);

        if (!GetAuthPath(handle, SV.varadmit))
        {
            InstallServerAuthPath(handle, &SV.varadmit, &SV.varadmittop);
        }

        if (!GetAuthPath(handle, SV.vardeny))
        {
            InstallServerAuthPath(handle, &SV.vardeny, &SV.vardenytop);
        }

        RegisterLiteralServerData(ctx, handle, pp);
        ap = GetAuthPath(handle, SV.varadmit);
        dp = GetAuthPath(handle, SV.vardeny);
        ap->literal = true;
    }
    else
    {
        Log(LOG_LEVEL_VERBOSE,"Looking at context/var access promise '%s', type '%s'", pp->promiser, type);

        if (!GetAuthPath(pp->promiser, SV.varadmit))
        {
            InstallServerAuthPath(pp->promiser, &SV.varadmittop, &SV.varadmittop);
        }

        if (!GetAuthPath(pp->promiser, SV.vardeny))
        {
            InstallServerAuthPath(pp->promiser, &SV.vardeny, &SV.vardenytop);
        }


        if (strcmp(type, "context") == 0)
        {
            ap = GetAuthPath(pp->promiser, SV.varadmit);
            dp = GetAuthPath(pp->promiser, SV.vardeny);
            ap->classpattern = true;
        }

        if (strcmp(type, "variable") == 0)
        {
            ap = GetAuthPath(pp->promiser, SV.varadmit); // Allow the promiser (preferred) as well as handle as variable name
            dp = GetAuthPath(pp->promiser, SV.vardeny);
            ap->variable = true;
        }
    }
    
    for (size_t i = 0; i < SeqLength(pp->conlist); i++)
    {
        Constraint *cp = SeqAt(pp->conlist, i);

        if (!IsDefinedClass(ctx, cp->classes, PromiseGetNamespace(pp)))
        {
            continue;
        }

        switch (cp->rval.type)
        {
        case RVAL_TYPE_SCALAR:

            if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ENCRYPTED].lval) == 0)
            {
                ap->encrypt = true;
            }

            break;

        case RVAL_TYPE_LIST:

            for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next)
            {
                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ADMIT].lval) == 0)
                {
                    PrependItem(&(ap->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_DENY].lval) == 0)
                {
                    PrependItem(&(dp->accesslist), rp->item, NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_MAPROOT].lval) == 0)
                {
                    PrependItem(&(ap->maproot), rp->item, NULL);
                    continue;
                }
            }
            break;

        default:
            /* Shouldn't happen */
            break;
        }
    }
}
Exemple #24
0
int Unix_LoadProcessTable(Item **procdata)
{
    FILE *prp;
    char pscomm[CF_MAXLINKSIZE], vbuff[CF_BUFSIZE], *sp;
    Item *rootprocs = NULL;
    Item *otherprocs = NULL;
    const char *psopts = GetProcessOptions();

    snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VSYSTEMHARDCLASS], psopts);

    CfOut(cf_verbose, "", "Observe process table with %s\n", pscomm);

    if ((prp = cf_popen(pscomm, "r")) == NULL)
    {
        CfOut(cf_error, "popen", "Couldn't open the process list with command %s\n", pscomm);
        return false;
    }

    while (!feof(prp))
    {
        memset(vbuff, 0, CF_BUFSIZE);
        CfReadLine(vbuff, CF_BUFSIZE, prp);

        for (sp = vbuff + strlen(vbuff) - 1; sp > vbuff && isspace(*sp); sp--)
        {
            *sp = '\0';
        }

        if (ForeignZone(vbuff))
        {
            continue;
        }

        AppendItem(procdata, vbuff, "");
    }

    cf_pclose(prp);

/* Now save the data */

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_procs", CFWORKDIR);
    RawSaveItemList(*procdata, vbuff);

    CopyList(&rootprocs, *procdata);
    CopyList(&otherprocs, *procdata);

    while (DeleteItemNotContaining(&rootprocs, "root"))
    {
    }

    while (DeleteItemContaining(&otherprocs, "root"))
    {
    }

    if (otherprocs)
    {
        PrependItem(&rootprocs, otherprocs->name, NULL);
    }

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_rootprocs", CFWORKDIR);
    RawSaveItemList(rootprocs, vbuff);
    DeleteItemList(rootprocs);

    snprintf(vbuff, CF_MAXVARSIZE, "%s/state/cf_otherprocs", CFWORKDIR);
    RawSaveItemList(otherprocs, vbuff);
    DeleteItemList(otherprocs);

    return true;
}
Exemple #25
0
static void KeepControlPromises(EvalContext *ctx, const Policy *policy, GenericAgentConfig *config)
{
    CFD_MAXPROCESSES = 30;
    MAXTRIES = 5;
    DENYBADCLOCKS = true;
    CFRUNCOMMAND[0] = '\0';
    SetChecksumUpdatesDefault(ctx, true);

    /* Keep promised agent behaviour - control bodies */

    Banner("Server control promises..");

    PolicyResolve(ctx, policy, config);

    /* Now expand */

    Seq *constraints = ControlBodyConstraints(policy, AGENT_TYPE_SERVER);
    if (constraints)
    {
        for (size_t i = 0; i < SeqLength(constraints); i++)
        {
            Constraint *cp = SeqAt(constraints, i);
#define IsControlBody(e) (strcmp(cp->lval, CFS_CONTROLBODY[e].lval) == 0)

            if (!IsDefinedClass(ctx, cp->classes))
            {
                continue;
            }

            VarRef *ref = VarRefParseFromScope(cp->lval, "control_server");
            const void *value = EvalContextVariableGet(ctx, ref, NULL);
            VarRefDestroy(ref);

            if (!value)
            {
                Log(LOG_LEVEL_ERR,
                    "Unknown lval '%s' in server control body",
                    cp->lval);
            }
            else if (IsControlBody(SERVER_CONTROL_SERVER_FACILITY))
            {
                SetFacility(value);
            }
            else if (IsControlBody(SERVER_CONTROL_DENY_BAD_CLOCKS))
            {
                DENYBADCLOCKS = BooleanFromString(value);
                Log(LOG_LEVEL_VERBOSE,
                    "Setting denybadclocks to '%s'",
                    DENYBADCLOCKS ? "true" : "false");
            }
            else if (IsControlBody(SERVER_CONTROL_LOG_ENCRYPTED_TRANSFERS))
            {
                LOGENCRYPT = BooleanFromString(value);
                Log(LOG_LEVEL_VERBOSE,
                    "Setting logencrypt to '%s'",
                    LOGENCRYPT ? "true" : "false");
            }
            else if (IsControlBody(SERVER_CONTROL_LOG_ALL_CONNECTIONS))
            {
                SV.logconns = BooleanFromString(value);
                Log(LOG_LEVEL_VERBOSE, "Setting logconns to %d", SV.logconns);
            }
            else if (IsControlBody(SERVER_CONTROL_MAX_CONNECTIONS))
            {
                CFD_MAXPROCESSES = (int) IntFromString(value);
                MAXTRIES = CFD_MAXPROCESSES / 3;
                Log(LOG_LEVEL_VERBOSE,
                    "Setting maxconnections to %d",
                    CFD_MAXPROCESSES);
                /* The handling of max_readers in LMDB is not ideal, but
                 * here is how it is right now: We know that both cf-serverd and
                 * cf-hub will access the lastseen database. Worst case every
                 * single thread and process will do it at the same time, and
                 * this has in fact been observed. So we add the maximum of
                 * those two values together to provide a safe ceiling. In
                 * addition, cf-agent can access the database occasionally as
                 * well, so add a few extra for that too. */
                DBSetMaximumConcurrentTransactions(CFD_MAXPROCESSES
                                                   + EnterpriseGetMaxCfHubProcesses() + 10);
                continue;
            }
            else if (IsControlBody(SERVER_CONTROL_CALL_COLLECT_INTERVAL))
            {
                COLLECT_INTERVAL = (int) 60 * IntFromString(value);
                Log(LOG_LEVEL_VERBOSE,
                    "Setting call_collect_interval to %d (seconds)",
                    COLLECT_INTERVAL);
            }
            else if (IsControlBody(SERVER_CONTROL_LISTEN))
            {
                SERVER_LISTEN = BooleanFromString(value);
                Log(LOG_LEVEL_VERBOSE,
                    "Setting server listen to '%s' ",
                    SERVER_LISTEN ? "true" : "false");
            }
            else if (IsControlBody(SERVER_CONTROL_CALL_COLLECT_WINDOW))
            {
                COLLECT_WINDOW = (int) IntFromString(value);
                Log(LOG_LEVEL_VERBOSE,
                    "Setting collect_window to %d (seconds)",
                    COLLECT_INTERVAL);
            }
            else if (IsControlBody(SERVER_CONTROL_CF_RUN_COMMAND))
            {
                strlcpy(CFRUNCOMMAND, value, sizeof(CFRUNCOMMAND));
                Log(LOG_LEVEL_VERBOSE,
                    "Setting cfruncommand to '%s'",
                    CFRUNCOMMAND);
            }
            else if (IsControlBody(SERVER_CONTROL_ALLOW_CONNECTS))
            {
                Log(LOG_LEVEL_VERBOSE, "Setting allowing connections from ...");

                for (const Rlist *rp = value; rp != NULL; rp = rp->next)
                {
                    if (!IsItemIn(SV.nonattackerlist, RlistScalarValue(rp)))
                    {
                        PrependItem(&SV.nonattackerlist, RlistScalarValue(rp), cp->classes);
                    }
                }
            }
            else if (IsControlBody(SERVER_CONTROL_DENY_CONNECTS))
            {
                Log(LOG_LEVEL_VERBOSE, "Setting denying connections from ...");

                for (const Rlist *rp = value; rp != NULL; rp = rp->next)
                {
                    if (!IsItemIn(SV.attackerlist, RlistScalarValue(rp)))
                    {
                        PrependItem(&SV.attackerlist, RlistScalarValue(rp), cp->classes);
                    }
                }
            }
            else if (IsControlBody(SERVER_CONTROL_SKIP_VERIFY))
            {
                /* Skip. */
            }
            else if (IsControlBody(SERVER_CONTROL_ALLOW_ALL_CONNECTS))
            {
                Log(LOG_LEVEL_VERBOSE, "Setting allowing multiple connections from ...");

                for (const Rlist *rp = value; rp != NULL; rp = rp->next)
                {
                    if (!IsItemIn(SV.multiconnlist, RlistScalarValue(rp)))
                    {
                        PrependItem(&SV.multiconnlist, RlistScalarValue(rp), cp->classes);
                    }
                }
            }
            else if (IsControlBody(SERVER_CONTROL_ALLOW_USERS))
            {
                Log(LOG_LEVEL_VERBOSE, "SET Allowing users ...");

                for (const Rlist *rp = value; rp != NULL; rp = rp->next)
                {
                    if (!IsItemIn(SV.allowuserlist, RlistScalarValue(rp)))
                    {
                        PrependItem(&SV.allowuserlist, RlistScalarValue(rp), cp->classes);
                    }
                }
            }
            else if (IsControlBody(SERVER_CONTROL_TRUST_KEYS_FROM))
            {
                Log(LOG_LEVEL_VERBOSE, "Setting trust keys from ...");

                for (const Rlist *rp = value; rp != NULL; rp = rp->next)
                {
                    if (!IsItemIn(SV.trustkeylist, RlistScalarValue(rp)))
                    {
                        PrependItem(&SV.trustkeylist, RlistScalarValue(rp), cp->classes);
                    }
                }
            }
            else if (IsControlBody(SERVER_CONTROL_ALLOWLEGACYCONNECTS))
            {
                Log(LOG_LEVEL_VERBOSE, "Setting allowing legacy connections from ...");

                for (const Rlist *rp = value; rp != NULL; rp = rp->next)
                {
                    if (!IsItemIn(SV.allowlegacyconnects, RlistScalarValue(rp)))
                    {
                        PrependItem(&SV.allowlegacyconnects, RlistScalarValue(rp), cp->classes);
                    }
                }
            }
            else if (IsControlBody(SERVER_CONTROL_PORT_NUMBER))
            {
                CFENGINE_PORT = IntFromString(value);
                strlcpy(CFENGINE_PORT_STR, value, sizeof(CFENGINE_PORT_STR));
                Log(LOG_LEVEL_VERBOSE, "Setting default port number to %d",
                    CFENGINE_PORT);
            }
            else if (IsControlBody(SERVER_CONTROL_BIND_TO_INTERFACE))
            {
                strlcpy(BINDINTERFACE, value, sizeof(BINDINTERFACE));
                Log(LOG_LEVEL_VERBOSE, "Setting bindtointerface to '%s'", BINDINTERFACE);
            }
            else if (IsControlBody(SERVER_CONTROL_ALLOWCIPHERS))
            {

                SV.allowciphers = xstrdup(value);
                Log(LOG_LEVEL_VERBOSE, "Setting allowciphers to '%s'", SV.allowciphers);
            }
#undef IsControlBody
        }
    }

    const void *value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_SYSLOG_HOST);
    if (value)
    {
        /* Don't resolve syslog_host now, better do it per log request. */
        if (!SetSyslogHost(value))
        {
            Log(LOG_LEVEL_ERR, "Failed to set syslog_host, '%s' too long", (const char *)value);
        }
        else
        {
            Log(LOG_LEVEL_VERBOSE, "Setting syslog_host to '%s'", (const char *)value);
        }
    }

    value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_SYSLOG_PORT);
    if (value)
    {
        SetSyslogPort(IntFromString(value));
    }

    value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_FIPS_MODE);
    if (value)
    {
        FIPS_MODE = BooleanFromString(value);
        Log(LOG_LEVEL_VERBOSE, "Setting FIPS mode to to '%s'", FIPS_MODE ? "true" : "false");
    }

    value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_LASTSEEN_EXPIRE_AFTER);
    if (value)
    {
        LASTSEENEXPIREAFTER = IntFromString(value) * 60;
    }

    value = EvalContextVariableControlCommonGet(ctx, COMMON_CONTROL_BWLIMIT);
    if (value)
    {
        double bval;
        if (DoubleFromString(value, &bval))
        {
            bwlimit_kbytes = (uint32_t) ( bval / 1000.0);
            Log(LOG_LEVEL_VERBOSE, "Setting rate limit to %d kBytes/sec", bwlimit_kbytes);
        }
    }

}
Exemple #26
0
static bool GetSysUsers( int *userListSz, int *numRootProcs, int *numOtherProcs)
{
    FILE *fp;
    char user[CF_BUFSIZE];
    char vbuff[CF_BUFSIZE];
    char cbuff[CF_BUFSIZE];

    /*
     * The best would be to ask only "user" field from ps, but we are asking
     * for "user,pid". The reason is that we try to mimic cf-monitord's
     * behaviour, else a different number of users might be detected by the
     * test, as printing "user,pid" truncates the user column.  TODO fix the
     * ps command to use only "-o user" in both mon_processes.c and this test.
     */
#if defined(__sun)
    xsnprintf(cbuff, CF_BUFSIZE, "/bin/ps -eo user,pid > %s/users.txt", CFWORKDIR);
#elif defined(_AIX)
    xsnprintf(cbuff, CF_BUFSIZE, "/bin/ps -N -eo user,pid > %s/users.txt", CFWORKDIR);
#elif defined(__hpux)
    xsnprintf(cbuff, CF_BUFSIZE, "UNIX95=1  /bin/ps -eo user,pid > %s/users.txt", CFWORKDIR);
    /* SKIP on HP-UX since cf-monitord doesn't count processes correctly! */
    return false;
#else
    xsnprintf(cbuff, CF_BUFSIZE, "ps -eo user:30,pid > %s/users.txt", CFWORKDIR);
#endif

    Item *userList = NULL;
    system(cbuff);
    xsnprintf(cbuff, CF_BUFSIZE, "%s/users.txt", CFWORKDIR);
    if ((fp = fopen(cbuff, "r")) == NULL)
    {
        return false;
    }
    while (fgets(vbuff, CF_BUFSIZE, fp) != NULL)
    {
        int ret = sscanf(vbuff, " %s ", user);

        if (ret != 1 ||
            strcmp(user, "") == 0 ||
            strcmp(user, "USER") == 0 ||
            isdigit(user[0]))
        {
            continue;
        }

        if (!IsItemIn(userList, user))
        {
            PrependItem(&userList, user, NULL);
            (*userListSz)++;
        }

        if (strcmp(user, "root") == 0)
        {
            (*numRootProcs)++;
        }
        else
        {
            (*numOtherProcs)++;
        }
    }
    fclose(fp);

    if (LogGetGlobalLevel() >= LOG_LEVEL_DEBUG)
    {
        char *s = ItemList2CSV(userList);
        Log(LOG_LEVEL_DEBUG, "Users in the process table detected from the test: (%s)", s);
        free(s);
    }
    DeleteItemList(userList);
    return true;
}
Exemple #27
0
/**
 * @brief check whether the lastseen DB is coherent or not
 * 
 * A DB is coherent mainly if all the entries are valid and if there is
 * a strict one-to-one correspondance between hosts and key digests
 * (whether in MD5 or SHA1 format).
 *
 * @retval true if the lastseen DB is coherent, false otherwise
 */
bool IsLastSeenCoherent(void)
{
    DBHandle *db;
    DBCursor *cursor;
    bool res = true;

    if (!OpenDB(&db, dbid_lastseen))
    {
        Log(LOG_LEVEL_ERR, "Unable to open lastseen database");
        return false;
    }

    if (!NewDBCursor(db, &cursor))
    {
        Log(LOG_LEVEL_ERR, "Unable to create lastseen database cursor");
        CloseDB(db);
        return false;
    }

    char *key;
    void *value;
    int ksize, vsize;

    Item *qkeys=NULL;
    Item *akeys=NULL;
    Item *kkeys=NULL;
    Item *ahosts=NULL;
    Item *khosts=NULL;

    char val[CF_BUFSIZE];
    while (NextDB(cursor, &key, &ksize, &value, &vsize))
    {
        if (key[0] != 'k' && key[0] != 'q' && key[0] != 'a' )
        {
            continue;
        }

        if (key[0] == 'q' )
        {
            if (strncmp(key,"qiSHA=",5)==0 || strncmp(key,"qoSHA=",5)==0 ||
                strncmp(key,"qiMD5=",5)==0 || strncmp(key,"qoMD5=",5)==0)
            {
                if (IsItemIn(qkeys, key+2)==false)
                {
                    PrependItem(&qkeys, key+2, NULL);
                }
            }
        }

        if (key[0] == 'k' )
        {
            if (strncmp(key, "kSHA=", 4)==0 || strncmp(key, "kMD5=", 4)==0)
            {
                if (IsItemIn(kkeys, key+1)==false)
                {
                    PrependItem(&kkeys, key+1, NULL);
                }
                if (ReadDB(db, key, &val, vsize))
                {
                    if (IsItemIn(khosts, val)==false)
                    {
                        PrependItem(&khosts, val, NULL);
                    }
                }
            }
        }

        if (key[0] == 'a' )
        {
            if (IsItemIn(ahosts, key+1)==false)
            {
                PrependItem(&ahosts, key+1, NULL);
            }
            if (ReadDB(db, key, &val, vsize))
            {
                if (IsItemIn(akeys, val)==false)
                {
                    PrependItem(&akeys, val, NULL);
                }
            }
        }
    }

    DeleteDBCursor(cursor);
    CloseDB(db);

    if (ListsCompare(ahosts, khosts) == false)
    {
        res = false;
        goto clean;
    }
    if (ListsCompare(akeys, kkeys) == false)
    {
        res = false;
        goto clean;
    }

clean:
    DeleteItemList(qkeys);
    DeleteItemList(akeys);
    DeleteItemList(kkeys);
    DeleteItemList(ahosts);
    DeleteItemList(khosts);

    return res;
}
void KeepFileAccessPromise(EvalContext *ctx, const Promise *pp)
{
    Rlist *rp;
    Auth *ap, *dp;

    if (strlen(pp->promiser) != 1)
    {
        DeleteSlash(pp->promiser);
    }

    if (!GetAuthPath(pp->promiser, SV.admit))
    {
        InstallServerAuthPath(pp->promiser, &SV.admit, &SV.admittop);
    }

    if (!GetAuthPath(pp->promiser, SV.deny))
    {
        InstallServerAuthPath(pp->promiser, &SV.deny, &SV.denytop);
    }

    ap = GetAuthPath(pp->promiser, SV.admit);
    dp = GetAuthPath(pp->promiser, SV.deny);

    for (size_t i = 0; i < SeqLength(pp->conlist); i++)
    {
        Constraint *cp = SeqAt(pp->conlist, i);

        if (!IsDefinedClass(ctx, cp->classes, PromiseGetNamespace(pp)))
        {
            continue;
        }

        switch (cp->rval.type)
        {
        case RVAL_TYPE_SCALAR:

            if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ENCRYPTED].lval) == 0)
            {
                ap->encrypt = true;
            }

            break;

        case RVAL_TYPE_LIST:

            for (rp = (Rlist *) cp->rval.item; rp != NULL; rp = rp->next)
            {
                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_ADMIT].lval) == 0)
                {
                    PrependItem(&(ap->accesslist), RlistScalarValue(rp), NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_DENY].lval) == 0)
                {
                    PrependItem(&(dp->accesslist), RlistScalarValue(rp), NULL);
                    continue;
                }

                if (strcmp(cp->lval, CF_REMACCESS_BODIES[REMOTE_ACCESS_MAPROOT].lval) == 0)
                {
                    PrependItem(&(ap->maproot), RlistScalarValue(rp), NULL);
                    continue;
                }
            }
            break;

        default:
            UnexpectedError("Unknown constraint type!");
            break;
        }
    }
}
Exemple #29
0
int LoadProcessTable()
{
    FILE *prp;
    char pscomm[CF_MAXLINKSIZE];
    Item *rootprocs = NULL;
    Item *otherprocs = NULL;


    if (PROCESSTABLE)
    {
        Log(LOG_LEVEL_VERBOSE, "Reusing cached process table");
        return true;
    }

    LoadPlatformExtraTable();

    CheckPsLineLimitations();

    const char *psopts = GetProcessOptions();

    snprintf(pscomm, CF_MAXLINKSIZE, "%s %s", VPSCOMM[VPSHARDCLASS], psopts);

    Log(LOG_LEVEL_VERBOSE, "Observe process table with %s", pscomm);

    if ((prp = cf_popen(pscomm, "r", false)) == NULL)
    {
        Log(LOG_LEVEL_ERR, "Couldn't open the process list with command '%s'. (popen: %s)", pscomm, GetErrorStr());
        return false;
    }

    size_t vbuff_size = CF_BUFSIZE;
    char *vbuff = xmalloc(vbuff_size);

# ifdef HAVE_GETZONEID

    char *names[CF_PROCCOLS];
    int start[CF_PROCCOLS];
    int end[CF_PROCCOLS];
    Seq *pidlist = SeqNew(1, NULL);
    Seq *rootpidlist = SeqNew(1, NULL);
    bool global_zone = IsGlobalZone();

    if (global_zone)
    {
        int res = ZLoadProcesstable(pidlist, rootpidlist);

        if (res == false)
        {
            Log(LOG_LEVEL_ERR, "Unable to load solaris zone process table.");
            return false;
        }
    }

# endif

    ARG_UNUSED bool header = true;           /* used only if HAVE_GETZONEID */

    for (;;)
    {
        ssize_t res = CfReadLine(&vbuff, &vbuff_size, prp);
        if (res == -1)
        {
            if (!feof(prp))
            {
                Log(LOG_LEVEL_ERR, "Unable to read process list with command '%s'. (fread: %s)", pscomm, GetErrorStr());
                cf_pclose(prp);
                free(vbuff);
                return false;
            }
            else
            {
                break;
            }
        }
        Chop(vbuff, vbuff_size);

# ifdef HAVE_GETZONEID

        if (global_zone)
        {
            if (header)
            {   /* this is the banner so get the column header names for later use*/
                GetProcessColumnNames(vbuff, &names[0], start, end);
            }
            else
            {
               int gpid = ExtractPid(vbuff, names, end);

               if (!IsGlobalProcess(gpid, pidlist, rootpidlist))
               {
                    continue;
               }
            }
        }

# endif
        AppendItem(&PROCESSTABLE, vbuff, "");

        header = false;
    }

    cf_pclose(prp);

/* Now save the data */
    const char* const statedir = GetStateDir();

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_procs", statedir, FILE_SEPARATOR);
    RawSaveItemList(PROCESSTABLE, vbuff, NewLineMode_Unix);

# ifdef HAVE_GETZONEID
    if (global_zone) /* pidlist and rootpidlist are empty if we're not in the global zone */
    {
        Item *ip = PROCESSTABLE;
        while (ip != NULL)
        {
            ZCopyProcessList(&rootprocs, ip, rootpidlist, names, end);
            ip = ip->next;
        }
        ReverseItemList(rootprocs);
        ip = PROCESSTABLE;
        while (ip != NULL)
        {
            ZCopyProcessList(&otherprocs, ip, pidlist, names, end);
            ip = ip->next;
        }
        ReverseItemList(otherprocs);
    }
    else
# endif
    {
        CopyList(&rootprocs, PROCESSTABLE);
        CopyList(&otherprocs, PROCESSTABLE);

        while (DeleteItemNotContaining(&rootprocs, "root"))
        {
        }

        while (DeleteItemContaining(&otherprocs, "root"))
        {
        }
    }
    if (otherprocs)
    {
        PrependItem(&rootprocs, otherprocs->name, NULL);
    }

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_rootprocs", statedir, FILE_SEPARATOR);
    RawSaveItemList(rootprocs, vbuff, NewLineMode_Unix);
    DeleteItemList(rootprocs);

    snprintf(vbuff, CF_MAXVARSIZE, "%s%ccf_otherprocs", statedir, FILE_SEPARATOR);
    RawSaveItemList(otherprocs, vbuff, NewLineMode_Unix);
    DeleteItemList(otherprocs);

    free(vbuff);
    return true;
}
Exemple #30
0
CfLock AcquireLock(char *operand, char *host, time_t now, Attributes attr, Promise *pp, int ignoreProcesses)
{
    unsigned int pid;
    int i, err, sum = 0;
    time_t lastcompleted = 0, elapsedtime;
    char *promise, cc_operator[CF_BUFSIZE], cc_operand[CF_BUFSIZE];
    char cflock[CF_BUFSIZE], cflast[CF_BUFSIZE], cflog[CF_BUFSIZE];
    char str_digest[CF_BUFSIZE];
    CfLock this;
    unsigned char digest[EVP_MAX_MD_SIZE + 1];

    this.last = (char *) CF_UNDEFINED;
    this.lock = (char *) CF_UNDEFINED;
    this.log = (char *) CF_UNDEFINED;

    if (now == 0)
    {
        return this;
    }

    this.last = NULL;
    this.lock = NULL;
    this.log = NULL;

/* Indicate as done if we tried ... as we have passed all class
   constraints now but we should only do this for level 0
   promises. Sub routine bundles cannot be marked as done or it will
   disallow iteration over bundles */

    if (pp->done)
    {
        return this;
    }

    if (CF_STCKFRAME == 1)
    {
        *(pp->donep) = true;
        /* Must not set pp->done = true for editfiles etc */
    }

    HashPromise(operand, pp, digest, CF_DEFAULT_DIGEST);
    strcpy(str_digest, HashPrint(CF_DEFAULT_DIGEST, digest));

/* As a backup to "done" we need something immune to re-use */

    if (THIS_AGENT_TYPE == cf_agent)
    {
        if (IsItemIn(DONELIST, str_digest))
        {
            CfOut(cf_verbose, "", " -> This promise has already been verified");
            return this;
        }

        PrependItem(&DONELIST, str_digest, NULL);
    }

/* Finally if we're supposed to ignore locks ... do the remaining stuff */

    if (IGNORELOCK)
    {
        this.lock = xstrdup("dummy");
        return this;
    }

    promise = BodyName(pp);
    snprintf(cc_operator, CF_MAXVARSIZE - 1, "%s-%s", promise, host);
    strncpy(cc_operand, operand, CF_BUFSIZE - 1);
    CanonifyNameInPlace(cc_operand);
    RemoveDates(cc_operand);

    free(promise);

    CfDebug("AcquireLock(%s,%s), ExpireAfter=%d, IfElapsed=%d\n", cc_operator, cc_operand, attr.transaction.expireafter,
            attr.transaction.ifelapsed);

    for (i = 0; cc_operator[i] != '\0'; i++)
    {
        sum = (CF_MACROALPHABET * sum + cc_operator[i]) % CF_HASHTABLESIZE;
    }

    for (i = 0; cc_operand[i] != '\0'; i++)
    {
        sum = (CF_MACROALPHABET * sum + cc_operand[i]) % CF_HASHTABLESIZE;
    }

    snprintf(cflog, CF_BUFSIZE, "%s/cf3.%.40s.runlog", CFWORKDIR, host);
    snprintf(cflock, CF_BUFSIZE, "lock.%.100s.%s.%.100s_%d_%s", pp->bundle, cc_operator, cc_operand, sum, str_digest);
    snprintf(cflast, CF_BUFSIZE, "last.%.100s.%s.%.100s_%d_%s", pp->bundle, cc_operator, cc_operand, sum, str_digest);

    CfDebug("LOCK(%s)[%s]\n", pp->bundle, cflock);

// Now see if we can get exclusivity to edit the locks

    CFINITSTARTTIME = time(NULL);

    WaitForCriticalSection();

/* Look for non-existent (old) processes */

    lastcompleted = FindLock(cflast);
    elapsedtime = (time_t) (now - lastcompleted) / 60;

    if (elapsedtime < 0)
    {
        CfOut(cf_verbose, "", " XX Another cf-agent seems to have done this since I started (elapsed=%jd)\n",
              (intmax_t) elapsedtime);
        ReleaseCriticalSection();
        return this;
    }

    if (elapsedtime < attr.transaction.ifelapsed)
    {
        CfOut(cf_verbose, "", " XX Nothing promised here [%.40s] (%jd/%u minutes elapsed)\n", cflast,
              (intmax_t) elapsedtime, attr.transaction.ifelapsed);
        ReleaseCriticalSection();
        return this;
    }

/* Look for existing (current) processes */

    if (!ignoreProcesses)
    {
        lastcompleted = FindLock(cflock);
        elapsedtime = (time_t) (now - lastcompleted) / 60;

        if (lastcompleted != 0)
        {
            if (elapsedtime >= attr.transaction.expireafter)
            {
                CfOut(cf_inform, "", "Lock %s expired (after %jd/%u minutes)\n", cflock, (intmax_t) elapsedtime,
                      attr.transaction.expireafter);

                pid = FindLockPid(cflock);

                if (pid == -1)
                {
                    CfOut(cf_error, "", "Illegal pid in corrupt lock %s - ignoring lock\n", cflock);
                }
#ifdef MINGW                    // killing processes with e.g. task manager does not allow for termination handling
                else if (!NovaWin_IsProcessRunning(pid))
                {
                    CfOut(cf_verbose, "",
                          "Process with pid %d is not running - ignoring lock (Windows does not support graceful processes termination)\n",
                          pid);
                    LogLockCompletion(cflog, pid, "Lock expired, process not running", cc_operator, cc_operand);
                    unlink(cflock);
                }
#endif /* MINGW */
                else
                {
                    CfOut(cf_verbose, "", "Trying to kill expired process, pid %d\n", pid);

                    err = GracefulTerminate(pid);

                    if (err || errno == ESRCH)
                    {
                        LogLockCompletion(cflog, pid, "Lock expired, process killed", cc_operator, cc_operand);
                        unlink(cflock);
                    }
                    else
                    {
                        ReleaseCriticalSection();
                        FatalError("Unable to kill expired cfagent process %d from lock %s, exiting this time..\n", pid,
                                   cflock);
                    }
                }
            }
            else
            {
                ReleaseCriticalSection();
                CfOut(cf_verbose, "", "Couldn't obtain lock for %s (already running!)\n", cflock);
                return this;
            }
        }

        WriteLock(cflock);
    }

    ReleaseCriticalSection();

    this.lock = xstrdup(cflock);
    this.last = xstrdup(cflast);
    this.log = xstrdup(cflog);

/* Keep this as a global for signal handling */
    strcpy(CFLOCK, cflock);
    strcpy(CFLAST, cflast);
    strcpy(CFLOG, cflog);

    return this;
}