This file is indexed.

/usr/bin/neutron-rootwrap-xen-dom0 is in neutron-common 2:8.0.0-0ubuntu1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#!/usr/bin/python

# Copyright (c) 2012 OpenStack Foundation
# All Rights Reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

"""Neutron root wrapper for dom0.

Executes networking commands in dom0.  The XenAPI plugin is
responsible determining whether a command is safe to execute.

"""
from __future__ import print_function

from six.moves import configparser as ConfigParser
from oslo_serialization import jsonutils as json

import os
import select
import sys
import traceback

import XenAPI


RC_UNAUTHORIZED = 99
RC_NOCOMMAND = 98
RC_BADCONFIG = 97
RC_XENAPI_ERROR = 96


def parse_args():
    # Split arguments, require at least a command
    exec_name = sys.argv.pop(0)
    # argv[0] required; path to conf file
    if len(sys.argv) < 2:
        print("%s: No command specified" % exec_name)
        sys.exit(RC_NOCOMMAND)

    config_file = sys.argv.pop(0)
    user_args = sys.argv[:]

    return exec_name, config_file, user_args


def _xenapi_section_name(config):
    sections = [sect for sect in config.sections() if sect.lower() == "xenapi"]
    if len(sections) == 1:
        return sections[0]

    print("Multiple [xenapi] sections or no [xenapi] section found!")
    sys.exit(RC_BADCONFIG)


def load_configuration(exec_name, config_file):
    config = ConfigParser.RawConfigParser()
    config.read(config_file)
    try:
        exec_dirs = config.get("DEFAULT", "exec_dirs").split(",")
        filters_path = config.get("DEFAULT", "filters_path").split(",")
        section = _xenapi_section_name(config)
        url = config.get(section, "xenapi_connection_url")
        username = config.get(section, "xenapi_connection_username")
        password = config.get(section, "xenapi_connection_password")
    except ConfigParser.Error:
        print("%s: Incorrect configuration file: %s" % (exec_name, config_file))
        sys.exit(RC_BADCONFIG)
    if not url or not password:
        msg = ("%s: Must specify xenapi_connection_url, "
               "xenapi_connection_username (optionally), and "
               "xenapi_connection_password in %s") % (exec_name, config_file)
        print(msg)
        sys.exit(RC_BADCONFIG)
    return dict(
        filters_path=filters_path,
        url=url,
        username=username,
        password=password,
        exec_dirs=exec_dirs,
    )


def filter_command(exec_name, filters_path, user_args, exec_dirs):
    # Add ../ to sys.path to allow running from branch
    possible_topdir = os.path.normpath(os.path.join(os.path.abspath(exec_name),
                                                    os.pardir, os.pardir))
    if os.path.exists(os.path.join(possible_topdir, "neutron", "__init__.py")):
        sys.path.insert(0, possible_topdir)

    from oslo_rootwrap import wrapper

    # Execute command if it matches any of the loaded filters
    filters = wrapper.load_filters(filters_path)
    filter_match = wrapper.match_filter(
        filters, user_args, exec_dirs=exec_dirs)
    if not filter_match:
        print("Unauthorized command: %s" % ' '.join(user_args))
        sys.exit(RC_UNAUTHORIZED)


def run_command(url, username, password, user_args, cmd_input):
    try:
        session = XenAPI.Session(url)
        session.login_with_password(username, password)
        host = session.xenapi.session.get_this_host(session.handle)
        result = session.xenapi.host.call_plugin(
            host, 'netwrap', 'run_command',
            {'cmd': json.dumps(user_args), 'cmd_input': json.dumps(cmd_input)})
        return json.loads(result)
    except Exception as e:
        traceback.print_exc()
        sys.exit(RC_XENAPI_ERROR)


def main():
    exec_name, config_file, user_args = parse_args()
    config = load_configuration(exec_name, config_file)
    filter_command(exec_name, config['filters_path'], user_args, config['exec_dirs'])

    # If data is available on the standard input, we need to pass it to the
    # command executed in dom0
    cmd_input = None
    if select.select([sys.stdin,],[],[],0.0)[0]:
        cmd_input = "".join(sys.stdin)

    return run_command(config['url'], config['username'], config['password'],
                       user_args, cmd_input)


if __name__ == '__main__':
    print(main())