This documentation supports the 20.08 (12.1) version of BMC Discovery.To view an earlier version of the product, select the version from the Product version menu.

Changes to Discovery commands


The following sections show the discovery command changes between BMC Discovery versions.

The following changes are not shown:

  • Entirely new discovery platforms
  • Changes to comments only
  • Commands which have been removed and not replaced
  • Changes to echo only statements

Discovery command changes from 20.02 (12.0) to 20.08

Click here to expand...

FreeBSD

getHostInfo

The following code:

 
if [ -f /usr/sbin/dmidecode ]; then
    PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | awk '/DMI type 1,/,/^Handle 0x0*[2-9]+0*/ {
        if( $1 ~ /Manufacturer:/ ) { sub(".*Manufacturer: *","");  printf( "vendor: %s\n", $0 ); }
        if( $1 ~ /Product/ && $2 ~ /Name:/ ) { sub(".*Product Name: *",""); printf( "model: %s\n", $0 ); }
        if( $1 ~ /Serial/ && $2 ~ /Number:/ ) { sub(".*Serial Number: *",""); printf( "serial: %s\n", $0 ); }
    }'
fi

is replaced with:

if [ -f /usr/sbin/dmidecode ]; then
    PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | awk '/DMI type 1,/,/^Handle 0x0*[2-9]+0*/ {
        if( $1 ~ /Manufacturer:/ ) { sub(".*Manufacturer: *","");  printf( "candidate_vendor[]: %s\n", $0 ); }
        if( $1 ~ /Product/ && $2 ~ /Name:/ ) { sub(".*Product Name: *",""); printf( "candidate_model[]: %s\n", $0 ); }
        if( $1 ~ /Serial/ && $2 ~ /Number:/ ) { sub(".*Serial Number: *",""); printf( "serial: %s\n", $0 ); }
    }'
fi

The following code is added:

 

# Cloud instance metadata
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    if [ "$TW_CLOUD_PLATFORM" == "AWS" ]; then
        echo "aws_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Amazon Virtual Machine"
        echo "candidate_vendor[]: Amazon"

        # Get primary MAC so we can find VPC
        primary_mac=`$TW_CLOUD_IMDS_CMD/mac 2>/dev/null`
        if [ "$primary_mac" != "" ]; then
            scope=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$primary_mac/vpc-id 2>/dev/null | egrep '^vpc-[0-9a-f]+$'`
            if [ "$scope" != "" ]; then
                echo "scope: $scope"
            fi
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "AZURE" ]; then
        echo "azure_vm_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Virtual Machine"
        echo "candidate_vendor[]: Microsoft Corporation"

    elif [ "$TW_CLOUD_PLATFORM" == "GCE" ]; then
        echo "gce_instance_id: " "$TW_CLOUD_ID"
        echo "candidate_model[]: Google Compute Engine"
        echo "candidate_vendor[]: Google"

        # Get project IDs
        numeric_project_id=`$TW_CLOUD_IMDS_CMD/project/numeric-project-id 2>/dev/null`
        project_id=`$TW_CLOUD_IMDS_CMD/project/project-id 2>/dev/null`

        # Get VPC network
        network=`$TW_CLOUD_IMDS_CMD/instance/network-interfaces/0/network 2>/dev/null`

        # Build scope from network
        scope=`echo $network | sed -e "s/$numeric_project_id/$project_id/"`
        if [ "$scope" != "" ]; then
            echo "scope: $scope"
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "OPENSTACK" ]; then
        echo "openstack_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: OpenStack Compute"
    fi
fi

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# dmidecode requires superuser privileges to read data from the system BIOS
PRIV_DMIDECODE() {
    "$@"
}

is replaced with:

############################################################################
# Function to detect the cloud platform, if any

tw_detect_cloud_platform() {
    # Have we already detected the cloud platform?

    if [ -n "$TW_CLOUD_PLATFORM" ]; then
        return 0
    fi

    export TW_CLOUD_PLATFORM=
    export TW_CLOUD_ID=
    export TW_CLOUD_IMDS_CMD=

    # We need curl to make the required requests

    if [ ! -x /usr/local/bin/curl ]; then
        return 1
    fi
    CURL=/usr/local/bin/curl

    # Trying to detect Amazon EC2

    # These web requests are not chargeable.
    # See: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

    # Try IMDSv2 first
    TOKEN=`$CURL --connect-timeout 5 --max-time 10 --fail -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 1800" 2>/dev/null`
    if [ ! -z "$TOKEN" ]; then
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail -H \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data"
    else
        # Try IMDSv1
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/latest/meta-data"
    fi

    TW_CLOUD_ID=`$TW_CLOUD_IMDS_CMD/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    if [ -n "$TW_CLOUD_ID" ]; then
        # We need to check for OpenStack EC2-compatible metadata
        # https://docs.openstack.org/nova/latest/user/metadata.html#metadata-ec2-format
        OPENSTACK=`$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack 2>/dev/null`
        if [ ! -z "$OPENSTACK" ]; then
            TW_CLOUD_PLATFORM=OPENSTACK
            TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack/latest"
            return 0
        fi

        # Cloud platform is AWS
        TW_CLOUD_PLATFORM=AWS
        return 0
    fi

    # Try Azure
    # see: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service
    TW_CLOUD_ID=`$CURL --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' "http://169.254.169.254/metadata/instance/compute/vmId?api-version=2019-06-01&format=text" 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=AZURE
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' http://169.254.169.254/metadata"
        return 0
    fi

    # Try Google Compute engine
    # see: https://cloud.google.com/compute/docs/storing-retrieving-metadata
    TW_CLOUD_ID=`$CURL --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/id 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=GCE
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1"
        return 0
    fi

    TW_CLOUD_PLATFORM=None
    return 1
## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
# AWS Systems Manager : True
############################################################################

# AWS System Manager privilege elevation functions
if [ `whoami` = "ssm-user" ]; then

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        sudo cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        sudo "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        sudo "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        sudo ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        sudo "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        sudo "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        sudo test "$@"
    }

else

    # Default privilege elevation functions

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        test "$@"
    }

fi

getNetworkInterfaces

The following code is added:

 

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>"
                echo "        ether $mac"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0x00000000 broadcast 255.255.255.255 scope tw:internet"
                done
            done
        fi
    fi
fi

getIPAddresses

The following code is added:

 

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>"
                echo "        ether $mac"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0x00000000 broadcast 255.255.255.255 scope tw:internet"
                done
            done
        fi
    fi
fi

HP-UX

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports running privileged cstm command
PRIV_CSTM() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# lanadmin requires superuser privileges to display any interface speed
# and negotiation settings
PRIV_LANADMIN() {
    "$@"
}

# swlist requires superuser privileges to list all installed packages
PRIV_SWLIST() {
    "$@"
}

# fcmsutil requires superuser privileges to display any HBA information
PRIV_FCMSUTIL() {
    "$@"
}

is replaced with:

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
############################################################################


# cat requires superuser privileges to read some files belonging to
# other users
PRIV_CAT() {
    cat "$@"
}
# cstm requires superuser privileges
PRIV_CTSM() {
    "$@"
}
# df requires superuser privileges to report file systems owned by other
# users
PRIV_DF() {
    "$@"
}
# fcmsutil requires superuser privileges to display any HBA information
PRIV_FCMSUTIL() {
    "$@"
}
# landamin requires superuser privileges to display any interface speed
# and negotiation settings
PRIV_LANADMIN() {
    "$@"
}

# ls requires superuser privileges to allow access to some directories
# owned by other users
PRIV_LS() {
    ls "$@"
}
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
    "$@"
}
# Allow patterns to run commands with elevated privileges
PRIV_RUNCMD() {
    "$@"
}
# swlist requires superuser privileges to list all installed packages
PRIV_SWLIST() {
    "$@"
}
# test requires superuser privileges to allow access to some files owned
# by other users
PRIV_TEST() {
    test "$@"
}

VMware ESXi

initialise

The following code:

 
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_CAT() {
#   /usr/bin/sudo cat "$@"
# }
# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

is replaced with:

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
############################################################################


# cat requires superuser privileges to read some files belonging to
# other users
PRIV_CAT() {
    cat "$@"
}
# df requires superuser privileges to report file systems owned by other
# users
PRIV_DF() {
    "$@"
}
# ls requires superuser privileges to allow access to some directories
# owned by other users
PRIV_LS() {
    ls "$@"
}
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
    "$@"
}
# Allow patterns to run commands with elevated privileges
PRIV_RUNCMD() {
    "$@"
}
# test requires superuser privileges to allow access to some files owned
# by other users
PRIV_TEST() {
    test "$@"
}

NetBSD

getHostInfo

The following code:

 
 if [ -f /usr/sbin/dmidecode ]; then
     PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | awk '/DMI type 1,/,/^Handle 0x0*[2-9]+0*/ {
-        if( $1 ~ /Manufacturer:/ ) { sub(".*Manufacturer: *","");  printf( "vendor: %s\n", $0 ); }
-        if( $1 ~ /Product/ && $2 ~ /Name:/ ) { sub(".*Product Name: *",""); printf( "model: %s\n", $0 ); }
         if( $1 ~ /Serial/ && $2 ~ /Number:/ ) { sub(".*Serial Number: *",""); printf( "serial: %s\n", $0 ); }
     }'
 fi
 

is replaced with:

 if [ -f /usr/sbin/dmidecode ]; then
     PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | awk '/DMI type 1,/,/^Handle 0x0*[2-9]+0*/ {
+        if( $1 ~ /Manufacturer:/ ) { sub(".*Manufacturer: *","");  printf( "candidate_vendor[]: %s\n", $0 ); }
+        if( $1 ~ /Product/ && $2 ~ /Name:/ ) { sub(".*Product Name: *",""); printf( "candidate_model[]: %s\n", $0 ); }
         if( $1 ~ /Serial/ && $2 ~ /Number:/ ) { sub(".*Serial Number: *",""); printf( "serial: %s\n", $0 ); }
     }'
 fi

The following code is added:

 

# Cloud instance metadata
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    if [ "$TW_CLOUD_PLATFORM" == "AWS" ]; then
        echo "aws_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Amazon Virtual Machine"
        echo "candidate_vendor[]: Amazon"

        # Get primary MAC so we can find VPC
        primary_mac=`$TW_CLOUD_IMDS_CMD/mac 2>/dev/null`
        if [ "$primary_mac" != "" ]; then
            scope=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$primary_mac/vpc-id 2>/dev/null | egrep '^vpc-[0-9a-f]+$'`
            if [ "$scope" != "" ]; then
                echo "scope: $scope"
            fi
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "AZURE" ]; then
        echo "azure_vm_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Virtual Machine"
        echo "candidate_vendor[]: Microsoft Corporation"

    elif [ "$TW_CLOUD_PLATFORM" == "GCE" ]; then
        echo "gce_instance_id: " "$TW_CLOUD_ID"
        echo "candidate_model[]: Google Compute Engine"
        echo "candidate_vendor[]: Google"

        # Get project IDs
        numeric_project_id=`$TW_CLOUD_IMDS_CMD/project/numeric-project-id 2>/dev/null`
        project_id=`$TW_CLOUD_IMDS_CMD/project/project-id 2>/dev/null`

        # Get VPC network
        network=`$TW_CLOUD_IMDS_CMD/instance/network-interfaces/0/network 2>/dev/null`

        # Build scope from network
        scope=`echo $network | sed -e "s/$numeric_project_id/$project_id/"`
        if [ "$scope" != "" ]; then
            echo "scope: $scope"
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "OPENSTACK" ]; then
        echo "openstack_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: OpenStack Compute"
    fi
fi

NetBSD

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# dmidecode requires superuser privileges to read data from the system BIOS
PRIV_DMIDECODE() {
    "$@"
}

is replaced with:

############################################################################
# Function to detect the cloud platform, if any

tw_detect_cloud_platform() {
    # Have we already detected the cloud platform?

    if [ -n "$TW_CLOUD_PLATFORM" ]; then
        return 0
    fi

    export TW_CLOUD_PLATFORM=
    export TW_CLOUD_ID=
    export TW_CLOUD_IMDS_CMD=

    # We need curl to make the required requests

    if [ ! -x /usr/local/bin/curl ]; then
        return 1
    fi
    CURL=/usr/local/bin/curl

    # Trying to detect Amazon EC2

    # These web requests are not chargeable.
    # See: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

    # Try IMDSv2 first
    TOKEN=`$CURL --connect-timeout 5 --max-time 10 --fail -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 1800" 2>/dev/null`
    if [ ! -z "$TOKEN" ]; then
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail -H \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data"
    else
        # Try IMDSv1
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/latest/meta-data"
    fi

    TW_CLOUD_ID=`$TW_CLOUD_IMDS_CMD/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    if [ -n "$TW_CLOUD_ID" ]; then
        # We need to check for OpenStack EC2-compatible metadata
        # https://docs.openstack.org/nova/latest/user/metadata.html#metadata-ec2-format
        OPENSTACK=`$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack 2>/dev/null`
        if [ ! -z "$OPENSTACK" ]; then
            TW_CLOUD_PLATFORM=OPENSTACK
            TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack/latest"
            return 0
        fi

        # Cloud platform is AWS
        TW_CLOUD_PLATFORM=AWS
        return 0
    fi

    # Try Azure
    # see: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service
    TW_CLOUD_ID=`$CURL --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' "http://169.254.169.254/metadata/instance/compute/vmId?api-version=2019-06-01&format=text" 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=AZURE
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' http://169.254.169.254/metadata"
        return 0
    fi

    # Try Google Compute engine
    # see: https://cloud.google.com/compute/docs/storing-retrieving-metadata
    TW_CLOUD_ID=`$CURL --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/id 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=GCE
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1"
        return 0
    fi

    TW_CLOUD_PLATFORM=None
    return 1
}

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
# AWS Systems Manager : True
############################################################################

# AWS System Manager privilege elevation functions
if [ `whoami` = "ssm-user" ]; then

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        sudo cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        sudo "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        sudo "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        sudo ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        sudo "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        sudo "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        sudo test "$@"
    }

else

    # Default privilege elevation functions

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        test "$@"
    }

fi

getNetworkInterfaces

The following code is added:

 
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>"
                echo "        ether $mac"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0x00000000 broadcast 255.255.255.255 scope tw:internet"
                done
            done
        fi
    fi
fi

getIPAddresses

The following code is added:

 
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>"
                echo "        ether $mac"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0x00000000 broadcast 255.255.255.255 scope tw:internet"
                done
            done
        fi
    fi
fi

Windows

The PATH environment variable has changed from:

%SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem

to:

"$env:SystemRoot\system32;$env:SystemRoot;$env:SystemRoot\System32\Wbem"

The following methods are added:

  • getNetworkConnectionList
  • getHostInfo
  • getMACAddresses
  • getFileMetadata
  • getPackageList
  • getProcessList
  • getNetworkInterfaces
  • getPatchList
  • getDeviceInfo
  • getIPAddresses
  • getFileSystems
  • getServices
  • getFileContent
  • getDirectoryListing

OpenBSD

getHostInfo

The following code:

 
}'
if [ -f /usr/sbin/dmidecode ]; then
    PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | awk '/DMI type 1,/,/^Handle 0x0*[2-9]+0*/ {
        if( $1 ~ /Manufacturer:/ ) { sub(".*Manufacturer: *","");  printf( "vendor: %s\n", $0 ); }
        if( $1 ~ /Product/ && $2 ~ /Name:/ ) { sub(".*Product Name: *",""); printf( "model: %s\n", $0 ); }
        if( $1 ~ /Serial/ && $2 ~ /Number:/ ) { sub(".*Serial Number: *",""); printf( "serial: %s\n", $0 ); }
    }'
fi

is replaced with:

}'
if [ -f /usr/sbin/dmidecode ]; then
    PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | awk '/DMI type 1,/,/^Handle 0x0*[2-9]+0*/ {
        if( $1 ~ /Manufacturer:/ ) { sub(".*Manufacturer: *","");  printf( "candidate_vendor[]: %s\n", $0 ); }
        if( $1 ~ /Product/ && $2 ~ /Name:/ ) { sub(".*Product Name: *",""); printf( "candidate_model[]: %s\n", $0 ); }
        if( $1 ~ /Serial/ && $2 ~ /Number:/ ) { sub(".*Serial Number: *",""); printf( "serial: %s\n", $0 ); }
    }'
fi

The following code is added:

# Cloud instance metadata
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    if [ "$TW_CLOUD_PLATFORM" == "AWS" ]; then
        echo "aws_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Amazon Virtual Machine"
        echo "candidate_vendor[]: Amazon"

        # Get primary MAC so we can find VPC
        primary_mac=`$TW_CLOUD_IMDS_CMD/mac 2>/dev/null`
        if [ "$primary_mac" != "" ]; then
            scope=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$primary_mac/vpc-id 2>/dev/null | egrep '^vpc-[0-9a-f]+$'`
            if [ "$scope" != "" ]; then
                echo "scope: $scope"
            fi
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "AZURE" ]; then
        echo "azure_vm_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Virtual Machine"
        echo "candidate_vendor[]: Microsoft Corporation"

    elif [ "$TW_CLOUD_PLATFORM" == "GCE" ]; then
        echo "gce_instance_id: " "$TW_CLOUD_ID"
        echo "candidate_model[]: Google Compute Engine"
        echo "candidate_vendor[]: Google"

        # Get project IDs
        numeric_project_id=`$TW_CLOUD_IMDS_CMD/project/numeric-project-id 2>/dev/null`
        project_id=`$TW_CLOUD_IMDS_CMD/project/project-id 2>/dev/null`

        # Get VPC network
        network=`$TW_CLOUD_IMDS_CMD/instance/network-interfaces/0/network 2>/dev/null`

        # Build scope from network
        scope=`echo $network | sed -e "s/$numeric_project_id/$project_id/"`
        if [ "$scope" != "" ]; then
            echo "scope: $scope"
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "OPENSTACK" ]; then
        echo "openstack_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: OpenStack Compute"
    fi
fi

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# dmidecode requires superuser privileges to read data from the system BIOS
PRIV_DMIDECODE() {
    "$@"
}

is replaced with:

############################################################################
# Function to detect the cloud platform, if any

tw_detect_cloud_platform() {
    # Have we already detected the cloud platform?

    if [ -n "$TW_CLOUD_PLATFORM" ]; then
        return 0
    fi

    export TW_CLOUD_PLATFORM=
    export TW_CLOUD_ID=
    export TW_CLOUD_IMDS_CMD=

    # We need curl to make the required requests

    if [ ! -x /usr/local/bin/curl ]; then
        return 1
    fi
    CURL=/usr/local/bin/curl

    # Trying to detect Amazon EC2

    # These web requests are not chargeable.
    # See: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

    # Try IMDSv2 first
    TOKEN=`$CURL --connect-timeout 5 --max-time 10 --fail -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 1800" 2>/dev/null`
    if [ ! -z "$TOKEN" ]; then
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail -H \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data"
    else
        # Try IMDSv1
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/latest/meta-data"
    fi

    TW_CLOUD_ID=`$TW_CLOUD_IMDS_CMD/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    if [ -n "$TW_CLOUD_ID" ]; then
        # We need to check for OpenStack EC2-compatible metadata
        # https://docs.openstack.org/nova/latest/user/metadata.html#metadata-ec2-format
        OPENSTACK=`$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack 2>/dev/null`
        if [ ! -z "$OPENSTACK" ]; then
            TW_CLOUD_PLATFORM=OPENSTACK
            TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack/latest"
            return 0
        fi

        # Cloud platform is AWS
        TW_CLOUD_PLATFORM=AWS
        return 0
    fi

    # Try Azure
    # see: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service
    TW_CLOUD_ID=`$CURL --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' "http://169.254.169.254/metadata/instance/compute/vmId?api-version=2019-06-01&format=text" 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=AZURE
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' http://169.254.169.254/metadata"
        return 0
    fi

    # Try Google Compute engine
    # see: https://cloud.google.com/compute/docs/storing-retrieving-metadata
    TW_CLOUD_ID=`$CURL --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/id 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=GCE
        TW_CLOUD_IMDS_CMD="$CURL --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1"
        return 0
    fi

    TW_CLOUD_PLATFORM=None
    return 1
}

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
# AWS Systems Manager : True
############################################################################

# AWS System Manager privilege elevation functions
if [ `whoami` = "ssm-user" ]; then

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        sudo cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        sudo "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        sudo "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        sudo ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        sudo "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        sudo "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        sudo test "$@"
    }

else

    # Default privilege elevation functions

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        test "$@"
    }

fi

getNetworkInterfaces

The following code is added:

 

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>"
                echo "        ether $mac"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0x00000000 broadcast 255.255.255.255 scope tw:internet"
                done
            done
        fi
    fi
fi

getIPAddresses

The following code is added:

 
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST>"
                echo "        ether $mac"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0x00000000 broadcast 255.255.255.255 scope tw:internet"
                done
            done
        fi
    fi
fi

Tru64

initialise

The following code:

 
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# setld requires superuser privileges to display information on packages
PRIV_SETLD() {
  "$@"
}

# hwmgr requires superuser privileges to get hardware component information
PRIV_HWMGR() {
  "$@"
}

is replaced with:

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
############################################################################


# cat requires superuser privileges to read some files belonging to
# other users
PRIV_CAT() {
    cat "$@"
}
# df requires superuser privileges to report file systems owned by other
# users
PRIV_DF() {
    "$@"
}
# hwmgr requires superuser privileges to get hardware component
# information
PRIV_HWMGR() {
    "$@"
}
# ls requires superuser privileges to allow access to some directories
# owned by other users
PRIV_LS() {
    ls "$@"
}
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
    "$@"
}
# Allow patterns to run commands with elevated privileges
PRIV_RUNCMD() {
    "$@"
}
# setld requires superuser privileges to display information on packages
PRIV_SETLD() {
    "$@"
}
# test requires superuser privileges to allow access to some files owned
# by other users
PRIV_TEST() {
    test "$@"
}

IRIX

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

is replaced with:

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
############################################################################


# cat requires superuser privileges to read some files belonging to
# other users
PRIV_CAT() {
    cat "$@"
}
# df requires superuser privileges to report file systems owned by other
# users
PRIV_DF() {
    "$@"
}
# ls requires superuser privileges to allow access to some directories
# owned by other users
PRIV_LS() {
    ls "$@"
}
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
    "$@"
}
# Allow patterns to run commands with elevated privileges
PRIV_RUNCMD() {
    "$@"
}
# test requires superuser privileges to allow access to some files owned
# by other users
PRIV_TEST() {
    test "$@"
}

Linux

getHostInfo

The following code:

  
# The specification only allows for the physical RAM size to be given in either
# KB or MB.  [System Management BIOS (SMBIOS) Reference Specification, p.86 -
# http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.8.0.pdf]
if [ -f /usr/sbin/dmidecode ]; then
    dmidecode_ram=`PRIV_DMIDECODE /usr/sbin/dmidecode -t 17 2>/dev/null | awk '
        /Size:/ {
            if ($3 == "kB" || $3 == "KB")
                size += $2
            else if ($3 == "MB")
                size += $2*1024
        }

is replaced with:

# According to the dmidecode source code the physical RAM size
# can be given in any unit, from bytes to ZB.
# [https://github.com/mirror/dmidecode/blob/master/dmidecode.c, dmi_print_memory_size()]
# ('KB' stays in to support older versions)
if [ -f /usr/sbin/dmidecode ]; then
    dmidecode_ram=`PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | sed -n '/DMI type 17,/,/^Handle 0x0/p' | awk '
        BEGIN {
            powers["bytes"] = -1
            powers["kB"]    = 0 # kilobytes
            powers["KB"]    = 0 # Kilobytes
            powers["MB"]    = 1 # Megabytes
            powers["GB"]    = 2 # Gigabytes
            powers["TB"]    = 3 # Terabytes
            powers["PB"]    = 4 # Petabytes
            powers["EB"]    = 5 # Exabytes
            powers["ZB"]    = 6 # Zetabytes
        }
        /Size: ([0-9]+) bytes|([kKMGTPEZ]B)/ {
            size += int($2 * (1024 ^ powers[$3]))

The following code:

 
# Trying to get the Amazon EC2 instance ID, if any.
aws_instance_id=""
if [ -x /opt/aws/bin/ec2-metadata ]; then
    aws_instance_id=`/opt/aws/bin/ec2-metadata -i 2>/dev/null | awk '{print $2; }'`
fi
if [ -z "$aws_instance_id" -a -f /usr/bin/curl ]; then
    # These web requests are not chargeable.
    # See: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

    # Try IMDSv2 first. We only need a short session so set TTL to 60 seconds.
    TOKEN=`curl --connect-timeout 5 --max-time 10 --fail -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60" 2>/dev/null`
    if [ ! -z "$TOKEN" ]; then
        aws_instance_id=`curl --connect-timeout 5 --max-time 10 --fail -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    else
        # Try IMDSv1
        aws_instance_id=`curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    fi
fi
if [ "$aws_instance_id" != "" ]; then
    echo "aws_instance_id: " "$aws_instance_id"
fi

# Try to get the GCE IDs, if any
# see: https://cloud.google.com/compute/docs/storing-retrieving-metadata
if [ -f /usr/bin/curl ]; then
    # Get instance ID
    gce_instance_id=`curl --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/id 2>/dev/null`
    if [ -n "$gce_instance_id" ]; then
        echo "gce_instance_id: " "$gce_instance_id"
    fi
fi

is replaced with:

# Cloud instance metadata
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    if [ "$TW_CLOUD_PLATFORM" == "AWS" ]; then
        echo "aws_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Amazon Virtual Machine"
        echo "candidate_vendor[]: Amazon"

        # Get primary MAC so we can find VPC
        primary_mac=`$TW_CLOUD_IMDS_CMD/mac 2>/dev/null`
        if [ "$primary_mac" != "" ]; then
            scope=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$primary_mac/vpc-id 2>/dev/null | egrep '^vpc-[0-9a-f]+$'`
            if [ "$scope" != "" ]; then
                echo "scope: $scope"
            fi
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "AZURE" ]; then
        echo "azure_vm_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Virtual Machine"
        echo "candidate_vendor[]: Microsoft Corporation"

    elif [ "$TW_CLOUD_PLATFORM" == "GCE" ]; then
        echo "gce_instance_id: " "$TW_CLOUD_ID"
        echo "candidate_model[]: Google Compute Engine"
        echo "candidate_vendor[]: Google"

        # Get project IDs
        numeric_project_id=`$TW_CLOUD_IMDS_CMD/project/numeric-project-id 2>/dev/null`
        project_id=`$TW_CLOUD_IMDS_CMD/project/project-id 2>/dev/null`

        # Get VPC network
        network=`$TW_CLOUD_IMDS_CMD/instance/network-interfaces/0/network 2>/dev/null`

        # Build scope from network
        scope=`echo $network | sed -e "s/$numeric_project_id/$project_id/"`
        if [ "$scope" != "" ]; then
            echo "scope: $scope"
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "OPENSTACK" ]; then
        echo "openstack_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: OpenStack Compute"
    fi
fi

initialise

The following code:

 
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# dmidecode requires superuser privileges to read data from the system BIOS
PRIV_DMIDECODE() {
    "$@"
}

# hwinfo requires superuser privileges to read data from the system BIOS
PRIV_HWINFO() {
    "$@"
}

# mii-tool requires superuser privileges to display any interface speed
# and negotiation settings
PRIV_MIITOOL() {
    "$@"
}

# ethtool requires superuser privileges to display any interface speed
# and negotiation settings
PRIV_ETHTOOL() {
    "$@"
}

# netstat requires superuser privileges to display process identifiers (PIDs)
# for ports opened by processes not running as the current user
PRIV_NETSTAT() {
    "$@"
}

# ss requires superuser privileges to display process identifiers (PIDs)
# for ports opened by processes not running as the current user
PRIV_SS() {
    "$@"
}

# lputil requires superuser privileges to display any HBA information
PRIV_LPUTIL() {
    "$@"
}

# hbacmd requires superuser privileges to display any HBA information
PRIV_HBACMD() {
    "$@"
}

# Xen's xe command requires superuser privileges
PRIV_XE(){
    "$@"
}

# esxcfg-info command requires superuser privileges
PRIV_ESXCFG(){
    "$@"
}

is replaced with:

############################################################################
# Function to detect the cloud platform, if any

tw_detect_cloud_platform() {
    # Have we already detected the cloud platform?

    if [ -n "$TW_CLOUD_PLATFORM" ]; then
        return 0
    fi

    export TW_CLOUD_PLATFORM=
    export TW_CLOUD_ID=
    export TW_CLOUD_IMDS_CMD=

    # We need curl to make the required requests

    if [ ! -x /usr/bin/curl ]; then
        return 1
    fi

    # Trying to detect Amazon EC2

    # These web requests are not chargeable.
    # See: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

    # Try IMDSv2 first
    TOKEN=`curl --connect-timeout 5 --max-time 10 --fail -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 1800" 2>/dev/null`
    if [ ! -z "$TOKEN" ]; then
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail -H \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data"
    else
        # Try IMDSv1
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/latest/meta-data"
    fi

    TW_CLOUD_ID=`$TW_CLOUD_IMDS_CMD/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    if [ -n "$TW_CLOUD_ID" ]; then
        # We need to check for OpenStack EC2-compatible metadata
        # https://docs.openstack.org/nova/latest/user/metadata.html#metadata-ec2-format
        OPENSTACK=`curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack 2>/dev/null`
        if [ ! -z "$OPENSTACK" ]; then
            TW_CLOUD_PLATFORM=OPENSTACK
            TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack/latest"
            return 0
        fi

        # Cloud platform is AWS
        TW_CLOUD_PLATFORM=AWS
        return 0
    fi

    # Try Azure
    # see: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service
    TW_CLOUD_ID=`curl --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' "http://169.254.169.254/metadata/instance/compute/vmId?api-version=2019-06-01&format=text" 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=AZURE
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' http://169.254.169.254/metadata"
        return 0
    fi

    # Try Google Compute engine
    # see: https://cloud.google.com/compute/docs/storing-retrieving-metadata
    TW_CLOUD_ID=`curl --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/id 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=GCE
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1"
        return 0
    fi

    TW_CLOUD_PLATFORM=None
    return 1
}

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
# AWS Systems Manager : True
############################################################################

# AWS System Manager privilege elevation functions
if [ `whoami` = "ssm-user" ]; then

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        sudo cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        sudo "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        sudo "$@"
    }
    # VMware's esxcfg-info command requires superuser privileges
    PRIV_ESXCFG() {
        sudo "$@"
    }
    # ethtool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_ETHTOOL() {
        sudo "$@"
    }
    # hbacmd requires superuser privileges to display any HBA information
    PRIV_HBACMD() {
        sudo "$@"
    }
    # hwinfo requires superuser privileges to read data from the system BIOS
    PRIV_HWINFO() {
        sudo "$@"
    }
    # lputil requires superuser privileges to display any HBA information
    PRIV_LPUTIL() {
        sudo "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        sudo ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        sudo "$@"
    }
    # mii-tool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_MIITOOL() {
        sudo "$@"
    }
    # netstat requires superuser privileges to display process identifiers
    # (PIDs) for ports opened by processes not running as the current user
    PRIV_NETSTAT() {
        sudo "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        sudo "$@"
    }
    # ss requires superuser privileges to display process identifiers (PIDs)
    # for ports opened by processes not running as the current user
    PRIV_SS() {
        sudo "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        sudo test "$@"
    }
    # Xen's xe command requires superuser privileges
    PRIV_XE() {
        sudo "$@"
    }

else

    # Default privilege elevation functions

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        "$@"
    }
    # VMware's esxcfg-info command requires superuser privileges
    PRIV_ESXCFG() {
        "$@"
    }
    # ethtool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_ETHTOOL() {
        "$@"
    }
    # hbacmd requires superuser privileges to display any HBA information
    PRIV_HBACMD() {
        "$@"
    }
    # hwinfo requires superuser privileges to read data from the system BIOS
    PRIV_HWINFO() {
        "$@"
    }
    # lputil requires superuser privileges to display any HBA information
    PRIV_LPUTIL() {
        "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        "$@"
    }
    # mii-tool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_MIITOOL() {
        "$@"
    }
    # netstat requires superuser privileges to display process identifiers
    # (PIDs) for ports opened by processes not running as the current user
    PRIV_NETSTAT() {
        "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        "$@"
    }
    # ss requires superuser privileges to display process identifiers (PIDs)
    # for ports opened by processes not running as the current user
    PRIV_SS() {
        "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        test "$@"
    }
    # Xen's xe command requires superuser privileges
    PRIV_XE() {
        "$@"
    }

fi

getNetworkInterfaces

The following code:

ip -o link show 2>/dev/null
 if [ $? -eq 0 ]; then

 ETHTOOL=""
 if [ -f /sbin/ethtool ]; then

is replaced with:

ip -o link show 2>/dev/null
if [ $? -eq 0 ]; then

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 ENIs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                n=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/device-number 2>/dev/null`
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                echo "$n: $id: <UP> link/ether $mac"
            done
        fi
    fi
fi


ETHTOOL=""
if [ -f /sbin/ethtool ]; then

getNetworkInterfaces

The following code:

 
ifconfig -a 2>/dev/null
if [ $? -eq 0 ]; then

ETHTOOL=""
if [ -f /sbin/ethtool ]; then

is replaced with:

ifconfig -a 2>/dev/null
if [ $? -eq 0 ]; then

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 ENIs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                n=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/device-number 2>/dev/null`
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                echo "$id: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500"
                echo "        ether $mac"
            done
        fi
    fi
fi


ETHTOOL=""
if [ -f /sbin/ethtool ]; then

getIPAddresses

The following code:

 
ifconfig -a 2>/dev/null

is replaced with:

ifconfig -a 2>/dev/null

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0.0.0.0 scope tw:internet"
                done
                echo "        ether $mac"
            done
        fi
    fi
fi

getIPAddresses

The following code:

 ip address show 2>/dev/null

is replaced with:

ip address show 2>/dev/null

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                n=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/device-number 2>/dev/null`
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$n: $id: <UP> mtu 1500 state UP"
                echo "    link/ether $mac brd ff:ff:ff:ff:ff:ff"
                for public_ip in $public_ips
                do
                        echo "    inet $public_ip/0 brd 0.0.0.0 scope tw:internet eth$n"
                done
            done
        fi
    fi
fi

AIX

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# lslpp requires superuser privileges to list all installed packages
PRIV_LSLPP() {
    "$@"
}

# lswpar requires superuser privileges to get wpar information.
PRIV_LSWPAR() {
    "$@"
}

is replaced with:

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
############################################################################

# cat requires superuser privileges to read some files belonging to
# other users
PRIV_CAT() {
    cat "$@"
}
# df requires superuser privileges to report file systems owned by other
# users
PRIV_DF() {
    "$@"
}
# ls requires superuser privileges to allow access to some directories
# owned by other users
PRIV_LS() {
    ls "$@"
}

The following code is added:

 
}
# lslpp requires superuser privileges to list all installed packages
PRIV_LSLPP() {
    "$@"
}
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
    "$@"
}
# lswpar requires superuser privileges to get wpar information
PRIV_LSWPAR() {
    "$@"
}
# Allow patterns to run commands with elevated privileges
PRIV_RUNCMD() {
    "$@"
}
# test requires superuser privileges to allow access to some files owned
# by other users
PRIV_TEST() {
    test "$@"
}

Mac OS X

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

is replaced with:

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
# AWS Systems Manager : True
############################################################################

# AWS System Manager privilege elevation functions
if [ `whoami` = "ssm-user" ]; then

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        sudo cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        sudo "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        sudo ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        sudo "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        sudo "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        sudo test "$@"
    }

else

    # Default privilege elevation functions

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        test "$@"
    }
fi

UnixWare

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

is replaced with:

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
############################################################################


# cat requires superuser privileges to read some files belonging to
# other users
PRIV_CAT() {
    cat "$@"
}
# df requires superuser privileges to report file systems owned by other
# users
PRIV_DF() {
    "$@"
}
# ls requires superuser privileges to allow access to some directories
# owned by other users
PRIV_LS() {
    ls "$@"
}
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
    "$@"
}

# Allow patterns to run commands with elevated privileges
PRIV_RUNCMD() {
    "$@"
}

# test requires superuser privileges to allow access to some files owned
# by other users
PRIV_TEST() {
    test "$@"
}

Solaris

initialise

The following code is removed:

 
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"
}

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

The following code is removed:

# dmidecode requires superuser privileges to read data from the system BIOS
# on Solaris X86 platforms only
PRIV_DMIDECODE() {
    "$@"
}

# ifconfig requires superuser privileges to display the MAC address of each
# interface
PRIV_IFCONFIG() {
    "$@"
}

# dladm requires superuser privileges to display speed, duplex settings, and
# port aggregation information
PRIV_DLADM() {
    "$@"
}

# ndd requires superuser privileges to display any interface speed
# and negotiation settings
PRIV_NDD() {
    "$@"
}

The following code:

 
#
# In order for the Discovery Condition pattern to correctly detect whether
# ps is being executed with proc_owner privilege, this function must accept
# both the ps command and the ppriv command used by pattern.
PRIV_PS() {

# See comments above PRIV_PS, above
PRIV_PARGS() {
    "$@"
}

# lputil requires superuser privileges to display any HBA information
PRIV_LPUTIL() {
    "$@"
}

# hbacmd requires superuser privileges to display any HBA information
PRIV_HBACMD() {
    "$@"
}

# emlxadm requires superuser privileges to display any HBA information
PRIV_EMLXADM() {
    "$@"
}

# fcinfo requires superuser privileges to display any HBA information
PRIV_FCINFO() {
    "$@"
}

# pfiles requires superuser privileges to display open port information
# for processes not running as the current user
PRIV_PFILES() {
    "$@"
}

# At end as locale is slow leading to Solaris small input buffer overflowing
tw_locale=`locale -a | grep -i en_us | grep -i "utf.*8" | head -n 1 2>/dev/null`

is replaced with:

# In order for the Discovery Condition pattern to correctly detect whether
# ps is being executed with proc_owner privilege, the PRIV_PS function must
# accept both the ps command and the ppriv command used by pattern.

## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
############################################################################


# cat requires superuser privileges to read some files belonging to
# other users
PRIV_CAT() {
    cat "$@"
}
# df requires superuser privileges to report file systems owned by other
# users
PRIV_DF() {
    "$@"
}
# dladm requires superuser privileges to display any interface speed and
# negotiation settings and port aggregation information
PRIV_DLADM() {
    "$@"
}
# dmidecode requires superuser privileges to read data from the system
# BIOS on Solaris x86 system only
PRIV_DMIDECODE() {
    "$@"
}
# emlxadm requires superuser privileges to display any HBA information
PRIV_EMLXADM() {
    "$@"
}
# fcinfo requires superuser privileges to display any HBA information
PRIV_FCINFO() {
    "$@"
}
# hbacmd requires superuser privileges to display any HBA information
PRIV_HBACMD() {
    "$@"
}
# ifconfig requires superuser privileges to display the MAC address of
# each interface
PRIV_IFCONFIG() {
    "$@"
}
# lputil requires superuser privileges to display any HBA information
PRIV_LPUTIL() {
    "$@"
}
# ls requires superuser privileges to allow access to some directories
# owned by other users
PRIV_LS() {
    ls "$@"
}
# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
    "$@"
}
# ndd requires superuser privileges to display any interface speed and
# negotiation settings
PRIV_NDD() {
    "$@"
}
# pargs requires superuser privileges to report full command line
# information
PRIV_PARGS() {
    "$@"
}
# pfiles requires superuser privileges to display open port information
# for processes not running as the current user
PRIV_PFILES() {
    "$@"
}
# ps requires superuser privileges to report full command line
# information
PRIV_PS() {
    "$@"
}
# Allow patterns to run commands with elevated privileges
PRIV_RUNCMD() {
    "$@"
}
# test requires superuser privileges to allow access to some files owned
# by other users
PRIV_TEST() {
    test "$@"
}

## END PRIVILEGE FUNCTIONS ###############################################

# At end as locale is slow leading to Solaris small input buffer overflowing
tw_locale=`locale -a | grep -i en_us | grep -i "utf.*8" | head -n 1 2>/dev/null`

VMware ESX

getHostInfo

The following code:

  
# The specification only allows for the physical RAM size to be given in either
# KB or MB.  [System Management BIOS (SMBIOS) Reference Specification, p.86 -
# http://www.dmtf.org/sites/default/files/standards/documents/DSP0134_2.8.0.pdf]
if [ -f /usr/sbin/dmidecode ]; then
    dmidecode_ram=`PRIV_DMIDECODE /usr/sbin/dmidecode -t 17 2>/dev/null | awk '
        /Size:/ {
            if ($3 == "kB" || $3 == "KB")
                size += $2
            else if ($3 == "MB")
                size += $2*1024
        }

is replaced with:

# According to the dmidecode source code the physical RAM size
# can be given in any unit, from bytes to ZB.
# [https://github.com/mirror/dmidecode/blob/master/dmidecode.c, dmi_print_memory_size()]
# ('KB' stays in to support older versions)
if [ -f /usr/sbin/dmidecode ]; then
    dmidecode_ram=`PRIV_DMIDECODE /usr/sbin/dmidecode 2>/dev/null | sed -n '/DMI type 17,/,/^Handle 0x0/p' | awk '
        BEGIN {
            powers["bytes"] = -1
            powers["kB"]    = 0 # kilobytes
            powers["KB"]    = 0 # Kilobytes
            powers["MB"]    = 1 # Megabytes
            powers["GB"]    = 2 # Gigabytes
            powers["TB"]    = 3 # Terabytes
            powers["PB"]    = 4 # Petabytes
            powers["EB"]    = 5 # Exabytes
            powers["ZB"]    = 6 # Zetabytes
        }
        /Size: ([0-9]+) bytes|([kKMGTPEZ]B)/ {
            size += int($2 * (1024 ^ powers[$3]))
        }

The following code:

 
# Trying to get the Amazon EC2 instance ID, if any.
aws_instance_id=""
if [ -x /opt/aws/bin/ec2-metadata ]; then
    aws_instance_id=`/opt/aws/bin/ec2-metadata -i 2>/dev/null | awk '{print $2; }'`
fi
if [ -z "$aws_instance_id" -a -f /usr/bin/curl ]; then
    # These web requests are not chargeable.
    # See: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

    # Try IMDSv2 first. We only need a short session so set TTL to 60 seconds.
    TOKEN=`curl --connect-timeout 5 --max-time 10 --fail -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 60" 2>/dev/null`
    if [ ! -z "$TOKEN" ]; then
        aws_instance_id=`curl --connect-timeout 5 --max-time 10 --fail -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    else
        # Try IMDSv1
        aws_instance_id=`curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    fi
fi
if [ "$aws_instance_id" != "" ]; then
    echo "aws_instance_id: " "$aws_instance_id"
fi

# Try to get the GCE IDs, if any
# see: https://cloud.google.com/compute/docs/storing-retrieving-metadata
if [ -f /usr/bin/curl ]; then
    # Get instance ID
    gce_instance_id=`curl --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/id 2>/dev/null`
    if [ -n "$gce_instance_id" ]; then
        echo "gce_instance_id: " "$gce_instance_id"
    fi
fi

is replaced with:

# Cloud instance metadata
tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    if [ "$TW_CLOUD_PLATFORM" == "AWS" ]; then
        echo "aws_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Amazon Virtual Machine"
        echo "candidate_vendor[]: Amazon"

        # Get primary MAC so we can find VPC
        primary_mac=`$TW_CLOUD_IMDS_CMD/mac 2>/dev/null`
        if [ "$primary_mac" != "" ]; then
            scope=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$primary_mac/vpc-id 2>/dev/null | egrep '^vpc-[0-9a-f]+$'`
            if [ "$scope" != "" ]; then
                echo "scope: $scope"
            fi
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "AZURE" ]; then
        echo "azure_vm_id: $TW_CLOUD_ID"
        echo "candidate_model[]: Virtual Machine"
        echo "candidate_vendor[]: Microsoft Corporation"

    elif [ "$TW_CLOUD_PLATFORM" == "GCE" ]; then
        echo "gce_instance_id: " "$TW_CLOUD_ID"
        echo "candidate_model[]: Google Compute Engine"
        echo "candidate_vendor[]: Google"

        # Get project IDs
        numeric_project_id=`$TW_CLOUD_IMDS_CMD/project/numeric-project-id 2>/dev/null`
        project_id=`$TW_CLOUD_IMDS_CMD/project/project-id 2>/dev/null`

        # Get VPC network
        network=`$TW_CLOUD_IMDS_CMD/instance/network-interfaces/0/network 2>/dev/null`

        # Build scope from network
        scope=`echo $network | sed -e "s/$numeric_project_id/$project_id/"`
        if [ "$scope" != "" ]; then
            echo "scope: $scope"
        fi

    elif [ "$TW_CLOUD_PLATFORM" == "OPENSTACK" ]; then
        echo "openstack_instance_id: $TW_CLOUD_ID"
        echo "candidate_model[]: OpenStack Compute"
    fi
fi

VMware ESX

initialise

The following code:

  
# replace the following PRIV_XXX functions with one that has the path to a
# program to run the commands as super user, e.g. sudo. For example
# PRIV_LSOF() {
#   /usr/bin/sudo "$@"
# }

# lsof requires superuser privileges to display information on processes
# other than those running as the current user
PRIV_LSOF() {
  "$@"

# This function supports running privileged commands from patterns
PRIV_RUNCMD() {
  "$@"
}

# This function supports privileged cat of files.
# Used in patterns and to get file content.
PRIV_CAT() {
  cat "$@"
}

# This function supports privilege testing of attributes of files.
# Used in conjunction with PRIV_CAT and PRIV_LS
PRIV_TEST() {
  test "$@"
}

# This function supports privilege listing of files and directories
# Used in conjunction with PRIV_TEST
PRIV_LS() {
  ls "$@"
}

# This function supports privilege listing of file systems and related
# size and usage.
PRIV_DF() {
  "$@"
}

# dmidecode requires superuser privileges to read data from the system BIOS
PRIV_DMIDECODE() {
    "$@"
}

# hwinfo requires superuser privileges to read data from the system BIOS
PRIV_HWINFO() {
    "$@"
}

# mii-tool requires superuser privileges to display any interface speed
# and negotiation settings
PRIV_MIITOOL() {
    "$@"
}

# ethtool requires superuser privileges to display any interface speed
# and negotiation settings
PRIV_ETHTOOL() {
    "$@"
}

# netstat requires superuser privileges to display process identifiers (PIDs)
# for ports opened by processes not running as the current user
PRIV_NETSTAT() {
    "$@"
}

# ss requires superuser privileges to display process identifiers (PIDs)
# for ports opened by processes not running as the current user
PRIV_SS() {
    "$@"
}

# lputil requires superuser privileges to display any HBA information
PRIV_LPUTIL() {
    "$@"
}

# hbacmd requires superuser privileges to display any HBA information
PRIV_HBACMD() {
    "$@"
}

# Xen's xe command requires superuser privileges
PRIV_XE(){
    "$@"
}

# esxcfg-info command requires superuser privileges
PRIV_ESXCFG(){
    "$@"
}

is replaced with:

############################################################################
# Function to detect the cloud platform, if any

tw_detect_cloud_platform() {
    # Have we already detected the cloud platform?

    if [ -n "$TW_CLOUD_PLATFORM" ]; then
        return 0
    fi

    export TW_CLOUD_PLATFORM=
    export TW_CLOUD_ID=
    export TW_CLOUD_IMDS_CMD=

    # We need curl to make the required requests

    if [ ! -x /usr/bin/curl ]; then
        return 1
    fi

    # Trying to detect Amazon EC2

    # These web requests are not chargeable.
    # See: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html

    # Try IMDSv2 first
    TOKEN=`curl --connect-timeout 5 --max-time 10 --fail -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 1800" 2>/dev/null`
    if [ ! -z "$TOKEN" ]; then
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail -H \"X-aws-ec2-metadata-token: $TOKEN\" http://169.254.169.254/latest/meta-data"
    else
        # Try IMDSv1
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/latest/meta-data"
    fi

    TW_CLOUD_ID=`$TW_CLOUD_IMDS_CMD/instance-id 2>/dev/null | egrep '^i-[0-9a-f]+$'`
    if [ -n "$TW_CLOUD_ID" ]; then
        # We need to check for OpenStack EC2-compatible metadata
        # https://docs.openstack.org/nova/latest/user/metadata.html#metadata-ec2-format
        OPENSTACK=`curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack 2>/dev/null`
        if [ ! -z "$OPENSTACK" ]; then
            TW_CLOUD_PLATFORM=OPENSTACK
            TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail http://169.254.169.254/openstack/latest"
            return 0
        fi

        # Cloud platform is AWS
        TW_CLOUD_PLATFORM=AWS
        return 0
    fi

    # Try Azure
    # see: https://docs.microsoft.com/en-us/azure/virtual-machines/linux/instance-metadata-service
    TW_CLOUD_ID=`curl --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' "http://169.254.169.254/metadata/instance/compute/vmId?api-version=2019-06-01&format=text" 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=AZURE
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail -H 'Metadata:true' http://169.254.169.254/metadata"
        return 0
    fi

    # Try Google Compute engine
    # see: https://cloud.google.com/compute/docs/storing-retrieving-metadata
    TW_CLOUD_ID=`curl --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1/instance/id 2>/dev/null`
    if [ -n "$TW_CLOUD_ID" ]; then
        TW_CLOUD_PLATFORM=GCE
        TW_CLOUD_IMDS_CMD="curl --connect-timeout 5 --max-time 10 --fail --header 'Metadata-Flavor: Google' http://metadata.google.internal/computeMetadata/v1"
        return 0
    fi

    TW_CLOUD_PLATFORM=None
    return 1
}
## BEGIN PRIVILEGE FUNCTIONS ###############################################
# Privilege command   : None
# AWS Systems Manager : True
############################################################################

# AWS System Manager privilege elevation functions
if [ `whoami` = "ssm-user" ]; then

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        sudo cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        sudo "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        sudo "$@"
    }
    # VMware's esxcfg-info command requires superuser privileges
    PRIV_ESXCFG() {
        sudo "$@"
    }
    # ethtool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_ETHTOOL() {
        sudo "$@"
    }
    # hbacmd requires superuser privileges to display any HBA information
    PRIV_HBACMD() {
        sudo "$@"
    }
    # hwinfo requires superuser privileges to read data from the system BIOS
    PRIV_HWINFO() {
        sudo "$@"
    }
    # lputil requires superuser privileges to display any HBA information
    PRIV_LPUTIL() {
        sudo "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        sudo ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        sudo "$@"
    }
    # mii-tool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_MIITOOL() {
        sudo "$@"
    }
    # netstat requires superuser privileges to display process identifiers
    # (PIDs) for ports opened by processes not running as the current user
    PRIV_NETSTAT() {
        sudo "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        sudo "$@"
    }
    # ss requires superuser privileges to display process identifiers (PIDs)
    # for ports opened by processes not running as the current user
    PRIV_SS() {
        sudo "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        sudo test "$@"
    }
    # Xen's xe command requires superuser privileges
    PRIV_XE() {
        sudo "$@"
    }

else

    # Default privilege elevation functions

    # cat requires superuser privileges to read some files belonging to
    # other users
    PRIV_CAT() {
        cat "$@"
    }
    # df requires superuser privileges to report file systems owned by other
    # users
    PRIV_DF() {
        "$@"
    }
    # dmidecode requires superuser privileges to read data from the system
    # BIOS
    PRIV_DMIDECODE() {
        "$@"
    }
    # VMware's esxcfg-info command requires superuser privileges
    PRIV_ESXCFG() {
        "$@"
    }
    # ethtool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_ETHTOOL() {
        "$@"
    }
    # hbacmd requires superuser privileges to display any HBA information
    PRIV_HBACMD() {
        "$@"
    }
    # hwinfo requires superuser privileges to read data from the system BIOS
    PRIV_HWINFO() {
        "$@"
    }
    # lputil requires superuser privileges to display any HBA information
    PRIV_LPUTIL() {
        "$@"
    }
    # ls requires superuser privileges to allow access to some directories
    # owned by other users
    PRIV_LS() {
        ls "$@"
    }
    # lsof requires superuser privileges to display information on processes
    # other than those running as the current user
    PRIV_LSOF() {
        "$@"
    }
    # mii-tool requires superuser privileges to display any interface speed
    # and negotiation settings
    PRIV_MIITOOL() {
        "$@"
    }
    # netstat requires superuser privileges to display process identifiers
    # (PIDs) for ports opened by processes not running as the current user
    PRIV_NETSTAT() {
        "$@"
    }
    # Allow patterns to run commands with elevated privileges
    PRIV_RUNCMD() {
        "$@"
    }
    # ss requires superuser privileges to display process identifiers (PIDs)
    # for ports opened by processes not running as the current user
    PRIV_SS() {
        "$@"
    }
    # test requires superuser privileges to allow access to some files owned
    # by other users
    PRIV_TEST() {
        test "$@"
    }
    # Xen's xe command requires superuser privileges
    PRIV_XE() {
        "$@"
    }

fi

VMware ESX

getNetworkInterfaces

The following code:

 
ip -o link show 2>/dev/null
if [ $? -eq 0 ]; then

ETHTOOL=""
if [ -f /sbin/ethtool ]; then

is replaced with:

ip -o link show 2>/dev/null
if [ $? -eq 0 ]; then

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 ENIs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                n=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/device-number 2>/dev/null`
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                echo "$n: $id: <UP> link/ether $mac"
            done
        fi
    fi
fi


ETHTOOL=""
if [ -f /sbin/ethtool ]; then

getNetworkInterfaces

The following code:

 
ifconfig -a 2>/dev/null
if [ $? -eq 0 ]; then

ETHTOOL=""
if [ -f /sbin/ethtool ]; then

is replaced with:

ifconfig -a 2>/dev/null
if [ $? -eq 0 ]; then

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 ENIs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                n=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/device-number 2>/dev/null`
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                echo "$id: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500"
                echo "        ether $mac"
            done
        fi
    fi
fi


ETHTOOL=""
if [ -f /sbin/ethtool ]; then

getIPAddresses

The following code:

ifconfig -a 2>/dev/null

is replaced with:

ifconfig -a 2>/dev/null

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$id: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500"
                for public_ip in $public_ips
                do
                    echo "        inet $public_ip netmask 0.0.0.0 scope tw:internet"
                done
                echo "        ether $mac"
            done
        fi
    fi
fi

getIPAddresses

The following code:

 
ip address show 2>/dev/null

is replaced with:

ip address show 2>/dev/null

tw_detect_cloud_platform
if [ $? -eq 0 ]; then
    # AWS EC2 public/elastic IPs
    if [ "$TW_CLOUD_PLATFORM" = "AWS" ]; then
        macs=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/ 2>/dev/null | sed -e 's/\///g'`
        if [ ! -z "$macs" ]; then
            for mac in $macs
            do
                n=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/device-number 2>/dev/null`
                id=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/interface-id 2>/dev/null`
                public_ips=`$TW_CLOUD_IMDS_CMD/network/interfaces/macs/$mac/public-ipv4s 2>/dev/null`

                echo "$n: $id: <UP> mtu 1500 state UP"
                echo "    link/ether $mac brd ff:ff:ff:ff:ff:ff"
                for public_ip in $public_ips
                do
                        echo "    inet $public_ip/0 brd 0.0.0.0 scope tw:internet eth$n"
                done
            done
        fi
    fi
fi

 

Tip: For faster searching, add an asterisk to the end of your partial query. Example: cert*