mirror of
https://github.com/samba-team/samba.git
synced 2025-08-03 04:22:09 +03:00
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 061e20e509
)
This commit is contained in:
committed by
Gerald (Jerry) Carter
parent
e43e8fcf55
commit
056096c30b
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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,7 +180,6 @@ 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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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*/
|
||||
|
Reference in New Issue
Block a user