summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-07-10 06:21:03 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:19:30 -0500
commitf3c6f290f0c2ba84d8dbbae8d6d2bb50330a27c1 (patch)
tree797cdf2fc1dff0142bf32a1b0634a15a6adcbbe3
parentd084d6d24109ae615af89776519e7ebd722e9a4c (diff)
downloadsamba-f3c6f290f0c2ba84d8dbbae8d6d2bb50330a27c1.tar.gz
samba-f3c6f290f0c2ba84d8dbbae8d6d2bb50330a27c1.tar.bz2
samba-f3c6f290f0c2ba84d8dbbae8d6d2bb50330a27c1.zip
r8280: - added irpc_connect() for connecting to a irpc server by name
- make the dcerpc pipe in rpc_connect() a talloc child of the ejs connection variable. That means when the connection variable goes out of scope, the connection is automatically closed. That makes for a more natural interface for closing connections in a scripting language (tpot, you may wish to use mprSetPtrChild() in your smb glue code too) (This used to be commit 1c170138a8e82cb42958b88b94a1d567ffa88a92)
-rw-r--r--source4/scripting/ejs/config.mk2
-rw-r--r--source4/scripting/ejs/mprutil.c9
-rw-r--r--source4/scripting/ejs/smbcalls_rpc.c79
3 files changed, 87 insertions, 3 deletions
diff --git a/source4/scripting/ejs/config.mk b/source4/scripting/ejs/config.mk
index fce69fdb55..5c14dccfe3 100644
--- a/source4/scripting/ejs/config.mk
+++ b/source4/scripting/ejs/config.mk
@@ -19,7 +19,7 @@ OBJ_FILES = \
scripting/ejs/smbcalls_cli.o \
scripting/ejs/smbcalls_rpc.o \
scripting/ejs/mprutil.o
-REQUIRED_SUBSYSTEMS = AUTH EJS LIBBASIC EJSRPC
+REQUIRED_SUBSYSTEMS = AUTH EJS LIBBASIC EJSRPC MESSAGING
# End SUBSYSTEM SMBCALLS
#######################
diff --git a/source4/scripting/ejs/mprutil.c b/source4/scripting/ejs/mprutil.c
index 3c28cb4bf1..c614792d8e 100644
--- a/source4/scripting/ejs/mprutil.c
+++ b/source4/scripting/ejs/mprutil.c
@@ -271,6 +271,15 @@ void mprSetPtr(struct MprVar *v, const char *propname, const void *p)
}
/*
+ set a pointer in a existing MprVar, making it a child of the property
+*/
+void mprSetPtrChild(struct MprVar *v, const char *propname, const void *p)
+{
+ mprSetVar(v, propname, mprCreatePtrVar(discard_const(p), NULL));
+ talloc_steal(mprGetProperty(v, propname, NULL), p);
+}
+
+/*
get a pointer from a MprVar
*/
void *mprGetPtr(struct MprVar *v, const char *propname)
diff --git a/source4/scripting/ejs/smbcalls_rpc.c b/source4/scripting/ejs/smbcalls_rpc.c
index 9546dc5b01..857d590aa1 100644
--- a/source4/scripting/ejs/smbcalls_rpc.c
+++ b/source4/scripting/ejs/smbcalls_rpc.c
@@ -25,10 +25,82 @@
#include "lib/ejs/ejs.h"
#include "librpc/gen_ndr/ndr_echo.h"
#include "lib/cmdline/popt_common.h"
+#include "lib/messaging/irpc.h"
#include "scripting/ejs/ejsrpc.h"
#include "dlinklist.h"
/*
+ state of a irpc 'connection'
+*/
+struct ejs_irpc_connection {
+ const char *server_name;
+ uint32_t *dest_ids;
+ struct messaging_context *msg_ctx;
+};
+
+/*
+ messaging clients need server IDs as well ...
+ */
+#define EJS_ID_BASE 0x30000000
+
+/*
+ setup a context for talking to a irpc server
+ example:
+ var conn = new Object();
+ status = irpc_connect(conn, "smb_server");
+*/
+static int ejs_irpc_connect(MprVarHandle eid, int argc, struct MprVar **argv)
+{
+ NTSTATUS status;
+ int i;
+ struct MprVar *conn;
+ struct event_context *ev;
+ struct ejs_irpc_connection *p;
+
+ /* validate arguments */
+ if (argc != 2 ||
+ argv[0]->type != MPR_TYPE_OBJECT ||
+ argv[1]->type != MPR_TYPE_STRING) {
+ ejsSetErrorMsg(eid, "rpc_connect invalid arguments");
+ return -1;
+ }
+
+ p = talloc(conn, struct ejs_irpc_connection);
+ if (p == NULL) {
+ return -1;
+ }
+
+ conn = argv[0];
+ p->server_name = mprToString(argv[2]);
+
+ ev = talloc_find_parent_bytype(mprMemCtx(), struct event_context);
+
+ /* create a messaging context, looping as we have no way to
+ allocate temporary server ids automatically */
+ for (i=0;i<10000;i++) {
+ p->msg_ctx = messaging_init(p, EJS_ID_BASE + i, ev);
+ if (p->msg_ctx) break;
+ }
+ if (p->msg_ctx == NULL) {
+ ejsSetErrorMsg(eid, "irpc_connect unable to create a messaging context");
+ talloc_free(p);
+ return -1;
+ }
+
+ p->dest_ids = irpc_servers_byname(p->msg_ctx, p->server_name);
+ if (p->dest_ids == NULL || p->dest_ids[0] == 0) {
+ talloc_free(p);
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ } else {
+ mprSetPtrChild(conn, "pipe", p);
+ }
+
+ mpr_Return(eid, mprNTSTATUS(status));
+ return 0;
+}
+
+
+/*
connect to an rpc server
example:
var conn = new Object();
@@ -72,7 +144,7 @@ static int ejs_rpc_connect(MprVarHandle eid, int argc, struct MprVar **argv)
ev = talloc_find_parent_bytype(mprMemCtx(), struct event_context);
- status = dcerpc_pipe_connect(mprMemCtx(), &p, binding,
+ status = dcerpc_pipe_connect(conn, &p, binding,
iface->uuid, iface->if_version,
creds, ev);
if (!NT_STATUS_IS_OK(status)) goto done;
@@ -80,7 +152,9 @@ static int ejs_rpc_connect(MprVarHandle eid, int argc, struct MprVar **argv)
/* callers don't allocate ref vars in the ejs interface */
p->conn->flags |= DCERPC_NDR_REF_ALLOC;
- mprSetPtr(conn, "pipe", p);
+ /* by making the pipe a child of the connection variable, it will
+ auto close when it goes out of scope in the script */
+ mprSetPtrChild(conn, "pipe", p);
mprSetPtr(conn, "iface", iface);
done:
@@ -223,6 +297,7 @@ void smb_setup_ejs_rpc(void)
struct ejs_register *r;
ejsDefineCFunction(-1, "rpc_connect", ejs_rpc_connect, NULL, MPR_VAR_SCRIPT_HANDLE);
+ ejsDefineCFunction(-1, "irpc_connect", ejs_irpc_connect, NULL, MPR_VAR_SCRIPT_HANDLE);
for (r=ejs_registered;r;r=r->next) {
r->setup();
}