def delete_profiles(profs, dbo, table):
    ''' deletes all database entries matching user's command line options
    Args:
        profs - list of profiles to delete by name
        dbo - database object
        table - database table name
    Returns: True if any errors encountered, False otherwise
    Exceptions: none
    '''
    # if any serious errors encountered, set exit status
    has_errors = False
    queue = dbo.getQueue()
    # Build a list of criteria for WHERE clause
    db_cols = [u'rowid'] + [u'file']
    # loop through all profiles from command line and delete them
    for profile_name in profs:
        query_str = "SELECT " + ", ".join(db_cols) + " FROM " + table + \
                " WHERE name=" + AIdb.format_value('name', profile_name)
        logging.debug("query=" + query_str)
        query = AIdb.DBrequest(query_str, commit=True)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        rsp = query.getResponse()
        if rsp is None:
            has_errors = True
            continue
        if len(rsp) == 0:
            print >> sys.stderr, _("\tProfile %s not found.") % profile_name
            has_errors = True
            continue
        # delete database record and any accompanying internal profile file
        for response in rsp:
            deldict = dict()
            iresponse = iter(response)
            for crit in db_cols:
                deldict[crit] = next(iresponse)
            query_str = "DELETE FROM %s WHERE rowid=%d" % \
                    (table, deldict['rowid'])
            delquery = AIdb.DBrequest(query_str, commit=True)
            queue.put(delquery)
            delquery.waitAns()
            # check response, if failure, getResponse prints error
            if delquery.getResponse() is None:
                has_errors = True
                continue
            print >> sys.stderr, _("\tDeleted profile %s.") % profile_name
            # delete static (internal) files only
            if deldict['file'] is None or \
                not deldict['file'].startswith(sc.INTERNAL_PROFILE_DIRECTORY):
                continue
            try:
                os.unlink(deldict['file'])
            except OSError, (errno, errmsg):
                if errno != ENOENT:  # does not exist
                    print >> sys.stderr, _(
                            "Error (%s):  Problem deleting %s (%s): %s") \
                            % (errno, profile_name, deldict['file'], errmsg)
                has_errors = True
                continue
Exemplo n.º 2
0
def validate_internal(profile_list, database, table, image_dir):
    ''' given a list of profile files and the profile database and table,
        validate the list of profiles
    Args:
        profile_list - list of profile path names
        database - name of database
        table - name of database table
        image_dir - path of service image, used to locate service_bundle
    Returns True if all profiles are valid, return False if any are invalid
    '''
    # Open the database
    dbn = AIdb.DB(database, commit=True)
    dbn.verifyDBStructure()
    isvalid = True
    queue = dbn.getQueue()
    if not profile_list:
        profile_list = [None]
    for profile in profile_list:
        qstr = "SELECT name, file FROM %s WHERE name = %s" % \
                (table, AIdb.format_value('name', profile))
        query = AIdb.DBrequest(qstr, commit=True)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        if query.getResponse() is None:  # database error
            return False  # give up
        if len(query.getResponse()) == 0:
            print >> sys.stderr, \
                    _('No profiles in database with basename ') + profile
            isvalid = False
            continue  # to the next profile
        for response in query.getResponse():
            if not df.validate_file(response[0], response[1], image_dir):
                isvalid = False
    return isvalid
def delete_profiles(profs, dbo, table):
    ''' deletes all database entries matching user's command line options
    Args:
        profs - list of profiles to delete by name
        dbo - database object
        table - database table name
    Returns: True if any errors encountered, False otherwise
    Exceptions: none
    '''
    # if any serious errors encountered, set exit status
    has_errors = False
    queue = dbo.getQueue()
    # Build a list of criteria for WHERE clause
    db_cols = [u'rowid'] + [u'file']
    # loop through all profiles from command line and delete them
    for profile_name in profs:
        query_str = "SELECT " + ", ".join(db_cols) + " FROM " + table + \
                " WHERE name=" + AIdb.format_value('name', profile_name)
        logging.debug("query=" + query_str)
        query = AIdb.DBrequest(query_str, commit=True)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        rsp = query.getResponse()
        if rsp is None:
            has_errors = True
            continue
        if len(rsp) == 0:
            print >> sys.stderr, _("\tProfile %s not found.") % profile_name
            has_errors = True
            continue
        # delete database record and any accompanying internal profile file
        for response in rsp:
            deldict = dict()
            iresponse = iter(response)
            for crit in db_cols:
                deldict[crit] = next(iresponse)
            query_str = "DELETE FROM %s WHERE rowid=%d" % \
                    (table, deldict['rowid'])
            delquery = AIdb.DBrequest(query_str, commit=True)
            queue.put(delquery)
            delquery.waitAns()
            # check response, if failure, getResponse prints error
            if delquery.getResponse() is None:
                has_errors = True
                continue
            print >> sys.stderr, _("\tDeleted profile %s.") % profile_name
            # delete static (internal) files only
            if deldict['file'] is None or \
                not deldict['file'].startswith(sc.INTERNAL_PROFILE_DIRECTORY):
                continue
            try:
                os.unlink(deldict['file'])
            except OSError, (errno, errmsg):
                if errno != ENOENT:  # does not exist
                    print >> sys.stderr, _(
                            "Error (%s):  Problem deleting %s (%s): %s") \
                            % (errno, profile_name, deldict['file'], errmsg)
                has_errors = True
                continue
def validate_internal(profile_list, database, table, image_dir):
    ''' given a list of profile files and the profile database and table,
        validate the list of profiles
    Args:
        profile_list - list of profile path names
        database - name of database
        table - name of database table
        image_dir - path of service image, used to locate service_bundle
    Returns True if all profiles are valid, return False if any are invalid
    '''
    # Open the database
    dbn = AIdb.DB(database, commit=True)
    dbn.verifyDBStructure()
    isvalid = True
    queue = dbn.getQueue()
    if not profile_list:
        profile_list = [None]
    for profile in profile_list:
        qstr = "SELECT name, file FROM %s WHERE name = %s" % \
                (table, AIdb.format_value('name', profile))
        query = AIdb.DBrequest(qstr, commit=True)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        if query.getResponse() is None:  # database error
            return False  # give up
        if len(query.getResponse()) == 0:
            print >> sys.stderr, \
                    _('No profiles in database with basename ') + profile
            isvalid = False
            continue  # to the next profile
        for response in query.getResponse():
            if not df.validate_file(response[0], response[1], image_dir):
                isvalid = False
    return isvalid
Exemplo n.º 5
0
def add_profile(criteria, profile_name, profile_file, queue, table):
    """
    Set a profile record in the database with the criteria provided.
    Args:
        criteria - criteria object
        profile_name - name of profile to add
        profile_file - path of profile to add
        queue - database request queue
        table - profile table in database
    Returns: True if successful, false otherwise
    Effects:
        database record added
        stored resulting profile in internal profile directory
    """
    # get lists prepared for SQLite WHERE, INSERT VALUES from command line
    (wherel, insertl, valuesl) = \
        sc.sql_values_from_criteria(criteria, queue, table)

    # clear any profiles exactly matching the criteria
    wherel += ["name=" + AIdb.format_value('name', profile_name)]
    q_str = "DELETE FROM " + table + " WHERE " + " AND ".join(wherel)
    query = AIdb.DBrequest(q_str, commit=True)
    queue.put(query)
    query.waitAns()
    if query.getResponse() is None:
        return False

    # add profile to database
    insertl += ["name"]
    valuesl += [AIdb.format_value('name', profile_name)]
    insertl += ["file"]
    valuesl += [AIdb.format_value('name', profile_file)]
    q_str = "INSERT INTO " + table + "(" + ", ".join(insertl) + \
            ") VALUES (" + ", ".join(valuesl) + ")"
    query = AIdb.DBrequest(q_str, commit=True)
    queue.put(query)
    query.waitAns()
    if query.getResponse() is None:
        return False

    print >> sys.stderr, _('Profile %s added to database.') % profile_name
    return True
Exemplo n.º 6
0
def do_export_profile(options):
    '''
    Export a profile.
    '''
    save_errno = 0

    # Open the database
    aisql = AIdb.DB(options.service.database_path, commit=True)
    aisql.verifyDBStructure()

    queue = aisql.getQueue()
    for pname in options.pnames:
        # sanitize and format for SELECT
        fmtname = AIdb.format_value('name', pname)
        q_str = "SELECT file FROM  " + AIdb.PROFILES_TABLE + \
                " WHERE name=" + fmtname
        query = AIdb.DBrequest(q_str)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        if query.getResponse() is None:
            continue
        if len(query.getResponse()) == 0:
            print >> sys.stderr, _("Profile %s not found.") % fmtname
            continue
        for row in query.getResponse():
            profpath = row['file']

            if options.output_isdir:
                output_name = "/".join([options.output_name, pname])
            else:
                output_name = options.output_name

            if output_name == SCREEN and options.file_count > 1:
                display_file_header(_("profile: ") + pname)

            try:
                shutil.copyfile(profpath, output_name)
            except IOError as err:
                print >> sys.stderr, _(
                    "Error exporting profile: "
                    "%(error)s: %(file)s") % ({
                        "error": err.strerror,
                        "file": err.filename
                    })
                save_errno = err.errno
            print
    return save_errno
Exemplo n.º 7
0
def do_export_profile(options):
    '''
    Export a profile.
    '''
    save_errno = 0

    # Open the database
    aisql = AIdb.DB(options.service.database_path, commit=True)
    aisql.verifyDBStructure()

    queue = aisql.getQueue()
    for pname in options.pnames:
        # sanitize and format for SELECT
        fmtname = AIdb.format_value('name', pname)
        q_str = "SELECT file FROM  " + AIdb.PROFILES_TABLE + \
                " WHERE name=" + fmtname
        query = AIdb.DBrequest(q_str)
        queue.put(query)
        query.waitAns()
        # check response, if failure, getResponse prints error
        if query.getResponse() is None:
            continue
        if len(query.getResponse()) == 0:
            print >> sys.stderr, _("Profile %s not found.") % fmtname
            continue
        for row in query.getResponse():
            profpath = row['file']

            if options.output_isdir:
                output_name = "/".join([options.output_name, pname])
            else:
                output_name = options.output_name

            if output_name == SCREEN and options.file_count > 1:
                display_file_header(_("profile: ") + pname)

            try:
                shutil.copyfile(profpath, output_name)
            except IOError as err:
                print >> sys.stderr, _("Error exporting profile: "
                                       "%(error)s: %(file)s") % (
                                       {"error": err.strerror,
                                        "file": err.filename})
                save_errno = err.errno
            print
    return save_errno
Exemplo n.º 8
0
def do_update_profile(cmd_options=None):
    ''' Updates exisiting profile
    Arg: cmd_options - command line options
    Effect: update existing profile 
    Raises SystemExit if condition cannot be handled
    '''
    # check for authorization and euid
    try:
        check_auth_and_euid(PROFILE_AUTH)
    except UnauthorizedUserError as err:
        raise SystemExit(err)

    options = parse_options(DO_UPDATE, cmd_options)

    # verify the file
    profile_file = options.profile_file[0]
    if not os.path.exists(profile_file):
        raise SystemExit(_("Error:\tFile does not exist: %s\n") % profile_file)

    # get profile name
    if not options.profile_name:
        profile_name = os.path.basename(profile_file)
    else:
        profile_name = options.profile_name

    # get AI service image path and database name
    service = AIService(options.service_name)
    dbname = service.database_path
    image_dir = service.image.path

    # open database
    dbn = AIdb.DB(dbname, commit=True)
    dbn.verifyDBStructure()
    queue = dbn.getQueue()

    # Handle old DB versions which did not store a profile.
    if not AIdb.tableExists(queue, AIdb.PROFILES_TABLE):
        raise SystemExit(
            _("Error:\tService %s does not support profiles") %
            options.service_name)

    # check for the existence of profile
    missing_profile_error = _("Error:\tService {service} has no profile "
                              "named {profile}.")
    if not sc.is_name_in_table(profile_name, queue, AIdb.PROFILES_TABLE):
        raise SystemExit(
            missing_profile_error.format(service=options.service_name,
                                         profile=profile_name))

    # validates the profile and report the errors if found
    raw_profile = df.validate_file(profile_name,
                                   profile_file,
                                   image_dir,
                                   verbose=False)
    if not raw_profile:
        raise SystemExit(1)

    # create file from string and report failures
    tmp_profile_path = copy_profile_internally(raw_profile)
    if not tmp_profile_path:
        raise SystemExit(1)

    # get the path of profile in db
    q_str = "SELECT file FROM " + AIdb.PROFILES_TABLE + " WHERE name=" \
                + AIdb.format_value('name', profile_name)
    query = AIdb.DBrequest(q_str)
    queue.put(query)
    query.waitAns()
    response = query.getResponse()
    # database error
    if response is None:
        raise SystemExit(
            missing_profile_error.format(service=options.service_name,
                                         profile=profile_name))

    db_profile_path = response[0][0]

    # replace the file
    try:
        shutil.copyfile(tmp_profile_path, db_profile_path)
    except IOError as err:
        raise SystemExit(
            _("Error writing profile %(profile)s: %(err)s") % {
                'profile': profile_name,
                'err': err
            })
    finally:
        os.unlink(tmp_profile_path)

    print >> sys.stderr, _("Profile updated successfully.")
Exemplo n.º 9
0
def sql_values_from_criteria(criteria, queue, table, gbl=False):
    ''' Given a criteria dictionary, for the indicated DB table
    and queue, return a tuple composed of lists whose elements can be used
    to construct SQLite clauses.  If gbl is true, build a clause that
    will affect all database records if criteria is missing - a global effect.
    Args:
        criteria - criteria dictionary
        queue - database queue
        table - database table
        gbl - if True, global
    Returns: a tuple for SQLite clauses respectively: WHERE, INTO, VALUES
    '''
    where = list()  # for WHERE clause
    intol = list()  # for INTO clause
    vals = list()  # for VALUES clause
    for crit in AIdb.getCriteria(queue, table, onlyUsed=False, strip=True):

        # Determine if this crit is a range criteria or not.
        is_range_crit = AIdb.isRangeCriteria(queue, crit, table)

        # Get the value from the manifest
        values = criteria[crit]
        # the critera manifest didn't specify this criteria
        if values is None:
            # if the criteria we're processing is a range criteria, fill in
            # NULL for two columns, MINcrit and MAXcrit
            vals += ["NULL"]
            if is_range_crit:
                where += ["MIN" + crit + " IS NULL"]
                where += ["MAX" + crit + " IS NULL"]
                intol += ["MIN" + crit]
                intol += ["MAX" + crit]
                vals += ["NULL"]
            # this is a single value
            else:
                where += [crit + " IS NULL"]
                intol += [crit]
        # This is a value criteria (not a range).  'values' is a list
        # with one or more items.
        elif not is_range_crit:
            intol += [crit]
            val = AIdb.format_value(crit, " ".join(values))
            where += [crit + "=" + val]
            vals += [val]
        # Else this is a range criteria.  'values' is a two-item list
        else:
            # Set the MIN column for this range criteria
            if values[0] == 'unbounded':
                if not gbl:
                    where += ["MIN" + crit + " IS NULL"]
                    intol += ["MIN" + crit]
                    vals += ['NULL']
            else:
                intol += ["MIN" + crit]
                if crit == 'mac':
                    val = AIdb.format_value(crit, verifyXML.checkMAC(
                        values[0])).upper()
                    where += ["HEX(MIN" + crit + ")<=HEX(" + val + ")"]
                else:
                    val = AIdb.format_value(crit, values[0]).lower()
                    where += ["MIN" + crit + "<=" + val]
                vals += [val]
            # Set the MAX column for this range criteria
            if values[1] == 'unbounded':
                if not gbl:
                    where += ["MAX" + crit + " IS NULL"]
                    intol += ["MAX" + crit]
                    vals += ['NULL']
            else:
                intol += ["MAX" + crit]
                if crit == 'mac':
                    val = AIdb.format_value(crit, verifyXML.checkMAC(
                        values[1])).upper()
                    where += ["HEX(MAX" + crit + ")>=HEX(" + val + ")"]
                else:
                    val = AIdb.format_value(crit, values[1]).lower()
                    where += ["MAX" + crit + ">=" + val]
                vals += [val]
    return where, intol, vals
Exemplo n.º 10
0
def set_criteria(criteria, iname, dbn, table, append=False):
    """
    Set a manifest's record in the criteria database with the
    criteria provided.
    If append is True -- append ones that aren't already set for
    the manifest, and replace ones that are.
    if append is False -- completely remove all criteria already
    set for the manifest, and use only the criteria specified.
    """

    # Build a list of criteria nvpairs to update
    nvpairs = list()

    # we need to fill in the criteria or NULLs for each criteria the database
    # supports (so iterate over each criteria)
    for crit in AIdb.getCriteria(dbn.getQueue(),
                                 table=table,
                                 onlyUsed=False,
                                 strip=True):

        # Determine if this crit is a range criteria or not.
        is_range_crit = AIdb.isRangeCriteria(dbn.getQueue(), crit)

        # Get the value from the manifest
        values = criteria[crit]

        # the criteria manifest didn't specify this criteria
        if values is None:
            # If we not appending criteria, then we must write in NULLs
            # for this criteria since we're removing all criteria not
            # specified.
            if not append:
                # if the criteria we're processing is a range criteria, fill in
                # NULL for two columns, MINcrit and MAXcrit
                if is_range_crit:
                    nvpairs.append("MIN" + crit + "=NULL")
                    nvpairs.append("MAX" + crit + "=NULL")
                # this is a single value
                else:
                    nvpairs.append(crit + "=NULL")

        # Else if this is a value criteria (not a range), insert the
        # value as a space-separated list of values in case a list of
        # values have been given.
        elif not is_range_crit:
            nvstr = crit + "='" + AIdb.sanitizeSQL(" ".join(values)) + "'"
            nvpairs.append(nvstr)

        # Else the values are a list this is a range criteria
        else:
            # Set the MIN column for this range criteria
            nvpairs.append("MIN" + crit + "=" +
                           AIdb.format_value(crit, values[0]))

            # Set the MAX column for this range criteria
            nvpairs.append("MAX" + crit + "=" +
                           AIdb.format_value(crit, values[1]))

    query = "UPDATE " + table + " SET " + ",".join(nvpairs) + \
            " WHERE name='" + iname + "'"

    # update the DB
    query = AIdb.DBrequest(query, commit=True)
    dbn.getQueue().put(query)
    query.waitAns()
    # in case there's an error call the response function (which
    # will print the error)
    query.getResponse()
def set_criteria(criteria, iname, dbn, table, append=False):
    """
    Set a manifest's record in the criteria database with the
    criteria provided.
    If append is True -- append ones that aren't already set for
    the manifest, and replace ones that are.
    if append is False -- completely remove all criteria already
    set for the manifest, and use only the criteria specified.
    """

    # Build a list of criteria nvpairs to update
    nvpairs = list()

    # we need to fill in the criteria or NULLs for each criteria the database
    # supports (so iterate over each criteria)
    for crit in AIdb.getCriteria(dbn.getQueue(), table=table, onlyUsed=False,
                                 strip=True):

        # Determine if this crit is a range criteria or not.
        is_range_crit = AIdb.isRangeCriteria(dbn.getQueue(), crit)

        # Get the value from the manifest
        values = criteria[crit]

        # the criteria manifest didn't specify this criteria
        if values is None:
            # If we not appending criteria, then we must write in NULLs
            # for this criteria since we're removing all criteria not
            # specified.
            if not append:
                # if the criteria we're processing is a range criteria, fill in
                # NULL for two columns, MINcrit and MAXcrit
                if is_range_crit:
                    nvpairs.append("MIN" + crit + "=NULL")
                    nvpairs.append("MAX" + crit + "=NULL")
                # this is a single value
                else:
                    nvpairs.append(crit + "=NULL")

        # Else if this is a value criteria (not a range), insert the
        # value as a space-separated list of values in case a list of
        # values have been given. 
        elif not is_range_crit:
            nvstr = crit + "='" + AIdb.sanitizeSQL(" ".join(values)) + "'"
            nvpairs.append(nvstr)

        # Else the values are a list this is a range criteria
        else:
            # Set the MIN column for this range criteria
            nvpairs.append("MIN" + crit + "=" +
                           AIdb.format_value(crit, values[0]))

            # Set the MAX column for this range criteria
            nvpairs.append("MAX" + crit + "=" +
                           AIdb.format_value(crit, values[1]))

    query = "UPDATE " + table + " SET " + ",".join(nvpairs) + \
            " WHERE name='" + iname + "'"

    # update the DB
    query = AIdb.DBrequest(query, commit=True)
    dbn.getQueue().put(query)
    query.waitAns()
    # in case there's an error call the response function (which
    # will print the error)
    query.getResponse()
def sql_values_from_criteria(criteria, queue, table, gbl=False):
    ''' Given a criteria dictionary, for the indicated DB table
    and queue, return a tuple composed of lists whose elements can be used
    to construct SQLite clauses.  If gbl is true, build a clause that
    will affect all database records if criteria is missing - a global effect.
    Args:
        criteria - criteria dictionary
        queue - database queue
        table - database table
        gbl - if True, global
    Returns: a tuple for SQLite clauses respectively: WHERE, INTO, VALUES
    '''
    where = list()  # for WHERE clause
    intol = list()  # for INTO clause
    vals = list()  # for VALUES clause
    for crit in AIdb.getCriteria(queue, table, onlyUsed=False, strip=True):

        # Determine if this crit is a range criteria or not.
        is_range_crit = AIdb.isRangeCriteria(queue, crit, table)

        # Get the value from the manifest
        values = criteria[crit]
        # the critera manifest didn't specify this criteria
        if values is None:
            # if the criteria we're processing is a range criteria, fill in
            # NULL for two columns, MINcrit and MAXcrit
            vals += ["NULL"]
            if is_range_crit:
                where += ["MIN" + crit + " IS NULL"]
                where += ["MAX" + crit + " IS NULL"]
                intol += ["MIN" + crit]
                intol += ["MAX" + crit]
                vals += ["NULL"]
            # this is a single value
            else:
                where += [crit + " IS NULL"]
                intol += [crit]
        # This is a value criteria (not a range).  'values' is a list
        # with one or more items.
        elif not is_range_crit:
            intol += [crit]
            val = AIdb.format_value(crit, " ".join(values))
            where += [crit + "=" + val]
            vals += [val]
        # Else this is a range criteria.  'values' is a two-item list
        else:
            # Set the MIN column for this range criteria
            if values[0] == 'unbounded':
                if not gbl:
                    where += ["MIN" + crit + " IS NULL"]
                    intol += ["MIN" + crit]
                    vals += ['NULL']
            else:
                intol += ["MIN" + crit]
                if crit == 'mac':
                    val = AIdb.format_value(crit,
                            verifyXML.checkMAC(values[0])).upper()
                    where += ["HEX(MIN" + crit + ")<=HEX(" + val + ")"]
                else:
                    val = AIdb.format_value(crit, values[0]).lower()
                    where += ["MIN" + crit + "<=" + val]
                vals += [val]
            # Set the MAX column for this range criteria
            if values[1] == 'unbounded':
                if not gbl:
                    where += ["MAX" + crit + " IS NULL"]
                    intol += ["MAX" + crit]
                    vals += ['NULL']
            else:
                intol += ["MAX" + crit]
                if crit == 'mac':
                    val = AIdb.format_value(crit,
                            verifyXML.checkMAC(values[1])).upper()
                    where += ["HEX(MAX" + crit + ")>=HEX(" + val + ")"]
                else:
                    val = AIdb.format_value(crit, values[1]).lower()
                    where += ["MAX" + crit + ">=" + val]
                vals += [val]
    return where, intol, vals