예제 #1
0
static int ServicesSanityChecks(Attributes a, const Promise *pp)
{
    Rlist *dep;

    for (dep = a.service.service_depend; dep != NULL; dep = dep->next)
    {
        if (strcmp(pp->promiser, RlistScalarValue(dep)) == 0)
        {
            Log(LOG_LEVEL_ERR, "Service promiser '%s' has itself as dependency", pp->promiser);
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }
    }

    if (a.service.service_type == NULL)
    {
        Log(LOG_LEVEL_ERR, "Service type for service '%s' is not known", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#ifdef __MINGW32__

    if (strcmp(a.service.service_type, "windows") != 0)
    {
        Log(LOG_LEVEL_ERR, "Service type for promiser '%s' must be 'windows' on this system, but is '%s'",
            pp->promiser, a.service.service_type);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#endif /* __MINGW32__ */

    return true;
}
예제 #2
0
static int UserSanityCheck(Attributes a, Promise *pp)
{
    User *u = &a.users;
    switch (u->policy)
    {
    case USER_STATE_PRESENT:
    case USER_STATE_ABSENT:
    case USER_STATE_LOCKED:
        break;
    default:
        Log(LOG_LEVEL_ERR, "No policy specified for 'users' promise '%s'", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    if ((SafeStringLength(u->password) == 0 && u->password_format != PASSWORD_FORMAT_NONE)
        || (SafeStringLength(u->password) != 0 && u->password_format == PASSWORD_FORMAT_NONE))
    {
        Log(LOG_LEVEL_ERR, "Both 'data' and 'format' must be specified in password body for 'users' promise '%s'", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    return true;
}
예제 #3
0
static int ServicesSanityChecks(Attributes a, const Promise *pp)
{
    Rlist *dep;

    switch (a.service.service_policy)
    {
    case SERVICE_POLICY_START:
        break;

    case SERVICE_POLICY_STOP:
    case SERVICE_POLICY_DISABLE:
    case SERVICE_POLICY_RESTART:
    case SERVICE_POLICY_RELOAD:
        if (strcmp(a.service.service_autostart_policy, "none") != 0)
        {
            Log(LOG_LEVEL_ERR,
                "!! Autostart policy of service promiser '%s' needs to be 'none' when service policy is not 'start', but is '%s'",
                  pp->promiser, a.service.service_autostart_policy);
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }
        break;

    default:
        Log(LOG_LEVEL_ERR, "Invalid service policy for service '%s'", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    for (dep = a.service.service_depend; dep != NULL; dep = dep->next)
    {
        if (strcmp(pp->promiser, RlistScalarValue(dep)) == 0)
        {
            Log(LOG_LEVEL_ERR, "Service promiser '%s' has itself as dependency", pp->promiser);
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }
    }

    if (a.service.service_type == NULL)
    {
        Log(LOG_LEVEL_ERR, "Service type for service '%s' is not known", pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#ifdef __MINGW32__

    if (strcmp(a.service.service_type, "windows") != 0)
    {
        Log(LOG_LEVEL_ERR, "Service type for promiser '%s' must be 'windows' on this system, but is '%s'",
              pp->promiser, a.service.service_type);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#endif /* __MINGW32__ */

    return true;
}
예제 #4
0
static int ValidateRegistryPromiser(char *key, const Promise *pp)
{
    static char *const valid[] = { "HKEY_CLASSES_ROOT", "HKEY_CURRENT_CONFIG",
        "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE", "HKEY_USERS", NULL
    };
    char root_key[CF_MAXVARSIZE];
    char *sp;
    int i;

    /* First remove the root key */

    strlcpy(root_key, key, CF_MAXVARSIZE );
    sp = strchr(root_key, '\\');
    if (sp == NULL)
    {
        Log(LOG_LEVEL_ERR, "Cannot locate '\\' in '%s'", root_key);
        Log(LOG_LEVEL_ERR, "Failed validating registry promiser");
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }
    *sp = '\0';

    for (i = 0; valid[i] != NULL; i++)
    {
        if (strcmp(root_key, valid[i]) == 0)
        {
            return true;
        }
    }

    Log(LOG_LEVEL_ERR, "Non-editable registry prefix '%s'", root_key);
    PromiseRef(LOG_LEVEL_ERR, pp);
    return false;
}
예제 #5
0
static int ServicesSanityChecks(Attributes a, Promise *pp)
{
    Rlist *dep;

    switch (a.service.service_policy)
    {
    case SERVICE_POLICY_START:
        break;

    case SERVICE_POLICY_STOP:
    case SERVICE_POLICY_DISABLE:
        if (strcmp(a.service.service_autostart_policy, "none") != 0)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "",
                  "!! Autostart policy of service promiser \"%s\" needs to be \"none\" when service policy is not \"start\", but is \"%s\"",
                  pp->promiser, a.service.service_autostart_policy);
            PromiseRef(OUTPUT_LEVEL_ERROR, pp);
            return false;
        }
        break;

    default:
        CfOut(OUTPUT_LEVEL_ERROR, "", "!! Invalid service policy for service \"%s\"", pp->promiser);
        PromiseRef(OUTPUT_LEVEL_ERROR, pp);
        return false;
    }

    for (dep = a.service.service_depend; dep != NULL; dep = dep->next)
    {
        if (strcmp(pp->promiser, dep->item) == 0)
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "!! Service promiser \"%s\" has itself as dependency", pp->promiser);
            PromiseRef(OUTPUT_LEVEL_ERROR, pp);
            return false;
        }
    }

    if (a.service.service_type == NULL)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "!! Service type for service \"%s\" is not known", pp->promiser);
        PromiseRef(OUTPUT_LEVEL_ERROR, pp);
        return false;
    }

#ifdef __MINGW32__

    if (strcmp(a.service.service_type, "windows") != 0)
    {
        CfOut(OUTPUT_LEVEL_ERROR, "", "!! Service type for promiser \"%s\" must be \"windows\" on this system, but is \"%s\"",
              pp->promiser, a.service.service_type);
        PromiseRef(OUTPUT_LEVEL_ERROR, pp);
        return false;
    }

#endif /* __MINGW32__ */

    return true;
}
예제 #6
0
static bool DistributeClass(EvalContext *ctx, const Rlist *dist, const Promise *pp)
{
    int total = 0;
    const Rlist *rp;

    for (rp = dist; rp != NULL; rp = rp->next)
    {
        int result = IntFromString(RlistScalarValue(rp));

        if (result < 0)
        {
            Log(LOG_LEVEL_ERR, "Negative integer in class distribution");
            PromiseRef(LOG_LEVEL_ERR, pp);
            return false;
        }

        total += result;
    }

    if (total == 0)
    {
        Log(LOG_LEVEL_ERR, "An empty distribution was specified on RHS");
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    double fluct = drand48() * total;
    assert(0 <= fluct && fluct < total);

    for (rp = dist; rp != NULL; rp = rp->next)
    {
        fluct -= IntFromString(RlistScalarValue(rp));
        if (fluct < 0)
        {
            break;
        }
    }
    assert(rp);

    char buffer[CF_MAXVARSIZE];
    snprintf(buffer, CF_MAXVARSIZE, "%s_%s", pp->promiser, RlistScalarValue(rp));

    if (strcmp(PromiseGetBundle(pp)->type, "common") == 0)
    {
        EvalContextClassPutSoft(ctx, buffer, CONTEXT_SCOPE_NAMESPACE,
                                "source=promise");
    }
    else
    {
        EvalContextClassPutSoft(ctx, buffer, CONTEXT_SCOPE_BUNDLE,
                                "source=promise");
    }

    return true;
}
예제 #7
0
static bool SelectClass(EvalContext *ctx, const Rlist *list, const Promise *pp)
{
    int count = 0;
    for (const Rlist *rp = list; rp != NULL; rp = rp->next)
    {
        count++;
    }

    if (count == 0)
    {
        Log(LOG_LEVEL_ERR, "No classes to select on RHS");
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }
    assert(list);

    char splay[CF_MAXVARSIZE];
    snprintf(splay, CF_MAXVARSIZE, "%s+%s+%ju",
             VFQNAME, VIPADDRESS, (uintmax_t)getuid());
    double hash = (double) StringHash(splay, 0, CF_HASHTABLESIZE);
    assert(hash < CF_HASHTABLESIZE);
    int n = (int) (count * hash / (double) CF_HASHTABLESIZE);
    assert(n < count);

    while (n > 0 && list->next != NULL)
    {
        n--;
        list = list->next;
    }

    EvalContextClassPutSoft(ctx, RlistScalarValue(list),
                            CONTEXT_SCOPE_NAMESPACE, "source=promise");
    return true;
}
예제 #8
0
int CheckPosixLinuxACL(char *file_path, Acl acl, Attributes a, Promise *pp)
{
    cfPS(OUTPUT_LEVEL_ERROR, CF_FAIL, "", pp, a,
         "!! Posix ACLs are not supported on this Linux system - install the Posix acl library");
    PromiseRef(OUTPUT_LEVEL_ERROR, pp);
    return true;
}
예제 #9
0
파일: acl_posix.c 프로젝트: ajlill/core
PromiseResult CheckPosixLinuxACL(EvalContext *ctx, ARG_UNUSED const char *file_path, ARG_UNUSED Acl acl, Attributes a, const Promise *pp)
{
    cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a,
         "Posix ACLs are not supported on this Linux system - install the Posix acl library");
    PromiseRef(LOG_LEVEL_ERR, pp);
    return PROMISE_RESULT_FAIL;
}
예제 #10
0
static int SelectBSDMatch(struct stat *lstatptr,struct Rlist *bsdflags,struct Promise *pp)

{
#if defined HAVE_CHFLAGS
  u_long newflags,plus,minus;
  struct Rlist *rp;

if (!ParseFlagString(bsdflags,&plus,&minus))
   {
   CfOut(cf_error,""," !! Problem validating a BSD flag string");
   PromiseRef(cf_error,pp);
   }

newflags = (lstatptr->st_flags & CHFLAGS_MASK) ;
newflags |= plus;
newflags &= ~minus;

if ((newflags & CHFLAGS_MASK) == (lstatptr->st_flags & CHFLAGS_MASK))    /* file okay */
   {
   return true;
   }
#endif
  
return false;
} 
예제 #11
0
static int ValidateRegistryPromiser(char *key, Attributes a, Promise *pp)
{
    static char *valid[] = { "HKEY_CLASSES_ROOT", "HKEY_CURRENT_CONFIG",
        "HKEY_CURRENT_USER", "HKEY_LOCAL_MACHINE", "HKEY_USERS", NULL
    };
    char root_key[CF_MAXVARSIZE];
    char *sp;
    int i;

    /* First remove the root key */

    strncpy(root_key, key, CF_MAXVARSIZE - 1);
    sp = strchr(root_key, '\\');
    *sp = '\0';

    for (i = 0; valid[i] != NULL; i++)
    {
        if (strcmp(root_key, valid[i]) == 0)
        {
            return true;
        }
    }

    CfOut(cf_error, "", "Non-editable registry prefix \"%s\"", root_key);
    PromiseRef(cf_error, pp);
    return false;
}
예제 #12
0
파일: cf_acl.c 프로젝트: nyetsche/core
static int CheckPermTypeSyntax(char *permt, int deny_support, Promise *pp)
/*
  Checks if the given string corresponds to the perm_type syntax.
  Only "allow" or "deny", followed by NULL-termination are valid.
  In addition, "deny" is only valid for ACL types supporting it.
 */
{
    int valid;

    valid = false;

    if (strcmp(permt, "allow") == 0)
    {
        valid = true;
    }
    else if (strcmp(permt, "deny") == 0)
    {
        if (deny_support)
        {
            valid = true;
        }
        else
        {
            CfOut(cf_error, "", "Deny permission not supported by this ACL type");
            PromiseRef(cf_error, pp);
        }
    }

    return valid;
}
예제 #13
0
static int ProcessSanityChecks(Attributes a, Promise *pp)
{
    int promised_zero, ret = true;

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

    if (a.restart_class)
    {
        if ((RlistIsStringIn(a.signals, "term")) || (RlistIsStringIn(a.signals, "kill")))
        {
            Log(LOG_LEVEL_WARNING, "Promise '%s' kills then restarts - never strictly converges",
                  pp->promiser);
            PromiseRef(LOG_LEVEL_INFO, pp);
        }

        if (a.haveprocess_count)
        {
            Log(LOG_LEVEL_ERR,
                  "process_count and restart_class should not be used in the same promise as this makes no sense");
            PromiseRef(LOG_LEVEL_INFO, pp);
            ret = false;
        }
    }

    if (promised_zero && (a.restart_class))
    {
        Log(LOG_LEVEL_ERR, "Promise constraint conflicts - '%s' processes cannot have zero count if restarted",
              pp->promiser);
        PromiseRef(LOG_LEVEL_ERR, pp);
        ret = false;
    }

    if ((a.haveselect) && (!a.process_select.process_result))
    {
        Log(LOG_LEVEL_ERR, "Process select constraint body promised no result (check body definition)");
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    return ret;
}
예제 #14
0
static int ProcessSanityChecks(Attributes a, Promise *pp)
{
    int promised_zero, ret = true;

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

    if (a.restart_class)
    {
        if (IsStringIn(a.signals, "term") || IsStringIn(a.signals, "kill"))
        {
            CfOut(cf_inform, "", " -> (warning) Promise %s kills then restarts - never strictly converges",
                  pp->promiser);
            PromiseRef(cf_inform, pp);
        }

        if (a.haveprocess_count)
        {
            CfOut(cf_error, "",
                  " !! process_count and restart_class should not be used in the same promise as this makes no sense");
            PromiseRef(cf_inform, pp);
            ret = false;
        }
    }

    if (promised_zero && a.restart_class)
    {
        CfOut(cf_error, "", "Promise constraint conflicts - %s processes cannot have zero count if restarted",
              pp->promiser);
        PromiseRef(cf_error, pp);
        ret = false;
    }

    if (a.haveselect && !a.process_select.process_result)
    {
        CfOut(cf_error, "", " !! Process select constraint body promised no result (check body definition)");
        PromiseRef(cf_error, pp);
        return false;
    }

    return ret;
}
예제 #15
0
int CheckPosixLinuxACL(char *file_path, Acl acl, Attributes a, Promise *pp)
{
    if (!CheckPosixLinuxAccessACEs(acl.acl_entries, acl.acl_method, file_path, a, pp))
    {
        cfPS(OUTPUT_LEVEL_ERROR, CF_FAIL, "", pp, a, " !! Failed checking access ACL on %s", file_path);
        PromiseRef(OUTPUT_LEVEL_ERROR, pp);
        return false;
    }

    if (IsDir(file_path))
    {
        if (!CheckPosixLinuxInheritACEs
            (acl.acl_inherit_entries, acl.acl_method, acl.acl_directory_inherit, file_path, a, pp))
        {
            cfPS(OUTPUT_LEVEL_ERROR, CF_FAIL, "", pp, a, " !! Failed checking inheritance ACL on %s", file_path);
            PromiseRef(OUTPUT_LEVEL_ERROR, pp);
            return false;
        }
    }
    return true;
}
예제 #16
0
static int EnvironmentsSanityChecks(Attributes a, const Promise *pp)
{
    if (a.env.spec)
    {
        if (a.env.cpus != CF_NOINT || a.env.memory != CF_NOINT || a.env.disk != CF_NOINT)
        {
            Log(LOG_LEVEL_ERR, "Conflicting promise of both a spec and cpu/memory/disk resources");
            return false;
        }
    }

    if (a.env.host == NULL)
    {
        Log(LOG_LEVEL_ERR, "No environment_host defined for environment promise");
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

    switch (Str2Hypervisors(a.env.type))
    {
    case cfv_virt_xen_net:
    case cfv_virt_kvm_net:
    case cfv_virt_esx_net:
    case cfv_virt_test_net:
        if (a.env.cpus != CF_NOINT || a.env.memory != CF_NOINT || a.env.disk != CF_NOINT || a.env.name
            || a.env.addresses)
        {
            Log(LOG_LEVEL_ERR, "Network environment promises computational resources (%d,%d,%d,%s)", a.env.cpus,
                  a.env.memory, a.env.disk, a.env.name);
            PromiseRef(LOG_LEVEL_ERR, pp);
        }
        break;
    default:
        break;
    }

    return true;
}
예제 #17
0
파일: acl_posix.c 프로젝트: ajlill/core
PromiseResult CheckPosixLinuxACL(EvalContext *ctx, const char *file_path, Acl acl, Attributes a, const Promise *pp)
{
    PromiseResult result = PROMISE_RESULT_NOOP;

    if (!CheckPosixLinuxAccessACEs(ctx, acl.acl_entries, acl.acl_method, file_path, a, pp, &result))
    {
        cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Failed checking access ACL on %s", file_path);
        PromiseRef(LOG_LEVEL_ERR, pp);
        return PROMISE_RESULT_FAIL;
    }

    if (IsDir(file_path))
    {
        if (!CheckPosixLinuxDefaultACEs(ctx, acl.acl_default_entries, acl.acl_method, acl.acl_default,
                                        file_path, a, pp, &result))
        {
            cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_FAIL, pp, a, "Failed checking default ACL on '%s'", file_path);
            PromiseRef(LOG_LEVEL_ERR, pp);
            return PROMISE_RESULT_FAIL;
        }
    }
    return PROMISE_RESULT_NOOP;
}
예제 #18
0
파일: cf_acl.c 프로젝트: nyetsche/core
void VerifyACL(char *file, Attributes a, Promise *pp)
{
    if (!CheckACLSyntax(file, a.acl, pp))
    {
        cfPS(cf_error, CF_INTERPT, "", pp, a, " !! Syntax error in access control list for \"%s\"", file);
        PromiseRef(cf_error, pp);
        return;
    }

    SetACLDefaults(file, &a.acl);

// decide which ACL API to use
    switch (a.acl.acl_type)
    {
    case cfacl_notype: // fallthrough: acl_type defaults to generic
    case cfacl_generic:

#if defined(__linux__)
        CheckPosixLinuxACL(file, a.acl, a, pp);
#elif defined(__MINGW32__)
        Nova_CheckNtACL(file, a.acl, a, pp);
#else
        CfOut(cf_inform, "", "!! ACLs are not yet supported on this system.");
#endif
        break;

    case cfacl_posix:

#if defined(__linux__)
        CheckPosixLinuxACL(file, a.acl, a, pp);
#else
        CfOut(cf_inform, "", "!! Posix ACLs are not supported on this system");
#endif
        break;

    case cfacl_ntfs:

#if defined(__MINGW32__)
        Nova_CheckNtACL(file, a.acl, a, pp);
#else
        CfOut(cf_inform, "", "!! NTFS ACLs are not supported on this system");
#endif
        break;

    default:
        CfOut(cf_error, "", "!! Unknown ACL type - software error");
        break;
    }
}
예제 #19
0
파일: cf_acl.c 프로젝트: rpoyner/core
void VerifyACL(EvalContext *ctx, char *file, Attributes a, Promise *pp)
{
    if (!CheckACLSyntax(file, a.acl, pp))
    {
        cfPS(ctx, OUTPUT_LEVEL_ERROR, PROMISE_RESULT_INTERRUPTED, "", pp, a, " !! Syntax error in access control list for \"%s\"", file);
        PromiseRef(OUTPUT_LEVEL_ERROR, pp);
        return;
    }

    SetACLDefaults(file, &a.acl);

// decide which ACL API to use
    switch (a.acl.acl_type)
    {
    case ACL_TYPE_NONE: // fallthrough: acl_type defaults to generic
    case ACL_TYPE_GENERIC:

#if defined(__linux__)
        CheckPosixLinuxACL(ctx, file, a.acl, a, pp);
#elif defined(__MINGW32__)
        Nova_CheckNtACL(ctx, file, a.acl, a, pp);
#else
        CfOut(OUTPUT_LEVEL_INFORM, "", "!! ACLs are not yet supported on this system.");
#endif
        break;

    case ACL_TYPE_POSIX:

#if defined(__linux__)
        CheckPosixLinuxACL(ctx, file, a.acl, a, pp);
#else
        CfOut(OUTPUT_LEVEL_INFORM, "", "!! Posix ACLs are not supported on this system");
#endif
        break;

    case ACL_TYPE_NTFS_:

#if defined(__MINGW32__)
        Nova_CheckNtACL(ctx, file, a.acl, a, pp);
#else
        CfOut(OUTPUT_LEVEL_INFORM, "", "!! NTFS ACLs are not supported on this system");
#endif
        break;

    default:
        CfOut(OUTPUT_LEVEL_ERROR, "", "!! Unknown ACL type - software error");
        break;
    }
}
예제 #20
0
static Rlist *NewExpArgs(EvalContext *ctx, const Policy *policy, const FnCall *fp)
{
    {
        const FnCallType *fn = FnCallTypeGet(fp->name);
        int len = RlistLen(fp->args);

        if (!(fn->options & FNCALL_OPTION_VARARG))
        {
            if (len != FnNumArgs(fn))
            {
                Log(LOG_LEVEL_ERR, "Arguments to function '%s' do not tally. Expected %d not %d",
                      fp->name, FnNumArgs(fn), len);
                PromiseRef(LOG_LEVEL_ERR, fp->caller);
                exit(EXIT_FAILURE);
            }
        }
    }

    Rlist *expanded_args = NULL;
    for (const Rlist *rp = fp->args; rp != NULL; rp = rp->next)
    {
        Rval rval;

        switch (rp->val.type)
        {
        case RVAL_TYPE_FNCALL:
            {
                FnCall *subfp = RlistFnCallValue(rp);
                rval = FnCallEvaluate(ctx, policy, subfp, fp->caller).rval;
                assert(rval.item);
            }
            break;
        default:
            rval = ExpandPrivateRval(ctx, NULL, NULL, rp->val.item, rp->val.type);
            assert(rval.item);
            break;
        }

        RlistAppend(&expanded_args, rval.item, rval.type);
        RvalDestroy(rval);
    }

    return expanded_args;
}
예제 #21
0
파일: cf-know.c 프로젝트: dnaeon/core
static void VerifyOccurrenceGroup(char *file, Promise *pp)
{
    Attributes a = { {0} };
    struct stat sb;
    char *sp, url[CF_BUFSIZE];
    Rval retval;

    a = GetOccurrenceAttributes(pp);

    if (cfstat(file, &sb) == -1)
    {
        CfOut(cf_verbose, "", " !! File %s matched but could not be read", file);
        return;
    }

    if (a.path_root == NULL || a.web_root == NULL)
    {
        CfOut(cf_error, "", " !! No pathroot/webroot defined in representation");
        PromiseRef(cf_error, pp);
        return;
    }

    Chop(a.path_root);
    DeleteSlash(a.path_root);
    sp = file + strlen(a.path_root) + 1;

    FullTextMatch(pp->promiser, sp);
    retval = ExpandPrivateRval("this", (Rval) {a.represents, CF_LIST});
    DeleteScope("match");

    if (strlen(a.web_root) > 0)
    {
        snprintf(url, CF_BUFSIZE - 1, "%s/%s", a.web_root, sp);
    }
    else
    {
        snprintf(url, CF_BUFSIZE - 1, "%s", sp);
    }

    AddOccurrence(&OCCURRENCES, url, retval.item, cfk_url, pp->classes);
    CfOut(cf_verbose, "", " -> File %s matched and being logged at %s", file, url);

    DeleteRlist((Rlist *) retval.item);
}
예제 #22
0
파일: files_links.c 프로젝트: baptr/core
PromiseResult VerifyAbsoluteLink(EvalContext *ctx, char *destination, const char *source, Attributes attr, const Promise *pp)
{
    char absto[CF_BUFSIZE];
    char expand[CF_BUFSIZE];
    char linkto[CF_BUFSIZE];

    if (*source == '.')
    {
        strcpy(linkto, destination);
        ChopLastNode(linkto);
        AddSlash(linkto);
        strcat(linkto, source);
    }
    else
    {
        strcpy(linkto, source);
    }

    CompressPath(absto, linkto);

    expand[0] = '\0';

    if (attr.link.when_no_file == cfa_force)
    {
        if (!ExpandLinks(expand, absto, 0))     /* begin at level 1 and beam out at 15 */
        {
            Log(LOG_LEVEL_ERR, "Failed to make absolute link in");
            PromiseRef(LOG_LEVEL_ERR, pp);
            return PROMISE_RESULT_FAIL;
        }
        else
        {
            Log(LOG_LEVEL_DEBUG, "ExpandLinks returned '%s'", expand);
        }
    }
    else
    {
        strcpy(expand, absto);
    }

    CompressPath(linkto, expand);

    return VerifyLink(ctx, destination, linkto, attr, pp);
}
예제 #23
0
파일: args.c 프로젝트: shaunamarie/core
Rlist *NewExpArgs(EvalContext *ctx, const FnCall *fp, const Promise *pp)
{
    int len;
    Rval rval;
    Rlist *newargs = NULL;
    FnCall *subfp;
    const FnCallType *fn = FnCallTypeGet(fp->name);

    len = RlistLen(fp->args);

    if (!fn->varargs)
    {
        if (len != FnNumArgs(fn))
        {
            CfOut(OUTPUT_LEVEL_ERROR, "", "Arguments to function %s(.) do not tally. Expect %d not %d",
                  fp->name, FnNumArgs(fn), len);
            PromiseRef(OUTPUT_LEVEL_ERROR, pp);
            exit(1);
        }
    }

    for (const Rlist *rp = fp->args; rp != NULL; rp = rp->next)
    {
        switch (rp->type)
        {
        case RVAL_TYPE_FNCALL:
            subfp = (FnCall *) rp->item;
            rval = FnCallEvaluate(ctx, subfp, pp).rval;
            break;
        default:
            rval = ExpandPrivateRval(ScopeGetCurrent()->scope, (Rval) {rp->item, rp->type});
            break;
        }

        CfDebug("EXPARG: %s.%s\n", ScopeGetCurrent()->scope, (char *) rval.item);
        RlistAppend(&newargs, rval.item, rval.type);
        RvalDestroy(rval);
    }

    return newargs;
}
예제 #24
0
파일: fncall.c 프로젝트: cduclos/core
static Rlist *NewExpArgs(EvalContext *ctx, const FnCall *fp)
{
    int len;
    Rval rval;
    Rlist *newargs = NULL;
    FnCall *subfp;
    const FnCallType *fn = FnCallTypeGet(fp->name);

    len = RlistLen(fp->args);

    if (!(fn->options & FNCALL_OPTION_VARARG))
    {
        if (len != FnNumArgs(fn))
        {
            Log(LOG_LEVEL_ERR, "Arguments to function '%s' do not tally. Expected %d not %d",
                  fp->name, FnNumArgs(fn), len);
            PromiseRef(LOG_LEVEL_ERR, fp->caller);
            exit(1);
        }
    }

    for (const Rlist *rp = fp->args; rp != NULL; rp = rp->next)
    {
        switch (rp->val.type)
        {
        case RVAL_TYPE_FNCALL:
            subfp = RlistFnCallValue(rp);
            rval = FnCallEvaluate(ctx, subfp, fp->caller).rval;
            assert(rval.item);
            break;
        default:
            rval = ExpandPrivateRval(ctx, NULL, NULL, (Rval) { rp->val.item, rp->val.type});
            assert(rval.item);
            break;
        }

        RlistAppendRval(&newargs, rval);
    }

    return newargs;
}
예제 #25
0
파일: args.c 프로젝트: fbettag/core
Rlist *NewExpArgs(const FnCall *fp, const Promise *pp)
{
    int len;
    Rval rval;
    Rlist *newargs = NULL;
    FnCall *subfp;
    const FnCallType *fn = FindFunction(fp->name);

    len = RlistLen(fp->args);

    if (!fn->varargs)
    {
        if (len != FnNumArgs(fn))
        {
            CfOut(cf_error, "", "Arguments to function %s(.) do not tally. Expect %d not %d",
                  fp->name, FnNumArgs(fn), len);
            PromiseRef(cf_error, pp);
            exit(1);
        }
    }

    for (const Rlist *rp = fp->args; rp != NULL; rp = rp->next)
    {
        switch (rp->type)
        {
        case CF_FNCALL:
            subfp = (FnCall *) rp->item;
            rval = EvaluateFunctionCall(subfp, pp).rval;
            break;
        default:
            rval = ExpandPrivateRval(CONTEXTID, (Rval) {rp->item, rp->type});
            break;
        }

        CfDebug("EXPARG: %s.%s\n", CONTEXTID, (char *) rval.item);
        AppendRlist(&newargs, rval.item, rval.rtype);
        DeleteRvalItem(rval);
    }

    return newargs;
}
예제 #26
0
파일: conversion.c 프로젝트: atsaloli/core
gid_t Str2Gid(const char *gidbuff, char *groupcopy, const Promise *pp)
{
    struct group *gr;
    int gid = -2, tmp = -2;

    if (StringIsNumeric(gidbuff))
    {
        sscanf(gidbuff, "%d", &tmp);
        gid = (gid_t) tmp;
    }
    else
    {
        if (strcmp(gidbuff, "*") == 0)
        {
            gid = CF_SAME_GROUP;        /* signals wildcard */
        }
        else if ((gr = getgrnam(gidbuff)) == NULL)
        {
            Log(LOG_LEVEL_INFO, "Unknown group '%s' in promise", gidbuff);

            if (pp)
            {
                PromiseRef(LOG_LEVEL_INFO, pp);
            }

            gid = CF_UNKNOWN_GROUP;
        }
        else
        {
            gid = gr->gr_gid;

            if (groupcopy != NULL)
            {
                strcpy(groupcopy, gidbuff);
            }
        }
    }

    return gid;
}
예제 #27
0
파일: verify_acl.c 프로젝트: JarleB/core
static int CheckAclDefault(char *path, Acl *acl, Promise *pp)
/*
  Checks that acl_default is set to a valid value for this acl type.
  Returns true if so, or false otherwise.
*/
{
    int valid = false;

    switch (acl->acl_default)
    {
    case ACL_DEFAULT_NONE:      // unset is always valid
        valid = true;

        break;

    case ACL_DEFAULT_SPECIFY:        // NOTE: we assume all acls support specify

        // fallthrough
    case ACL_DEFAULT_ACCESS:

        // fallthrough
    default:

        if (IsDir(path))
        {
            valid = true;
        }
        else
        {
            Log(LOG_LEVEL_ERR, "acl_default can only be set on directories.");
            PromiseRef(LOG_LEVEL_ERR, pp);
            valid = false;
        }

        break;
    }

    return valid;
}
예제 #28
0
static bool SyntaxCheckExec(Attributes a, Promise *pp)
{
    if ((a.contain.nooutput) && (a.contain.preview))
    {
        Log(LOG_LEVEL_ERR, "no_output and preview are mutually exclusive (broken promise)");
        PromiseRef(LOG_LEVEL_ERR, pp);
        return false;
    }

#ifdef __MINGW32__
    if (a.contain.umask != (mode_t)CF_UNDEFINED)
    {
        Log(LOG_LEVEL_VERBOSE, "contain.umask is ignored on Windows");
    }

    if (a.contain.owner != CF_UNDEFINED)
    {
        Log(LOG_LEVEL_VERBOSE, "contain.exec_owner is ignored on Windows");
    }

    if (a.contain.group != CF_UNDEFINED)
    {
        Log(LOG_LEVEL_VERBOSE, "contain.exec_group is ignored on Windows");
    }

    if (a.contain.chroot != NULL)
    {
        Log(LOG_LEVEL_VERBOSE, "contain.chroot is ignored on Windows");
    }

#else /* !__MINGW32__ */
    if (a.contain.umask == (mode_t)CF_UNDEFINED)
    {
        a.contain.umask = 077;
    }
#endif /* !__MINGW32__ */

    return true;
}
예제 #29
0
파일: cf_acl.c 프로젝트: nyetsche/core
static int CheckDirectoryInherit(char *path, Acl *acl, Promise *pp)
/*
  Checks that acl_directory_inherit is set to a valid value for this acl type.
  Returns true if so, or false otherwise.
*/
{
    int valid = false;

    switch (acl->acl_directory_inherit)
    {
    case cfacl_noinherit:      // unset is always valid
        valid = true;

        break;

    case cfacl_specify:        // NOTE: we assume all acls support specify

    // fallthrough
    case cfacl_parent:

    // fallthrough
    default:

        if (IsDir(path))
        {
            valid = true;
        }
        else
        {
            CfOut(cf_error, "", "acl_directory_inherit can only be set on directories.");
            PromiseRef(cf_error, pp);
            valid = false;
        }

        break;
    }

    return valid;
}
예제 #30
0
static int ExecSanityChecks(Attributes a, Promise *pp)
{
    if (a.contain.nooutput && a.contain.preview)
    {
        CfOut(cf_error, "", "no_output and preview are mutually exclusive (broken promise)");
        PromiseRef(cf_error, pp);
        return false;
    }

#ifdef MINGW
    if (a.contain.umask != CF_UNDEFINED)        // TODO: Always true (077 != -1?, compare positive and negative number), make false when umask not set
    {
        CfOut(cf_verbose, "", "contain.umask is ignored on Windows");
    }

    if (a.contain.owner != CF_UNDEFINED)
    {
        CfOut(cf_verbose, "", "contain.exec_owner is ignored on Windows");
    }

    if (a.contain.group != CF_UNDEFINED)
    {
        CfOut(cf_verbose, "", "contain.exec_group is ignored on Windows");
    }

    if (a.contain.chroot != NULL)
    {
        CfOut(cf_verbose, "", "contain.chroot is ignored on Windows");
    }

#else /* NOT MINGW */
    if (a.contain.umask == CF_UNDEFINED)
    {
        a.contain.umask = 077;
    }
#endif /* NOT MINGW */

    return true;
}