ACL formats used by sharesec in 4.2
Christof Schmitt
cs at samba.org
Fri Apr 24 12:46:23 MDT 2015
On Thu, Apr 23, 2015 at 01:28:30PM -0700, Jeremy Allison wrote:
> On Thu, Apr 23, 2015 at 09:44:20AM -0700, Christof Schmitt wrote:
> > Hi,
> >
> > i noticed that the ACL output printed by sharesec has been changed
> > through this commit:
> >
> > commit 4a9d64e37a72cd1384c1e8db54532b8e850715cd
> > Author: David Disseldorp <ddiss at samba.org>
> > Date: Mon May 26 14:38:24 2014 +0200
> >
> > sharesec: use NDR security descriptor print fns
> >
> > Signed-off-by: David Disseldorp <ddiss at samba.org>
> > Reviewed-by: Jeremy Allison <jra at samba.org>
> > Reviewed-by: Volker Lendecke <vl at samba.org>
> >
> > While i understand the goal to share code, now the input format of
> > sharesec is different than the output format:
> >
> > Setting a share-level ACL uses the old format:
> > # sharesec test -a S-1-5-21-1866488690-1365729215-3963860297-17724:ALLOWED/0/FULL
> >
> > Quering it returns the NDR dump:
> > # sharesec test -v
> > : struct security_descriptor
> > revision : SECURITY_DESCRIPTOR_REVISION_1 (1)
> > type : 0x8004 (32772)
> > 0: SEC_DESC_OWNER_DEFAULTED
> > 0: SEC_DESC_GROUP_DEFAULTED
> > 1: SEC_DESC_DACL_PRESENT
> > 0: SEC_DESC_DACL_DEFAULTED
> > 0: SEC_DESC_SACL_PRESENT
> > 0: SEC_DESC_SACL_DEFAULTED
> > 0: SEC_DESC_DACL_TRUSTED
> > ...
> >
> > This is probably not very useful. Should we revert the patches to return
> > to the old output format?
>
> Yeah, the old code to do this now exists in source3/utils/smbcacls.c
> only. Maybe we should move it to a common file source3/lib/util_sdprint.c
> or something and just share it between sharesec and smbcacls.
See the attached patches that move the print and parse functions to a
common file and restore the old output format in sharesec. I also logged
a bugzilla for backporting the changes to 4.2, once they are in master.
There are also other areas that should be looked at in the future: There
is more duplication of the same code in libsmb and smbcquotas, but that
is a cleanup for another day. Also having to option to use names instead
of SIDs in sharesec might be worthwhile to consider, but that is also a
separate item.
Christof
-------------- next part --------------
From 4c2976c9b2f8cf854256738579ef5d3d3a90a69f Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 08:31:41 -0700
Subject: [PATCH 1/9] smbcacls: Make 'numeric' a local variable
This will allow moving code to a shared file without relying on a global
variable.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/utils/smbcacls.c | 45 +++++++++++++++++++++++++--------------------
1 files changed, 25 insertions(+), 20 deletions(-)
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 13262ed..742b822 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -36,10 +36,6 @@ static int test_args;
#define CREATE_ACCESS_READ READ_CONTROL_ACCESS
-/* numeric is set when the user wants numeric SIDs and ACEs rather
- than going via LSA calls to resolve them */
-static int numeric;
-
static int sddl;
static int query_sec_info = -1;
static int set_sec_info = -1;
@@ -255,7 +251,8 @@ static struct dom_sid *get_domain_sid(struct cli_state *cli)
/* convert a SID to a string, either numeric or username/group */
-static void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid)
+static void SidToString(struct cli_state *cli, fstring str,
+ const struct dom_sid *sid, bool numeric)
{
char *domain = NULL;
char *name = NULL;
@@ -356,14 +353,15 @@ static void print_ace_flags(FILE *f, uint8_t flags)
}
/* print an ACE on a FILE, using either numeric or ascii representation */
-static void print_ace(struct cli_state *cli, FILE *f, struct security_ace *ace)
+static void print_ace(struct cli_state *cli, FILE *f, struct security_ace *ace,
+ bool numeric)
{
const struct perm_value *v;
fstring sidstr;
int do_print = 0;
uint32 got_mask;
- SidToString(cli, sidstr, &ace->trustee);
+ SidToString(cli, sidstr, &ace->trustee, numeric);
fprintf(f, "%s:", sidstr);
@@ -739,7 +737,7 @@ static const struct {
{SEC_DESC_SELF_RELATIVE , "SR", "Self Relative"},
};
-static void print_acl_ctrl(FILE *file, uint16_t ctrl)
+static void print_acl_ctrl(FILE *file, uint16_t ctrl, bool numeric)
{
int i;
const char* separator = "";
@@ -760,18 +758,19 @@ static void print_acl_ctrl(FILE *file, uint16_t ctrl)
}
/* print a ascii version of a security descriptor on a FILE handle */
-static void sec_desc_print(struct cli_state *cli, FILE *f, struct security_descriptor *sd)
+static void sec_desc_print(struct cli_state *cli, FILE *f,
+ struct security_descriptor *sd, bool numeric)
{
fstring sidstr;
uint32 i;
fprintf(f, "REVISION:%d\n", sd->revision);
- print_acl_ctrl(f, sd->type);
+ print_acl_ctrl(f, sd->type, numeric);
/* Print owner and group sid */
if (sd->owner_sid) {
- SidToString(cli, sidstr, sd->owner_sid);
+ SidToString(cli, sidstr, sd->owner_sid, numeric);
} else {
fstrcpy(sidstr, "");
}
@@ -779,7 +778,7 @@ static void sec_desc_print(struct cli_state *cli, FILE *f, struct security_descr
fprintf(f, "OWNER:%s\n", sidstr);
if (sd->group_sid) {
- SidToString(cli, sidstr, sd->group_sid);
+ SidToString(cli, sidstr, sd->group_sid, numeric);
} else {
fstrcpy(sidstr, "");
}
@@ -790,7 +789,7 @@ static void sec_desc_print(struct cli_state *cli, FILE *f, struct security_descr
for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
struct security_ace *ace = &sd->dacl->aces[i];
fprintf(f, "ACL:");
- print_ace(cli, f, ace);
+ print_ace(cli, f, ace, numeric);
fprintf(f, "\n");
}
@@ -942,7 +941,7 @@ static bool set_secdesc(struct cli_state *cli, const char *filename,
/*****************************************************
dump the acls for a file
*******************************************************/
-static int cacl_dump(struct cli_state *cli, const char *filename)
+static int cacl_dump(struct cli_state *cli, const char *filename, bool numeric)
{
struct security_descriptor *sd;
@@ -963,7 +962,7 @@ static int cacl_dump(struct cli_state *cli, const char *filename)
printf("%s\n", str);
TALLOC_FREE(str);
} else {
- sec_desc_print(cli, stdout, sd);
+ sec_desc_print(cli, stdout, sd, numeric);
}
return EXIT_OK;
@@ -1070,7 +1069,7 @@ set the ACLs on a file given an ascii description
*******************************************************/
static int cacl_set(struct cli_state *cli, const char *filename,
- char *the_acl, enum acl_mode mode)
+ char *the_acl, enum acl_mode mode, bool numeric)
{
struct security_descriptor *sd, *old;
uint32 i, j;
@@ -1113,7 +1112,8 @@ static int cacl_set(struct cli_state *cli, const char *filename,
if (!found) {
printf("ACL for ACE:");
- print_ace(cli, stdout, &sd->dacl->aces[i]);
+ print_ace(cli, stdout, &sd->dacl->aces[i],
+ numeric);
printf(" not found\n");
}
}
@@ -1135,7 +1135,8 @@ static int cacl_set(struct cli_state *cli, const char *filename,
fstring str;
SidToString(cli, str,
- &sd->dacl->aces[i].trustee);
+ &sd->dacl->aces[i].trustee,
+ numeric);
printf("ACL for SID %s not found\n", str);
}
}
@@ -1368,6 +1369,10 @@ int main(int argc, char *argv[])
char *path;
char *filename = NULL;
poptContext pc;
+ /* numeric is set when the user wants numeric SIDs and ACEs rather
+ than going via LSA calls to resolve them */
+ int numeric;
+
struct poptOption long_options[] = {
POPT_AUTOHELP
{ "delete", 'D', POPT_ARG_STRING, NULL, 'D', "Delete an acl", "ACL" },
@@ -1530,9 +1535,9 @@ int main(int argc, char *argv[])
} else if (change_mode != REQUEST_NONE) {
result = owner_set(cli, change_mode, filename, owner_username);
} else if (the_acl) {
- result = cacl_set(cli, filename, the_acl, mode);
+ result = cacl_set(cli, filename, the_acl, mode, numeric);
} else {
- result = cacl_dump(cli, filename);
+ result = cacl_dump(cli, filename, numeric);
}
TALLOC_FREE(frame);
--
1.7.1
From 014963201f735a708ae8f2fee1ab6d616ba1aa0d Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 08:51:32 -0700
Subject: [PATCH 2/9] smbcacls: Use defines for security flags
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/utils/smbcacls.c | 19 ++++++++++---------
1 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 742b822..f3e0eb5 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -54,19 +54,20 @@ struct perm_value {
/* These values discovered by inspection */
static const struct perm_value special_values[] = {
- { "R", 0x00120089 },
- { "W", 0x00120116 },
- { "X", 0x001200a0 },
- { "D", 0x00010000 },
- { "P", 0x00040000 },
- { "O", 0x00080000 },
+ { "R", SEC_RIGHTS_FILE_READ },
+ { "W", SEC_RIGHTS_FILE_WRITE },
+ { "X", SEC_RIGHTS_FILE_EXECUTE },
+ { "D", SEC_STD_DELETE },
+ { "P", SEC_STD_WRITE_DAC },
+ { "O", SEC_STD_WRITE_OWNER },
{ NULL, 0 },
};
static const struct perm_value standard_values[] = {
- { "READ", 0x001200a9 },
- { "CHANGE", 0x001301bf },
- { "FULL", 0x001f01ff },
+ { "READ", SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
+ { "CHANGE", SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
+ SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE },
+ { "FULL", SEC_RIGHTS_DIR_ALL },
{ NULL, 0 },
};
--
1.7.1
From 9b1357a1b793a1b942d22ab57dd91a3ceec61cb3 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 08:37:13 -0700
Subject: [PATCH 3/9] smbcacls: Move SidToString to common file
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/include/util_sd.h | 30 ++++++++++++
source3/lib/util_sd.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
source3/utils/smbcacls.c | 86 +----------------------------------
source3/wscript_build | 2 +-
4 files changed, 145 insertions(+), 86 deletions(-)
create mode 100644 source3/include/util_sd.h
create mode 100644 source3/lib/util_sd.c
diff --git a/source3/include/util_sd.h b/source3/include/util_sd.h
new file mode 100644
index 0000000..55e2205
--- /dev/null
+++ b/source3/include/util_sd.h
@@ -0,0 +1,30 @@
+/*
+ Unix SMB/CIFS implementation.
+ Security Descriptor (SD) helper functions
+
+ Copyright (C) Andrew Tridgell 2000
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Jeremy Allison 2000
+ Copyright (C) Jelmer Vernooij 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __UTIL_SD_H__
+#define __UTIL_SD_H__
+
+void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid,
+ bool numeric);
+
+#endif
diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
new file mode 100644
index 0000000..b653fe9
--- /dev/null
+++ b/source3/lib/util_sd.c
@@ -0,0 +1,113 @@
+/*
+ Unix SMB/CIFS implementation.
+ Security Descriptor (SD) helper functions
+
+ Copyright (C) Andrew Tridgell 2000
+ Copyright (C) Tim Potter 2000
+ Copyright (C) Jeremy Allison 2000
+ Copyright (C) Jelmer Vernooij 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 3 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, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "libsmb/libsmb.h"
+#include "util_sd.h"
+#include "librpc/gen_ndr/ndr_lsa.h"
+#include "../libcli/security/security.h"
+#include "rpc_client/cli_pipe.h"
+#include "rpc_client/cli_lsarpc.h"
+
+/* Open cli connection and policy handle */
+static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
+ const struct dom_sid *sid,
+ TALLOC_CTX *mem_ctx,
+ enum lsa_SidType *type,
+ char **domain, char **name)
+{
+ uint16 orig_cnum = cli_state_get_tid(cli);
+ struct rpc_pipe_client *p = NULL;
+ struct policy_handle handle;
+ NTSTATUS status;
+ TALLOC_CTX *frame = talloc_stackframe();
+ enum lsa_SidType *types;
+ char **domains;
+ char **names;
+
+ status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto tcon_fail;
+ }
+
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
+ &p);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = rpccli_lsa_open_policy(p, talloc_tos(), True,
+ GENERIC_EXECUTE_ACCESS, &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = rpccli_lsa_lookup_sids(p, talloc_tos(), &handle, 1, sid,
+ &domains, &names, &types);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ *type = types[0];
+ *domain = talloc_move(mem_ctx, &domains[0]);
+ *name = talloc_move(mem_ctx, &names[0]);
+
+ status = NT_STATUS_OK;
+ fail:
+ TALLOC_FREE(p);
+ cli_tdis(cli);
+ tcon_fail:
+ cli_state_set_tid(cli, orig_cnum);
+ TALLOC_FREE(frame);
+ return status;
+}
+
+/* convert a SID to a string, either numeric or username/group */
+void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid,
+ bool numeric)
+{
+ char *domain = NULL;
+ char *name = NULL;
+ enum lsa_SidType type;
+ NTSTATUS status;
+
+ sid_to_fstring(str, sid);
+
+ if (numeric) {
+ return;
+ }
+
+ status = cli_lsa_lookup_sid(cli, sid, talloc_tos(), &type,
+ &domain, &name);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return;
+ }
+
+ if (*domain) {
+ slprintf(str, sizeof(fstring) - 1, "%s%s%s",
+ domain, lp_winbind_separator(), name);
+ } else {
+ fstrcpy(str, name);
+ }
+}
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index f3e0eb5..5bbc8fa 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -31,6 +31,7 @@
#include "libsmb/clirap.h"
#include "passdb/machine_sid.h"
#include "../librpc/gen_ndr/ndr_lsa_c.h"
+#include "util_sd.h"
static int test_args;
@@ -71,60 +72,6 @@ static const struct perm_value standard_values[] = {
{ NULL, 0 },
};
-/* Open cli connection and policy handle */
-
-static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
- const struct dom_sid *sid,
- TALLOC_CTX *mem_ctx,
- enum lsa_SidType *type,
- char **domain, char **name)
-{
- uint16 orig_cnum = cli_state_get_tid(cli);
- struct rpc_pipe_client *p = NULL;
- struct policy_handle handle;
- NTSTATUS status;
- TALLOC_CTX *frame = talloc_stackframe();
- enum lsa_SidType *types;
- char **domains;
- char **names;
-
- status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
- if (!NT_STATUS_IS_OK(status)) {
- goto tcon_fail;
- }
-
- status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
- &p);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- status = rpccli_lsa_open_policy(p, talloc_tos(), True,
- GENERIC_EXECUTE_ACCESS, &handle);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- status = rpccli_lsa_lookup_sids(p, talloc_tos(), &handle, 1, sid,
- &domains, &names, &types);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- *type = types[0];
- *domain = talloc_move(mem_ctx, &domains[0]);
- *name = talloc_move(mem_ctx, &names[0]);
-
- status = NT_STATUS_OK;
- fail:
- TALLOC_FREE(p);
- cli_tdis(cli);
- tcon_fail:
- cli_state_set_tid(cli, orig_cnum);
- TALLOC_FREE(frame);
- return status;
-}
-
static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
const char *name,
enum lsa_SidType *type,
@@ -250,37 +197,6 @@ static struct dom_sid *get_domain_sid(struct cli_state *cli)
return sid;
}
-
-/* convert a SID to a string, either numeric or username/group */
-static void SidToString(struct cli_state *cli, fstring str,
- const struct dom_sid *sid, bool numeric)
-{
- char *domain = NULL;
- char *name = NULL;
- enum lsa_SidType type;
- NTSTATUS status;
-
- sid_to_fstring(str, sid);
-
- if (numeric) {
- return;
- }
-
- status = cli_lsa_lookup_sid(cli, sid, talloc_tos(), &type,
- &domain, &name);
-
- if (!NT_STATUS_IS_OK(status)) {
- return;
- }
-
- if (*domain) {
- slprintf(str, sizeof(fstring) - 1, "%s%s%s",
- domain, lp_winbind_separator(), name);
- } else {
- fstrcpy(str, name);
- }
-}
-
/* convert a string to a SID, either numeric or username/group */
static bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str)
{
diff --git a/source3/wscript_build b/source3/wscript_build
index d8b0bf3..36eb1b7 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -1340,7 +1340,7 @@ bld.SAMBA3_BINARY('msg_source',
install=False)
bld.SAMBA3_BINARY('smbcacls',
- source='utils/smbcacls.c',
+ source='utils/smbcacls.c lib/util_sd.c',
deps='''
talloc
popt_samba3
--
1.7.1
From 366522fc6ebd3fe1d3a9b74d79fe235edee24029 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 09:15:13 -0700
Subject: [PATCH 4/9] smbcacls: Move StringToSid to common file
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/include/util_sd.h | 1 +
source3/lib/util_sd.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
source3/utils/smbcacls.c | 62 ---------------------------------------------
3 files changed, 62 insertions(+), 62 deletions(-)
diff --git a/source3/include/util_sd.h b/source3/include/util_sd.h
index 55e2205..7f21c64 100644
--- a/source3/include/util_sd.h
+++ b/source3/include/util_sd.h
@@ -26,5 +26,6 @@
void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid,
bool numeric);
+bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str);
#endif
diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
index b653fe9..584d34a 100644
--- a/source3/lib/util_sd.c
+++ b/source3/lib/util_sd.c
@@ -111,3 +111,64 @@ void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid,
fstrcpy(str, name);
}
}
+
+static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
+ const char *name,
+ enum lsa_SidType *type,
+ struct dom_sid *sid)
+{
+ uint16 orig_cnum = cli_state_get_tid(cli);
+ struct rpc_pipe_client *p;
+ struct policy_handle handle;
+ NTSTATUS status;
+ TALLOC_CTX *frame = talloc_stackframe();
+ struct dom_sid *sids;
+ enum lsa_SidType *types;
+
+ status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto tcon_fail;
+ }
+
+ status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
+ &p);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = rpccli_lsa_open_policy(p, talloc_tos(), True,
+ GENERIC_EXECUTE_ACCESS, &handle);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ status = rpccli_lsa_lookup_names(p, talloc_tos(), &handle, 1, &name,
+ NULL, 1, &sids, &types);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto fail;
+ }
+
+ *type = types[0];
+ *sid = sids[0];
+
+ status = NT_STATUS_OK;
+ fail:
+ TALLOC_FREE(p);
+ cli_tdis(cli);
+ tcon_fail:
+ cli_state_set_tid(cli, orig_cnum);
+ TALLOC_FREE(frame);
+ return status;
+}
+
+/* convert a string to a SID, either numeric or username/group */
+bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str)
+{
+ enum lsa_SidType type;
+
+ if (string_to_sid(sid, str)) {
+ return true;
+ }
+
+ return NT_STATUS_IS_OK(cli_lsa_lookup_name(cli, str, &type, sid));
+}
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 5bbc8fa..778d30d 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -72,56 +72,6 @@ static const struct perm_value standard_values[] = {
{ NULL, 0 },
};
-static NTSTATUS cli_lsa_lookup_name(struct cli_state *cli,
- const char *name,
- enum lsa_SidType *type,
- struct dom_sid *sid)
-{
- uint16 orig_cnum = cli_state_get_tid(cli);
- struct rpc_pipe_client *p;
- struct policy_handle handle;
- NTSTATUS status;
- TALLOC_CTX *frame = talloc_stackframe();
- struct dom_sid *sids;
- enum lsa_SidType *types;
-
- status = cli_tree_connect(cli, "IPC$", "?????", "", 0);
- if (!NT_STATUS_IS_OK(status)) {
- goto tcon_fail;
- }
-
- status = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc,
- &p);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- status = rpccli_lsa_open_policy(p, talloc_tos(), True,
- GENERIC_EXECUTE_ACCESS, &handle);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- status = rpccli_lsa_lookup_names(p, talloc_tos(), &handle, 1, &name,
- NULL, 1, &sids, &types);
- if (!NT_STATUS_IS_OK(status)) {
- goto fail;
- }
-
- *type = types[0];
- *sid = sids[0];
-
- status = NT_STATUS_OK;
- fail:
- TALLOC_FREE(p);
- cli_tdis(cli);
- tcon_fail:
- cli_state_set_tid(cli, orig_cnum);
- TALLOC_FREE(frame);
- return status;
-}
-
-
static NTSTATUS cli_lsa_lookup_domain_sid(struct cli_state *cli,
struct dom_sid *sid)
{
@@ -197,18 +147,6 @@ static struct dom_sid *get_domain_sid(struct cli_state *cli)
return sid;
}
-/* convert a string to a SID, either numeric or username/group */
-static bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str)
-{
- enum lsa_SidType type;
-
- if (string_to_sid(sid, str)) {
- return true;
- }
-
- return NT_STATUS_IS_OK(cli_lsa_lookup_name(cli, str, &type, sid));
-}
-
static void print_ace_flags(FILE *f, uint8_t flags)
{
char *str = talloc_strdup(NULL, "");
--
1.7.1
From 05d8ce2c78da344af18ed01b142b6dbc3f7343a3 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 09:22:14 -0700
Subject: [PATCH 5/9] smbcacls: Move print_ace and parse_ace to common file
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/include/util_sd.h | 4 +
source3/lib/util_sd.c | 354 +++++++++++++++++++++++++++++++++++++++++++++
source3/utils/smbcacls.c | 354 ---------------------------------------------
3 files changed, 358 insertions(+), 354 deletions(-)
diff --git a/source3/include/util_sd.h b/source3/include/util_sd.h
index 7f21c64..1b22bb0 100644
--- a/source3/include/util_sd.h
+++ b/source3/include/util_sd.h
@@ -27,5 +27,9 @@
void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid,
bool numeric);
bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str);
+void print_ace(struct cli_state *cli, FILE *f, struct security_ace *ace,
+ bool numeric);
+bool parse_ace(struct cli_state *cli, struct security_ace *ace,
+ const char *orig_str);
#endif
diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
index 584d34a..616418a 100644
--- a/source3/lib/util_sd.c
+++ b/source3/lib/util_sd.c
@@ -29,6 +29,31 @@
#include "rpc_client/cli_pipe.h"
#include "rpc_client/cli_lsarpc.h"
+/* These values discovered by inspection */
+
+struct perm_value {
+ const char *perm;
+ uint32 mask;
+};
+
+static const struct perm_value special_values[] = {
+ { "R", SEC_RIGHTS_FILE_READ },
+ { "W", SEC_RIGHTS_FILE_WRITE },
+ { "X", SEC_RIGHTS_FILE_EXECUTE },
+ { "D", SEC_STD_DELETE },
+ { "P", SEC_STD_WRITE_DAC },
+ { "O", SEC_STD_WRITE_OWNER },
+ { NULL, 0 },
+};
+
+static const struct perm_value standard_values[] = {
+ { "READ", SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
+ { "CHANGE", SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
+ SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE },
+ { "FULL", SEC_RIGHTS_DIR_ALL },
+ { NULL, 0 },
+};
+
/* Open cli connection and policy handle */
static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
const struct dom_sid *sid,
@@ -172,3 +197,332 @@ bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str)
return NT_STATUS_IS_OK(cli_lsa_lookup_name(cli, str, &type, sid));
}
+
+static void print_ace_flags(FILE *f, uint8_t flags)
+{
+ char *str = talloc_strdup(NULL, "");
+
+ if (!str) {
+ goto out;
+ }
+
+ if (flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
+ str = talloc_asprintf(str, "%s%s",
+ str, "OI|");
+ if (!str) {
+ goto out;
+ }
+ }
+ if (flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
+ str = talloc_asprintf(str, "%s%s",
+ str, "CI|");
+ if (!str) {
+ goto out;
+ }
+ }
+ if (flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
+ str = talloc_asprintf(str, "%s%s",
+ str, "NP|");
+ if (!str) {
+ goto out;
+ }
+ }
+ if (flags & SEC_ACE_FLAG_INHERIT_ONLY) {
+ str = talloc_asprintf(str, "%s%s",
+ str, "IO|");
+ if (!str) {
+ goto out;
+ }
+ }
+ if (flags & SEC_ACE_FLAG_INHERITED_ACE) {
+ str = talloc_asprintf(str, "%s%s",
+ str, "I|");
+ if (!str) {
+ goto out;
+ }
+ }
+ /* Ignore define SEC_ACE_FLAG_SUCCESSFUL_ACCESS ( 0x40 )
+ and SEC_ACE_FLAG_FAILED_ACCESS ( 0x80 ) as they're
+ audit ace flags. */
+
+ if (str[strlen(str)-1] == '|') {
+ str[strlen(str)-1] = '\0';
+ fprintf(f, "/%s/", str);
+ } else {
+ fprintf(f, "/0x%x/", flags);
+ }
+ TALLOC_FREE(str);
+ return;
+
+ out:
+ fprintf(f, "/0x%x/", flags);
+}
+
+/* print an ACE on a FILE, using either numeric or ascii representation */
+void print_ace(struct cli_state *cli, FILE *f, struct security_ace *ace,
+ bool numeric)
+{
+ const struct perm_value *v;
+ fstring sidstr;
+ int do_print = 0;
+ uint32 got_mask;
+
+ SidToString(cli, sidstr, &ace->trustee, numeric);
+
+ fprintf(f, "%s:", sidstr);
+
+ if (numeric) {
+ fprintf(f, "%d/0x%x/0x%08x",
+ ace->type, ace->flags, ace->access_mask);
+ return;
+ }
+
+ /* Ace type */
+
+ if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
+ fprintf(f, "ALLOWED");
+ } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
+ fprintf(f, "DENIED");
+ } else {
+ fprintf(f, "%d", ace->type);
+ }
+
+ print_ace_flags(f, ace->flags);
+
+ /* Standard permissions */
+
+ for (v = standard_values; v->perm; v++) {
+ if (ace->access_mask == v->mask) {
+ fprintf(f, "%s", v->perm);
+ return;
+ }
+ }
+
+ /* Special permissions. Print out a hex value if we have
+ leftover bits in the mask. */
+
+ got_mask = ace->access_mask;
+
+ again:
+ for (v = special_values; v->perm; v++) {
+ if ((ace->access_mask & v->mask) == v->mask) {
+ if (do_print) {
+ fprintf(f, "%s", v->perm);
+ }
+ got_mask &= ~v->mask;
+ }
+ }
+
+ if (!do_print) {
+ if (got_mask != 0) {
+ fprintf(f, "0x%08x", ace->access_mask);
+ } else {
+ do_print = 1;
+ goto again;
+ }
+ }
+}
+
+static bool parse_ace_flags(const char *str, unsigned int *pflags)
+{
+ const char *p = str;
+ *pflags = 0;
+
+ while (*p) {
+ if (strnequal(p, "OI", 2)) {
+ *pflags |= SEC_ACE_FLAG_OBJECT_INHERIT;
+ p += 2;
+ } else if (strnequal(p, "CI", 2)) {
+ *pflags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
+ p += 2;
+ } else if (strnequal(p, "NP", 2)) {
+ *pflags |= SEC_ACE_FLAG_NO_PROPAGATE_INHERIT;
+ p += 2;
+ } else if (strnequal(p, "IO", 2)) {
+ *pflags |= SEC_ACE_FLAG_INHERIT_ONLY;
+ p += 2;
+ } else if (*p == 'I') {
+ *pflags |= SEC_ACE_FLAG_INHERITED_ACE;
+ p += 1;
+ } else if (*p) {
+ return false;
+ }
+
+ switch (*p) {
+ case '|':
+ p++;
+ case '\0':
+ continue;
+ default:
+ return false;
+ }
+ }
+ return true;
+}
+
+/* parse an ACE in the same format as print_ace() */
+bool parse_ace(struct cli_state *cli, struct security_ace *ace,
+ const char *orig_str)
+{
+ char *p;
+ const char *cp;
+ char *tok;
+ unsigned int atype = 0;
+ unsigned int aflags = 0;
+ unsigned int amask = 0;
+ struct dom_sid sid;
+ uint32_t mask;
+ const struct perm_value *v;
+ char *str = SMB_STRDUP(orig_str);
+ TALLOC_CTX *frame = talloc_stackframe();
+
+ if (!str) {
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+ ZERO_STRUCTP(ace);
+ p = strchr_m(str,':');
+ if (!p) {
+ printf("ACE '%s': missing ':'.\n", orig_str);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+ *p = '\0';
+ p++;
+ /* Try to parse numeric form */
+
+ if (sscanf(p, "%u/%u/%u", &atype, &aflags, &amask) == 3 &&
+ StringToSid(cli, &sid, str)) {
+ goto done;
+ }
+
+ /* Try to parse text form */
+
+ if (!StringToSid(cli, &sid, str)) {
+ printf("ACE '%s': failed to convert '%s' to SID\n",
+ orig_str, str);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+ cp = p;
+ if (!next_token_talloc(frame, &cp, &tok, "/")) {
+ printf("ACE '%s': failed to find '/' character.\n",
+ orig_str);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+ if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
+ atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
+ } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
+ atype = SEC_ACE_TYPE_ACCESS_DENIED;
+ } else {
+ printf("ACE '%s': missing 'ALLOWED' or 'DENIED' entry at '%s'\n",
+ orig_str, tok);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+ /* Only numeric form accepted for flags at present */
+
+ if (!next_token_talloc(frame, &cp, &tok, "/")) {
+ printf("ACE '%s': bad flags entry at '%s'\n",
+ orig_str, tok);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+ if (tok[0] < '0' || tok[0] > '9') {
+ if (!parse_ace_flags(tok, &aflags)) {
+ printf("ACE '%s': bad named flags entry at '%s'\n",
+ orig_str, tok);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+ } else if (strnequal(tok, "0x", 2)) {
+ if (!sscanf(tok, "%x", &aflags)) {
+ printf("ACE '%s': bad hex flags entry at '%s'\n",
+ orig_str, tok);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+ } else {
+ if (!sscanf(tok, "%u", &aflags)) {
+ printf("ACE '%s': bad integer flags entry at '%s'\n",
+ orig_str, tok);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+ }
+
+ if (!next_token_talloc(frame, &cp, &tok, "/")) {
+ printf("ACE '%s': missing / at '%s'\n",
+ orig_str, tok);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+
+ if (strncmp(tok, "0x", 2) == 0) {
+ if (sscanf(tok, "%u", &amask) != 1) {
+ printf("ACE '%s': bad hex number at '%s'\n",
+ orig_str, tok);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+ goto done;
+ }
+
+ for (v = standard_values; v->perm; v++) {
+ if (strcmp(tok, v->perm) == 0) {
+ amask = v->mask;
+ goto done;
+ }
+ }
+
+ p = tok;
+
+ while(*p) {
+ bool found = False;
+
+ for (v = special_values; v->perm; v++) {
+ if (v->perm[0] == *p) {
+ amask |= v->mask;
+ found = True;
+ }
+ }
+
+ if (!found) {
+ printf("ACE '%s': bad permission value at '%s'\n",
+ orig_str, p);
+ SAFE_FREE(str);
+ TALLOC_FREE(frame);
+ return False;
+ }
+ p++;
+ }
+
+ if (*p) {
+ TALLOC_FREE(frame);
+ SAFE_FREE(str);
+ return False;
+ }
+
+ done:
+ mask = amask;
+ init_sec_ace(ace, &sid, atype, mask, aflags);
+ TALLOC_FREE(frame);
+ SAFE_FREE(str);
+ return True;
+}
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 778d30d..9081ebf 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -47,31 +47,6 @@ enum acl_mode {SMB_ACL_SET, SMB_ACL_DELETE, SMB_ACL_MODIFY, SMB_ACL_ADD };
enum chown_mode {REQUEST_NONE, REQUEST_CHOWN, REQUEST_CHGRP, REQUEST_INHERIT};
enum exit_values {EXIT_OK, EXIT_FAILED, EXIT_PARSE_ERROR};
-struct perm_value {
- const char *perm;
- uint32 mask;
-};
-
-/* These values discovered by inspection */
-
-static const struct perm_value special_values[] = {
- { "R", SEC_RIGHTS_FILE_READ },
- { "W", SEC_RIGHTS_FILE_WRITE },
- { "X", SEC_RIGHTS_FILE_EXECUTE },
- { "D", SEC_STD_DELETE },
- { "P", SEC_STD_WRITE_DAC },
- { "O", SEC_STD_WRITE_OWNER },
- { NULL, 0 },
-};
-
-static const struct perm_value standard_values[] = {
- { "READ", SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
- { "CHANGE", SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
- SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE },
- { "FULL", SEC_RIGHTS_DIR_ALL },
- { NULL, 0 },
-};
-
static NTSTATUS cli_lsa_lookup_domain_sid(struct cli_state *cli,
struct dom_sid *sid)
{
@@ -147,335 +122,6 @@ static struct dom_sid *get_domain_sid(struct cli_state *cli)
return sid;
}
-static void print_ace_flags(FILE *f, uint8_t flags)
-{
- char *str = talloc_strdup(NULL, "");
-
- if (!str) {
- goto out;
- }
-
- if (flags & SEC_ACE_FLAG_OBJECT_INHERIT) {
- str = talloc_asprintf(str, "%s%s",
- str, "OI|");
- if (!str) {
- goto out;
- }
- }
- if (flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
- str = talloc_asprintf(str, "%s%s",
- str, "CI|");
- if (!str) {
- goto out;
- }
- }
- if (flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
- str = talloc_asprintf(str, "%s%s",
- str, "NP|");
- if (!str) {
- goto out;
- }
- }
- if (flags & SEC_ACE_FLAG_INHERIT_ONLY) {
- str = talloc_asprintf(str, "%s%s",
- str, "IO|");
- if (!str) {
- goto out;
- }
- }
- if (flags & SEC_ACE_FLAG_INHERITED_ACE) {
- str = talloc_asprintf(str, "%s%s",
- str, "I|");
- if (!str) {
- goto out;
- }
- }
- /* Ignore define SEC_ACE_FLAG_SUCCESSFUL_ACCESS ( 0x40 )
- and SEC_ACE_FLAG_FAILED_ACCESS ( 0x80 ) as they're
- audit ace flags. */
-
- if (str[strlen(str)-1] == '|') {
- str[strlen(str)-1] = '\0';
- fprintf(f, "/%s/", str);
- } else {
- fprintf(f, "/0x%x/", flags);
- }
- TALLOC_FREE(str);
- return;
-
- out:
- fprintf(f, "/0x%x/", flags);
-}
-
-/* print an ACE on a FILE, using either numeric or ascii representation */
-static void print_ace(struct cli_state *cli, FILE *f, struct security_ace *ace,
- bool numeric)
-{
- const struct perm_value *v;
- fstring sidstr;
- int do_print = 0;
- uint32 got_mask;
-
- SidToString(cli, sidstr, &ace->trustee, numeric);
-
- fprintf(f, "%s:", sidstr);
-
- if (numeric) {
- fprintf(f, "%d/0x%x/0x%08x",
- ace->type, ace->flags, ace->access_mask);
- return;
- }
-
- /* Ace type */
-
- if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED) {
- fprintf(f, "ALLOWED");
- } else if (ace->type == SEC_ACE_TYPE_ACCESS_DENIED) {
- fprintf(f, "DENIED");
- } else {
- fprintf(f, "%d", ace->type);
- }
-
- print_ace_flags(f, ace->flags);
-
- /* Standard permissions */
-
- for (v = standard_values; v->perm; v++) {
- if (ace->access_mask == v->mask) {
- fprintf(f, "%s", v->perm);
- return;
- }
- }
-
- /* Special permissions. Print out a hex value if we have
- leftover bits in the mask. */
-
- got_mask = ace->access_mask;
-
- again:
- for (v = special_values; v->perm; v++) {
- if ((ace->access_mask & v->mask) == v->mask) {
- if (do_print) {
- fprintf(f, "%s", v->perm);
- }
- got_mask &= ~v->mask;
- }
- }
-
- if (!do_print) {
- if (got_mask != 0) {
- fprintf(f, "0x%08x", ace->access_mask);
- } else {
- do_print = 1;
- goto again;
- }
- }
-}
-
-static bool parse_ace_flags(const char *str, unsigned int *pflags)
-{
- const char *p = str;
- *pflags = 0;
-
- while (*p) {
- if (strnequal(p, "OI", 2)) {
- *pflags |= SEC_ACE_FLAG_OBJECT_INHERIT;
- p += 2;
- } else if (strnequal(p, "CI", 2)) {
- *pflags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
- p += 2;
- } else if (strnequal(p, "NP", 2)) {
- *pflags |= SEC_ACE_FLAG_NO_PROPAGATE_INHERIT;
- p += 2;
- } else if (strnequal(p, "IO", 2)) {
- *pflags |= SEC_ACE_FLAG_INHERIT_ONLY;
- p += 2;
- } else if (*p == 'I') {
- *pflags |= SEC_ACE_FLAG_INHERITED_ACE;
- p += 1;
- } else if (*p) {
- return false;
- }
-
- switch (*p) {
- case '|':
- p++;
- case '\0':
- continue;
- default:
- return false;
- }
- }
- return true;
-}
-
-/* parse an ACE in the same format as print_ace() */
-static bool parse_ace(struct cli_state *cli, struct security_ace *ace,
- const char *orig_str)
-{
- char *p;
- const char *cp;
- char *tok;
- unsigned int atype = 0;
- unsigned int aflags = 0;
- unsigned int amask = 0;
- struct dom_sid sid;
- uint32_t mask;
- const struct perm_value *v;
- char *str = SMB_STRDUP(orig_str);
- TALLOC_CTX *frame = talloc_stackframe();
-
- if (!str) {
- TALLOC_FREE(frame);
- return False;
- }
-
- ZERO_STRUCTP(ace);
- p = strchr_m(str,':');
- if (!p) {
- printf("ACE '%s': missing ':'.\n", orig_str);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
- *p = '\0';
- p++;
- /* Try to parse numeric form */
-
- if (sscanf(p, "%u/%u/%u", &atype, &aflags, &amask) == 3 &&
- StringToSid(cli, &sid, str)) {
- goto done;
- }
-
- /* Try to parse text form */
-
- if (!StringToSid(cli, &sid, str)) {
- printf("ACE '%s': failed to convert '%s' to SID\n",
- orig_str, str);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- cp = p;
- if (!next_token_talloc(frame, &cp, &tok, "/")) {
- printf("ACE '%s': failed to find '/' character.\n",
- orig_str);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
- atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
- } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
- atype = SEC_ACE_TYPE_ACCESS_DENIED;
- } else {
- printf("ACE '%s': missing 'ALLOWED' or 'DENIED' entry at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- /* Only numeric form accepted for flags at present */
-
- if (!next_token_talloc(frame, &cp, &tok, "/")) {
- printf("ACE '%s': bad flags entry at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- if (tok[0] < '0' || tok[0] > '9') {
- if (!parse_ace_flags(tok, &aflags)) {
- printf("ACE '%s': bad named flags entry at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
- } else if (strnequal(tok, "0x", 2)) {
- if (!sscanf(tok, "%x", &aflags)) {
- printf("ACE '%s': bad hex flags entry at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
- } else {
- if (!sscanf(tok, "%u", &aflags)) {
- printf("ACE '%s': bad integer flags entry at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
- }
-
- if (!next_token_talloc(frame, &cp, &tok, "/")) {
- printf("ACE '%s': missing / at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- if (strncmp(tok, "0x", 2) == 0) {
- if (sscanf(tok, "%u", &amask) != 1) {
- printf("ACE '%s': bad hex number at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
- goto done;
- }
-
- for (v = standard_values; v->perm; v++) {
- if (strcmp(tok, v->perm) == 0) {
- amask = v->mask;
- goto done;
- }
- }
-
- p = tok;
-
- while(*p) {
- bool found = False;
-
- for (v = special_values; v->perm; v++) {
- if (v->perm[0] == *p) {
- amask |= v->mask;
- found = True;
- }
- }
-
- if (!found) {
- printf("ACE '%s': bad permission value at '%s'\n",
- orig_str, p);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
- p++;
- }
-
- if (*p) {
- TALLOC_FREE(frame);
- SAFE_FREE(str);
- return False;
- }
-
- done:
- mask = amask;
- init_sec_ace(ace, &sid, atype, mask, aflags);
- TALLOC_FREE(frame);
- SAFE_FREE(str);
- return True;
-}
-
/* add an ACE to a list of ACEs in a struct security_acl */
static bool add_ace(struct security_acl **the_acl, struct security_ace *ace)
{
--
1.7.1
From 7a484775b651780352e19687b9ee60a2c7a7903b Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 09:28:02 -0700
Subject: [PATCH 6/9] smbcacls: Move sec_desc_print to common file
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/include/util_sd.h | 2 +
source3/lib/util_sd.c | 82 +++++++++++++++++++++++++++++++++++++++++++++
source3/utils/smbcacls.c | 81 --------------------------------------------
3 files changed, 84 insertions(+), 81 deletions(-)
diff --git a/source3/include/util_sd.h b/source3/include/util_sd.h
index 1b22bb0..7f82969 100644
--- a/source3/include/util_sd.h
+++ b/source3/include/util_sd.h
@@ -31,5 +31,7 @@ void print_ace(struct cli_state *cli, FILE *f, struct security_ace *ace,
bool numeric);
bool parse_ace(struct cli_state *cli, struct security_ace *ace,
const char *orig_str);
+void sec_desc_print(struct cli_state *cli, FILE *f,
+ struct security_descriptor *sd, bool numeric);
#endif
diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
index 616418a..7f5badf 100644
--- a/source3/lib/util_sd.c
+++ b/source3/lib/util_sd.c
@@ -54,6 +54,29 @@ static const struct perm_value standard_values[] = {
{ NULL, 0 },
};
+static const struct {
+ uint16_t mask;
+ const char *str;
+ const char *desc;
+} sec_desc_ctrl_bits[] = {
+ {SEC_DESC_OWNER_DEFAULTED, "OD", "Owner Defaulted"},
+ {SEC_DESC_GROUP_DEFAULTED, "GD", "Group Defaulted"},
+ {SEC_DESC_DACL_PRESENT, "DP", "DACL Present"},
+ {SEC_DESC_DACL_DEFAULTED, "DD", "DACL Defaulted"},
+ {SEC_DESC_SACL_PRESENT, "SP", "SACL Present"},
+ {SEC_DESC_SACL_DEFAULTED, "SD", "SACL Defaulted"},
+ {SEC_DESC_DACL_TRUSTED, "DT", "DACL Trusted"},
+ {SEC_DESC_SERVER_SECURITY, "SS", "Server Security"},
+ {SEC_DESC_DACL_AUTO_INHERIT_REQ, "DR", "DACL Inheritance Required"},
+ {SEC_DESC_SACL_AUTO_INHERIT_REQ, "SR", "SACL Inheritance Required"},
+ {SEC_DESC_DACL_AUTO_INHERITED, "DI", "DACL Auto Inherited"},
+ {SEC_DESC_SACL_AUTO_INHERITED, "SI", "SACL Auto Inherited"},
+ {SEC_DESC_DACL_PROTECTED, "PD", "DACL Protected"},
+ {SEC_DESC_SACL_PROTECTED, "PS", "SACL Protected"},
+ {SEC_DESC_RM_CONTROL_VALID, "RM", "RM Control Valid"},
+ {SEC_DESC_SELF_RELATIVE , "SR", "Self Relative"},
+};
+
/* Open cli connection and policy handle */
static NTSTATUS cli_lsa_lookup_sid(struct cli_state *cli,
const struct dom_sid *sid,
@@ -526,3 +549,62 @@ bool parse_ace(struct cli_state *cli, struct security_ace *ace,
SAFE_FREE(str);
return True;
}
+
+static void print_acl_ctrl(FILE *file, uint16_t ctrl, bool numeric)
+{
+ int i;
+ const char* separator = "";
+
+ fprintf(file, "CONTROL:");
+ if (numeric) {
+ fprintf(file, "0x%x\n", ctrl);
+ return;
+ }
+
+ for (i = ARRAY_SIZE(sec_desc_ctrl_bits) - 1; i >= 0; i--) {
+ if (ctrl & sec_desc_ctrl_bits[i].mask) {
+ fprintf(file, "%s%s",
+ separator, sec_desc_ctrl_bits[i].str);
+ separator = "|";
+ }
+ }
+ fputc('\n', file);
+}
+
+/* print a ascii version of a security descriptor on a FILE handle */
+void sec_desc_print(struct cli_state *cli, FILE *f,
+ struct security_descriptor *sd, bool numeric)
+{
+ fstring sidstr;
+ uint32 i;
+
+ fprintf(f, "REVISION:%d\n", sd->revision);
+ print_acl_ctrl(f, sd->type, numeric);
+
+ /* Print owner and group sid */
+
+ if (sd->owner_sid) {
+ SidToString(cli, sidstr, sd->owner_sid, numeric);
+ } else {
+ fstrcpy(sidstr, "");
+ }
+
+ fprintf(f, "OWNER:%s\n", sidstr);
+
+ if (sd->group_sid) {
+ SidToString(cli, sidstr, sd->group_sid, numeric);
+ } else {
+ fstrcpy(sidstr, "");
+ }
+
+ fprintf(f, "GROUP:%s\n", sidstr);
+
+ /* Print aces */
+ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
+ struct security_ace *ace = &sd->dacl->aces[i];
+ fprintf(f, "ACL:");
+ print_ace(cli, f, ace, numeric);
+ fprintf(f, "\n");
+ }
+
+}
diff --git a/source3/utils/smbcacls.c b/source3/utils/smbcacls.c
index 9081ebf..926e496 100644
--- a/source3/utils/smbcacls.c
+++ b/source3/utils/smbcacls.c
@@ -215,87 +215,6 @@ static struct security_descriptor *sec_desc_parse(TALLOC_CTX *ctx, struct cli_st
return ret;
}
-static const struct {
- uint16_t mask;
- const char *str;
- const char *desc;
-} sec_desc_ctrl_bits[] = {
- {SEC_DESC_OWNER_DEFAULTED, "OD", "Owner Defaulted"},
- {SEC_DESC_GROUP_DEFAULTED, "GD", "Group Defaulted"},
- {SEC_DESC_DACL_PRESENT, "DP", "DACL Present"},
- {SEC_DESC_DACL_DEFAULTED, "DD", "DACL Defaulted"},
- {SEC_DESC_SACL_PRESENT, "SP", "SACL Present"},
- {SEC_DESC_SACL_DEFAULTED, "SD", "SACL Defaulted"},
- {SEC_DESC_DACL_TRUSTED, "DT", "DACL Trusted"},
- {SEC_DESC_SERVER_SECURITY, "SS", "Server Security"},
- {SEC_DESC_DACL_AUTO_INHERIT_REQ, "DR", "DACL Inheritance Required"},
- {SEC_DESC_SACL_AUTO_INHERIT_REQ, "SR", "SACL Inheritance Required"},
- {SEC_DESC_DACL_AUTO_INHERITED, "DI", "DACL Auto Inherited"},
- {SEC_DESC_SACL_AUTO_INHERITED, "SI", "SACL Auto Inherited"},
- {SEC_DESC_DACL_PROTECTED, "PD", "DACL Protected"},
- {SEC_DESC_SACL_PROTECTED, "PS", "SACL Protected"},
- {SEC_DESC_RM_CONTROL_VALID, "RM", "RM Control Valid"},
- {SEC_DESC_SELF_RELATIVE , "SR", "Self Relative"},
-};
-
-static void print_acl_ctrl(FILE *file, uint16_t ctrl, bool numeric)
-{
- int i;
- const char* separator = "";
-
- fprintf(file, "CONTROL:");
- if (numeric) {
- fprintf(file, "0x%x\n", ctrl);
- return;
- }
-
- for (i = ARRAY_SIZE(sec_desc_ctrl_bits) - 1; i >= 0; i--) {
- if (ctrl & sec_desc_ctrl_bits[i].mask) {
- fprintf(file, "%s%s", separator, sec_desc_ctrl_bits[i].str);
- separator = "|";
- }
- }
- fputc('\n', file);
-}
-
-/* print a ascii version of a security descriptor on a FILE handle */
-static void sec_desc_print(struct cli_state *cli, FILE *f,
- struct security_descriptor *sd, bool numeric)
-{
- fstring sidstr;
- uint32 i;
-
- fprintf(f, "REVISION:%d\n", sd->revision);
- print_acl_ctrl(f, sd->type, numeric);
-
- /* Print owner and group sid */
-
- if (sd->owner_sid) {
- SidToString(cli, sidstr, sd->owner_sid, numeric);
- } else {
- fstrcpy(sidstr, "");
- }
-
- fprintf(f, "OWNER:%s\n", sidstr);
-
- if (sd->group_sid) {
- SidToString(cli, sidstr, sd->group_sid, numeric);
- } else {
- fstrcpy(sidstr, "");
- }
-
- fprintf(f, "GROUP:%s\n", sidstr);
-
- /* Print aces */
- for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
- struct security_ace *ace = &sd->dacl->aces[i];
- fprintf(f, "ACL:");
- print_ace(cli, f, ace, numeric);
- fprintf(f, "\n");
- }
-
-}
-
/*****************************************************
get fileinfo for filename
*******************************************************/
--
1.7.1
From 45974908628a3bb82a2e58d591a0365478be9c99 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 09:49:23 -0700
Subject: [PATCH 7/9] util_sd: Make server conncection optional
If cli is not set, only attempt numeric conversions.
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/lib/util_sd.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/source3/lib/util_sd.c b/source3/lib/util_sd.c
index 7f5badf..8100539 100644
--- a/source3/lib/util_sd.c
+++ b/source3/lib/util_sd.c
@@ -141,7 +141,7 @@ void SidToString(struct cli_state *cli, fstring str, const struct dom_sid *sid,
sid_to_fstring(str, sid);
- if (numeric) {
+ if (numeric || cli == NULL) {
return;
}
@@ -218,6 +218,10 @@ bool StringToSid(struct cli_state *cli, struct dom_sid *sid, const char *str)
return true;
}
+ if (cli == NULL) {
+ return false;
+ }
+
return NT_STATUS_IS_OK(cli_lsa_lookup_name(cli, str, &type, sid));
}
--
1.7.1
From e0c9378d07c7e8a6a1dcf9a4db2d179e093dce95 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 09:51:28 -0700
Subject: [PATCH 8/9] sharesec: Print ACEs in similar format as expected in input
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/utils/sharesec.c | 18 ++++++------------
source3/wscript_build | 4 +++-
2 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/source3/utils/sharesec.c b/source3/utils/sharesec.c
index 132ca7e..44cab17 100644
--- a/source3/utils/sharesec.c
+++ b/source3/utils/sharesec.c
@@ -21,12 +21,13 @@
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
+struct cli_state;
#include "includes.h"
#include "popt_common.h"
#include "../libcli/security/security.h"
-#include "../librpc/gen_ndr/ndr_security.h"
#include "passdb/machine_sid.h"
+#include "util_sd.h"
static TALLOC_CTX *ctx;
@@ -334,7 +335,6 @@ static int change_share_sec(TALLOC_CTX *mem_ctx, const char *sharename, char *th
struct security_descriptor *old = NULL;
size_t sd_size = 0;
uint32 i, j;
- char *sd_str;
if (mode != SMB_ACL_SET && mode != SMB_SD_DELETE) {
if (!(old = get_share_security( mem_ctx, sharename, &sd_size )) ) {
@@ -355,11 +355,7 @@ static int change_share_sec(TALLOC_CTX *mem_ctx, const char *sharename, char *th
/* should not happen */
return 0;
case SMB_ACL_VIEW:
- sd_str = ndr_print_struct_string(mem_ctx,
- (ndr_print_fn_t)ndr_print_security_descriptor,
- "", old);
- fprintf(stdout, "%s\n", sd_str);
- talloc_free(sd_str);
+ sec_desc_print(NULL, stdout, old, true);
return 0;
case SMB_ACL_DELETE:
for (i=0;sd->dacl && i<sd->dacl->num_aces;i++) {
@@ -379,11 +375,9 @@ static int change_share_sec(TALLOC_CTX *mem_ctx, const char *sharename, char *th
}
if (!found) {
- sd_str = ndr_print_struct_string(mem_ctx,
- (ndr_print_fn_t)ndr_print_security_ace,
- "", &sd->dacl->aces[i]);
- printf("ACL for ACE: %s not found\n", sd_str);
- talloc_free(sd_str);
+ printf("ACL for ACE:");
+ print_ace(NULL, stdout, &sd->dacl->aces[i], true);
+ printf(" not found\n");
}
}
break;
diff --git a/source3/wscript_build b/source3/wscript_build
index 36eb1b7..ef4c986 100755
--- a/source3/wscript_build
+++ b/source3/wscript_build
@@ -1365,9 +1365,11 @@ bld.SAMBA3_BINARY('eventlogadm',
LIBEVENTLOG''')
bld.SAMBA3_BINARY('sharesec',
- source='utils/sharesec.c',
+ source='utils/sharesec.c lib/util_sd.c',
deps='''
talloc
+ msrpc3
+ libcli_lsa3
popt_samba3''')
bld.SAMBA3_BINARY('pdbtest',
--
1.7.1
From 68bceaf6c8127d2458dfb6c522a954cfff8e66f0 Mon Sep 17 00:00:00 2001
From: Christof Schmitt <cs at samba.org>
Date: Fri, 24 Apr 2015 10:00:19 -0700
Subject: [PATCH 9/9] sharesec: Use common parse_ace function
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11237
Signed-off-by: Christof Schmitt <cs at samba.org>
---
source3/utils/sharesec.c | 175 +---------------------------------------------
1 files changed, 1 insertions(+), 174 deletions(-)
diff --git a/source3/utils/sharesec.c b/source3/utils/sharesec.c
index 44cab17..ed4c3ee 100644
--- a/source3/utils/sharesec.c
+++ b/source3/utils/sharesec.c
@@ -41,179 +41,6 @@ enum acl_mode { SMB_ACL_DELETE,
SMB_ACL_VIEW,
SMB_ACL_VIEW_ALL };
-struct perm_value {
- const char *perm;
- uint32 mask;
-};
-
-/* These values discovered by inspection */
-
-static const struct perm_value special_values[] = {
- { "R", SEC_RIGHTS_FILE_READ },
- { "W", SEC_RIGHTS_FILE_WRITE },
- { "X", SEC_RIGHTS_FILE_EXECUTE },
- { "D", SEC_STD_DELETE },
- { "P", SEC_STD_WRITE_DAC },
- { "O", SEC_STD_WRITE_OWNER },
- { NULL, 0 },
-};
-
-#define SEC_RIGHTS_DIR_CHANGE ( SEC_RIGHTS_DIR_READ|SEC_STD_DELETE|\
- SEC_RIGHTS_DIR_WRITE|SEC_DIR_TRAVERSE )
-
-static const struct perm_value standard_values[] = {
- { "READ", SEC_RIGHTS_DIR_READ|SEC_DIR_TRAVERSE },
- { "CHANGE", SEC_RIGHTS_DIR_CHANGE },
- { "FULL", SEC_RIGHTS_DIR_ALL },
- { NULL, 0 },
-};
-
-/********************************************************************
- parse an ACE in the same format as print_ace()
-********************************************************************/
-
-static bool parse_ace(struct security_ace *ace, const char *orig_str)
-{
- char *p;
- const char *cp;
- char *tok;
- unsigned int atype = 0;
- unsigned int aflags = 0;
- unsigned int amask = 0;
- struct dom_sid sid;
- uint32_t mask;
- const struct perm_value *v;
- char *str = SMB_STRDUP(orig_str);
- TALLOC_CTX *frame = talloc_stackframe();
-
- if (!str) {
- TALLOC_FREE(frame);
- return False;
- }
-
- ZERO_STRUCTP(ace);
- p = strchr_m(str,':');
- if (!p) {
- fprintf(stderr, "ACE '%s': missing ':'.\n", orig_str);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
- *p = '\0';
- p++;
- /* Try to parse numeric form */
-
- if (sscanf(p, "%u/%u/%u", &atype, &aflags, &amask) == 3 &&
- string_to_sid(&sid, str)) {
- goto done;
- }
-
- /* Try to parse text form */
-
- if (!string_to_sid(&sid, str)) {
- fprintf(stderr, "ACE '%s': failed to convert '%s' to SID\n",
- orig_str, str);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- cp = p;
- if (!next_token_talloc(frame, &cp, &tok, "/")) {
- fprintf(stderr, "ACE '%s': failed to find '/' character.\n",
- orig_str);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- if (strncmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) {
- atype = SEC_ACE_TYPE_ACCESS_ALLOWED;
- } else if (strncmp(tok, "DENIED", strlen("DENIED")) == 0) {
- atype = SEC_ACE_TYPE_ACCESS_DENIED;
- } else {
- fprintf(stderr, "ACE '%s': missing 'ALLOWED' or 'DENIED' "
- "entry at '%s'\n", orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- /* Only numeric form accepted for flags at present */
- /* no flags on share permissions */
-
- if (!(next_token_talloc(frame, &cp, &tok, "/") &&
- sscanf(tok, "%u", &aflags) && aflags == 0)) {
- fprintf(stderr, "ACE '%s': bad integer flags entry at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- if (!next_token_talloc(frame, &cp, &tok, "/")) {
- fprintf(stderr, "ACE '%s': missing / at '%s'\n",
- orig_str, tok);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return False;
- }
-
- if (strncmp(tok, "0x", 2) == 0) {
- if (sscanf(tok, "%u", &amask) != 1) {
- fprintf(stderr, "ACE '%s': bad hex number at '%s'\n",
- orig_str, tok);
- TALLOC_FREE(frame);
- SAFE_FREE(str);
- return False;
- }
- goto done;
- }
-
- for (v = standard_values; v->perm; v++) {
- if (strcmp(tok, v->perm) == 0) {
- amask = v->mask;
- goto done;
- }
- }
-
- p = tok;
-
- while(*p) {
- bool found = False;
-
- for (v = special_values; v->perm; v++) {
- if (v->perm[0] == *p) {
- amask |= v->mask;
- found = True;
- }
- }
-
- if (!found) {
- fprintf(stderr, "ACE '%s': bad permission value at "
- "'%s'\n", orig_str, p);
- TALLOC_FREE(frame);
- SAFE_FREE(str);
- return False;
- }
- p++;
- }
-
- if (*p) {
- TALLOC_FREE(frame);
- SAFE_FREE(str);
- return False;
- }
-
- done:
- mask = amask;
- init_sec_ace(ace, &sid, atype, mask, aflags);
- SAFE_FREE(str);
- TALLOC_FREE(frame);
- return True;
-}
-
-
/********************************************************************
********************************************************************/
@@ -242,7 +69,7 @@ static struct security_descriptor* parse_acl_string(TALLOC_CTX *mem_ctx, const c
strncpy( acl_string, pacl, MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1) );
acl_string[MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1)] = '\0';
- if ( !parse_ace( &ace[i], acl_string ) )
+ if ( !parse_ace(NULL, &ace[i], acl_string ) )
return NULL;
pacl = end_acl;
--
1.7.1
More information about the samba-technical
mailing list