diff options
-rw-r--r-- | libcli/security/access_check.c | 144 | ||||
-rw-r--r-- | libcli/security/access_check.h | 27 | ||||
-rw-r--r-- | libcli/security/create_descriptor.c (renamed from source4/libcli/security/create_descriptor.c) | 0 | ||||
-rw-r--r-- | libcli/security/dom_sid.c | 4 | ||||
-rw-r--r-- | libcli/security/dom_sid.h | 50 | ||||
-rw-r--r-- | libcli/security/object_tree.c (renamed from source4/libcli/security/object_tree.c) | 0 | ||||
-rw-r--r-- | libcli/security/security.h | 4 | ||||
-rw-r--r-- | libcli/security/security_descriptor.h | 13 | ||||
-rw-r--r-- | libcli/security/util_sid.c | 371 | ||||
-rw-r--r-- | libcli/security/wscript_build | 4 | ||||
-rw-r--r-- | nsswitch/wscript_build | 2 | ||||
-rw-r--r-- | source3/Makefile.in | 5 | ||||
-rw-r--r-- | source3/include/proto.h | 18 | ||||
-rw-r--r-- | source3/include/smb.h | 26 | ||||
-rw-r--r-- | source3/lib/util_sid.c | 314 | ||||
-rw-r--r-- | source3/winbindd/winbindd_util.c | 2 | ||||
-rw-r--r-- | source4/libcli/raw/smb.h | 13 | ||||
-rw-r--r-- | source4/libcli/security/access_check.c | 316 | ||||
-rw-r--r-- | source4/libcli/security/wscript_build | 8 | ||||
-rw-r--r-- | source4/torture/rpc/lsa.c | 17 | ||||
-rw-r--r-- | source4/torture/rpc/lsa_lookup.c | 17 |
21 files changed, 615 insertions, 740 deletions
diff --git a/libcli/security/access_check.c b/libcli/security/access_check.c index 081efe8711..e7c48cae08 100644 --- a/libcli/security/access_check.c +++ b/libcli/security/access_check.c @@ -250,3 +250,147 @@ done: return NT_STATUS_OK; } + + +static const struct GUID *get_ace_object_type(struct security_ace *ace) +{ + struct GUID *type; + + if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) + type = &ace->object.object.type.type; + else if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) + type = &ace->object.object.inherited_type.inherited_type; /* This doesn't look right. Is something wrong with the IDL? */ + else + type = NULL; + + return type; + +} + +/* modified access check for the purposes of DS security + * Lots of code duplication, it will ve united in just one + * function eventually */ + +NTSTATUS sec_access_check_ds(const struct security_descriptor *sd, + const struct security_token *token, + uint32_t access_desired, + uint32_t *access_granted, + struct object_tree *tree, + struct dom_sid *replace_sid) +{ + uint32_t i; + uint32_t bits_remaining; + struct object_tree *node; + const struct GUID *type; + struct dom_sid *ps_sid = dom_sid_parse_talloc(NULL, SID_NT_SELF); + + *access_granted = access_desired; + bits_remaining = access_desired; + + /* handle the maximum allowed flag */ + if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) { + access_desired |= access_check_max_allowed(sd, token); + access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED; + *access_granted = access_desired; + bits_remaining = access_desired & ~SEC_STD_DELETE; + } + + if (access_desired & SEC_FLAG_SYSTEM_SECURITY) { + if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) { + bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY; + } else { + return NT_STATUS_PRIVILEGE_NOT_HELD; + } + } + + /* a NULL dacl allows access */ + if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) { + *access_granted = access_desired; + return NT_STATUS_OK; + } + + /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */ + if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) && + security_token_has_sid(token, sd->owner_sid)) { + bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE); + } + if ((bits_remaining & SEC_STD_DELETE) && + security_token_has_privilege(token, SEC_PRIV_RESTORE)) { + bits_remaining &= ~SEC_STD_DELETE; + } + + if (sd->dacl == NULL) { + goto done; + } + + /* check each ace in turn. */ + for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) { + struct dom_sid *trustee; + struct security_ace *ace = &sd->dacl->aces[i]; + + if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { + continue; + } + if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) { + trustee = replace_sid; + } + else + { + trustee = &ace->trustee; + } + if (!security_token_has_sid(token, trustee)) { + continue; + } + + switch (ace->type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED: + if (tree) + object_tree_modify_access(tree, ace->access_mask); + + bits_remaining &= ~ace->access_mask; + break; + case SEC_ACE_TYPE_ACCESS_DENIED: + if (bits_remaining & ace->access_mask) { + return NT_STATUS_ACCESS_DENIED; + } + break; + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + /* check only in case we have provided a tree, + * the ACE has an object type and that type + * is in the tree */ + type = get_ace_object_type(ace); + + if (!tree) + continue; + + if (!type) + node = tree; + else + if (!(node = get_object_tree_by_GUID(tree, type))) + continue; + + if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { + object_tree_modify_access(node, ace->access_mask); + if (node->remaining_access == 0) { + return NT_STATUS_OK; + } + } + else { + if (node->remaining_access & ace->access_mask){ + return NT_STATUS_ACCESS_DENIED; + } + } + break; + default: /* Other ACE types not handled/supported */ + break; + } + } + +done: + if (bits_remaining != 0) { + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} diff --git a/libcli/security/access_check.h b/libcli/security/access_check.h index 548e5a1437..700f981879 100644 --- a/libcli/security/access_check.h +++ b/libcli/security/access_check.h @@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "libcli/security/security_token.h" +#include "librpc/gen_ndr/security.h" /* Map generic access rights to object specific rights. This technique is used to give meaning to assigning read, write, execute and all access to @@ -51,3 +51,28 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, const struct security_token *token, uint32_t access_desired, uint32_t *access_granted); + +/* modified access check for the purposes of DS security + * Lots of code duplication, it will ve united in just one + * function eventually */ + +NTSTATUS sec_access_check_ds(const struct security_descriptor *sd, + const struct security_token *token, + uint32_t access_desired, + uint32_t *access_granted, + struct object_tree *tree, + struct dom_sid *replace_sid); + +bool insert_in_object_tree(TALLOC_CTX *mem_ctx, + const struct GUID *guid, + uint32_t init_access, + struct object_tree **root, + struct object_tree **new_node); + +/* search by GUID */ +struct object_tree *get_object_tree_by_GUID(struct object_tree *root, + const struct GUID *guid); + +/* Change the granted access per each ACE */ +void object_tree_modify_access(struct object_tree *root, + uint32_t access); diff --git a/source4/libcli/security/create_descriptor.c b/libcli/security/create_descriptor.c index bc3f42e1f2..bc3f42e1f2 100644 --- a/source4/libcli/security/create_descriptor.c +++ b/libcli/security/create_descriptor.c diff --git a/libcli/security/dom_sid.c b/libcli/security/dom_sid.c index f94d952b4d..217d7bb8d4 100644 --- a/libcli/security/dom_sid.c +++ b/libcli/security/dom_sid.c @@ -28,8 +28,8 @@ Compare the auth portion of two sids. *****************************************************************/ -static int dom_sid_compare_auth(const struct dom_sid *sid1, - const struct dom_sid *sid2) +int dom_sid_compare_auth(const struct dom_sid *sid1, + const struct dom_sid *sid2) { int i; diff --git a/libcli/security/dom_sid.h b/libcli/security/dom_sid.h index ac8669d725..8c60f761e4 100644 --- a/libcli/security/dom_sid.h +++ b/libcli/security/dom_sid.h @@ -25,10 +25,40 @@ #include "librpc/gen_ndr/security.h" +/* Some well-known SIDs */ +extern const struct dom_sid global_sid_World_Domain; +extern const struct dom_sid global_sid_World; +extern const struct dom_sid global_sid_Creator_Owner_Domain; +extern const struct dom_sid global_sid_NT_Authority; +extern const struct dom_sid global_sid_System; +extern const struct dom_sid global_sid_NULL; +extern const struct dom_sid global_sid_Authenticated_Users; +extern const struct dom_sid global_sid_Network; +extern const struct dom_sid global_sid_Creator_Owner; +extern const struct dom_sid global_sid_Creator_Group; +extern const struct dom_sid global_sid_Anonymous; +extern const struct dom_sid global_sid_Builtin; +extern const struct dom_sid global_sid_Builtin_Administrators; +extern const struct dom_sid global_sid_Builtin_Users; +extern const struct dom_sid global_sid_Builtin_Guests; +extern const struct dom_sid global_sid_Builtin_Power_Users; +extern const struct dom_sid global_sid_Builtin_Account_Operators; +extern const struct dom_sid global_sid_Builtin_Server_Operators; +extern const struct dom_sid global_sid_Builtin_Print_Operators; +extern const struct dom_sid global_sid_Builtin_Backup_Operators; +extern const struct dom_sid global_sid_Builtin_Replicator; +extern const struct dom_sid global_sid_Builtin_PreWin2kAccess; +extern const struct dom_sid global_sid_Unix_Users; +extern const struct dom_sid global_sid_Unix_Groups; + +int dom_sid_compare_auth(const struct dom_sid *sid1, + const struct dom_sid *sid2); int dom_sid_compare(const struct dom_sid *sid1, const struct dom_sid *sid2); int dom_sid_compare_domain(const struct dom_sid *sid1, const struct dom_sid *sid2); bool dom_sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2); +bool sid_append_rid(struct dom_sid *sid, uint32_t rid); +bool string_to_sid(struct dom_sid *sidout, const char *sidstr); bool dom_sid_parse(const char *sidstr, struct dom_sid *ret); struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr); struct dom_sid *dom_sid_parse_length(TALLOC_CTX *mem_ctx, const DATA_BLOB *sid); @@ -42,5 +72,25 @@ bool dom_sid_in_domain(const struct dom_sid *domain_sid, const struct dom_sid *sid); char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); + +const char *sid_type_lookup(uint32_t sid_type); +const struct security_token *get_system_token(void); +bool sid_compose(struct dom_sid *dst, const struct dom_sid *domain_sid, uint32_t rid); +bool sid_split_rid(struct dom_sid *sid, uint32_t *rid); +bool sid_peek_rid(const struct dom_sid *sid, uint32_t *rid); +bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid *sid, uint32_t *rid); +void sid_copy(struct dom_sid *dst, const struct dom_sid *src); +bool sid_parse(const char *inbuf, size_t len, struct dom_sid *sid); +int sid_compare_domain(const struct dom_sid *sid1, const struct dom_sid *sid2); +bool sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2); +NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, + struct dom_sid **sids, uint32_t *num); +NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, + struct dom_sid **sids, uint32_t *num_sids); +void del_sid_from_array(const struct dom_sid *sid, struct dom_sid **sids, size_t *num); +bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx, + uint32_t rid, uint32_t **pp_rids, size_t *p_num); +bool is_null_sid(const struct dom_sid *sid); + #endif /*_DOM_SID_H_*/ diff --git a/source4/libcli/security/object_tree.c b/libcli/security/object_tree.c index 7c7d644543..7c7d644543 100644 --- a/source4/libcli/security/object_tree.c +++ b/libcli/security/object_tree.c diff --git a/libcli/security/security.h b/libcli/security/security.h index f0e507231b..39ae3ec6cc 100644 --- a/libcli/security/security.h +++ b/libcli/security/security.h @@ -106,8 +106,4 @@ struct object_tree { #include "libcli/security/privileges.h" #include "libcli/security/access_check.h" -#if _SAMBA_BUILD_ >= 4 -#include "libcli/security/proto.h" -#endif - #endif diff --git a/libcli/security/security_descriptor.h b/libcli/security/security_descriptor.h index bc5761ab6f..1c7f893ead 100644 --- a/libcli/security/security_descriptor.h +++ b/libcli/security/security_descriptor.h @@ -68,4 +68,17 @@ struct security_acl *security_acl_concatenate(TALLOC_CTX *mem_ctx, const struct security_acl *acl1, const struct security_acl *acl2); +uint32_t map_generic_rights_ds(uint32_t access_mask); + +struct security_descriptor *create_security_descriptor(TALLOC_CTX *mem_ctx, + struct security_descriptor *parent_sd, + struct security_descriptor *creator_sd, + bool is_container, + struct GUID *object_list, + uint32_t inherit_flags, + struct security_token *token, + struct dom_sid *default_owner, /* valid only for DS, NULL for the other RSs */ + struct dom_sid *default_group, /* valid only for DS, NULL for the other RSs */ + uint32_t (*generic_map)(uint32_t access_mask)); + #endif /* __SECURITY_DESCRIPTOR_H__ */ diff --git a/libcli/security/util_sid.c b/libcli/security/util_sid.c new file mode 100644 index 0000000000..9ba28ebc75 --- /dev/null +++ b/libcli/security/util_sid.c @@ -0,0 +1,371 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Luke Kenneth Caseson Leighton 1998-1999 + Copyright (C) Jeremy Allison 1999 + Copyright (C) Stefan (metze) Metzmacher 2002 + Copyright (C) Simo Sorce 2002 + Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005 + Copyright (C) Andrew Bartlett 2010 + + 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 "../librpc/gen_ndr/ndr_security.h" +#include "../librpc/gen_ndr/netlogon.h" +#include "../libcli/security/security.h" + +/* + * Some useful sids, more well known sids can be found at + * http://support.microsoft.com/kb/243330/EN-US/ + */ + + +const struct dom_sid global_sid_World_Domain = /* Everyone domain */ +{ 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_World = /* Everyone */ +{ 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Creator_Owner_Domain = /* Creator Owner domain */ +{ 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_NT_Authority = /* NT Authority */ +{ 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_System = /* System */ +{ 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_NULL = /* NULL sid */ +{ 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Authenticated_Users = /* All authenticated rids */ +{ 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +#if 0 +/* for documentation */ +const struct dom_sid global_sid_Restriced = /* Restriced Code */ +{ 1, 1, {0,0,0,0,0,5}, {12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +#endif +const struct dom_sid global_sid_Network = /* Network rids */ +{ 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; + +const struct dom_sid global_sid_Creator_Owner = /* Creator Owner */ +{ 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Creator_Group = /* Creator Group */ +{ 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Anonymous = /* Anonymous login */ +{ 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Enterprise_DCs = /* Enterprise DCs */ +{ 1, 1, {0,0,0,0,0,5}, {9,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin = /* Local well-known domain */ +{ 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Administrators = /* Builtin administrators */ +{ 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Users = /* Builtin users */ +{ 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Guests = /* Builtin guest users */ +{ 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Power_Users = /* Builtin power users */ +{ 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Account_Operators = /* Builtin account operators */ +{ 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Server_Operators = /* Builtin server operators */ +{ 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Print_Operators = /* Builtin print operators */ +{ 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Backup_Operators = /* Builtin backup operators */ +{ 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_Replicator = /* Builtin replicator */ +{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Builtin_PreWin2kAccess = /* Builtin pre win2k access */ +{ 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}}; + +const struct dom_sid global_sid_Unix_Users = /* Unmapped Unix users */ +{ 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; +const struct dom_sid global_sid_Unix_Groups = /* Unmapped Unix groups */ +{ 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; + +/* Unused, left here for documentary purposes */ +#if 0 +#define SECURITY_NULL_SID_AUTHORITY 0 +#define SECURITY_WORLD_SID_AUTHORITY 1 +#define SECURITY_LOCAL_SID_AUTHORITY 2 +#define SECURITY_CREATOR_SID_AUTHORITY 3 +#define SECURITY_NT_AUTHORITY 5 +#endif + +static struct dom_sid system_sid_array[1] = +{ { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} }; +static const struct security_token system_token = { + .num_sids = ARRAY_SIZE(system_sid_array), + .sids = system_sid_array, + .privilege_mask = SE_ALL_PRIVS +}; + +/**************************************************************************** + Lookup string names for SID types. +****************************************************************************/ + +static const struct { + enum lsa_SidType sid_type; + const char *string; +} sid_name_type[] = { + {SID_NAME_USE_NONE, "None"}, + {SID_NAME_USER, "User"}, + {SID_NAME_DOM_GRP, "Domain Group"}, + {SID_NAME_DOMAIN, "Domain"}, + {SID_NAME_ALIAS, "Local Group"}, + {SID_NAME_WKN_GRP, "Well-known Group"}, + {SID_NAME_DELETED, "Deleted Account"}, + {SID_NAME_INVALID, "Invalid Account"}, + {SID_NAME_UNKNOWN, "UNKNOWN"}, + {SID_NAME_COMPUTER, "Computer"}, + + {(enum lsa_SidType)0, NULL} +}; + +const char *sid_type_lookup(uint32_t sid_type) +{ + int i = 0; + + /* Look through list */ + while(sid_name_type[i].sid_type != 0) { + if (sid_name_type[i].sid_type == sid_type) + return sid_name_type[i].string; + i++; + } + + /* Default return */ + return "SID *TYPE* is INVALID"; +} + +/************************************************************************** + Create the SYSTEM token. +***************************************************************************/ + +const struct security_token *get_system_token(void) +{ + return &system_token; +} + +bool sid_compose(struct dom_sid *dst, const struct dom_sid *domain_sid, uint32_t rid) +{ + sid_copy(dst, domain_sid); + return sid_append_rid(dst, rid); +} + +/***************************************************************** + Removes the last rid from the end of a sid +*****************************************************************/ + +bool sid_split_rid(struct dom_sid *sid, uint32_t *rid) +{ + if (sid->num_auths > 0) { + sid->num_auths--; + *rid = sid->sub_auths[sid->num_auths]; + return true; + } + return false; +} + +/***************************************************************** + Return the last rid from the end of a sid +*****************************************************************/ + +bool sid_peek_rid(const struct dom_sid *sid, uint32_t *rid) +{ + if (!sid || !rid) + return false; + + if (sid->num_auths > 0) { + *rid = sid->sub_auths[sid->num_auths - 1]; + return true; + } + return false; +} + +/***************************************************************** + Return the last rid from the end of a sid + and check the sid against the exp_dom_sid +*****************************************************************/ + +bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid *sid, uint32_t *rid) +{ + if (!exp_dom_sid || !sid || !rid) + return false; + + if (sid->num_auths != (exp_dom_sid->num_auths+1)) { + return false; + } + + if (sid_compare_domain(exp_dom_sid, sid)!=0){ + *rid=(-1); + return false; + } + + return sid_peek_rid(sid, rid); +} + +/***************************************************************** + Copies a sid +*****************************************************************/ + +void sid_copy(struct dom_sid *dst, const struct dom_sid *src) +{ + int i; + + ZERO_STRUCTP(dst); + + dst->sid_rev_num = src->sid_rev_num; + dst->num_auths = src->num_auths; + + memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth)); + + for (i = 0; i < src->num_auths; i++) + dst->sub_auths[i] = src->sub_auths[i]; +} + +/***************************************************************** + Parse a on-the-wire SID to a struct dom_sid. +*****************************************************************/ + +bool sid_parse(const char *inbuf, size_t len, struct dom_sid *sid) +{ + enum ndr_err_code ndr_err; + DATA_BLOB in = data_blob_const(inbuf, len); + ndr_err = ndr_pull_struct_blob_all(&in, NULL, sid, + (ndr_pull_flags_fn_t)ndr_pull_dom_sid); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } + return true; +} + +/***************************************************************** + See if 2 SIDs are in the same domain + this just compares the leading sub-auths +*****************************************************************/ + +int sid_compare_domain(const struct dom_sid *sid1, const struct dom_sid *sid2) +{ + int n, i; + + n = MIN(sid1->num_auths, sid2->num_auths); + + for (i = n-1; i >= 0; --i) + if (sid1->sub_auths[i] != sid2->sub_auths[i]) + return sid1->sub_auths[i] - sid2->sub_auths[i]; + + return dom_sid_compare_auth(sid1, sid2); +} + +/***************************************************************** + Compare two sids. +*****************************************************************/ + +bool sid_equal(const struct dom_sid *sid1, const struct dom_sid *sid2) +{ + return dom_sid_compare(sid1, sid2) == 0; +} + +/******************************************************************** + Add SID to an array SIDs +********************************************************************/ + +NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, + struct dom_sid **sids, uint32_t *num) +{ + *sids = talloc_realloc(mem_ctx, *sids, struct dom_sid, + (*num)+1); + if (*sids == NULL) { + *num = 0; + return NT_STATUS_NO_MEMORY; + } + + sid_copy(&((*sids)[*num]), sid); + *num += 1; + + return NT_STATUS_OK; +} + + +/******************************************************************** + Add SID to an array SIDs ensuring that it is not already there +********************************************************************/ + +NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, + struct dom_sid **sids, uint32_t *num_sids) +{ + size_t i; + + for (i=0; i<(*num_sids); i++) { + if (dom_sid_compare(sid, &(*sids)[i]) == 0) + return NT_STATUS_OK; + } + + return add_sid_to_array(mem_ctx, sid, sids, num_sids); +} + +/******************************************************************** + Remove SID from an array +********************************************************************/ + +void del_sid_from_array(const struct dom_sid *sid, struct dom_sid **sids, size_t *num) +{ + struct dom_sid *sid_list = *sids; + size_t i; + + for ( i=0; i<*num; i++ ) { + + /* if we find the SID, then decrement the count + and break out of the loop */ + + if ( sid_equal(sid, &sid_list[i]) ) { + *num -= 1; + break; + } + } + + /* This loop will copy the remainder of the array + if i < num of sids ni the array */ + + for ( ; i<*num; i++ ) + sid_copy( &sid_list[i], &sid_list[i+1] ); + + return; +} + +bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx, + uint32_t rid, uint32_t **pp_rids, size_t *p_num) +{ + size_t i; + + for (i=0; i<*p_num; i++) { + if ((*pp_rids)[i] == rid) + return true; + } + + *pp_rids = talloc_realloc(mem_ctx, *pp_rids, uint32_t, *p_num+1); + + if (*pp_rids == NULL) { + *p_num = 0; + return false; + } + + (*pp_rids)[*p_num] = rid; + *p_num += 1; + return true; +} + +bool is_null_sid(const struct dom_sid *sid) +{ + static const struct dom_sid null_sid = {0}; + return sid_equal(sid, &null_sid); +} diff --git a/libcli/security/wscript_build b/libcli/security/wscript_build index 5dac9019fb..aaaf8d8372 100644 --- a/libcli/security/wscript_build +++ b/libcli/security/wscript_build @@ -1,8 +1,8 @@ #!/usr/bin/env python -bld.SAMBA_SUBSYSTEM('LIBSECURITY_COMMON', - source='dom_sid.c display_sec.c secace.c secacl.c security_descriptor.c sddl.c privileges.c security_token.c', +bld.SAMBA_SUBSYSTEM('LIBSECURITY', + source='dom_sid.c display_sec.c secace.c secacl.c security_descriptor.c sddl.c privileges.c security_token.c access_check.c object_tree.c create_descriptor.c util_sid.c', deps='talloc LIBNDR' ) diff --git a/nsswitch/wscript_build b/nsswitch/wscript_build index eb3beb3cd7..e190198002 100644 --- a/nsswitch/wscript_build +++ b/nsswitch/wscript_build @@ -15,7 +15,7 @@ bld.SAMBA_BINARY('nsstest', bld.SAMBA_BINARY('wbinfo', source='wbinfo.c', - deps='LIBSAMBA-UTIL LIBCLI_AUTH popt POPT_SAMBA LIBWINBIND-CLIENT LIBWBCLIENT tevent UTIL_TEVENT LIBASYNC_REQ UID_WRAPPER LIBSECURITY_COMMON LIBNDR NDR_SECURITY' + deps='LIBSAMBA-UTIL LIBCLI_AUTH popt POPT_SAMBA LIBWINBIND-CLIENT LIBWBCLIENT tevent UTIL_TEVENT LIBASYNC_REQ UID_WRAPPER LIBSECURITY LIBNDR NDR_SECURITY' ) bld.SAMBA_LIBRARY('nss_winbind', diff --git a/source3/Makefile.in b/source3/Makefile.in index a73ce26a3a..491c1a9f6a 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -470,14 +470,15 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \ lib/server_contexts.o \ lib/ldap_escape.o @CHARSET_STATIC@ \ - lib/secdesc.o ../libcli/security/access_check.o ../libcli/security/secace.o \ + lib/secdesc.o ../libcli/security/access_check.o \ + ../libcli/security/secace.o ../libcli/security/object_tree.o \ ../libcli/security/sddl.o \ ../libcli/security/secacl.o @PTHREADPOOL_OBJ@ \ lib/fncall.o \ libads/krb5_errs.o lib/system_smbd.o lib/audit.o $(LIBNDR_OBJ) \ lib/file_id.o lib/idmap_cache.o \ ../libcli/security/dom_sid.o ../libcli/security/security_descriptor.o \ - ../libcli/security/security_token.o + ../libcli/security/security_token.o ../libcli/security/util_sid.o LIB_DUMMY_OBJ = lib/dummysmbd.o lib/dummyroot.o LIB_NONSMBD_OBJ = $(LIB_OBJ) $(LIB_DUMMY_OBJ) diff --git a/source3/include/proto.h b/source3/include/proto.h index 81e1909521..3725ea3fa8 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -1258,31 +1258,13 @@ bool is_setuid_root(void) ; /* The following definitions come from lib/util_sid.c */ -const char *sid_type_lookup(uint32 sid_type) ; -const struct security_token *get_system_token(void) ; char *sid_to_fstring(fstring sidstr_out, const struct dom_sid *sid); char *sid_string_talloc(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); char *sid_string_dbg(const struct dom_sid *sid); char *sid_string_tos(const struct dom_sid *sid); -bool string_to_sid(struct dom_sid *sidout, const char *sidstr); -bool sid_append_rid(struct dom_sid *sid, uint32 rid); -bool sid_compose(struct dom_sid *dst, const struct dom_sid *domain_sid, uint32 rid); -bool sid_split_rid(struct dom_sid *sid, uint32 *rid); -bool sid_peek_rid(const struct dom_sid *sid, uint32 *rid); -bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid *sid, uint32 *rid); -void sid_copy(struct dom_sid *dst, const struct dom_sid *src); bool sid_linearize(char *outbuf, size_t len, const struct dom_sid *sid); -bool sid_parse(const char *inbuf, size_t len, struct dom_sid *sid); bool non_mappable_sid(struct dom_sid *sid); char *sid_binstring_hex(const struct dom_sid *sid); -NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, - struct dom_sid **sids, uint32_t *num); -NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, - struct dom_sid **sids, uint32_t *num_sids); -void del_sid_from_array(const struct dom_sid *sid, struct dom_sid **sids, size_t *num); -bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx, - uint32 rid, uint32 **pp_rids, size_t *p_num); -bool is_null_sid(const struct dom_sid *sid); NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, const struct netr_SamInfo3 *info3, struct dom_sid **user_sids, diff --git a/source3/include/smb.h b/source3/include/smb.h index ae93bbbe7e..07a53de8e6 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -193,32 +193,6 @@ struct lsa_name_info { int dom_idx; }; -/* Some well-known SIDs */ -extern const struct dom_sid global_sid_World_Domain; -extern const struct dom_sid global_sid_World; -extern const struct dom_sid global_sid_Creator_Owner_Domain; -extern const struct dom_sid global_sid_NT_Authority; -extern const struct dom_sid global_sid_System; -extern const struct dom_sid global_sid_NULL; -extern const struct dom_sid global_sid_Authenticated_Users; -extern const struct dom_sid global_sid_Network; -extern const struct dom_sid global_sid_Creator_Owner; -extern const struct dom_sid global_sid_Creator_Group; -extern const struct dom_sid global_sid_Anonymous; -extern const struct dom_sid global_sid_Builtin; -extern const struct dom_sid global_sid_Builtin_Administrators; -extern const struct dom_sid global_sid_Builtin_Users; -extern const struct dom_sid global_sid_Builtin_Guests; -extern const struct dom_sid global_sid_Builtin_Power_Users; -extern const struct dom_sid global_sid_Builtin_Account_Operators; -extern const struct dom_sid global_sid_Builtin_Server_Operators; -extern const struct dom_sid global_sid_Builtin_Print_Operators; -extern const struct dom_sid global_sid_Builtin_Backup_Operators; -extern const struct dom_sid global_sid_Builtin_Replicator; -extern const struct dom_sid global_sid_Builtin_PreWin2kAccess; -extern const struct dom_sid global_sid_Unix_Users; -extern const struct dom_sid global_sid_Unix_Groups; - /* * The complete list of SIDS belonging to this user. * Created when a vuid is registered. diff --git a/source3/lib/util_sid.c b/source3/lib/util_sid.c index 25933116c4..bb9e2e98f9 100644 --- a/source3/lib/util_sid.c +++ b/source3/lib/util_sid.c @@ -25,132 +25,8 @@ #include "includes.h" #include "../librpc/gen_ndr/ndr_security.h" #include "../librpc/gen_ndr/netlogon.h" -#include "../libcli/security/dom_sid.h" - -/* - * Some useful sids, more well known sids can be found at - * http://support.microsoft.com/kb/243330/EN-US/ - */ - - -const struct dom_sid global_sid_World_Domain = /* Everyone domain */ -{ 1, 0, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_World = /* Everyone */ -{ 1, 1, {0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Creator_Owner_Domain = /* Creator Owner domain */ -{ 1, 0, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_NT_Authority = /* NT Authority */ -{ 1, 0, {0,0,0,0,0,5}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_System = /* System */ -{ 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_NULL = /* NULL sid */ -{ 1, 1, {0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Authenticated_Users = /* All authenticated rids */ -{ 1, 1, {0,0,0,0,0,5}, {11,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -#if 0 -/* for documentation */ -const struct dom_sid global_sid_Restriced = /* Restriced Code */ -{ 1, 1, {0,0,0,0,0,5}, {12,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -#endif -const struct dom_sid global_sid_Network = /* Network rids */ -{ 1, 1, {0,0,0,0,0,5}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - -const struct dom_sid global_sid_Creator_Owner = /* Creator Owner */ -{ 1, 1, {0,0,0,0,0,3}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Creator_Group = /* Creator Group */ -{ 1, 1, {0,0,0,0,0,3}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Anonymous = /* Anonymous login */ -{ 1, 1, {0,0,0,0,0,5}, {7,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - -const struct dom_sid global_sid_Builtin = /* Local well-known domain */ -{ 1, 1, {0,0,0,0,0,5}, {32,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Administrators = /* Builtin administrators */ -{ 1, 2, {0,0,0,0,0,5}, {32,544,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Users = /* Builtin users */ -{ 1, 2, {0,0,0,0,0,5}, {32,545,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Guests = /* Builtin guest users */ -{ 1, 2, {0,0,0,0,0,5}, {32,546,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Power_Users = /* Builtin power users */ -{ 1, 2, {0,0,0,0,0,5}, {32,547,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Account_Operators = /* Builtin account operators */ -{ 1, 2, {0,0,0,0,0,5}, {32,548,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Server_Operators = /* Builtin server operators */ -{ 1, 2, {0,0,0,0,0,5}, {32,549,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Print_Operators = /* Builtin print operators */ -{ 1, 2, {0,0,0,0,0,5}, {32,550,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Backup_Operators = /* Builtin backup operators */ -{ 1, 2, {0,0,0,0,0,5}, {32,551,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_Replicator = /* Builtin replicator */ -{ 1, 2, {0,0,0,0,0,5}, {32,552,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Builtin_PreWin2kAccess = /* Builtin pre win2k access */ -{ 1, 2, {0,0,0,0,0,5}, {32,554,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - -const struct dom_sid global_sid_Unix_Users = /* Unmapped Unix users */ -{ 1, 1, {0,0,0,0,0,22}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; -const struct dom_sid global_sid_Unix_Groups = /* Unmapped Unix groups */ -{ 1, 1, {0,0,0,0,0,22}, {2,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}; - -/* Unused, left here for documentary purposes */ -#if 0 -#define SECURITY_NULL_SID_AUTHORITY 0 -#define SECURITY_WORLD_SID_AUTHORITY 1 -#define SECURITY_LOCAL_SID_AUTHORITY 2 -#define SECURITY_CREATOR_SID_AUTHORITY 3 -#define SECURITY_NT_AUTHORITY 5 -#endif - -static struct dom_sid system_sid_array[1] = -{ { 1, 1, {0,0,0,0,0,5}, {18,0,0,0,0,0,0,0,0,0,0,0,0,0,0}} }; -static const struct security_token system_token = { - .num_sids = ARRAY_SIZE(system_sid_array), - .sids = system_sid_array, - .privilege_mask = SE_ALL_PRIVS -}; - -/**************************************************************************** - Lookup string names for SID types. -****************************************************************************/ - -static const struct { - enum lsa_SidType sid_type; - const char *string; -} sid_name_type[] = { - {SID_NAME_USER, "User"}, - {SID_NAME_DOM_GRP, "Domain Group"}, - {SID_NAME_DOMAIN, "Domain"}, - {SID_NAME_ALIAS, "Local Group"}, - {SID_NAME_WKN_GRP, "Well-known Group"}, - {SID_NAME_DELETED, "Deleted Account"}, - {SID_NAME_INVALID, "Invalid Account"}, - {SID_NAME_UNKNOWN, "UNKNOWN"}, - {SID_NAME_COMPUTER, "Computer"}, - - {(enum lsa_SidType)0, NULL} -}; - -const char *sid_type_lookup(uint32 sid_type) -{ - int i = 0; - - /* Look through list */ - while(sid_name_type[i].sid_type != 0) { - if (sid_name_type[i].sid_type == sid_type) - return sid_name_type[i].string; - i++; - } +#include "../libcli/security/security.h" - /* Default return */ - return "SID *TYPE* is INVALID"; -} - -/************************************************************************** - Create the SYSTEM token. -***************************************************************************/ - -const struct security_token *get_system_token(void) -{ - return &system_token; -} /***************************************************************** Convert a SID to an ascii string. @@ -194,83 +70,6 @@ char *sid_string_tos(const struct dom_sid *sid) return sid_string_talloc(talloc_tos(), sid); } -bool sid_compose(struct dom_sid *dst, const struct dom_sid *domain_sid, uint32 rid) -{ - sid_copy(dst, domain_sid); - return sid_append_rid(dst, rid); -} - -/***************************************************************** - Removes the last rid from the end of a sid -*****************************************************************/ - -bool sid_split_rid(struct dom_sid *sid, uint32 *rid) -{ - if (sid->num_auths > 0) { - sid->num_auths--; - *rid = sid->sub_auths[sid->num_auths]; - return True; - } - return False; -} - -/***************************************************************** - Return the last rid from the end of a sid -*****************************************************************/ - -bool sid_peek_rid(const struct dom_sid *sid, uint32 *rid) -{ - if (!sid || !rid) - return False; - - if (sid->num_auths > 0) { - *rid = sid->sub_auths[sid->num_auths - 1]; - return True; - } - return False; -} - -/***************************************************************** - Return the last rid from the end of a sid - and check the sid against the exp_dom_sid -*****************************************************************/ - -bool sid_peek_check_rid(const struct dom_sid *exp_dom_sid, const struct dom_sid *sid, uint32 *rid) -{ - if (!exp_dom_sid || !sid || !rid) - return False; - - if (sid->num_auths != (exp_dom_sid->num_auths+1)) { - return False; - } - - if (dom_sid_compare_domain(exp_dom_sid, sid)!=0){ - *rid=(-1); - return False; - } - - return sid_peek_rid(sid, rid); -} - -/***************************************************************** - Copies a sid -*****************************************************************/ - -void sid_copy(struct dom_sid *dst, const struct dom_sid *src) -{ - int i; - - ZERO_STRUCTP(dst); - - dst->sid_rev_num = src->sid_rev_num; - dst->num_auths = src->num_auths; - - memcpy(&dst->id_auth[0], &src->id_auth[0], sizeof(src->id_auth)); - - for (i = 0; i < src->num_auths; i++) - dst->sub_auths[i] = src->sub_auths[i]; -} - /***************************************************************** Write a sid out into on-the-wire format. *****************************************************************/ @@ -292,22 +91,6 @@ bool sid_linearize(char *outbuf, size_t len, const struct dom_sid *sid) } /***************************************************************** - Parse a on-the-wire SID to a struct dom_sid. -*****************************************************************/ - -bool sid_parse(const char *inbuf, size_t len, struct dom_sid *sid) -{ - enum ndr_err_code ndr_err; - DATA_BLOB in = data_blob_const(inbuf, len); - ndr_err = ndr_pull_struct_blob_all(&in, NULL, sid, - (ndr_pull_flags_fn_t)ndr_pull_dom_sid); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return false; - } - return true; -} - -/***************************************************************** Returns true if SID is internal (and non-mappable). *****************************************************************/ @@ -346,101 +129,6 @@ char *sid_binstring_hex(const struct dom_sid *sid) return s; } -/******************************************************************** - Add SID to an array SIDs -********************************************************************/ - -NTSTATUS add_sid_to_array(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, - struct dom_sid **sids, uint32_t *num) -{ - *sids = TALLOC_REALLOC_ARRAY(mem_ctx, *sids, struct dom_sid, - (*num)+1); - if (*sids == NULL) { - *num = 0; - return NT_STATUS_NO_MEMORY; - } - - sid_copy(&((*sids)[*num]), sid); - *num += 1; - - return NT_STATUS_OK; -} - - -/******************************************************************** - Add SID to an array SIDs ensuring that it is not already there -********************************************************************/ - -NTSTATUS add_sid_to_array_unique(TALLOC_CTX *mem_ctx, const struct dom_sid *sid, - struct dom_sid **sids, uint32_t *num_sids) -{ - size_t i; - - for (i=0; i<(*num_sids); i++) { - if (dom_sid_compare(sid, &(*sids)[i]) == 0) - return NT_STATUS_OK; - } - - return add_sid_to_array(mem_ctx, sid, sids, num_sids); -} - -/******************************************************************** - Remove SID from an array -********************************************************************/ - -void del_sid_from_array(const struct dom_sid *sid, struct dom_sid **sids, size_t *num) -{ - struct dom_sid *sid_list = *sids; - size_t i; - - for ( i=0; i<*num; i++ ) { - - /* if we find the SID, then decrement the count - and break out of the loop */ - - if ( dom_sid_equal(sid, &sid_list[i]) ) { - *num -= 1; - break; - } - } - - /* This loop will copy the remainder of the array - if i < num of sids ni the array */ - - for ( ; i<*num; i++ ) - sid_copy( &sid_list[i], &sid_list[i+1] ); - - return; -} - -bool add_rid_to_array_unique(TALLOC_CTX *mem_ctx, - uint32 rid, uint32 **pp_rids, size_t *p_num) -{ - size_t i; - - for (i=0; i<*p_num; i++) { - if ((*pp_rids)[i] == rid) - return True; - } - - *pp_rids = TALLOC_REALLOC_ARRAY(mem_ctx, *pp_rids, uint32, *p_num+1); - - if (*pp_rids == NULL) { - *p_num = 0; - return False; - } - - (*pp_rids)[*p_num] = rid; - *p_num += 1; - return True; -} - -bool is_null_sid(const struct dom_sid *sid) -{ - static const struct dom_sid null_sid = {0}; - return dom_sid_equal(sid, &null_sid); -} - NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, const struct netr_SamInfo3 *info3, struct dom_sid **user_sids, diff --git a/source3/winbindd/winbindd_util.c b/source3/winbindd/winbindd_util.c index aec4cc60a2..afdce47d2d 100644 --- a/source3/winbindd/winbindd_util.c +++ b/source3/winbindd/winbindd_util.c @@ -31,7 +31,7 @@ extern struct winbindd_methods cache_methods; /** - * @file winbindd_util.c + * @file winbindd_util.cq * * Winbind daemon for NT domain authentication nss module. **/ diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index 7291821fae..d93ad0d005 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -366,19 +366,6 @@ #define DESIRED_ACCESS_PIPE 0x2019f -/* Mapping of generic access rights for files to specific rights. */ -#define FILE_GENERIC_ALL (STANDARD_RIGHTS_REQUIRED_ACCESS| NT_ACCESS_SYNCHRONIZE_ACCESS|FILE_ALL_ACCESS) - -#define FILE_GENERIC_READ (STANDARD_RIGHTS_READ_ACCESS|FILE_READ_DATA|FILE_READ_ATTRIBUTES|\ - FILE_READ_EA|NT_ACCESS_SYNCHRONIZE_ACCESS) - -#define FILE_GENERIC_WRITE (STANDARD_RIGHTS_WRITE_ACCESS|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|\ - FILE_WRITE_EA|FILE_APPEND_DATA|NT_ACCESS_SYNCHRONIZE_ACCESS) - -#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|FILE_READ_ATTRIBUTES|\ - FILE_EXECUTE|NT_ACCESS_SYNCHRONIZE_ACCESS) - - /* FileAttributes (search attributes) field */ #define FILE_ATTRIBUTE_READONLY 0x0001 #define FILE_ATTRIBUTE_HIDDEN 0x0002 diff --git a/source4/libcli/security/access_check.c b/source4/libcli/security/access_check.c deleted file mode 100644 index 5ae318be43..0000000000 --- a/source4/libcli/security/access_check.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - security access checking routines - - Copyright (C) Andrew Tridgell 2004 - - 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 "libcli/security/security.h" - -/* - perform a SEC_FLAG_MAXIMUM_ALLOWED access check -*/ -static uint32_t access_check_max_allowed(const struct security_descriptor *sd, - const struct security_token *token) -{ - uint32_t denied = 0, granted = 0; - uint32_t i; - - if (security_token_has_sid(token, sd->owner_sid)) { - granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE; - } else if (security_token_has_privilege(token, SEC_PRIV_RESTORE)) { - granted |= SEC_STD_DELETE; - } - - if (sd->dacl == NULL) { - return granted & ~denied; - } - - for (i = 0;i<sd->dacl->num_aces; i++) { - struct security_ace *ace = &sd->dacl->aces[i]; - - if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { - continue; - } - - if (!security_token_has_sid(token, &ace->trustee)) { - continue; - } - - switch (ace->type) { - case SEC_ACE_TYPE_ACCESS_ALLOWED: - granted |= ace->access_mask; - break; - case SEC_ACE_TYPE_ACCESS_DENIED: - case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: - denied |= ace->access_mask; - break; - default: /* Other ACE types not handled/supported */ - break; - } - } - - return granted & ~denied; -} - -static const struct GUID *get_ace_object_type(struct security_ace *ace) -{ - struct GUID *type; - - if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) - type = &ace->object.object.type.type; - else if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) - type = &ace->object.object.inherited_type.inherited_type; /* This doesn't look right. Is something wrong with the IDL? */ - else - type = NULL; - - return type; - -} - -/* - The main entry point for access checking. If returning ACCESS_DENIED - this function returns the denied bits in the uint32_t pointed - to by the access_granted pointer. -*/ -NTSTATUS se_access_check(const struct security_descriptor *sd, - const struct security_token *token, - uint32_t access_desired, - uint32_t *access_granted) -{ - uint32_t i; - uint32_t bits_remaining; - - *access_granted = access_desired; - bits_remaining = access_desired; - - /* handle the maximum allowed flag */ - if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) { - uint32_t orig_access_desired = access_desired; - - access_desired |= access_check_max_allowed(sd, token); - access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED; - *access_granted = access_desired; - bits_remaining = access_desired & ~SEC_STD_DELETE; - - DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n", - orig_access_desired, - *access_granted, - bits_remaining)); - } - - if (access_desired & SEC_FLAG_SYSTEM_SECURITY) { - if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) { - bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY; - } else { - return NT_STATUS_PRIVILEGE_NOT_HELD; - } - } - - /* a NULL dacl allows access */ - if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) { - *access_granted = access_desired; - return NT_STATUS_OK; - } - - /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */ - if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) && - security_token_has_sid(token, sd->owner_sid)) { - bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE); - } - if ((bits_remaining & SEC_STD_DELETE) && - (security_token_has_privilege(token, SEC_PRIV_RESTORE))) { - bits_remaining &= ~SEC_STD_DELETE; - } - if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) && - security_token_has_privilege(token, SEC_PRIV_RESTORE)) { - bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE); - } - if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) && - security_token_has_privilege(token, SEC_PRIV_BACKUP)) { - bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP); - } - - if (sd->dacl == NULL) { - goto done; - } - - /* check each ace in turn. */ - for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) { - struct security_ace *ace = &sd->dacl->aces[i]; - - if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { - continue; - } - - if (!security_token_has_sid(token, &ace->trustee)) { - continue; - } - - switch (ace->type) { - case SEC_ACE_TYPE_ACCESS_ALLOWED: - bits_remaining &= ~ace->access_mask; - break; - case SEC_ACE_TYPE_ACCESS_DENIED: - case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: - if (bits_remaining & ace->access_mask) { - return NT_STATUS_ACCESS_DENIED; - } - break; - default: /* Other ACE types not handled/supported */ - break; - } - } - -done: - if (bits_remaining != 0) { - *access_granted = bits_remaining; - return NT_STATUS_ACCESS_DENIED; - } - - return NT_STATUS_OK; -} - -/* modified access check for the purposes of DS security - * Lots of code duplication, it will ve united in just one - * function eventually */ - -NTSTATUS sec_access_check_ds(const struct security_descriptor *sd, - const struct security_token *token, - uint32_t access_desired, - uint32_t *access_granted, - struct object_tree *tree, - struct dom_sid *replace_sid) -{ - uint32_t i; - uint32_t bits_remaining; - struct object_tree *node; - const struct GUID *type; - struct dom_sid *ps_sid = dom_sid_parse_talloc(NULL, SID_NT_SELF); - - *access_granted = access_desired; - bits_remaining = access_desired; - - /* handle the maximum allowed flag */ - if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) { - access_desired |= access_check_max_allowed(sd, token); - access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED; - *access_granted = access_desired; - bits_remaining = access_desired & ~SEC_STD_DELETE; - } - - if (access_desired & SEC_FLAG_SYSTEM_SECURITY) { - if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) { - bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY; - } else { - return NT_STATUS_PRIVILEGE_NOT_HELD; - } - } - - /* a NULL dacl allows access */ - if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) { - *access_granted = access_desired; - return NT_STATUS_OK; - } - - /* the owner always gets SEC_STD_WRITE_DAC, SEC_STD_READ_CONTROL and SEC_STD_DELETE */ - if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE)) && - security_token_has_sid(token, sd->owner_sid)) { - bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL|SEC_STD_DELETE); - } - if ((bits_remaining & SEC_STD_DELETE) && - security_token_has_privilege(token, SEC_PRIV_RESTORE)) { - bits_remaining &= ~SEC_STD_DELETE; - } - - if (sd->dacl == NULL) { - goto done; - } - - /* check each ace in turn. */ - for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) { - struct dom_sid *trustee; - struct security_ace *ace = &sd->dacl->aces[i]; - - if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) { - continue; - } - if (dom_sid_equal(&ace->trustee, ps_sid) && replace_sid) { - trustee = replace_sid; - } - else - { - trustee = &ace->trustee; - } - if (!security_token_has_sid(token, trustee)) { - continue; - } - - switch (ace->type) { - case SEC_ACE_TYPE_ACCESS_ALLOWED: - if (tree) - object_tree_modify_access(tree, ace->access_mask); - - bits_remaining &= ~ace->access_mask; - break; - case SEC_ACE_TYPE_ACCESS_DENIED: - if (bits_remaining & ace->access_mask) { - return NT_STATUS_ACCESS_DENIED; - } - break; - case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: - case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: - /* check only in case we have provided a tree, - * the ACE has an object type and that type - * is in the tree */ - type = get_ace_object_type(ace); - - if (!tree) - continue; - - if (!type) - node = tree; - else - if (!(node = get_object_tree_by_GUID(tree, type))) - continue; - - if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) { - object_tree_modify_access(node, ace->access_mask); - if (node->remaining_access == 0) { - return NT_STATUS_OK; - } - } - else { - if (node->remaining_access & ace->access_mask){ - return NT_STATUS_ACCESS_DENIED; - } - } - break; - default: /* Other ACE types not handled/supported */ - break; - } - } - -done: - if (bits_remaining != 0) { - return NT_STATUS_ACCESS_DENIED; - } - - return NT_STATUS_OK; -} - diff --git a/source4/libcli/security/wscript_build b/source4/libcli/security/wscript_build index 02d79428d0..f06899e9d4 100644 --- a/source4/libcli/security/wscript_build +++ b/source4/libcli/security/wscript_build @@ -3,12 +3,6 @@ bld.SAMBA_SUBSYSTEM('LIBSECURITY_SESSION', source='session.c', autoproto='session_proto.h', - public_deps='LIBSECURITY_COMMON' - ) - -bld.SAMBA_SUBSYSTEM('LIBSECURITY', - source='access_check.c create_descriptor.c object_tree.c', - autoproto='proto.h', - public_deps='LIBNDR LIBSECURITY_COMMON' + public_deps='LIBSECURITY' ) diff --git a/source4/torture/rpc/lsa.c b/source4/torture/rpc/lsa.c index a1ad9fde1d..c963d4fe02 100644 --- a/source4/torture/rpc/lsa.c +++ b/source4/torture/rpc/lsa.c @@ -148,23 +148,6 @@ bool test_lsa_OpenPolicy2(struct dcerpc_binding_handle *b, return test_lsa_OpenPolicy2_ex(b, tctx, handle, NT_STATUS_OK); } -static const char *sid_type_lookup(enum lsa_SidType r) -{ - switch (r) { - case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break; - case SID_NAME_USER: return "SID_NAME_USER"; break; - case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break; - case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break; - case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break; - case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break; - case SID_NAME_DELETED: return "SID_NAME_DELETED"; break; - case SID_NAME_INVALID: return "SID_NAME_INVALID"; break; - case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break; - case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break; - } - return "Invalid sid type\n"; -} - static bool test_LookupNames(struct dcerpc_binding_handle *b, struct torture_context *tctx, struct policy_handle *handle, diff --git a/source4/torture/rpc/lsa_lookup.c b/source4/torture/rpc/lsa_lookup.c index 88834176cd..d474ca1656 100644 --- a/source4/torture/rpc/lsa_lookup.c +++ b/source4/torture/rpc/lsa_lookup.c @@ -119,23 +119,6 @@ static NTSTATUS lookup_sids(struct torture_context *tctx, return r.out.result; } -static const char *sid_type_lookup(enum lsa_SidType r) -{ - switch (r) { - case SID_NAME_USE_NONE: return "SID_NAME_USE_NONE"; break; - case SID_NAME_USER: return "SID_NAME_USER"; break; - case SID_NAME_DOM_GRP: return "SID_NAME_DOM_GRP"; break; - case SID_NAME_DOMAIN: return "SID_NAME_DOMAIN"; break; - case SID_NAME_ALIAS: return "SID_NAME_ALIAS"; break; - case SID_NAME_WKN_GRP: return "SID_NAME_WKN_GRP"; break; - case SID_NAME_DELETED: return "SID_NAME_DELETED"; break; - case SID_NAME_INVALID: return "SID_NAME_INVALID"; break; - case SID_NAME_UNKNOWN: return "SID_NAME_UNKNOWN"; break; - case SID_NAME_COMPUTER: return "SID_NAME_COMPUTER"; break; - } - return "Invalid sid type\n"; -} - static bool test_lookupsids(struct torture_context *tctx, struct dcerpc_binding_handle *b, struct policy_handle *handle, |