summaryrefslogtreecommitdiffstats
path: root/source4/libcli
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-11-04 09:10:31 +0000
committerAndrew Tridgell <tridge@samba.org>2003-11-04 09:10:31 +0000
commit46046aa69be01d4868395b9b52b8bcd22c3859e5 (patch)
tree3af71169e89f42282e6a4363bc27863ed41ce31d /source4/libcli
parentd8cbe76b868eb6f2b3876fa540e0847bd2d4f9d7 (diff)
yipee! we can now do lsaOpenPolicy() via the new interfaces, without
using any of the old lsa code (This used to be commit f5bd301ff7befa223a1d761a37ae8f7ce7f1fcd1)
Diffstat (limited to 'source4/libcli')
-rw-r--r--source4/libcli/ndr/libndr.h6
-rw-r--r--source4/libcli/ndr/ndr_basic.c96
-rw-r--r--source4/libcli/ndr/ndr_echo.c6
-rw-r--r--source4/libcli/ndr/ndr_lsa.c85
-rw-r--r--source4/libcli/ndr/ndr_lsa.h47
-rw-r--r--source4/libcli/ndr/ndr_misc.c45
-rw-r--r--source4/libcli/ndr/ndr_misc.h26
-rw-r--r--source4/libcli/raw/rawdcerpc.c62
-rw-r--r--source4/libcli/rpc/dcerpc.c10
-rw-r--r--source4/libcli/rpc/rpc_lsa.c64
10 files changed, 422 insertions, 25 deletions
diff --git a/source4/libcli/ndr/libndr.h b/source4/libcli/ndr/libndr.h
index 0205a64552..931fc1c341 100644
--- a/source4/libcli/ndr/libndr.h
+++ b/source4/libcli/ndr/libndr.h
@@ -54,6 +54,10 @@ struct ndr_push {
TALLOC_CTX *mem_ctx;
};
+struct ndr_push_save {
+ uint32 offset;
+};
+
#define NDR_BASE_MARSHALL_SIZE 1024
@@ -90,4 +94,6 @@ typedef NTSTATUS (*ndr_pull_fn_t)(struct ndr_pull *, void *);
/* now pull in the individual parsers */
#include "libcli/ndr/ndr_sec.h"
+#include "libcli/ndr/ndr_misc.h"
#include "libcli/ndr/ndr_echo.h"
+#include "libcli/ndr/ndr_lsa.h"
diff --git a/source4/libcli/ndr/ndr_basic.c b/source4/libcli/ndr/ndr_basic.c
index d06eac3ca9..8cbf375403 100644
--- a/source4/libcli/ndr/ndr_basic.c
+++ b/source4/libcli/ndr/ndr_basic.c
@@ -36,21 +36,6 @@
} while(0)
/*
- parse a GUID
-*/
-NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid)
-{
- int i;
- NDR_PULL_NEED_BYTES(ndr, GUID_SIZE);
- for (i=0;i<GUID_SIZE;i++) {
- guid->info[i] = CVAL(ndr->data, ndr->offset + i);
- }
- ndr->offset += i;
- return NT_STATUS_OK;
-}
-
-
-/*
parse a u8
*/
NTSTATUS ndr_pull_u8(struct ndr_pull *ndr, uint8 *v)
@@ -96,17 +81,40 @@ NTSTATUS ndr_pull_u32(struct ndr_pull *ndr, uint32 *v)
}
/*
+ pull a NTSTATUS
+*/
+NTSTATUS ndr_pull_status(struct ndr_pull *ndr, NTSTATUS *status)
+{
+ uint32 v;
+ NDR_CHECK(ndr_pull_u32(ndr, &v));
+ *status = NT_STATUS(v);
+ return NT_STATUS_OK;
+}
+
+/*
parse a set of bytes
*/
-NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char **data, uint32 n)
+NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, char *data, uint32 n)
{
NDR_PULL_NEED_BYTES(ndr, n);
- NDR_ALLOC_N(ndr, *data, n);
- memcpy(*data, ndr->data + ndr->offset, n);
+ memcpy(data, ndr->data + ndr->offset, n);
ndr->offset += n;
return NT_STATUS_OK;
}
+/*
+ parse a GUID
+*/
+NTSTATUS ndr_pull_guid(struct ndr_pull *ndr, GUID *guid)
+{
+ int i;
+ NDR_PULL_NEED_BYTES(ndr, GUID_SIZE);
+ for (i=0;i<GUID_SIZE;i++) {
+ guid->info[i] = CVAL(ndr->data, ndr->offset + i);
+ }
+ ndr->offset += i;
+ return NT_STATUS_OK;
+}
#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n)))
@@ -161,3 +169,55 @@ NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const char *data, uint32 n)
ndr->offset += n;
return NT_STATUS_OK;
}
+
+
+/*
+ this is used when a packet has a 4 byte length field. We remember the start position
+ and come back to it later to fill in the size
+*/
+NTSTATUS ndr_push_length4_start(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ save->offset = ndr->offset;
+ return ndr_push_u32(ndr, 0);
+}
+
+NTSTATUS ndr_push_length4_end(struct ndr_push *ndr, struct ndr_push_save *save)
+{
+ uint32 offset = ndr->offset;
+ ndr->offset = save->offset;
+ NDR_CHECK(ndr_push_u32(ndr, offset - save->offset));
+ ndr->offset = offset;
+ return NT_STATUS_OK;
+}
+
+/*
+ push a 1 if a pointer is non-NULL, otherwise 0
+*/
+NTSTATUS ndr_push_ptr(struct ndr_push *ndr, const void *p)
+{
+ return ndr_push_u32(ndr, p?1:0);
+}
+
+/*
+ push a comformant, variable ucs2 string onto the wire from a C string
+*/
+NTSTATUS ndr_push_unistr(struct ndr_push *ndr, const char *s)
+{
+ smb_ucs2_t *ws;
+ ssize_t len;
+ int i;
+ len = push_ucs2_talloc(ndr->mem_ctx, &ws, s);
+ if (len == -1) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ NDR_CHECK(ndr_push_u32(ndr, len));
+ NDR_CHECK(ndr_push_u32(ndr, 0));
+ NDR_CHECK(ndr_push_u32(ndr, len-2));
+ NDR_PUSH_NEED_BYTES(ndr, len);
+ for (i=0;i<len;i+=2) {
+ SSVAL(ndr->data, ndr->offset + i, ws[i]);
+ }
+ ndr->offset += i;
+ return NT_STATUS_OK;
+}
+
diff --git a/source4/libcli/ndr/ndr_echo.c b/source4/libcli/ndr/ndr_echo.c
index a085a6534d..c60569676c 100644
--- a/source4/libcli/ndr/ndr_echo.c
+++ b/source4/libcli/ndr/ndr_echo.c
@@ -53,7 +53,8 @@ NTSTATUS ndr_pull_rpcecho_echodata(struct ndr_pull *ndr,
struct rpcecho_echodata *r)
{
NDR_CHECK(ndr_pull_u32(ndr, &r->out.len));
- NDR_CHECK(ndr_pull_bytes(ndr, &r->out.data, r->out.len));
+ NDR_ALLOC_N(ndr, r->out.data, r->out.len);
+ NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len));
return NT_STATUS_OK;
}
@@ -97,7 +98,8 @@ NTSTATUS ndr_pull_rpcecho_sourcedata(struct ndr_pull *ndr,
struct rpcecho_sourcedata *r)
{
NDR_CHECK(ndr_pull_u32(ndr, &r->out.len));
- NDR_CHECK(ndr_pull_bytes(ndr, &r->out.data, r->out.len));
+ NDR_ALLOC_N(ndr, r->out.data, r->out.len);
+ NDR_CHECK(ndr_pull_bytes(ndr, r->out.data, r->out.len));
return NT_STATUS_OK;
}
diff --git a/source4/libcli/ndr/ndr_lsa.c b/source4/libcli/ndr/ndr_lsa.c
new file mode 100644
index 0000000000..6649bd04c2
--- /dev/null
+++ b/source4/libcli/ndr/ndr_lsa.c
@@ -0,0 +1,85 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling lsa pipe
+
+ Copyright (C) Andrew Tridgell 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include "includes.h"
+
+NTSTATUS ndr_push_lsa_QosInfo(struct ndr_push *ndr,
+ struct lsa_QosInfo *r)
+{
+ struct ndr_push_save length;
+
+ NDR_CHECK(ndr_push_length4_start(ndr, &length));
+ NDR_CHECK(ndr_push_u16(ndr, r->impersonation_level));
+ NDR_CHECK(ndr_push_u8(ndr, r->context_mode));
+ NDR_CHECK(ndr_push_u8(ndr, r->effective_only));
+ NDR_CHECK(ndr_push_length4_end(ndr, &length));
+
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_push_lsa_ObjectAttribute(struct ndr_push *ndr,
+ struct lsa_ObjectAttribute *r)
+{
+ struct ndr_push_save length;
+
+ NDR_CHECK(ndr_push_length4_start(ndr, &length));
+ NDR_CHECK(ndr_push_ptr(ndr, r->root_dir));
+ NDR_CHECK(ndr_push_ptr(ndr, r->object_name));
+ NDR_CHECK(ndr_push_u32(ndr, r->attributes));
+ NDR_CHECK(ndr_push_ptr(ndr, r->sec_desc));
+ NDR_CHECK(ndr_push_ptr(ndr, r->sec_qos));
+
+ if (r->root_dir) NDR_CHECK(ndr_push_u8(ndr, r->root_dir[0]));
+ if (r->object_name) NDR_CHECK(ndr_push_unistr(ndr, r->object_name));
+ if (r->sec_desc) NDR_CHECK(ndr_push_security_descriptor(ndr, r->sec_desc));
+ if (r->sec_qos) NDR_CHECK(ndr_push_lsa_QosInfo(ndr, r->sec_qos));
+
+ NDR_CHECK(ndr_push_length4_end(ndr, &length));
+
+ return NT_STATUS_OK;
+}
+
+/*
+ push a openpolicy
+*/
+NTSTATUS ndr_push_lsa_OpenPolicy(struct ndr_push *ndr,
+ struct lsa_OpenPolicy *r)
+{
+ NDR_CHECK(ndr_push_ptr(ndr, r->in.system_name));
+ NDR_CHECK(ndr_push_u16(ndr, r->in.system_name[0]));
+ NDR_CHECK(ndr_push_lsa_ObjectAttribute(ndr, r->in.attr));
+ NDR_CHECK(ndr_push_u32(ndr, r->in.desired_access));
+ return NT_STATUS_OK;
+}
+
+
+/*
+ parse a openpolicy
+*/
+NTSTATUS ndr_pull_lsa_OpenPolicy(struct ndr_pull *ndr,
+ struct lsa_OpenPolicy *r)
+{
+ NDR_CHECK(ndr_pull_policy_handle(ndr, &r->out.handle));
+ NDR_CHECK(ndr_pull_status(ndr, &r->out.status));
+ return NT_STATUS_OK;
+}
diff --git a/source4/libcli/ndr/ndr_lsa.h b/source4/libcli/ndr/ndr_lsa.h
new file mode 100644
index 0000000000..4a0aff8323
--- /dev/null
+++ b/source4/libcli/ndr/ndr_lsa.h
@@ -0,0 +1,47 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ definitions for marshalling/unmarshalling the lsa pipe
+
+ Copyright (C) Andrew Tridgell 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+struct lsa_QosInfo {
+ uint16 impersonation_level;
+ uint8 context_mode;
+ uint8 effective_only;
+};
+
+struct lsa_ObjectAttribute {
+ const char *root_dir;
+ const char *object_name;
+ uint32 attributes;
+ struct security_descriptor *sec_desc;
+ struct lsa_QosInfo *sec_qos;
+};
+
+struct lsa_OpenPolicy {
+ struct {
+ const char *system_name;
+ struct lsa_ObjectAttribute *attr;
+ uint32 desired_access;
+ } in;
+ struct {
+ struct policy_handle handle;
+ NTSTATUS status;
+ } out;
+};
diff --git a/source4/libcli/ndr/ndr_misc.c b/source4/libcli/ndr/ndr_misc.c
new file mode 100644
index 0000000000..cdd6652068
--- /dev/null
+++ b/source4/libcli/ndr/ndr_misc.c
@@ -0,0 +1,45 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling miscellaneous rpc structures
+
+ Copyright (C) Andrew Tridgell 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include "includes.h"
+
+
+/*
+ parse a policy handle
+*/
+NTSTATUS ndr_pull_policy_handle(struct ndr_pull *ndr,
+ struct policy_handle *r)
+{
+ NDR_CHECK(ndr_pull_bytes(ndr, r->data, 20));
+ return NT_STATUS_OK;
+}
+
+/*
+ push a policy handle
+*/
+NTSTATUS ndr_push_policy_handle(struct ndr_push *ndr,
+ struct policy_handle *r)
+{
+ NDR_CHECK(ndr_push_bytes(ndr, r->data, 20));
+ return NT_STATUS_OK;
+}
diff --git a/source4/libcli/ndr/ndr_misc.h b/source4/libcli/ndr/ndr_misc.h
new file mode 100644
index 0000000000..cc3576b3e8
--- /dev/null
+++ b/source4/libcli/ndr/ndr_misc.h
@@ -0,0 +1,26 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ definitions for marshalling/unmarshalling miscellaneous structures
+
+ Copyright (C) Andrew Tridgell 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* policy handles are used all over the place */
+struct policy_handle {
+ char data[20];
+};
diff --git a/source4/libcli/raw/rawdcerpc.c b/source4/libcli/raw/rawdcerpc.c
index a6cd75eeaa..6a3275c7a4 100644
--- a/source4/libcli/raw/rawdcerpc.c
+++ b/source4/libcli/raw/rawdcerpc.c
@@ -22,6 +22,68 @@
#include "includes.h"
+
+/*
+ open a rpc connection to a named pipe
+*/
+NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_pipe *p, const char *pipe_name)
+{
+ NTSTATUS status;
+ char *name = NULL;
+ union smb_open io;
+ TALLOC_CTX *mem_ctx;
+
+ asprintf(&name, "\\%s", pipe_name);
+ if (!name) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ io.ntcreatex.level = RAW_OPEN_NTCREATEX;
+ io.ntcreatex.in.flags = 0;
+ io.ntcreatex.in.root_fid = 0;
+ io.ntcreatex.in.access_mask =
+ STD_RIGHT_READ_CONTROL_ACCESS |
+ SA_RIGHT_FILE_WRITE_ATTRIBUTES |
+ SA_RIGHT_FILE_WRITE_EA |
+ GENERIC_RIGHTS_FILE_READ |
+ GENERIC_RIGHTS_FILE_WRITE;
+ io.ntcreatex.in.file_attr = 0;
+ io.ntcreatex.in.alloc_size = 0;
+ io.ntcreatex.in.share_access =
+ NTCREATEX_SHARE_ACCESS_READ |
+ NTCREATEX_SHARE_ACCESS_WRITE;
+ io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN;
+ io.ntcreatex.in.create_options = 0;
+ io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
+ io.ntcreatex.in.security_flags = 0;
+ io.ntcreatex.in.fname = name;
+
+ mem_ctx = talloc_init("torture_rpc_connection");
+ status = smb_raw_open(p->tree, mem_ctx, &io);
+ free(name);
+ talloc_destroy(mem_ctx);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ p->fnum = io.ntcreatex.out.fnum;
+
+ /* bind to the pipe, using the pipe_name as the key */
+ status = dcerpc_bind_byname(p, pipe_name);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ union smb_close c;
+ c.close.level = RAW_CLOSE_CLOSE;
+ c.close.in.fnum = p->fnum;
+ c.close.in.write_time = 0;
+ smb_raw_close(p->tree, &c);
+ }
+
+ return status;
+}
+
+
struct cli_request *dcerpc_raw_send(struct dcerpc_pipe *p, DATA_BLOB *blob)
{
struct smb_trans2 trans;
diff --git a/source4/libcli/rpc/dcerpc.c b/source4/libcli/rpc/dcerpc.c
index 7d6888dde7..89f2c6d5b1 100644
--- a/source4/libcli/rpc/dcerpc.c
+++ b/source4/libcli/rpc/dcerpc.c
@@ -28,7 +28,7 @@ struct dcerpc_pipe *dcerpc_pipe_init(struct cli_tree *tree)
{
struct dcerpc_pipe *p;
- TALLOC_CTX *mem_ctx = talloc_init("cli_dcerpc_tree");
+ TALLOC_CTX *mem_ctx = talloc_init("dcerpc_tree");
if (mem_ctx == NULL)
return NULL;
@@ -513,7 +513,7 @@ NTSTATUS dcerpc_bind(struct dcerpc_pipe *p,
DATA_BLOB blob;
DATA_BLOB blob_out;
- mem_ctx = talloc_init("cli_dcerpc_bind");
+ mem_ctx = talloc_init("dcerpc_bind");
if (!mem_ctx) {
return NT_STATUS_NO_MEMORY;
}
@@ -590,7 +590,7 @@ static const struct {
/* Perform a bind using the given well-known pipe name */
-NTSTATUS cli_dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name)
+NTSTATUS dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name)
{
int i;
@@ -609,7 +609,7 @@ NTSTATUS cli_dcerpc_bind_byname(struct dcerpc_pipe *p, const char *pipe_name)
/*
perform a full request/response pair on a dcerpc pipe
*/
-NTSTATUS cli_dcerpc_request(struct dcerpc_pipe *p,
+NTSTATUS dcerpc_request(struct dcerpc_pipe *p,
uint16 opnum,
TALLOC_CTX *mem_ctx,
DATA_BLOB *stub_data_in,
@@ -777,7 +777,7 @@ NTSTATUS dcerpc_ndr_request(struct dcerpc_pipe *p,
request = ndr_push_blob(push);
/* make the actual dcerpc request */
- status = cli_dcerpc_request(p, opnum, mem_ctx, &request, &response);
+ status = dcerpc_request(p, opnum, mem_ctx, &request, &response);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
diff --git a/source4/libcli/rpc/rpc_lsa.c b/source4/libcli/rpc/rpc_lsa.c
new file mode 100644
index 0000000000..b747762984
--- /dev/null
+++ b/source4/libcli/rpc/rpc_lsa.c
@@ -0,0 +1,64 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ rpc lsa pipe calls
+
+ Copyright (C) Andrew Tridgell 2003
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*
+ OpenPolicy interface
+*/
+NTSTATUS dcerpc_lsa_OpenPolicy(struct dcerpc_pipe *p,
+ const char *server,
+ struct lsa_ObjectAttribute *attr,
+ uint32 access_mask,
+ struct policy_handle *handle)
+{
+ struct lsa_OpenPolicy r;
+ NTSTATUS status;
+ TALLOC_CTX *mem_ctx;
+
+ mem_ctx = talloc_init("dcerpc_rpcecho_addone");
+ if (!mem_ctx) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* fill the .in side of the call */
+ r.in.system_name = server;
+ r.in.attr = attr;
+ r.in.desired_access = access_mask;
+
+ /* make the call */
+ status = dcerpc_ndr_request(p, LSA_OPENPOLICY, mem_ctx,
+ (ndr_push_fn_t) ndr_push_lsa_OpenPolicy,
+ (ndr_pull_fn_t) ndr_pull_lsa_OpenPolicy,
+ &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto done;
+ }
+
+ /* and extract the .out parameters */
+ *handle = r.out.handle;
+ status = r.out.status;
+
+done:
+ talloc_destroy(mem_ctx);
+ return status;
+}