Removing obsolete functionality

This commit is contained in:
Miroslav Stampar 2016-09-28 15:00:26 +02:00
parent 3ef01f0e31
commit e77126e847
5 changed files with 4 additions and 830 deletions

View File

@ -19,7 +19,7 @@ from lib.core.enums import OS
from lib.core.revision import getRevisionNumber
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.0.9.47"
VERSION = "1.0.9.48"
REVISION = getRevisionNumber()
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}

View File

@ -68,7 +68,6 @@ from lib.core.settings import URI_INJECTABLE_REGEX
from lib.core.settings import USER_AGENT_ALIASES
from lib.core.settings import XML_RECOGNITION_REGEX
from lib.utils.hashdb import HashDB
from lib.core.xmldump import dumper as xmldumper
from thirdparty.odict.odict import OrderedDict
def _setRequestParams():
@ -593,11 +592,7 @@ def _createDumpDir():
conf.dumpPath = tempDir
def _configureDumper():
if hasattr(conf, 'xmlFile') and conf.xmlFile:
conf.dumper = xmldumper
else:
conf.dumper = dumper
conf.dumper = dumper
conf.dumper.setOutputFile()
def _createTargetDirs():

View File

@ -1,536 +0,0 @@
#!/usr/bin/env python
import codecs
import os
import re
import xml
import xml.sax.saxutils as saxutils
from lib.core.common import getUnicode
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
from lib.core.exception import SqlmapFilePathException
from lib.core.settings import UNICODE_ENCODING
from thirdparty.prettyprint import prettyprint
from xml.dom.minidom import Document
from xml.parsers.expat import ExpatError
TECHNIC_ELEM_NAME = "Technic"
TECHNICS_ELEM_NAME = "Technics"
BANNER_ELEM_NAME = "Banner"
COLUMNS_ELEM_NAME = "DatabaseColumns"
COLUMN_ELEM_NAME = "Column"
CELL_ELEM_NAME = "Cell"
COLUMN_ATTR = "column"
ROW_ELEM_NAME = "Row"
TABLES_ELEM_NAME = "tables"
DATABASE_COLUMNS_ELEM = "DB"
DB_TABLES_ELEM_NAME = "DBTables"
DB_TABLE_ELEM_NAME = "DBTable"
IS_DBA_ELEM_NAME = "isDBA"
FILE_CONTENT_ELEM_NAME = "FileContent"
DB_ATTR = "db"
UNKNOWN_COLUMN_TYPE = "unknown"
USER_SETTINGS_ELEM_NAME = "UserSettings"
USER_SETTING_ELEM_NAME = "UserSetting"
USERS_ELEM_NAME = "Users"
USER_ELEM_NAME = "User"
DB_USER_ELEM_NAME = "DBUser"
SETTINGS_ELEM_NAME = "Settings"
DBS_ELEM_NAME = "DBs"
DB_NAME_ELEM_NAME = "DBName"
DATABASE_ELEM_NAME = "Database"
TABLE_ELEM_NAME = "Table"
DB_TABLE_VALUES_ELEM_NAME = "DBTableValues"
DB_VALUES_ELEM = "DBValues"
QUERIES_ELEM_NAME = "Queries"
QUERY_ELEM_NAME = "Query"
REGISTERY_ENTRIES_ELEM_NAME = "RegistryEntries"
REGISTER_DATA_ELEM_NAME = "RegisterData"
DEFAULT_DB = "All"
MESSAGE_ELEM = "Message"
MESSAGES_ELEM_NAME = "Messages"
ERROR_ELEM_NAME = "Error"
LST_ELEM_NAME = "List"
LSTS_ELEM_NAME = "Lists"
CURRENT_USER_ELEM_NAME = "CurrentUser"
CURRENT_DB_ELEM_NAME = "CurrentDB"
MEMBER_ELEM = "Member"
ADMIN_USER = "Admin"
REGULAR_USER = "User"
STATUS_ELEM_NAME = "Status"
RESULTS_ELEM_NAME = "Results"
UNHANDLED_PROBLEM_TYPE = "Unhandled"
NAME_ATTR = "name"
TYPE_ATTR = "type"
VALUE_ATTR = "value"
SUCESS_ATTR = "success"
NAME_SPACE_ATTR = 'http://www.w3.org/2001/XMLSchema-instance'
XMLNS_ATTR = "xmlns:xsi"
SCHEME_NAME = "sqlmap.xsd"
SCHEME_NAME_ATTR = "xsi:noNamespaceSchemaLocation"
CHARACTERS_TO_ENCODE = range(32) + range(127, 256)
ENTITIES = {'"': '&quot;', "'": "&apos;"}
class XMLDump(object):
'''
This class purpose is to dump the data into an xml Format.
The format of the xml file is described in the scheme file xml/sqlmap.xsd
'''
def __init__(self):
self._outputFile = None
self._outputFP = None
self.__root = None
self.__doc = Document()
def _addToRoot(self, element):
'''
Adds element to the root element
'''
self.__root.appendChild(element)
def __write(self, data, n=True):
'''
Writes the data into the file
'''
if n:
self._outputFP.write("%s\n" % data)
else:
self._outputFP.write("%s " % data)
self._outputFP.flush()
kb.dataOutputFlag = True
def _getRootChild(self, elemName):
'''
Returns the child of the root with the described name
'''
elements = self.__root.getElementsByTagName(elemName)
if elements:
return elements[0]
return elements
def _createTextNode(self, data):
'''
Creates a text node with utf8 data inside.
The text is escaped to an fit the xml text Format.
'''
if data is None:
return self.__doc.createTextNode(u'')
else:
escaped_data = saxutils.escape(data, ENTITIES)
return self.__doc.createTextNode(escaped_data)
def _createAttribute(self, attrName, attrValue):
'''
Creates an attribute node with utf8 data inside.
The text is escaped to an fit the xml text Format.
'''
attr = self.__doc.createAttribute(attrName)
if attrValue is None:
attr.nodeValue = u''
else:
attr.nodeValue = getUnicode(attrValue)
return attr
def string(self, header, data, sort=True):
'''
Adds string element to the xml.
'''
if isinstance(data, (list, tuple, set)):
self.lister(header, data, sort)
return
messagesElem = self._getRootChild(MESSAGES_ELEM_NAME)
if (not(messagesElem)):
messagesElem = self.__doc.createElement(MESSAGES_ELEM_NAME)
self._addToRoot(messagesElem)
if data:
data = self._formatString(data)
else:
data = ""
elem = self.__doc.createElement(MESSAGE_ELEM)
elem.setAttributeNode(self._createAttribute(TYPE_ATTR, header))
elem.appendChild(self._createTextNode(data))
messagesElem.appendChild(elem)
def lister(self, header, elements, sort=True):
'''
Adds information formatted as list element
'''
lstElem = self.__doc.createElement(LST_ELEM_NAME)
lstElem.setAttributeNode(self._createAttribute(TYPE_ATTR, header))
if elements:
if sort:
try:
elements = set(elements)
elements = list(elements)
elements.sort(key=lambda x: x.lower())
except:
pass
for element in elements:
memberElem = self.__doc.createElement(MEMBER_ELEM)
lstElem.appendChild(memberElem)
if isinstance(element, basestring):
memberElem.setAttributeNode(self._createAttribute(TYPE_ATTR, "string"))
memberElem.appendChild(self._createTextNode(element))
elif isinstance(element, (list, tuple, set)):
memberElem.setAttributeNode(self._createAttribute(TYPE_ATTR, "list"))
for e in element:
memberElemStr = self.__doc.createElement(MEMBER_ELEM)
memberElemStr.setAttributeNode(self._createAttribute(TYPE_ATTR, "string"))
memberElemStr.appendChild(self._createTextNode(getUnicode(e)))
memberElem.appendChild(memberElemStr)
listsElem = self._getRootChild(LSTS_ELEM_NAME)
if not(listsElem):
listsElem = self.__doc.createElement(LSTS_ELEM_NAME)
self._addToRoot(listsElem)
listsElem.appendChild(lstElem)
def technic(self, technicType, data):
'''
Adds information about the technic used to extract data from the db
'''
technicElem = self.__doc.createElement(TECHNIC_ELEM_NAME)
technicElem.setAttributeNode(self._createAttribute(TYPE_ATTR, technicType))
textNode = self._createTextNode(data)
technicElem.appendChild(textNode)
technicsElem = self._getRootChild(TECHNICS_ELEM_NAME)
if not(technicsElem):
technicsElem = self.__doc.createElement(TECHNICS_ELEM_NAME)
self._addToRoot(technicsElem)
technicsElem.appendChild(technicElem)
def banner(self, data):
'''
Adds information about the database banner to the xml.
The banner contains information about the type and the version of the database.
'''
bannerElem = self.__doc.createElement(BANNER_ELEM_NAME)
bannerElem.appendChild(self._createTextNode(data))
self._addToRoot(bannerElem)
def currentUser(self, data):
'''
Adds information about the current database user to the xml
'''
currentUserElem = self.__doc.createElement(CURRENT_USER_ELEM_NAME)
textNode = self._createTextNode(data)
currentUserElem.appendChild(textNode)
self._addToRoot(currentUserElem)
def currentDb(self, data):
'''
Adds information about the current database is use to the xml
'''
currentDBElem = self.__doc.createElement(CURRENT_DB_ELEM_NAME)
textNode = self._createTextNode(data)
currentDBElem.appendChild(textNode)
self._addToRoot(currentDBElem)
def dba(self, isDBA):
'''
Adds information to the xml that indicates whether the user has DBA privileges
'''
isDBAElem = self.__doc.createElement(IS_DBA_ELEM_NAME)
isDBAElem.setAttributeNode(self._createAttribute(VALUE_ATTR, getUnicode(isDBA)))
self._addToRoot(isDBAElem)
def users(self, users):
'''
Adds a list of the existing users to the xml
'''
usersElem = self.__doc.createElement(USERS_ELEM_NAME)
if isinstance(users, basestring):
users = [users]
if users:
for user in users:
userElem = self.__doc.createElement(DB_USER_ELEM_NAME)
usersElem.appendChild(userElem)
userElem.appendChild(self._createTextNode(user))
self._addToRoot(usersElem)
def dbs(self, dbs):
'''
Adds a list of the existing databases to the xml
'''
dbsElem = self.__doc.createElement(DBS_ELEM_NAME)
if dbs:
for db in dbs:
dbElem = self.__doc.createElement(DB_NAME_ELEM_NAME)
dbsElem.appendChild(dbElem)
dbElem.appendChild(self._createTextNode(db))
self._addToRoot(dbsElem)
def userSettings(self, header, userSettings, subHeader):
'''
Adds information about the user's settings to the xml.
The information can be user's passwords, privileges and etc..
'''
self._areAdmins = set()
userSettingsElem = self._getRootChild(USER_SETTINGS_ELEM_NAME)
if (not(userSettingsElem)):
userSettingsElem = self.__doc.createElement(USER_SETTINGS_ELEM_NAME)
self._addToRoot(userSettingsElem)
userSettingElem = self.__doc.createElement(USER_SETTING_ELEM_NAME)
userSettingElem.setAttributeNode(self._createAttribute(TYPE_ATTR, header))
if isinstance(userSettings, (tuple, list, set)):
self._areAdmins = userSettings[1]
userSettings = userSettings[0]
users = userSettings.keys()
users.sort(key=lambda x: x.lower())
for user in users:
userElem = self.__doc.createElement(USER_ELEM_NAME)
userSettingElem.appendChild(userElem)
if user in self._areAdmins:
userElem.setAttributeNode(self._createAttribute(TYPE_ATTR, ADMIN_USER))
else:
userElem.setAttributeNode(self._createAttribute(TYPE_ATTR, REGULAR_USER))
settings = userSettings[user]
settings.sort()
for setting in settings:
settingsElem = self.__doc.createElement(SETTINGS_ELEM_NAME)
settingsElem.setAttributeNode(self._createAttribute(TYPE_ATTR, subHeader))
settingTextNode = self._createTextNode(setting)
settingsElem.appendChild(settingTextNode)
userElem.appendChild(settingsElem)
userSettingsElem.appendChild(userSettingElem)
def dbTables(self, dbTables):
'''
Adds information of the existing db tables to the xml
'''
if not isinstance(dbTables, dict):
self.string(TABLES_ELEM_NAME, dbTables)
return
dbTablesElem = self.__doc.createElement(DB_TABLES_ELEM_NAME)
for db, tables in dbTables.items():
tables.sort(key=lambda x: x.lower())
dbElem = self.__doc.createElement(DATABASE_ELEM_NAME)
dbElem.setAttributeNode(self._createAttribute(NAME_ATTR, db))
dbTablesElem.appendChild(dbElem)
for table in tables:
tableElem = self.__doc.createElement(DB_TABLE_ELEM_NAME)
tableElem.appendChild(self._createTextNode(table))
dbElem.appendChild(tableElem)
self._addToRoot(dbTablesElem)
def dbTableColumns(self, tableColumns):
'''
Adds information about the columns of the existing tables to the xml
'''
columnsElem = self._getRootChild(COLUMNS_ELEM_NAME)
if not(columnsElem):
columnsElem = self.__doc.createElement(COLUMNS_ELEM_NAME)
for db, tables in tableColumns.items():
if not db:
db = DEFAULT_DB
dbElem = self.__doc.createElement(DATABASE_COLUMNS_ELEM)
dbElem.setAttributeNode(self._createAttribute(NAME_ATTR, db))
columnsElem.appendChild(dbElem)
for table, columns in tables.items():
tableElem = self.__doc.createElement(TABLE_ELEM_NAME)
tableElem.setAttributeNode(self._createAttribute(NAME_ATTR, table))
colList = columns.keys()
colList.sort(key=lambda x: x.lower())
for column in colList:
colType = columns[column]
colElem = self.__doc.createElement(COLUMN_ELEM_NAME)
if colType is not None:
colElem.setAttributeNode(self._createAttribute(TYPE_ATTR, colType))
else:
colElem.setAttributeNode(self._createAttribute(TYPE_ATTR, UNKNOWN_COLUMN_TYPE))
colElem.appendChild(self._createTextNode(column))
tableElem.appendChild(colElem)
self._addToRoot(columnsElem)
def dbTableValues(self, tableValues):
'''
Adds the values of specific table to the xml.
The values are organized according to the relevant row and column.
'''
tableElem = self.__doc.createElement(DB_TABLE_VALUES_ELEM_NAME)
if (tableValues is not None):
db = tableValues["__infos__"]["db"]
if not db:
db = "All"
table = tableValues["__infos__"]["table"]
count = int(tableValues["__infos__"]["count"])
columns = tableValues.keys()
columns.sort(key=lambda x: x.lower())
tableElem.setAttributeNode(self._createAttribute(DB_ATTR, db))
tableElem.setAttributeNode(self._createAttribute(NAME_ATTR, table))
for i in range(count):
rowElem = self.__doc.createElement(ROW_ELEM_NAME)
tableElem.appendChild(rowElem)
for column in columns:
if column != "__infos__":
info = tableValues[column]
value = info["values"][i]
if re.search("^[\ *]*$", value):
value = "NULL"
cellElem = self.__doc.createElement(CELL_ELEM_NAME)
cellElem.setAttributeNode(self._createAttribute(COLUMN_ATTR, column))
cellElem.appendChild(self._createTextNode(value))
rowElem.appendChild(cellElem)
dbValuesElem = self._getRootChild(DB_VALUES_ELEM)
if (not(dbValuesElem)):
dbValuesElem = self.__doc.createElement(DB_VALUES_ELEM)
self._addToRoot(dbValuesElem)
dbValuesElem.appendChild(tableElem)
logger.info("Table '%s.%s' dumped to XML file" % (db, table))
def dbColumns(self, dbColumns, colConsider, dbs):
'''
Adds information about the columns
'''
for column in dbColumns.keys():
printDbs = {}
for db, tblData in dbs.items():
for tbl, colData in tblData.items():
for col, dataType in colData.items():
if column in col:
if db in printDbs:
if tbl in printDbs[db]:
printDbs[db][tbl][col] = dataType
else:
printDbs[db][tbl] = {col: dataType}
else:
printDbs[db] = {}
printDbs[db][tbl] = {col: dataType}
continue
self.dbTableColumns(printDbs)
def query(self, query, queryRes):
'''
Adds details of an executed query to the xml.
The query details are the query itself and its results.
'''
queryElem = self.__doc.createElement(QUERY_ELEM_NAME)
queryElem.setAttributeNode(self._createAttribute(VALUE_ATTR, query))
queryElem.appendChild(self._createTextNode(queryRes))
queriesElem = self._getRootChild(QUERIES_ELEM_NAME)
if (not(queriesElem)):
queriesElem = self.__doc.createElement(QUERIES_ELEM_NAME)
self._addToRoot(queriesElem)
queriesElem.appendChild(queryElem)
def registerValue(self, registerData):
'''
Adds information about an extracted registry key to the xml
'''
registerElem = self.__doc.createElement(REGISTER_DATA_ELEM_NAME)
registerElem.appendChild(self._createTextNode(registerData))
registriesElem = self._getRootChild(REGISTERY_ENTRIES_ELEM_NAME)
if (not(registriesElem)):
registriesElem = self.__doc.createElement(REGISTERY_ENTRIES_ELEM_NAME)
self._addToRoot(registriesElem)
registriesElem.appendChild(registerElem)
def rFile(self, filePath, data):
'''
Adds an extracted file's content to the xml
'''
fileContentElem = self.__doc.createElement(FILE_CONTENT_ELEM_NAME)
fileContentElem.setAttributeNode(self._createAttribute(NAME_ATTR, filePath))
fileContentElem.appendChild(self._createTextNode(data))
self._addToRoot(fileContentElem)
def setOutputFile(self):
'''
Initiates the xml file from the configuration.
'''
if (conf.xmlFile):
try:
self._outputFile = conf.xmlFile
self.__root = None
if os.path.exists(self._outputFile):
try:
self.__doc = xml.dom.minidom.parse(self._outputFile)
self.__root = self.__doc.childNodes[0]
except ExpatError:
self.__doc = Document()
self._outputFP = codecs.open(self._outputFile, "w+", UNICODE_ENCODING)
if self.__root is None:
self.__root = self.__doc.createElementNS(NAME_SPACE_ATTR, RESULTS_ELEM_NAME)
self.__root.setAttributeNode(self._createAttribute(XMLNS_ATTR, NAME_SPACE_ATTR))
self.__root.setAttributeNode(self._createAttribute(SCHEME_NAME_ATTR, SCHEME_NAME))
self.__doc.appendChild(self.__root)
except IOError:
raise SqlmapFilePathException("Wrong filename provided for saving the xml file: %s" % conf.xmlFile)
def getOutputFile(self):
return self._outputFile
def finish(self, resultStatus, resultMsg=""):
'''
Finishes the dumper operation:
1. Adds the session status to the xml
2. Writes the xml to the file
3. Closes the xml file
'''
if ((self._outputFP is not None) and not(self._outputFP.closed)):
statusElem = self.__doc.createElement(STATUS_ELEM_NAME)
statusElem.setAttributeNode(self._createAttribute(SUCESS_ATTR, getUnicode(resultStatus)))
if not resultStatus:
errorElem = self.__doc.createElement(ERROR_ELEM_NAME)
if isinstance(resultMsg, Exception):
errorElem.setAttributeNode(self._createAttribute(TYPE_ATTR, type(resultMsg).__name__))
else:
errorElem.setAttributeNode(self._createAttribute(TYPE_ATTR, UNHANDLED_PROBLEM_TYPE))
errorElem.appendChild(self._createTextNode(getUnicode(resultMsg)))
statusElem.appendChild(errorElem)
self._addToRoot(statusElem)
self.__write(prettyprint.formatXML(self.__doc, encoding=UNICODE_ENCODING))
self._outputFP.close()
def closeDumper(status, msg=""):
"""
Closes the dumper of the session
"""
if hasattr(conf, "dumper") and hasattr(conf.dumper, "finish"):
conf.dumper.finish(status, msg)
dumper = XMLDump()

View File

@ -45,16 +45,15 @@ e60456db5380840a586654344003d4e6 lib/core/readlineng.py
5ef56abb8671c2ca6ceecb208258e360 lib/core/replication.py
99a2b496b9d5b546b335653ca801153f lib/core/revision.py
7c15dd2777af4dac2c89cab6df17462e lib/core/session.py
01e265a726458e3e503f7f857c367d76 lib/core/settings.py
2fc7f7fc1754a396b950236aa5290ed4 lib/core/settings.py
7af83e4f18cab6dff5e67840eb65be80 lib/core/shell.py
23657cd7d924e3c6d225719865855827 lib/core/subprocessng.py
0bc2fae1dec18cdd11954b22358293f2 lib/core/target.py
c3ace7874a536d801f308cf1fd03df99 lib/core/target.py
d43f059747ffd48952922c94152e2a07 lib/core/testing.py
2cafee22d9f8018e7efff0a5e3178596 lib/core/threads.py
53c15b78e0288274f52410db25406432 lib/core/unescaper.py
6bdc53e2ca152ff8cd35ad671e48a96b lib/core/update.py
8485a3cd94c0a5af2718bad60c5f1ae5 lib/core/wordlist.py
354ecc0c6d3e0ac9c06ed897c4d52edf lib/core/xmldump.py
cc9c82cfffd8ee9b25ba3af6284f057e lib/__init__.py
c1288bc4ce5651dbdd82d4a9435fdc03 lib/parse/banner.py
498be08b12a01bd79d82fc993bd07965 lib/parse/cmdline.py

View File

@ -1,284 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="Results">
<xs:complexType>
<xs:all>
<xs:element ref="Messages" minOccurs="0" />
<xs:element ref="Banner" minOccurs="0"/>
<xs:element ref="CurrentUser" minOccurs="0"/>
<xs:element ref="CurrentDB" minOccurs="0"/>
<xs:element ref="isDBA" minOccurs="0"/>
<xs:element ref="Users" minOccurs="0"/>
<xs:element ref="UserSettings" minOccurs="0"/>
<xs:element ref="DBs" minOccurs="0"/>
<xs:element ref="DBTables" minOccurs="0"/>
<xs:element ref="Technics" minOccurs="0" />
<xs:element ref="Lists" minOccurs="0" />
<xs:element ref="DatabaseColumns" minOccurs="0" />
<xs:element ref="DBValues" minOccurs="0"/>
<xs:element ref="Queries" minOccurs="0"/>
<xs:element ref="RegistryEntries" minOccurs="0"/>
<xs:element ref="FileContent" minOccurs="0"/>
<xs:element ref="Status"/>
</xs:all>
</xs:complexType>
</xs:element>
<!-- Simple Types -->
<xs:element name="Banner" type="xs:string"/>
<xs:element name="CurrentUser" type="xs:string"/>
<xs:element name="CurrentDB" type="xs:string"/>
<!-- File Content -->
<xs:element name="FileContent">
<xs:complexType mixed="true">
<xs:attribute name="name" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- RegistryEntries -->
<xs:element name="RegistryEntries">
<xs:complexType>
<xs:sequence>
<xs:element ref="RegisterData" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="RegisterData" type="xs:string"/>
<!-- Queries -->
<xs:element name="Queries">
<xs:complexType>
<xs:sequence>
<xs:element ref="Query" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Query">
<xs:complexType mixed="true">
<xs:attribute name="value" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- Columns -->
<xs:element name="DatabaseColumns">
<xs:complexType>
<xs:sequence>
<xs:element ref="DB" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DB">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element ref="Table" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Table">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element ref="Column" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="name" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Column">
<xs:complexType mixed="true">
<xs:attribute name="type" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- List -->
<xs:element name="Member">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element ref="Member" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="type" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="List">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element ref="Member" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="type" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Lists">
<xs:complexType>
<xs:sequence>
<xs:element ref="List" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<!-- Technics -->
<xs:element name="Technics">
<xs:complexType>
<xs:sequence>
<xs:element ref="Technic" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Technic">
<xs:complexType mixed="true">
<xs:attribute name="type" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- Messages -->
<xs:element name="Messages">
<xs:complexType>
<xs:sequence>
<xs:element ref="Message" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Message">
<xs:complexType mixed="true">
<xs:attribute name="type" use="required" type="xs:string"/>
</xs:complexType>
</xs:element>
<!-- is DBA -->
<xs:element name="isDBA">
<xs:complexType>
<xs:attribute name="value" use="required" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<!-- Users -->
<xs:element name="Users">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" ref="DBUser"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DBUser" type="xs:string"/>
<!-- User Settings -->
<xs:element name="UserSettings">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="UserSetting"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="UserSetting">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="User"/>
</xs:sequence>
<xs:attribute name="type" use="required"/>
</xs:complexType>
</xs:element>
<xs:element name="User">
<xs:complexType>
<xs:sequence>
<xs:element ref="Settings" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="type" use="required" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<xs:element name="Settings">
<xs:complexType mixed="true">
<xs:attribute name="type" use="required"/>
</xs:complexType>
</xs:element>
<!-- Databases -->
<xs:element name="DBs">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" ref="DBName"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DBName" type="xs:NCName"/>
<!-- DB Tables -->
<xs:element name="DBTables">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" ref="Database"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Database">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" ref="DBTable"/>
</xs:sequence>
<xs:attribute name="name" use="required" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<xs:element name="DBTable" type="xs:NCName"/>
<!-- Table Values -->
<xs:element name="DBValues">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="DBTableValues"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="DBTableValues">
<xs:complexType>
<xs:sequence>
<xs:element ref="Row" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="db" type="xs:string"/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
</xs:element>
<xs:element name="Row">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" ref="Cell"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Cell">
<xs:complexType mixed="true">
<xs:attribute name="column" use="required" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<!-- Status Elements -->
<xs:element name="Status">
<xs:complexType>
<xs:sequence>
<xs:element ref="Error" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="success" use="required" type="xs:NCName"/>
</xs:complexType>
</xs:element>
<xs:element name="Error">
<xs:complexType mixed="true">
<xs:attribute name="type" use="required" type="xs:NCName"/>
</xs:complexType>
</xs:element>
</xs:schema>