Esempio n. 1
0
def removeReceipts(pkgkeylist, noupdateapplepkgdb):
    """
    Removes receipt data from /Library/Receipts,
    /Library/Receipts/boms, our internal package database,
    and optionally Apple's package database.
    """
    munkicommon.display_status_minor('Removing receipt info')
    munkicommon.display_percent_done(0, 4)

    conn = sqlite3.connect(packagedb)
    curs = conn.cursor()

    os_version = munkicommon.getOsVersion(as_tuple=True)

    applepkgdb = '/Library/Receipts/db/a.receiptdb'
    if not noupdateapplepkgdb and os_version <= (10, 5):
        aconn = sqlite3.connect(applepkgdb)
        acurs = aconn.cursor()

    munkicommon.display_percent_done(1, 4)

    for pkgkey in pkgkeylist:
        pkgid = ''
        pkgkey_t = (pkgkey, )
        row = curs.execute('SELECT pkgname, pkgid from pkgs where pkg_key = ?',
                           pkgkey_t).fetchone()
        if row:
            pkgname = row[0]
            pkgid = row[1]
            receiptpath = None
            if os_version <= (10, 5):
                if pkgname.endswith('.pkg'):
                    receiptpath = os.path.join('/Library/Receipts', pkgname)
                if pkgname.endswith('.bom'):
                    receiptpath = os.path.join('/Library/Receipts/boms',
                                               pkgname)
            else:
                # clean up /Library/Receipts in case there's stuff left there
                receiptpath = findBundleReceiptFromID(pkgid)

            if receiptpath and os.path.exists(receiptpath):
                munkicommon.display_detail("Removing %s...", receiptpath)
                dummy_retcode = subprocess.call(
                    ["/bin/rm", "-rf", receiptpath])

        # remove pkg info from our database
        munkicommon.display_detail(
            "Removing package data from internal database...")
        curs.execute('DELETE FROM pkgs_paths where pkg_key = ?', pkgkey_t)
        curs.execute('DELETE FROM pkgs where pkg_key = ?', pkgkey_t)

        # then remove pkg info from Apple's database unless option is passed
        if not noupdateapplepkgdb and pkgid:
            if os_version <= (10, 5):
                # Leopard
                pkgid_t = (pkgid, )
                row = acurs.execute('SELECT pkg_key FROM pkgs where pkgid = ?',
                                    pkgid_t).fetchone()
                if row:
                    munkicommon.display_detail(
                        "Removing package data from Apple package " +
                        "database...")
                    apple_pkg_key = row[0]
                    pkgkey_t = (apple_pkg_key, )
                    acurs.execute('DELETE FROM pkgs where pkg_key = ?',
                                  pkgkey_t)
                    acurs.execute('DELETE FROM pkgs_paths where pkg_key = ?',
                                  pkgkey_t)
                    acurs.execute('DELETE FROM pkgs_groups where pkg_key = ?',
                                  pkgkey_t)
                    acurs.execute('DELETE FROM acls where pkg_key = ?',
                                  pkgkey_t)
                    acurs.execute('DELETE FROM taints where pkg_key = ?',
                                  pkgkey_t)
                    acurs.execute('DELETE FROM sha1s where pkg_key = ?',
                                  pkgkey_t)
                    acurs.execute('DELETE FROM oldpkgs where pkg_key = ?',
                                  pkgkey_t)
            else:
                # Snow Leopard or higher, must use pkgutil
                cmd = ['/usr/sbin/pkgutil', '--forget', pkgid]
                proc = subprocess.Popen(cmd,
                                        bufsize=1,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                (output, dummy_err) = proc.communicate()
                if output:
                    munkicommon.display_detail(
                        str(output).decode('UTF-8').rstrip('\n'))

    munkicommon.display_percent_done(2, 4)

    # now remove orphaned paths from paths table
    # first, Apple's database if option is passed
    if not noupdateapplepkgdb:
        if os_version <= (10, 5):
            munkicommon.display_detail(
                "Removing unused paths from Apple package database...")
            acurs.execute('''DELETE FROM paths where path_key not in
                   (select distinct path_key from pkgs_paths)''')
            aconn.commit()
            acurs.close()
            aconn.close()

    munkicommon.display_percent_done(3, 4)

    # we do our database last so its modtime is later than the modtime for the
    # Apple DB...
    munkicommon.display_detail("Removing unused paths from internal package "
                               "database...")
    curs.execute('''DELETE FROM paths where path_key not in
           (select distinct path_key from pkgs_paths)''')
    conn.commit()
    curs.close()
    conn.close()

    munkicommon.display_percent_done(4, 4)
Esempio n. 2
0
def initDatabase(forcerebuild=False):
    """
    Builds or rebuilds our internal package database.
    """
    if not shouldRebuildDB(packagedb) and not forcerebuild:
        return True

    munkicommon.display_status_minor(
        'Gathering information on installed packages')

    if os.path.exists(packagedb):
        try:
            os.remove(packagedb)
        except (OSError, IOError):
            munkicommon.display_error(
                "Could not remove out-of-date receipt database.")
            return False

    os_version = munkicommon.getOsVersion(as_tuple=True)
    pkgcount = 0
    receiptsdir = "/Library/Receipts"
    bomsdir = "/Library/Receipts/boms"
    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if item.endswith(".pkg"):
                pkgcount += 1
    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if item.endswith(".bom"):
                pkgcount += 1

    if os_version >= (10, 6):  # Snow Leopard or later
        pkglist = []
        cmd = ['/usr/sbin/pkgutil', '--pkgs']
        proc = subprocess.Popen(cmd,
                                shell=False,
                                bufsize=1,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        while True:
            line = proc.stdout.readline()
            if not line and (proc.poll() != None):
                break

            pkglist.append(line.rstrip('\n'))
            pkgcount += 1

    conn = sqlite3.connect(packagedb)
    conn.text_factory = str
    curs = conn.cursor()
    CreateTables(curs)

    currentpkgindex = 0
    munkicommon.display_percent_done(0, pkgcount)

    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".pkg"):
                receiptpath = os.path.join(receiptsdir, item)
                munkicommon.display_detail("Importing %s...", receiptpath)
                ImportPackage(receiptpath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)

    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".bom"):
                bompath = os.path.join(bomsdir, item)
                munkicommon.display_detail("Importing %s...", bompath)
                ImportBom(bompath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)
    if os_version >= (10, 6):  # Snow Leopard or later
        for pkg in pkglist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            munkicommon.display_detail("Importing %s...", pkg)
            ImportFromPkgutil(pkg, curs)
            currentpkgindex += 1
            munkicommon.display_percent_done(currentpkgindex, pkgcount)

    # in case we didn't quite get to 100% for some reason
    if currentpkgindex < pkgcount:
        munkicommon.display_percent_done(pkgcount, pkgcount)

    # commit and close the db when we're done.
    conn.commit()
    curs.close()
    conn.close()
    return True
Esempio n. 3
0
def initDatabase(forcerebuild=False):
    """
    Builds or rebuilds our internal package database.
    """
    if not shouldRebuildDB(packagedb) and not forcerebuild:
        return True

    munkicommon.display_status_minor(
        'Gathering information on installed packages')

    if os.path.exists(packagedb):
        try:
            os.remove(packagedb)
        except (OSError, IOError):
            munkicommon.display_error(
                "Could not remove out-of-date receipt database.")
            return False

    os_version = munkicommon.getOsVersion(as_tuple=True)
    pkgcount = 0
    receiptsdir = "/Library/Receipts"
    bomsdir = "/Library/Receipts/boms"
    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if item.endswith(".pkg"):
                pkgcount += 1
    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if item.endswith(".bom"):
                pkgcount += 1

    if os_version >= (10, 6): # Snow Leopard or later
        pkglist = []
        cmd = ['/usr/sbin/pkgutil', '--pkgs']
        proc = subprocess.Popen(cmd, shell=False, bufsize=1,
                                stdin=subprocess.PIPE,
                                stdout=subprocess.PIPE,
                                stderr=subprocess.PIPE)
        while True:
            line =  proc.stdout.readline()
            if not line and (proc.poll() != None):
                break

            pkglist.append(line.rstrip('\n'))
            pkgcount += 1

    conn = sqlite3.connect(packagedb)
    conn.text_factory = str
    curs = conn.cursor()
    CreateTables(curs)

    currentpkgindex = 0
    munkicommon.display_percent_done(0, pkgcount)

    if os.path.exists(receiptsdir):
        receiptlist = munkicommon.listdir(receiptsdir)
        for item in receiptlist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".pkg"):
                receiptpath = os.path.join(receiptsdir, item)
                munkicommon.display_detail("Importing %s...", receiptpath)
                ImportPackage(receiptpath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)

    if os.path.exists(bomsdir):
        bomslist = munkicommon.listdir(bomsdir)
        for item in bomslist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            if item.endswith(".bom"):
                bompath = os.path.join(bomsdir, item)
                munkicommon.display_detail("Importing %s...", bompath)
                ImportBom(bompath, curs)
                currentpkgindex += 1
                munkicommon.display_percent_done(currentpkgindex, pkgcount)
    if os_version >= (10, 6):  # Snow Leopard or later
        for pkg in pkglist:
            if munkicommon.stopRequested():
                curs.close()
                conn.close()
                #our package db isn't valid, so we should delete it
                os.remove(packagedb)
                return False

            munkicommon.display_detail("Importing %s...", pkg)
            ImportFromPkgutil(pkg, curs)
            currentpkgindex += 1
            munkicommon.display_percent_done(currentpkgindex, pkgcount)

    # in case we didn't quite get to 100% for some reason
    if currentpkgindex < pkgcount:
        munkicommon.display_percent_done(pkgcount, pkgcount)

    # commit and close the db when we're done.
    conn.commit()
    curs.close()
    conn.close()
    return True
Esempio n. 4
0
def removeReceipts(pkgkeylist, noupdateapplepkgdb):
    """
    Removes receipt data from /Library/Receipts,
    /Library/Receipts/boms, our internal package database,
    and optionally Apple's package database.
    """
    munkicommon.display_status_minor('Removing receipt info')
    munkicommon.display_percent_done(0, 4)

    conn = sqlite3.connect(packagedb)
    curs = conn.cursor()

    os_version = munkicommon.getOsVersion(as_tuple=True)

    applepkgdb = '/Library/Receipts/db/a.receiptdb'
    if not noupdateapplepkgdb and os_version <= (10, 5):
        aconn = sqlite3.connect(applepkgdb)
        acurs = aconn.cursor()

    munkicommon.display_percent_done(1, 4)

    for pkgkey in pkgkeylist:
        pkgid = ''
        pkgkey_t = (pkgkey, )
        row = curs.execute(
            'SELECT pkgname, pkgid from pkgs where pkg_key = ?',
                                                        pkgkey_t).fetchone()
        if row:
            pkgname = row[0]
            pkgid = row[1]
            receiptpath = None
            if os_version <= (10, 5):
                if pkgname.endswith('.pkg'):
                    receiptpath = os.path.join('/Library/Receipts', pkgname)
                if pkgname.endswith('.bom'):
                    receiptpath = os.path.join('/Library/Receipts/boms',
                                                pkgname)
            else:
                # clean up /Library/Receipts in case there's stuff left there
                receiptpath = findBundleReceiptFromID(pkgid)

            if receiptpath and os.path.exists(receiptpath):
                munkicommon.display_detail("Removing %s...", receiptpath)
                unused_retcode = subprocess.call(
                                            ["/bin/rm", "-rf", receiptpath])

        # remove pkg info from our database
        munkicommon.display_detail(
            "Removing package data from internal database...")
        curs.execute('DELETE FROM pkgs_paths where pkg_key = ?', pkgkey_t)
        curs.execute('DELETE FROM pkgs where pkg_key = ?', pkgkey_t)

        # then remove pkg info from Apple's database unless option is passed
        if not noupdateapplepkgdb and pkgid:
            if os_version <= (10, 5):
                # Leopard
                pkgid_t = (pkgid, )
                row = acurs.execute(
                        'SELECT pkg_key FROM pkgs where pkgid = ?',
                            pkgid_t).fetchone()
                if row:
                    munkicommon.display_detail(
                        "Removing package data from Apple package "+
                        "database...")
                    apple_pkg_key = row[0]
                    pkgkey_t = (apple_pkg_key, )
                    acurs.execute(
                        'DELETE FROM pkgs where pkg_key = ?', pkgkey_t)
                    acurs.execute(
                        'DELETE FROM pkgs_paths where pkg_key = ?', pkgkey_t)
                    acurs.execute(
                        'DELETE FROM pkgs_groups where pkg_key = ?', pkgkey_t)
                    acurs.execute(
                        'DELETE FROM acls where pkg_key = ?', pkgkey_t)
                    acurs.execute(
                        'DELETE FROM taints where pkg_key = ?', pkgkey_t)
                    acurs.execute(
                        'DELETE FROM sha1s where pkg_key = ?', pkgkey_t)
                    acurs.execute(
                        'DELETE FROM oldpkgs where pkg_key = ?', pkgkey_t)
            else:
                # Snow Leopard or higher, must use pkgutil
                cmd = ['/usr/sbin/pkgutil', '--forget', pkgid]
                proc = subprocess.Popen(cmd, bufsize=1,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
                (output, unused_err) = proc.communicate()
                if output:
                    munkicommon.display_detail(
                        str(output).decode('UTF-8').rstrip('\n'))

    munkicommon.display_percent_done(2, 4)

    # now remove orphaned paths from paths table
    # first, Apple's database if option is passed
    if not noupdateapplepkgdb:
        if os_version <= (10, 5):
            munkicommon.display_detail(
                "Removing unused paths from Apple package database...")
            acurs.execute(
                '''DELETE FROM paths where path_key not in
                   (select distinct path_key from pkgs_paths)''')
            aconn.commit()
            acurs.close()
            aconn.close()

    munkicommon.display_percent_done(3, 4)

    # we do our database last so its modtime is later than the modtime for the
    # Apple DB...
    munkicommon.display_detail("Removing unused paths from internal package "
                               "database...")
    curs.execute(
        '''DELETE FROM paths where path_key not in
           (select distinct path_key from pkgs_paths)''')
    conn.commit()
    curs.close()
    conn.close()

    munkicommon.display_percent_done(4, 4)
Esempio n. 5
0
                custom_header = custom_header.strip().encode('utf-8')
                if re.search(r'^[\w-]+:.+', custom_header):
                    print >> fileobj, ('header = "%s"' % custom_header)
                else:
                    munkicommon.display_warning(
                        'Skipping invalid HTTP header: %s' % custom_header)

        fileobj.close()
    except Exception, e:
        raise CurlError(-5, 'Error writing curl directive: %s' % str(e))

    # In Mavericks we need to wrap our call to curl with a utility
    # that makes curl think it is connected to a tty-like
    # device so its output is unbuffered so we can get progress info
    cmd = []
    minor_os_version = munkicommon.getOsVersion(as_tuple=True)[1]
    if minor_os_version > 8:
        # Try to find our ptyexec tool
        # first look in the parent directory of this file's directory
        # (../)
        parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
        ptyexec_path = os.path.join(parent_dir, 'ptyexec')
        if not os.path.exists(ptyexec_path):
            # try absolute path in munki's normal install dir
            ptyexec_path = '/usr/local/munki/ptyexec'
        if os.path.exists(ptyexec_path):
            cmd = [ptyexec_path]

    # Workaround for current issue in OS X 10.9's included curl
    # Allows for alternate curl binary path as Apple's included curl currently
    # broken for client-side certificate usage