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