diff options
-rw-r--r-- | services/request.esp | 8 | ||||
-rw-r--r-- | services/resources.esp | 51 | ||||
-rw-r--r-- | services/samba/ldb.esp | 99 | ||||
-rw-r--r-- | swat/apps/samba/utils/ldbbrowse.html | 183 |
4 files changed, 218 insertions, 123 deletions
diff --git a/services/request.esp b/services/request.esp index 982f39fcaa..970ea6b4fb 100644 --- a/services/request.esp +++ b/services/request.esp @@ -118,7 +118,7 @@ jsonrpc.Constant.ErrorCode.MethodNotFound = 4; * This error is also used to indicate an illegal parameter value, in server * scripts. */ -jsonrpc.Constant.ErrorCode.PaameterMismatch = 5; +jsonrpc.Constant.ErrorCode.ParameterMismatch = 5; /** * Error code, value 6: Permission Denied @@ -337,7 +337,7 @@ var nameFirstLetter = if (strspn(jsonInput.method, nameChars) != strlen(jsonInput.method)) { /* There's some illegal character in the service name */ - error.setError(JsonRpcError.MethodNotFound, + error.setError(jsonrpc.Constant.ErrorCode.MethodNotFound, "Illegal character found in method name."); error.Send(); return; @@ -364,7 +364,7 @@ if (strspn(substr(jsonInput.method, 0, 1), nameFirstLetter) != 1) if (strspn(jsonInput.service, "." + nameChars) != strlen(jsonInput.service)) { /* There's some illegal character in the service name */ - error.setError(JsonRpcError.IllegalService, + error.setError(jsonrpc.Constant.ErrorCode.IllegalService, "Illegal character found in service name."); error.Send(); return; @@ -379,7 +379,7 @@ if (strspn(jsonInput.service, "." + nameChars) != strlen(jsonInput.service)) */ if (typeof(strstr(jsonInput.service, "..")) != "pointer") { - error.setError(JsonRpcError.IllegalService, + error.setError(jsonrpc.Constant.ErrorCode.IllegalService, "Illegal use of two consecutive dots in service name"); error.Send(); return; diff --git a/services/resources.esp b/services/resources.esp index d4a77f7907..d491ed5701 100644 --- a/services/resources.esp +++ b/services/resources.esp @@ -28,15 +28,6 @@ function _resourcesCreate() /* We'll maintain our own count of the number of open resources */ o.resourceList.count = 0; - /* - * Resource types - */ - o.Type = new Object(); - o.Type.ldb = 1; /* database handle */ - o.Type.tid = 2; /* tree id */ - o.Type.fid = 3; /* file id */ - /* etc., etc., etc. */ - /* * Set a new saved resource. @@ -48,7 +39,7 @@ function _resourcesCreate() { /* Yup. */ error.setOrigin(jsonrpc.Constant.ErrorOrigin.Server); - error.setError(JsonRpcError_ResourceError, + error.setError(jsonrpc.Constant.ErrorCode.ResourceError, "Session limit on resources (" + RESOURCE_LIMIT + ") exceeded."); @@ -81,7 +72,7 @@ function _resourcesCreate() /* * Get a previously-saved resource */ - function _get(resourceId, type, error) + function _get(resourceId, error) { /* Does the specified resource id exist? */ if (! this.resourceList[resourceId]) @@ -96,22 +87,40 @@ function _resourcesCreate() /* Retrieve the resource */ var r = this.resourceList[resourceId]; - /* Is the specified resource the correct type? */ - if (r.type != type) - { - /* Nope. */ - error.setOrigin(jsonrpc.Constant.ErrorOrigin.Server); - error.setError(jsonrpc.Constant.ErrorCode.ResourceError, - "Incorrect type for specified resource id."); - return error; - } - /* Give 'em what they came for! */ return r.resource; } o.get = _get; /* + * Find a previously-saved resource + */ + function _find(type, error) + { + /* Does the specified resource id exist? */ + for (var resourceId in this.resourceList) + { + /* Retrieve the resource */ + var r = this.resourceList[resourceId]; + + /* Ignore "id" and "count" integer fields */ + if (typeof(r) == "object") + { + /* Is the specified resource the correct type? */ + if (r.type == type) + { + /* Yup, this is the one they want. */ + return resourceId; + } + } + } + + /* It wasn't found. */ + return undefined; + } + o.find = _find; + + /* * Release a previously-saved resource, allowing it to be freed */ function _release(resourceId, error) diff --git a/services/samba/ldb.esp b/services/samba/ldb.esp index 2eff5ba57d..d886d1a566 100644 --- a/services/samba/ldb.esp +++ b/services/samba/ldb.esp @@ -39,18 +39,25 @@ function _connect(params, error) { if (params.length < 1) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <db_name> [<option> ...]"); return error; } + /* First, see if this database was already opened */ + var resourceId = session.resources.find("ldb:" + params[0], error); + if (resourceId != undefined) + { + /* It was. Give 'em the resource id */ + return resourceId; + } + + /* Database was not previously opened. Connect to it. */ ldb = ldb_init(); var ret = ldb.connect(params[0]); if (ret && ldb.db) { - return session.resources.set(ldb, - session.resources.Type.ldb, - error); + return session.resources.set(ldb, "ldb:" + params[0], error); } else { @@ -78,14 +85,12 @@ function _close(params, error) { if (params.length != 1) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -121,14 +126,12 @@ function _transaction_start(params, error) { if (params.length != 1) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -156,14 +159,12 @@ function _transaction_cancel(params, error) { if (params.length != 1) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -191,14 +192,12 @@ function _transaction_commit(params, error) { if (params.length != 1) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -243,15 +242,13 @@ function _search(params, error) { if (params.length < 2 || params.length > 5) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: " + "<resource_id> <expr> [<baseDN> [<scope> [<attrs>]]]"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -287,12 +284,12 @@ function _search(params, error) } else { - error.setError(JsonRpcError_ParameterMismatch, - "invalid scope"); + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, + "invalid scope: " + scope); return error; } - return ldb.transaction_search(expr, baseDN, scope, attrs); + return ldb.search(expr, baseDN, scope, attrs); } jsonrpc.method.search = _search; @@ -317,14 +314,12 @@ function _add(params, error) { if (params.length != 2) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id> <ldif>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -355,14 +350,12 @@ function _modify(params, error) { if (params.length != 2) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id> <ldif>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -393,14 +386,12 @@ function _del(params, error) { if (params.length != 2) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id> <dn>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -434,14 +425,12 @@ function _rename(params, error) { if (params.length != 3) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id> <old_dn> <new_dn>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -472,14 +461,12 @@ function _base64encode(params, error) { if (params.length != 2) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id> <string_to_be_encoded>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -510,14 +497,12 @@ function _base64decode(params, error) { if (params.length != 2) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id> <string_to_be_decoded>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -548,14 +533,12 @@ function _base64decode(params, error) { if (params.length != 2) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id> <string_to_be_decoded>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; @@ -582,14 +565,12 @@ function _errstring(params, error) { if (params.length != 1) { - error.setError(JsonRpcError_ParameterMismatch, + error.setError(jsonrpc.Constant.ErrorCode.ParameterMismatch, "usage: <resource_id>"); return error; } - ldb = session.resources.get(params[0], - session.resources.Type.ldb, - error); + ldb = session.resources.get(params[0], error); if (ldb["__type"] == "_JsonRpcError") { return ldb; diff --git a/swat/apps/samba/utils/ldbbrowse.html b/swat/apps/samba/utils/ldbbrowse.html index adfe78e754..028289e9f1 100644 --- a/swat/apps/samba/utils/ldbbrowse.html +++ b/swat/apps/samba/utils/ldbbrowse.html @@ -22,8 +22,15 @@ /* Root is as found by: - source/bin/ldbsearch -H /usr/local/samba/private/sam.ldb -b '' \ - -s base defaultNamingContext + source/bin/ldbsearch -H /usr/local/samba/private/sam.ldb -b '' \ + -s base defaultNamingContext + +Schema page: + source/bin/ldbsearch -H /usr/local/samba/private/sam.ldb -b '' \ + -s base subschemaSubentry + source/bin/ldbsearch -H /usr/local/samba/private/sam.ldb -b \ + 'CN=Aggregate,CN=Schema,CN=Configuration,DC=workgroup,DC=example,DC=com' \ + -s base objectClasses attributeTypes matchingRules ldapSyntaxes */ function setAppearances() @@ -51,7 +58,7 @@ function setAppearances() appearance.initial = function(vTheme) { var res = oldInitial ? oldInitial.apply(this, arguments) : {}; - res.width = "96%"; + res.width = "90%"; return res; } } @@ -185,7 +192,10 @@ function setupTabs(clientDocument) new qx.ui.pageview.tabview.TabViewPage(tabView_Schema); // Build the search page - buildPageSearch(tabViewPage_Search); + var searchResultsTable = buildPageSearch(tabViewPage_Search); + + // Provide access to the search results table + tabView_.searchResultTable = searchResultsTable; // Build the browse page buildPageBrowse(tabViewPage_Browse); @@ -207,51 +217,109 @@ function setupTabs(clientDocument) function buildPageSearch(page) { + // We need a horizontal layout for the combox box and "Find" button + var layout = new qx.ui.layout.HorizontalBoxLayout(); + layout.setWidth("100%"); + // Create a combo box for entry of the search expression var search = new qx.ui.form.ComboBox(); search.getField().setWidth("100%"); search.setEditable(true); - // Add the combo box to the page - page.add(search); + // Add the combo box to the horizontal layout + layout.add(search); - // Create a simple table model - var tableModel = new qx.ui.table.SimpleTableModel(); - tableModel.setColumns([ "Attribute", "Value" ]); + // Right-justify the 'Find' button + var spacer = new qx.ui.basic.HorizontalSpacer; + layout.add(spacer); - // Add some garbage data to it - var attributeNames = - [ - [ "Nickname" ], - [ "Hostname" ], - [ "Port" ], - [ "Connection caching" ], - [ "TLS" ], - [ "Client-side caching" ], - [ "Connections so far" ], - [ "LDAP protocol version" ], - [ "Vendor Name" ], - [ "Vendor Version" ], - [ "Support LDAP Version" ], - [ "Supported SASL Mechanisms" ], - [ "Junk 1" ], - [ "Junk 2" ], - [ "Junk 3" ] - ]; - + // Create the 'Find' button + var find = new qx.ui.form.Button('Find'); - var rowData = []; - for (var row = 0; row < attributeNames.length; row++) + // We'll be setting url and service upon execute; no need to do it now. + var rpc = new qx.io.remote.Rpc(); + rpc.setTimeout(10000); + var mycall = null; + + find.addEventListener("execute", function() { - rowData.push([ attributeNames[row], "" + (Math.random() * 10000) ]); - } - tableModel.setData(rowData); + // Set the URL and Service + rpc.setUrl("/services/"); + rpc.setServiceName("samba.ldb"); + rpc.setCrossDomain(false); + + find.setEnabled(false); +// abort.setEnabled(true); + mycall = rpc.callAsync(function(result, ex, id) + { + mycall = null; + if (ex == null) + { + var rowData = []; + for (var i = 0; i < result.length; i++) + { + var o = result[i]; + if (typeof(o) != "object") + { + alert("Found unexpected result, type " + + typeof(o) + + ", " + + o + + "\n"); + continue; + } + for (var field in o) + { + // skip dn and distinguishedName fields; + // they're shown in each row anyway. + if (field == "dn" || field == "distinguishedName") + { + continue; + } + rowData.push( [ + o["dn"], + field, + o[field] + ] ); + } + + // Tell the table to use the new data + tableModel.setData(rowData); + } + } + else + { + alert("Async(" + id + ") exception: " + ex); + } + find.setEnabled(true); +// abort.setEnabled(false); + }, + "search", // method + db_handle, // database handle + search.getValue(), // search expression + "", // baseDN + "default", // scope + [ "*" ]); // attributes + }); + + // Add the button to horizontal layout + layout.add(find); + + // Add the horizontal box layout to the page + page.add(layout); + + // Create a simple table model + var tableModel = new qx.ui.table.SimpleTableModel(); + tableModel.setColumns([ "Distinguished Name", "Attribute", "Value" ]); + tableModel.setColumnEditable(0, false); - tableModel.setColumnEditable(1, true); + tableModel.setColumnEditable(1, false); + tableModel.setColumnEditable(2, false); // Create a table var table = new qx.ui.table.Table(tableModel); - with (table) { + with (table) + { set({ top: 40, left: 0, @@ -260,12 +328,15 @@ function buildPageSearch(page) statusBarVisible: false, columnVisibilityButtonVisible: false }); - setColumnWidth(0, 200); - setColumnWidth(1, 440); - setMetaColumnCounts([1, -1]); + setColumnWidth(0, 300); + setColumnWidth(1, 180); + setColumnWidth(2, 240); + setMetaColumnCounts([ 1, -1 ]); // h-scroll attribute and value together }; page.add(table); + + return table; } function buildPageBrowse(page) @@ -531,6 +602,23 @@ function buildPageSchema(page) qx.core.Init.getInstance().defineMain( function() { + // Enable JSON-RPC debugging + qx.Settings.setCustomOfClass("qx.io.Json", "enableDebug", true); + + if (false) + { + // We'd like all table columns to do "live resize". Unfortunately, + // it's too slow. Maybe someone wants to work on it... + var constructor = qx.OO.classes["qx.ui.table.TablePaneScroller"]; + qx.Proto = constructor.prototype; + qx.OO.changeProperty( + { + name : "liveResize", + type : qx.constant.Type.BOOLEAN, + defaultValue : true + }); + } + // Set appearances for this application setAppearances(); @@ -542,6 +630,23 @@ qx.core.Init.getInstance().defineMain( // Create the tabs and their windows, and attach to client document var tabView = setupTabs(clientDocument); + + // Open a database connection. Uses the dangerous sync request. + var rpc = new qx.io.remote.Rpc(); + rpc.setUrl("/services/"); + rpc.setServiceName("samba.ldb"); + rpc.setCrossDomain(false); + + try + { + // db_handle is global!!! no 'var' is intentional. + db_handle = rpc.callSync("connect", + "/usr/local/samba/private/sam.ldb"); + } + catch (ex) + { + alert("Sync exception: " + ex); + } }); /* * Local Variables: |