]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
Add SMB2 lsa helper routines
authorDavid Mulder <dmulder@suse.com>
Fri, 20 Dec 2019 21:10:49 +0000 (14:10 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 28 Apr 2020 18:09:39 +0000 (18:09 +0000)
Signed-off-by: David Mulder <dmulder@suse.com>
Reviewed-by: Noel Power <noel.power@suse.com>
Reviewed-by: Jeremy Allison <jra@samba.org>
(cherry picked from commit 3763052c2a95ac9bd60f00458389a5245cf5d58d)

source4/libcli/smb2/smb2.h
source4/libcli/util/clilsa.c
source4/torture/raw/acls.c
source4/torture/smb2/util.c
source4/torture/util_smb.c

index 73e117a961d550ff8efe37543c17ce88f8585169..4aadab21c4cf5f606e220ba9b4917f8dc7139aab 100644 (file)
@@ -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;
 };
 
 /*
index b9f220f48ab78ba225649ca090edba0da8573c47..8476fd890c359fb404b4418833f1d9e5f631eb54 100644 (file)
@@ -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<rights.count;i++) {
+               if (strcmp(rights.names[i].string, privilege) == 0) {
+                       talloc_free(mem_ctx);
+                       return NT_STATUS_OK;
+               }
+       }
+
+       talloc_free(mem_ctx);
+       return NT_STATUS_NOT_FOUND;
+}
+
+
 /*
   lookup a SID, returning its name
 */
index 9e3202b6fbdc88d29233a04a7a6a56bbfcb2d152..9d9b6b130f3d1f229fc729cd6eae4fe491debd67 100644 (file)
@@ -24,6 +24,7 @@
 #include "libcli/raw/libcliraw.h"
 #include "libcli/libcli.h"
 #include "librpc/gen_ndr/lsa.h"
+#include "libcli/smb2/smb2.h"
 #include "libcli/util/clilsa.h"
 #include "libcli/security/security.h"
 #include "torture/util.h"
index bdae7886edef68036add3a395cd8881ca48b6469..29b5c64dc463be72bfae7bc9442f1f5a43c3cced 100644 (file)
@@ -34,6 +34,9 @@
 #include "torture/torture.h"
 #include "torture/smb2/proto.h"
 #include "source4/torture/util.h"
+#include "libcli/security/dom_sid.h"
+#include "librpc/gen_ndr/lsa.h"
+#include "libcli/util/clilsa.h"
 
 
 /*
@@ -979,3 +982,45 @@ void smb2_oplock_create(struct smb2_create *io, const char *name, uint8_t oplock
                                 oplock);
 }
 
+/*
+   a wrapper around smblsa_sid_check_privilege, that tries to take
+   account of the fact that the lsa privileges calls don't expand
+   group memberships, using an explicit check for administrator. There
+   must be a better way ...
+ */
+NTSTATUS torture_smb2_check_privilege(struct smb2_tree *tree,
+                                    const char *sid_str,
+                                    const char *privilege)
+{
+       struct dom_sid *sid = NULL;
+       TALLOC_CTX *tmp_ctx = NULL;
+       uint32_t rid;
+       NTSTATUS status;
+
+       tmp_ctx = talloc_new(tree);
+       if (tmp_ctx == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       sid = dom_sid_parse_talloc(tmp_ctx, sid_str);
+       if (sid == NULL) {
+               talloc_free(tmp_ctx);
+               return NT_STATUS_INVALID_SID;
+       }
+
+       status = dom_sid_split_rid(tmp_ctx, sid, NULL, &rid);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(tmp_ctx);
+               return status;
+       }
+
+       if (rid == DOMAIN_RID_ADMINISTRATOR) {
+               /* assume the administrator has them all */
+               TALLOC_FREE(tmp_ctx);
+               return NT_STATUS_OK;
+       }
+
+       talloc_free(tmp_ctx);
+
+       return smb2lsa_sid_check_privilege(tree, sid_str, privilege);
+}
index 5ca816f7cdee35f64311b7c6fb3af274b427d41c..7641b1fbc0bfb7ebeb53c3516af44d784427d52f 100644 (file)
@@ -33,6 +33,7 @@
 #include "libcli/resolve/resolve.h"
 #include "param/param.h"
 #include "libcli/security/security.h"
+#include "libcli/smb2/smb2.h"
 #include "libcli/util/clilsa.h"
 #include "torture/util.h"
 #include "libcli/smb/smbXcli_base.h"