diff options
author | Andrew Tridgell <tridge@samba.org> | 2003-11-04 09:10:31 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2003-11-04 09:10:31 +0000 |
commit | 46046aa69be01d4868395b9b52b8bcd22c3859e5 (patch) | |
tree | 3af71169e89f42282e6a4363bc27863ed41ce31d /source4/libcli | |
parent | d8cbe76b868eb6f2b3876fa540e0847bd2d4f9d7 (diff) | |
download | samba-46046aa69be01d4868395b9b52b8bcd22c3859e5.tar.gz samba-46046aa69be01d4868395b9b52b8bcd22c3859e5.tar.bz2 samba-46046aa69be01d4868395b9b52b8bcd22c3859e5.zip |
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.h | 6 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_basic.c | 96 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_echo.c | 6 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_lsa.c | 85 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_lsa.h | 47 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_misc.c | 45 | ||||
-rw-r--r-- | source4/libcli/ndr/ndr_misc.h | 26 | ||||
-rw-r--r-- | source4/libcli/raw/rawdcerpc.c | 62 | ||||
-rw-r--r-- | source4/libcli/rpc/dcerpc.c | 10 | ||||
-rw-r--r-- | source4/libcli/rpc/rpc_lsa.c | 64 |
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; +} |