From: David Mulder Date: Fri, 20 Dec 2019 21:10:49 +0000 (-0700) Subject: Add SMB2 lsa helper routines X-Git-Tag: ldb-2.2.0~852 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a3ddd679d7438256f894dc50de917328fab822ab;p=thirdparty%2Fsamba.git Add SMB2 lsa helper routines Signed-off-by: David Mulder Reviewed-by: Noel Power Reviewed-by: Jeremy Allison (cherry picked from commit 3763052c2a95ac9bd60f00458389a5245cf5d58d) --- diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 73e117a961d..4aadab21c4c 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -101,12 +101,23 @@ struct smb2_transport { }; +/* + SMB2 LSA state +*/ +struct smb2lsa_state { + struct dcerpc_binding_handle *binding_handle; + struct smb2_tree *ipc_tree; + struct policy_handle handle; +}; + + /* SMB2 tree context */ struct smb2_tree { struct smb2_session *session; struct smbXcli_tcon *smbXcli; + struct smb2lsa_state *lsa; }; /* diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c index b9f220f48ab..8476fd890c3 100644 --- a/source4/libcli/util/clilsa.c +++ b/source4/libcli/util/clilsa.c @@ -27,6 +27,7 @@ #include "includes.h" #include "libcli/raw/libcliraw.h" +#include "libcli/smb2/smb2.h" #include "libcli/libcli.h" #include "libcli/security/security.h" #include "librpc/gen_ndr/ndr_lsa.h" @@ -142,6 +143,81 @@ static NTSTATUS smblsa_connect(struct smbcli_state *cli) } +static NTSTATUS smb2lsa_connect(struct smb2_tree *tree) +{ + struct smb2lsa_state *lsa = NULL; + struct dcerpc_pipe *lsa_pipe = NULL; + NTSTATUS status; + struct lsa_OpenPolicy2 r = {{0}, {0}}; + const char *system_name = "\\"; + struct lsa_ObjectAttribute attr = {0}; + struct lsa_QosInfo qos = {0}; + + if (tree->lsa != NULL) { + return NT_STATUS_OK; + } + + lsa = talloc(tree, struct smb2lsa_state); + if (lsa == NULL) { + return NT_STATUS_NO_MEMORY; + } + + lsa_pipe = dcerpc_pipe_init(lsa, tree->session->transport->ev); + if (lsa_pipe == NULL) { + talloc_free(lsa); + return NT_STATUS_NO_MEMORY; + } + + /* open the LSA pipe */ + status = dcerpc_pipe_open_smb2(lsa_pipe, tree, NDR_LSARPC_NAME); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lsa); + return status; + } + + /* bind to the LSA pipe */ + status = dcerpc_bind_auth_none(lsa_pipe, &ndr_table_lsarpc); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lsa); + return status; + } + lsa->binding_handle = lsa_pipe->binding_handle; + + /* open a lsa policy handle */ + qos.len = 0; + qos.impersonation_level = 2; + qos.context_mode = 1; + qos.effective_only = 0; + + attr.len = 0; + attr.root_dir = NULL; + attr.object_name = NULL; + attr.attributes = 0; + attr.sec_desc = NULL; + attr.sec_qos = &qos; + + r.in.system_name = system_name; + r.in.attr = &attr; + r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; + r.out.handle = &lsa->handle; + + status = dcerpc_lsa_OpenPolicy2_r(lsa->binding_handle, lsa, &r); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(lsa); + return status; + } + + if (!NT_STATUS_IS_OK(r.out.result)) { + talloc_free(lsa); + return r.out.result; + } + + tree->lsa = lsa; + + return NT_STATUS_OK; +} + + /* return the set of privileges for the given sid */ @@ -170,6 +246,31 @@ NTSTATUS smblsa_sid_privileges(struct smbcli_state *cli, struct dom_sid *sid, } +NTSTATUS smb2lsa_sid_privileges(struct smb2_tree *tree, struct dom_sid *sid, + TALLOC_CTX *mem_ctx, + struct lsa_RightSet *rights) +{ + NTSTATUS status; + struct lsa_EnumAccountRights r = {{0}, {0}}; + + status = smb2lsa_connect(tree); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + r.in.handle = &tree->lsa->handle; + r.in.sid = sid; + r.out.rights = rights; + + status = dcerpc_lsa_EnumAccountRights_r(tree->lsa->binding_handle, mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return r.out.result; +} + + /* check if a named sid has a particular named privilege */ @@ -207,6 +308,45 @@ NTSTATUS smblsa_sid_check_privilege(struct smbcli_state *cli, } +NTSTATUS smb2lsa_sid_check_privilege(struct smb2_tree *tree, + const char *sid_str, + const char *privilege) +{ + struct lsa_RightSet rights = {0}; + NTSTATUS status; + TALLOC_CTX *mem_ctx = NULL; + struct dom_sid *sid = NULL; + unsigned i; + + mem_ctx = talloc_new(tree); + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } + + sid = dom_sid_parse_talloc(mem_ctx, sid_str); + if (sid == NULL) { + talloc_free(mem_ctx); + return NT_STATUS_INVALID_SID; + } + + status = smb2lsa_sid_privileges(tree, sid, mem_ctx, &rights); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(mem_ctx); + return status; + } + + for (i=0;i