(file) Return to Macro.c CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Executor

File: [Pegasus] / pegasus / src / Executor / Macro.c (download)
Revision: 1.2, Fri May 25 17:35:07 2007 UTC (17 years, 1 month ago) by kumpf
Branch: MAIN
CVS Tags: TASK-Bug2102Final-root, TASK-Bug2102Final-merged_out_to_branch, TASK-Bug2102Final-merged_out_from_trunk, TASK-Bug2102Final-merged_in_to_trunk, TASK-Bug2102Final-merged_in_from_branch, TASK-Bug2102Final-branch
Changes since 1.1: +347 -0 lines
BUG#: 6037
TITLE: PEP 286 Privilege Separation
DESCRIPTION: Implement privilege separation for the CIM Server.  This allows the CIM Server to run without privilege, using a separate small process to perform privileged operations as necessary.

/*
//%2006////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
// Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
// Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
// IBM Corp.; EMC Corporation, The Open Group.
// Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
// IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
// Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
// EMC Corporation; VERITAS Software Corporation; The Open Group.
// Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
// EMC Corporation; Symantec Corporation; The Open Group.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
// ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
// "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//%/////////////////////////////////////////////////////////////////////////////
*/

#include <string.h>
#include "Defines.h"
#include "Macro.h"
#include "Strlcpy.h"
#include "Strlcat.h"
#include "Log.h"
#include "Config.h"
#include "Globals.h"
#include "Path.h"
#include <assert.h>

/*
**==============================================================================
**
** Macro
**
**     This structure defines a macro (a name-value pair).
**
**==============================================================================
*/

struct Macro
{
    char* name;
    char* value;
    struct Macro* next;
};

/*
**==============================================================================
**
** _macros
**
**     The list of process macros.
**
**==============================================================================
*/

static struct Macro* _macros = 0;

/*
**==============================================================================
**
** FindMacro()
**
**     Find the value of the named macro. Return pointer to value or NULL if
**     not found.
**
**==============================================================================
*/

const char* FindMacro(const char* name)
{
    const struct Macro* p;

    for (p = _macros; p; p = p->next)
    {
        if (strcmp(p->name, name) == 0)
            return p->value;
    }

    /* Not found. */
    return NULL;
}

/*
**==============================================================================
**
** DefineMacro()
**
**     Add a new macro to the macro list.
**
**==============================================================================
*/

int DefineMacro(const char* name, const char* value)
{
    struct Macro* macro;

    /* Reject if the macro is already defined. */

    if (FindMacro(name) != NULL)
        return -1;

    /* Create new macro. */

    macro = (struct Macro*)malloc(sizeof(struct Macro));
    macro->name = strdup(name);
    macro->value = strdup(value);

    /* Add to end of list. */

    {
        struct Macro* p;
        struct Macro* prev = NULL;

        for (p = _macros; p; p = p->next)
            prev = p;

        if (prev)
            prev->next = macro;
        else
            _macros = macro;

        macro->next = NULL;
    }

    return 0;
}

/*
**==============================================================================
**
** UndefineMacro()
**
**     Remove the given macro from the macro table.
**
**==============================================================================
*/

int UndefineMacro(const char* name)
{
    struct Macro* p;
    struct Macro* prev;

    for (p = _macros, prev = 0; p; p = p->next)
    {
        if (strcmp(p->name, name) == 0)
        {
            if (prev)
                prev->next = p->next;
            else
                _macros = p->next;

            free(p->name);
            free(p->value);
            free(p);
            return 0;
        }

        prev = p;
    }

    /* Not found. */
    return -1;
}

/*
**==============================================================================
**
** ExpandMacros()
**
**     Expand all macros in *input*. Leave result in *output*.
**
**==============================================================================
*/

int ExpandMacros(const char* input, char output[EXECUTOR_BUFFER_SIZE])
{
    char buffer[EXECUTOR_BUFFER_SIZE];
    char* p;

    /* Make copy of input since we'll need to destroy it. */

    Strlcpy(buffer, input, sizeof(buffer));
    output[0] = '\0';

    /* Traverse buffer, copying characters and expanding macros as we go. */

    for (p = buffer; *p; )
    {
        /* Look for start of macro. */

        if (p[0] == '$' && p[1] == '{')
        {
            char* q;

            /* Set p and q as follows.
             *
             *       p       q
             *       |       |
             *       v       v
             * "...${MY_MACRO}..."
             */

            p += 2;

            /* Find end of macro. */

            for (q = p; *q && *q != '}'; q++)
                ;

            if (*q != '}')
            {
                Log(LL_SEVERE, "ExpandMacros(): corrupt input: %s", input);
                return -1;
            }

            /* Replace '}' with null-terminator. */

            *q = '\0';

            /* Lookup macro and append value. */

            {
                const char* value;
                value = FindMacro(p);

                if (!value)
                {
                    Log(LL_SEVERE, "ExpandMacros(): Undefined macro: %s", p);
                    return -1;
                }

                Strlcat(output, value, EXECUTOR_BUFFER_SIZE);
            }

            p = q + 1;
        }
        else
        {
            /* Append current character to output. */

            char two[2];
            two[0] = *p++;
            two[1] = '\0';

            Strlcat(output, two, EXECUTOR_BUFFER_SIZE);
        }
    }

    return 0;
}

/*
**==============================================================================
**
** DefineConfigPathMacro()
**
**     Define a new path macro whose value is taken from the given
**     configuration parameter. If no such configuration parameter is defined,
**     use the defaultPath.
**
**==============================================================================
*/

int DefineConfigPathMacro(const char* configParam, const char* defaultPath)
{
    char path[EXECUTOR_BUFFER_SIZE];
    int status;

    status = 0;

    do
    {
        char buffer[EXECUTOR_BUFFER_SIZE];

        /* First try to get value from configuration. */

        if (GetConfigParam(configParam, buffer) == 0)
        {
            if (buffer[0] == '/')
            {
                Strlcpy(path, buffer, sizeof(path));
                break;
            }
            else if (GetHomedPath(buffer, buffer) == 0)
            {
                Strlcpy(path, buffer, sizeof(path));
                break;
            }
        }

        /* Just use the default value. */

        if (GetHomedPath(defaultPath, buffer) == 0)
        {
            Strlcpy(path, buffer, sizeof(path));
            break;
        }

        /* Failed. */

        status = -1;
    }
    while (0);

    if (status == 0)
        DefineMacro(configParam, path);

    return status;
}

/*
**==============================================================================
**
** DumpMacros()
**
**     Dump all macros to standard output.
**
**==============================================================================
*/

void DumpMacros()
{
    const struct Macro* p;

    printf("===== Macros:\n");

    for (p = _macros; p; p = p->next)
        printf("%s=%s\n", p->name, p->value);

    putchar('\n');
}

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2