summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-07-10 08:35:18 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:19:31 -0500
commit056096c30ba73cbc5304c99af5d5a08d89111aab (patch)
tree411dade1ba4bbfc5a958515d300e0227893a86e1
parente43e8fcf55e55fa2cc54b83c8a4111f3a6e4eae7 (diff)
downloadsamba-056096c30ba73cbc5304c99af5d5a08d89111aab.tar.gz
samba-056096c30ba73cbc5304c99af5d5a08d89111aab.tar.bz2
samba-056096c30ba73cbc5304c99af5d5a08d89111aab.zip
r8284: - fixed some uninitialised variables in the irpc code
- added code to send multiple irpc calls in parallel, to all servers that have registered the given name, with output going in io.results[i]. This allows you to make rpc calls to multiple servers at once, which is needed for clients like smbstatus (This used to be commit 061e20e509d95ffe16d7dd6fba7db39fc7a165ed)
-rw-r--r--source4/lib/messaging/messaging.c12
-rw-r--r--source4/scripting/ejs/mprutil.c6
-rw-r--r--source4/scripting/ejs/smbcalls.h2
-rw-r--r--source4/scripting/ejs/smbcalls_rpc.c97
-rw-r--r--source4/scripting/ejs/smbscript.c1
5 files changed, 107 insertions, 11 deletions
diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c
index 5afcf91bab..a29f14f065 100644
--- a/source4/lib/messaging/messaging.c
+++ b/source4/lib/messaging/messaging.c
@@ -375,6 +375,10 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, uint32_t server_id
return NULL;
}
+ if (ev == NULL) {
+ ev = event_context_init(msg);
+ }
+
/* create the messaging directory if needed */
path = smbd_tmp_path(msg, "messaging");
mkdir(path, 0700);
@@ -483,6 +487,7 @@ static void irpc_handler_reply(struct messaging_context *msg_ctx,
irpc->status = header->status;
}
irpc->done = True;
+ talloc_steal(irpc, ndr);
if (irpc->async.fn) {
irpc->async.fn(irpc);
}
@@ -572,7 +577,9 @@ static void irpc_handler(struct messaging_context *msg_ctx, void *private,
irpc_handler_reply(msg_ctx, ndr, &header);
} else {
irpc_handler_request(msg_ctx, ndr, &header, src);
+ talloc_free(ndr);
}
+ return;
failed:
talloc_free(ndr);
@@ -674,16 +681,13 @@ failed:
*/
NTSTATUS irpc_call_recv(struct irpc_request *irpc)
{
- NTSTATUS status;
NT_STATUS_HAVE_NO_MEMORY(irpc);
while (!irpc->done) {
if (event_loop_once(irpc->msg_ctx->event.ev) != 0) {
return NT_STATUS_CONNECTION_DISCONNECTED;
}
}
- status = irpc->status;
- talloc_free(irpc);
- return status;
+ return irpc->status;
}
/*
diff --git a/source4/scripting/ejs/mprutil.c b/source4/scripting/ejs/mprutil.c
index c614792d8e..c915174126 100644
--- a/source4/scripting/ejs/mprutil.c
+++ b/source4/scripting/ejs/mprutil.c
@@ -88,11 +88,12 @@
/*
add an indexed array element to a property
*/
-static void mprAddArray(struct MprVar *var, int i, struct MprVar v)
+ void mprAddArray(struct MprVar *var, int i, struct MprVar v)
{
char idx[16];
mprItoa(i, idx, sizeof(idx));
mprSetVar(var, idx, v);
+ mprSetVar(var, "length", mprCreateIntegerVar(i+1));
}
/*
@@ -179,8 +180,7 @@ struct MprVar mprLdbArray(struct ldb_message **msg, int count, const char *name)
for (i=0;i<count;i++) {
mprAddArray(&res, i, mprLdbMessage(msg[i]));
}
- mprSetPropertyValue(&res, "length", mprCreateIntegerVar(i));
- return res;
+ return res;
}
diff --git a/source4/scripting/ejs/smbcalls.h b/source4/scripting/ejs/smbcalls.h
index c16b65b3c1..5bd7d4e448 100644
--- a/source4/scripting/ejs/smbcalls.h
+++ b/source4/scripting/ejs/smbcalls.h
@@ -25,5 +25,7 @@
void mpr_Return(int eid, struct MprVar);
NTSTATUS mprSetVar(struct MprVar *v, const char *name, struct MprVar val);
NTSTATUS mprGetVar(struct MprVar **v, const char *name);
+void mprAddArray(struct MprVar *var, int i, struct MprVar v);
+
diff --git a/source4/scripting/ejs/smbcalls_rpc.c b/source4/scripting/ejs/smbcalls_rpc.c
index 735383df08..bb05eda426 100644
--- a/source4/scripting/ejs/smbcalls_rpc.c
+++ b/source4/scripting/ejs/smbcalls_rpc.c
@@ -65,13 +65,14 @@ static int ejs_irpc_connect(MprVarHandle eid, int argc, struct MprVar **argv)
return -1;
}
+ conn = argv[0];
+
p = talloc(conn, struct ejs_irpc_connection);
if (p == NULL) {
return -1;
}
- conn = argv[0];
- p->server_name = mprToString(argv[2]);
+ p->server_name = mprToString(argv[1]);
ev = talloc_find_parent_bytype(mprMemCtx(), struct event_context);
@@ -92,7 +93,8 @@ static int ejs_irpc_connect(MprVarHandle eid, int argc, struct MprVar **argv)
talloc_free(p);
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
} else {
- mprSetPtrChild(conn, "pipe", p);
+ mprSetPtrChild(conn, "irpc", p);
+ status = NT_STATUS_OK;
}
mpr_Return(eid, mprNTSTATUS(status));
@@ -170,6 +172,95 @@ static int ejs_irpc_call(int eid, struct MprVar *conn, struct MprVar *io,
const struct dcerpc_interface_table *iface, int callnum,
ejs_pull_function_t ejs_pull, ejs_push_function_t ejs_push)
{
+ NTSTATUS status;
+ void *ptr;
+ struct ejs_rpc *ejs;
+ const struct dcerpc_interface_call *call;
+ struct ejs_irpc_connection *p;
+ struct irpc_request **reqs;
+ int i, count;
+ struct MprVar *results;
+
+ p = mprGetPtr(conn, "irpc");
+
+ ejs = talloc(mprMemCtx(), struct ejs_rpc);
+ if (ejs == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ call = &iface->calls[callnum];
+
+ ejs->eid = eid;
+ ejs->callname = call->name;
+
+ /* allocate the C structure */
+ ptr = talloc_zero_size(ejs, call->struct_size);
+ if (ptr == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* convert the mpr object into a C structure */
+ status = ejs_pull(ejs, io, ptr);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ for (count=0;p->dest_ids[count];count++) /* noop */ ;
+
+ /* we need to make a call per server */
+ reqs = talloc_array(ejs, struct irpc_request *, count);
+ if (reqs == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ /* make the actual calls */
+ for (i=0;i<count;i++) {
+ reqs[i] = irpc_call_send(p->msg_ctx, p->dest_ids[i],
+ iface, callnum, ptr);
+ if (reqs[i] == NULL) {
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ talloc_steal(reqs, reqs[i]);
+ }
+
+ mprSetVar(io, "results", mprCreateObjVar("results", MPR_DEFAULT_HASH_SIZE));
+ results = mprGetProperty(io, "results", NULL);
+
+ /* and receive the results, placing them in io.results[i] */
+ for (i=0;i<count;i++) {
+ struct MprVar *output;
+
+ status = irpc_call_recv(reqs[i]);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ status = ejs_push(ejs, io, ptr);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+ talloc_free(reqs[i]);
+
+ /* add to the results array */
+ output = mprGetProperty(io, "output", NULL);
+ if (output) {
+ char idx[16];
+ mprItoa(i, idx, sizeof(idx));
+ mprSetProperty(results, idx, output);
+ mprDeleteProperty(io, "output");
+ }
+ }
+ mprSetVar(results, "length", mprCreateIntegerVar(i));
+
+done:
+ talloc_free(ejs);
+ mpr_Return(eid, mprNTSTATUS(status));
+ if (NT_STATUS_EQUAL(status, NT_STATUS_INTERNAL_ERROR)) {
+ return -1;
+ }
return 0;
}
diff --git a/source4/scripting/ejs/smbscript.c b/source4/scripting/ejs/smbscript.c
index 80ef96e1af..bf9049af36 100644
--- a/source4/scripting/ejs/smbscript.c
+++ b/source4/scripting/ejs/smbscript.c
@@ -97,7 +97,6 @@ void ejs_exception(const char *reason)
}
talloc_steal(mem_ctx, argv_list);
v = mprList("ARGV", argv_list);
- mprSetPropertyValue(&v, "length", mprCreateIntegerVar(i-1));
mprSetVar(ejsGetGlobalObject(eid), "ARGV", v);
/* load the script and advance past interpreter line*/