From bacb168c3a619ee896e4a1b00cf4235a8ab79612 Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit d0c496958192bef7446c760df689f1fecb28cb71) --- 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 c771225..53ee749 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 ff57cdacf9f509927b801dc68ee4a6cc364b3259 Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit 9e1ebdc7ec3b0a7c49d8b7469c0d07486f797a74) --- 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 53ee749..1409189 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 7e068719682bb2b20e3f77c9f61084788f5abbf2 Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit 7eeca44f03e8bc52533ee7bf004261b096b5243f) --- 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 . +*/ + +#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 . +*/ + +#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 1409189..0ca12f2 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 eadf832..ff20710 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1317,7 +1317,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 09bd184f4234fa548f31784ff9f695457e4f32e1 Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit a519b3e6c6e4c57863e02975ff2cc8b36c34ea6f) --- 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 0ca12f2..f10343f 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 90652bfd5c5f8f8b4e6044daa6cfedc47fc9f55d Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit 541ddde872b4bf37b6f63abef648bd5ffd6482c4) --- 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 f10343f..934aee9 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 3a4fd156eed8b90ee085510a0097b18861bafea4 Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit 42c46ab642fa989a4e7606b4abd213e2b6c808a7) --- 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 934aee9..c7ed6f3 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 d09357d44396bb42d6ce25d4d864601afe8a9cb5 Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit 9e10ddd00e5d0bfe47930adb4627c7a5efc543fb) --- 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 238f8a1ab3349c8755b2036d7f0647611681cbd5 Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit cea50454129b1a10d1350dde2f6440c249f89c85) --- 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 f6e71d7..cedcbc8 100644 --- a/source3/utils/sharesec.c +++ b/source3/utils/sharesec.c @@ -21,12 +21,13 @@ * along with this program; if not, see . */ +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 && idacl->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 ff20710..8c09dd0 100755 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -1342,9 +1342,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 d298353ac4321a73bc12bde7fb5e5f85290f24ed Mon Sep 17 00:00:00 2001 From: Christof Schmitt 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 Reviewed-by: Jeremy Allison (cherry picked from commit e4f2fa2c67ead2edf23c55b4d2941e69849edac2) --- 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 cedcbc8..71a55b5 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