diff options
author | Andrew Tridgell <tridge@samba.org> | 2002-03-10 01:54:44 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2002-03-10 01:54:44 +0000 |
commit | cfbbf736777aca366e388882a389a214b87ca612 (patch) | |
tree | f048decf972c08834b4dde8b3f29148a3c444e92 /source3 | |
parent | 9b9d681870453c488a3c258ce7b56c5d250f3dc7 (diff) | |
download | samba-cfbbf736777aca366e388882a389a214b87ca612.tar.gz samba-cfbbf736777aca366e388882a389a214b87ca612.tar.bz2 samba-cfbbf736777aca366e388882a389a214b87ca612.zip |
yipee! Finally put in the patch from Alexey Kotovich
<a.kotovich@sam-solutions.net> that adds the security decsriptor code
for ADS workstation accounts
thanks for your patience Cat, and thanks to Andrew Bartlett for
extensive reviews and suggestions about this code.
(This used to be commit 6891393b5db868246fe52ff62b3dc6aa5ca6f726)
Diffstat (limited to 'source3')
-rw-r--r-- | source3/Makefile.in | 2 | ||||
-rw-r--r-- | source3/include/rpc_secdes.h | 113 | ||||
-rw-r--r-- | source3/include/smb.h | 6 | ||||
-rw-r--r-- | source3/libads/ldap.c | 129 | ||||
-rw-r--r-- | source3/rpc_parse/parse_sec.c | 266 |
5 files changed, 438 insertions, 78 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index effc37cbe8..44a16dd8e3 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -141,7 +141,7 @@ PARAM_OBJ = param/loadparm.o param/params.o dynconfig.o LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \ libads/krb5_setpw.o libads/kerberos.o \ libads/ads_struct.o libads/ads_status.o passdb/secrets.o \ - libads/util.o + libads/util.o libads/disp_sec.o LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clikrb5.o libsmb/clispnego.o libsmb/asn1.o \ diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index be5b120c2e..8304530e08 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -22,30 +22,54 @@ #ifndef _RPC_SECDES_H /* _RPC_SECDES_H */ #define _RPC_SECDES_H -#define SEC_RIGHTS_QUERY_VALUE 0x00000001 -#define SEC_RIGHTS_SET_VALUE 0x00000002 -#define SEC_RIGHTS_CREATE_SUBKEY 0x00000004 -#define SEC_RIGHTS_ENUM_SUBKEYS 0x00000008 -#define SEC_RIGHTS_NOTIFY 0x00000010 -#define SEC_RIGHTS_CREATE_LINK 0x00000020 - -#define SEC_RIGHTS_READ 0x00020019 -#define SEC_RIGHTS_FULL_CONTROL 0x000f003f -#define SEC_RIGHTS_MAXIMUM_ALLOWED 0x02000000 - -#define SEC_ACE_TYPE_ACCESS_ALLOWED 0x0 -#define SEC_ACE_TYPE_ACCESS_DENIED 0x1 -#define SEC_ACE_TYPE_SYSTEM_AUDIT 0x2 -#define SEC_ACE_TYPE_SYSTEM_ALARM 0x3 - -#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1 -#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2 +#define SEC_RIGHTS_QUERY_VALUE 0x00000001 +#define SEC_RIGHTS_SET_VALUE 0x00000002 +#define SEC_RIGHTS_CREATE_SUBKEY 0x00000004 +#define SEC_RIGHTS_ENUM_SUBKEYS 0x00000008 +#define SEC_RIGHTS_NOTIFY 0x00000010 +#define SEC_RIGHTS_CREATE_LINK 0x00000020 +#define SEC_RIGHTS_READ 0x00020019 +#define SEC_RIGHTS_FULL_CONTROL 0x000f003f +#define SEC_RIGHTS_MAXIMUM_ALLOWED 0x02000000 +/* for ADS */ +#define SEC_RIGHTS_LIST_CONTENTS 0x4 +#define SEC_RIGHTS_LIST_OBJECT 0x80 +#define SEC_RIGHTS_READ_ALL_PROP 0x10 +#define SEC_RIGHTS_READ_PERMS 0x20000 +#define SEC_RIGHTS_WRITE_ALL_VALID 0x8 +#define SEC_RIGHTS_WRITE_ALL_PROP 0x20 +#define SEC_RIGHTS_MODIFY_OWNER 0x80000 +#define SEC_RIGHTS_MODIFY_PERMS 0x40000 +#define SEC_RIGHTS_CREATE_CHILD 0x1 +#define SEC_RIGHTS_DELETE_CHILD 0x2 +#define SEC_RIGHTS_DELETE_SUBTREE 0x40 +#define SEC_RIGHTS_DELETE 0x10000 /* advanced/special/object/delete */ +#define SEC_RIGHTS_EXTENDED 0x100 /* change/reset password, receive/send as*/ +#define SEC_RIGHTS_CHANGE_PASSWD SEC_RIGHTS_EXTENDED +#define SEC_RIGHTS_RESET_PASSWD SEC_RIGHTS_EXTENDED +#define SEC_RIGHTS_FULL_CTRL 0xf01ff + +#define SEC_ACE_OBJECT_PRESENT 0x00000001 /* thanks for Jim McDonough <jmcd@us.ibm.com> */ +#define SEC_ACE_OBJECT_INHERITED_PRESENT 0x00000002 + +#define SEC_ACE_FLAG_OBJECT_INHERIT 0x1 +#define SEC_ACE_FLAG_CONTAINER_INHERIT 0x2 #define SEC_ACE_FLAG_NO_PROPAGATE_INHERIT 0x4 -#define SEC_ACE_FLAG_INHERIT_ONLY 0x8 -#define SEC_ACE_FLAG_INHERITED_ACE 0x10 /* New for Windows 2000 */ -#define SEC_ACE_FLAG_VALID_INHERIT 0xf -#define SEC_ACE_FLAG_SUCCESSFUL_ACCESS 0x40 -#define SEC_ACE_FLAG_FAILED_ACCESS 0x80 +#define SEC_ACE_FLAG_INHERIT_ONLY 0x8 +#define SEC_ACE_FLAG_INHERITED_ACE 0x10 /* New for Windows 2000 */ +#define SEC_ACE_FLAG_VALID_INHERIT 0xf +#define SEC_ACE_FLAG_SUCCESSFUL_ACCESS 0x40 +#define SEC_ACE_FLAG_FAILED_ACCESS 0x80 + +#define SEC_ACE_TYPE_ACCESS_ALLOWED 0x0 +#define SEC_ACE_TYPE_ACCESS_DENIED 0x1 +#define SEC_ACE_TYPE_SYSTEM_AUDIT 0x2 +#define SEC_ACE_TYPE_SYSTEM_ALARM 0x3 +#define SEC_ACE_TYPE_ALLOWED_COMPOUND 0x4 +#define SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT 0x5 +#define SEC_ACE_TYPE_ACCESS_DENIED_OBJECT 0x6 +#define SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT 0x7 +#define SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT 0x8 #define SEC_DESC_OWNER_DEFAULTED 0x0001 #define SEC_DESC_GROUP_DEFAULTED 0x0002 @@ -53,39 +77,40 @@ #define SEC_DESC_DACL_DEFAULTED 0x0008 #define SEC_DESC_SACL_PRESENT 0x0010 #define SEC_DESC_SACL_DEFAULTED 0x0020 +#define SEC_DESC_SELF_RELATIVE 0x8000 /* * New Windows 2000 bits. */ -#define SE_DESC_DACL_AUTO_INHERIT_REQ 0x0100 -#define SE_DESC_SACL_AUTO_INHERIT_REQ 0x0200 -#define SE_DESC_DACL_AUTO_INHERITED 0x0400 -#define SE_DESC_SACL_AUTO_INHERITED 0x0800 +#define SE_DESC_DACL_AUTO_INHERIT_REQ 0x0100 +#define SE_DESC_SACL_AUTO_INHERIT_REQ 0x0200 +#define SE_DESC_DACL_AUTO_INHERITED 0x0400 +#define SE_DESC_SACL_AUTO_INHERITED 0x0800 #define SE_DESC_DACL_PROTECTED 0x1000 #define SE_DESC_SACL_PROTECTED 0x2000 -#define SEC_DESC_SELF_RELATIVE 0x8000 - /* security information */ - -#define OWNER_SECURITY_INFORMATION 0x00000001 -#define GROUP_SECURITY_INFORMATION 0x00000002 -#define DACL_SECURITY_INFORMATION 0x00000004 -#define SACL_SECURITY_INFORMATION 0x00000008 +#define OWNER_SECURITY_INFORMATION 0x00000001 +#define GROUP_SECURITY_INFORMATION 0x00000002 +#define DACL_SECURITY_INFORMATION 0x00000004 +#define SACL_SECURITY_INFORMATION 0x00000008 #define ALL_SECURITY_INFORMATION (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|\ DACL_SECURITY_INFORMATION|SACL_SECURITY_INFORMATION) -#ifndef _SEC_ACCESS +/* Globally Unique ID */ +#define GUID_SIZE 16 +typedef struct guid_info +{ + uint8 info[GUID_SIZE]; +} GUID; + /* SEC_ACCESS */ typedef struct security_info_info { uint32 mask; } SEC_ACCESS; -#define _SEC_ACCESS -#endif -#ifndef _SEC_ACE /* SEC_ACE */ typedef struct security_ace_info { @@ -94,11 +119,17 @@ typedef struct security_ace_info uint16 size; SEC_ACCESS info; + + /* this stuff may be present when type is XXXX_TYPE_XXXX_OBJECT */ + uint32 obj_flags; /* xxxx_ACE_OBJECT_xxxx e.g present/inherited present etc */ + GUID obj_guid; /* object GUID */ + GUID inh_guid; /* inherited object GUID */ + /* eof object stuff */ + DOM_SID trustee; } SEC_ACE; -#define _SEC_ACE -#endif +#define SEC_ACE_HEADER_SIZE (2 * sizeof(uint8) + sizeof(uint16) + sizeof(uint32)) #ifndef ACL_REVISION #define ACL_REVISION 0x3 @@ -119,6 +150,7 @@ typedef struct security_acl_info SEC_ACE *ace; } SEC_ACL; +#define SEC_ACL_HEADER_SIZE (2 * sizeof(uint16) + sizeof(uint32)) #define _SEC_ACL #endif @@ -144,6 +176,7 @@ typedef struct security_descriptor_info DOM_SID *grp_sid; } SEC_DESC; +#define SEC_DESC_HEADER_SIZE (2 * sizeof(uint16) + 4 * sizeof(uint32)) #define _SEC_DESC #endif diff --git a/source3/include/smb.h b/source3/include/smb.h index f2d67b992f..f626394845 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -248,7 +248,6 @@ typedef uint32 WERROR; #define MAXSUBAUTHS 15 /* max sub authorities in a SID */ #endif -#ifndef _DOM_SID /** * @brief Security Identifier * @@ -268,8 +267,6 @@ typedef struct sid_info uint32 sub_auths[MAXSUBAUTHS]; } DOM_SID; -#define _DOM_SID -#endif /* * The complete list of SIDS belonging to this user. @@ -284,13 +281,10 @@ typedef struct sid_info #define PRIMARY_USER_SID_INDEX 0 #define PRIMARY_GROUP_SID_INDEX 1 -#ifndef _NT_USER_TOKEN typedef struct _nt_user_token { size_t num_sids; DOM_SID *user_sids; } NT_USER_TOKEN; -#define _NT_USER_TOKEN -#endif /*** query a local group, get a list of these: shows who is in that group ***/ diff --git a/source3/libads/ldap.c b/source3/libads/ldap.c index ef1902960f..a8f9298b0f 100644 --- a/source3/libads/ldap.c +++ b/source3/libads/ldap.c @@ -180,7 +180,7 @@ ADS_MODLIST ads_init_mods(TALLOC_CTX *ctx) add an attribute to the list, with values list already constructed */ static ADS_STATUS ads_modlist_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, char **values) + int mod_op, const char *name, char **values) { int curmod; LDAPMod **modlist = (LDAPMod **) *mods; @@ -238,7 +238,7 @@ ADS_STATUS ads_mod_repl_list(TALLOC_CTX *ctx, ADS_MODLIST *mods, add an attribute to the list, with values list to be built from args */ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, ...) + int mod_op, const char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -267,7 +267,7 @@ ADS_STATUS ads_mod_add_var(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_add_ber(TALLOC_CTX *ctx, ADS_MODLIST *mods, - int mod_op, char *name, ...) + int mod_op, const char *name, ...) { va_list ap; int num_vals, i, do_op; @@ -308,7 +308,7 @@ ADS_STATUS ads_mod_repl(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_add(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, char *val) + const char *name, const char *val) { return ads_mod_add_var(ctx, mods, LDAP_MOD_ADD, name, val, NULL); } @@ -329,7 +329,7 @@ ADS_STATUS ads_mod_add_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, } ADS_STATUS ads_mod_repl_len(TALLOC_CTX *ctx, ADS_MODLIST *mods, - char *name, size_t size, char *val) + const char *name, size_t size, char *val) { struct berval *bval = NULL; @@ -457,7 +457,8 @@ static ADS_STATUS ads_add_machine_acct(ADS_STRUCT *ads, const char *hostname, ads_mod_add(ctx, &mods, "operatingSystem", "Samba"); ads_mod_add(ctx, &mods, "operatingSystemVersion", VERSION); - ret = ads_gen_add(ads, new_dn, mods); + ads_gen_add(ads, new_dn, mods); + ret = ads_set_machine_sd(ads, hostname, new_dn); done: talloc_destroy(ctx); @@ -493,6 +494,36 @@ static void dump_sid(const char *field, struct berval **values) } /* + dump ntSecurityDescriptor +*/ +static void dump_sd(const char *filed, struct berval **values) +{ + prs_struct ps; + + SEC_DESC *psd = 0; + TALLOC_CTX *ctx = 0; + + if (!(ctx = talloc_init_named("sec_io_desc"))) + return; + + /* prepare data */ + prs_init(&ps, values[0]->bv_len, ctx, UNMARSHALL); + prs_append_data(&ps, values[0]->bv_val, values[0]->bv_len); + ps.data_offset = 0; + + /* parse secdesc */ + if (!sec_io_desc("sd", &psd, &ps, 1)) { + prs_mem_free(&ps); + talloc_destroy(ctx); + return; + } + if (psd) ads_disp_sd(psd); + + prs_mem_free(&ps); + talloc_destroy(ctx); +} + +/* dump a string result from ldap */ static void dump_string(const char *field, struct berval **values) @@ -517,7 +548,7 @@ void ads_dump(ADS_STRUCT *ads, void *res) void (*handler)(const char *, struct berval **); } handlers[] = { {"objectGUID", dump_binary}, - {"nTSecurityDescriptor", dump_binary}, + {"nTSecurityDescriptor", dump_sd}, {"objectSid", dump_sid}, {NULL, NULL} }; @@ -573,7 +604,7 @@ ADS_STATUS ads_join_realm(ADS_STRUCT *ads, const char *hostname, const char *org status = ads_find_machine_acct(ads, (void **)&res, host); if (ADS_ERR_OK(status) && ads_count_replies(ads, res) == 1) { - DEBUG(0, ("Host account for %s already exists - deleting for readd\n", host)); + DEBUG(0, ("Host account for %s already exists - deleting old account\n", host)); status = ads_leave_realm(ads, host); if (!ADS_ERR_OK(status)) { DEBUG(0, ("Failed to delete host '%s' from the '%s' realm.\n", @@ -637,6 +668,83 @@ ADS_STATUS ads_leave_realm(ADS_STRUCT *ads, const char *hostname) return status; } +/* + add machine account to existing security descriptor +*/ +ADS_STATUS ads_set_machine_sd(ADS_STRUCT *ads, const char *hostname, char *dn) +{ + const char *attrs[] = {"ntSecurityDescriptor", "objectSid", 0}; + char *exp = 0; + size_t sd_size = 0; + struct berval **bvals = 0; + prs_struct ps; + prs_struct ps_wire; + + LDAPMessage *res = 0; + LDAPMessage *msg = 0; + ADS_MODLIST mods = 0; + + NTSTATUS status; + ADS_STATUS ret; + DOM_SID sid; + SEC_DESC *psd = 0; + TALLOC_CTX *ctx = 0; + + if (!ads) return ADS_ERROR(LDAP_SERVER_DOWN); + + ret = ADS_ERROR(LDAP_SUCCESS); + + asprintf(&exp, "(samAccountName=%s$)", hostname); + ret = ads_search(ads, (void *) &res, exp, attrs); + + if (!ADS_ERR_OK(ret)) return ret; + + msg = ads_first_entry(ads, res); + bvals = ldap_get_values_len(ads->ld, msg, attrs[0]); + ads_pull_sid(ads, msg, attrs[1], &sid); + ads_msgfree(ads, res); +#if 0 + file_save("/tmp/sec_desc.old", bvals[0]->bv_val, bvals[0]->bv_len); +#endif + if (!(ctx = talloc_init_named("sec_io_desc"))) + return ADS_ERROR(LDAP_NO_MEMORY); + + prs_init(&ps, bvals[0]->bv_len, ctx, UNMARSHALL); + prs_append_data(&ps, bvals[0]->bv_val, bvals[0]->bv_len); + ps.data_offset = 0; + ldap_value_free_len(bvals); + + if (!sec_io_desc("sd", &psd, &ps, 1)) + goto ads_set_sd_error; + + status = sec_desc_add_sid(ctx, &psd, &sid, SEC_RIGHTS_FULL_CTRL, &sd_size); + + if (!NT_STATUS_IS_OK(status)) + goto ads_set_sd_error; + + prs_init(&ps_wire, sd_size, ctx, MARSHALL); + if (!sec_io_desc("sd_wire", &psd, &ps_wire, 1)) + goto ads_set_sd_error; + +#if 0 + file_save("/tmp/sec_desc.new", ps_wire.data_p, sd_size); +#endif + if (!(mods = ads_init_mods(ctx))) return ADS_ERROR(LDAP_NO_MEMORY); + + ads_mod_repl_len(ctx, &mods, attrs[0], sd_size, ps_wire.data_p); + ret = ads_gen_mod(ads, dn, mods); + + prs_mem_free(&ps); + prs_mem_free(&ps_wire); + talloc_destroy(ctx); + return ret; + +ads_set_sd_error: + prs_mem_free(&ps); + prs_mem_free(&ps_wire); + talloc_destroy(ctx); + return ADS_ERROR(LDAP_NO_MEMORY); +} ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, const char *hostname, @@ -646,6 +754,11 @@ ADS_STATUS ads_set_machine_password(ADS_STRUCT *ads, char *host = strdup(hostname); char *principal; + if (!ads->kdc_server) { + DEBUG(0, ("Unable to find KDC server\n")); + return ADS_ERROR(LDAP_SERVER_DOWN); + } + strlower(host); asprintf(&principal, "%s@%s", host, ads->realm); diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c index 8237ccf95d..4f093b2422 100644 --- a/source3/rpc_parse/parse_sec.c +++ b/source3/rpc_parse/parse_sec.c @@ -23,8 +23,6 @@ #include "includes.h" -#define SD_HEADER_SIZE 0x14 - /******************************************************************* Sets up a SEC_ACCESS structure. ********************************************************************/ @@ -55,6 +53,35 @@ BOOL sec_io_access(char *desc, SEC_ACCESS *t, prs_struct *ps, int depth) return True; } +/******************************************************************* + Check if ACE has OBJECT type. +********************************************************************/ + +BOOL sec_ace_object(uint8 type) +{ + if (type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT || + type == SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT || + type == SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT) { + return True; + } + return False; +} + +/******************************************************************* + copy a SEC_ACE structure. +********************************************************************/ +void sec_ace_copy(SEC_ACE *ace_dest, SEC_ACE *ace_src) +{ + ace_dest->type = ace_src->type; + ace_dest->flags = ace_src->flags; + ace_dest->size = ace_src->size; + ace_dest->info.mask = ace_src->info.mask; + ace_dest->obj_flags = ace_src->obj_flags; + memcpy(&ace_dest->obj_guid, &ace_src->obj_guid, GUID_SIZE); + memcpy(&ace_dest->inh_guid, &ace_src->inh_guid, GUID_SIZE); + sid_copy(&ace_dest->trustee, &ace_src->trustee); +} /******************************************************************* Sets up a SEC_ACE structure. @@ -106,16 +133,105 @@ BOOL sec_io_ace(char *desc, SEC_ACE *psa, prs_struct *ps, int depth) if(!prs_align(ps)) return False; - if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) - return False; + /* check whether object access is present */ + if (!sec_ace_object(psa->type)) { + if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) + return False; + } else { + if (!prs_uint32("obj_flags", ps, depth, &psa->obj_flags)) + return False; + + if (psa->obj_flags & SEC_ACE_OBJECT_PRESENT) + if (!prs_uint8s(False, "obj_guid", ps, depth, psa->obj_guid.info, GUID_SIZE)) + return False; + + if (psa->obj_flags & SEC_ACE_OBJECT_INHERITED_PRESENT) + if (!prs_uint8s(False, "inh_guid", ps, depth, psa->inh_guid.info, GUID_SIZE)) + return False; + + if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) + return False; + } if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset)) return False; - return True; } /******************************************************************* + adds new SID with its permissions to ACE list +********************************************************************/ + +NTSTATUS sec_ace_add_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid, uint32 mask) +{ + int i = 0; + + if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; + + *num += 1; + + if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0) + return NT_STATUS_NO_MEMORY; + + for (i = 0; i < *num - 1; i ++) + sec_ace_copy(&(*new)[i], &old[i]); + + (*new)[i].type = 0; + (*new)[i].flags = 0; + (*new)[i].size = SEC_ACE_HEADER_SIZE + sid_size(sid); + (*new)[i].info.mask = mask; + sid_copy(&(*new)[i].trustee, sid); + return NT_STATUS_OK; +} + +/******************************************************************* + modify SID's permissions at ACL +********************************************************************/ + +NTSTATUS sec_ace_mod_sid(SEC_ACE *ace, size_t num, DOM_SID *sid, uint32 mask) +{ + int i = 0; + + if (!ace || !sid) return NT_STATUS_INVALID_PARAMETER; + + for (i = 0; i < num; i ++) { + if (sid_compare(&ace[i].trustee, sid) == 0) { + ace[i].info.mask = mask; + return NT_STATUS_OK; + } + } + return NT_STATUS_NOT_FOUND; +} + +/******************************************************************* + delete SID from ACL +********************************************************************/ + +NTSTATUS sec_ace_del_sid(TALLOC_CTX *ctx, SEC_ACE **new, SEC_ACE *old, size_t *num, DOM_SID *sid) +{ + int i = 0; + int n_del = 0; + + if (!ctx || !new || !old || !sid || !num) return NT_STATUS_INVALID_PARAMETER; + + if((new[0] = (SEC_ACE *) talloc_zero(ctx, *num * sizeof(SEC_ACE))) == 0) + return NT_STATUS_NO_MEMORY; + + for (i = 0; i < *num; i ++) { + if (sid_compare(&old[i].trustee, sid) != 0) + sec_ace_copy(&(*new)[i], &old[i]); + else + n_del ++; + } + if (n_del == 0) + return NT_STATUS_NOT_FOUND; + else { + *num -= n_del; + return NT_STATUS_OK; + } +} + +/******************************************************************* Create a SEC_ACL structure. ********************************************************************/ @@ -129,7 +245,7 @@ SEC_ACL *make_sec_acl(TALLOC_CTX *ctx, uint16 revision, int num_aces, SEC_ACE *a dst->revision = revision; dst->num_aces = num_aces; - dst->size = 8; + dst->size = SEC_ACL_HEADER_SIZE; /* Now we need to return a non-NULL address for the ace list even if the number of aces required is zero. This is because there @@ -244,7 +360,7 @@ size_t sec_desc_size(SEC_DESC *psd) if (!psd) return 0; - offset = SD_HEADER_SIZE; + offset = SEC_DESC_HEADER_SIZE; if (psd->owner_sid != NULL) offset += ((sid_size(psd->owner_sid) + 3) & ~3); @@ -482,7 +598,9 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, SEC_ACL *sacl, SEC_ACL *dacl, size_t *sd_size) { SEC_DESC *dst; - uint32 offset; + uint32 offset = 0; + uint32 offset_sid = SEC_DESC_HEADER_SIZE; + uint32 offset_acl = 0; *sd_size = 0; @@ -511,50 +629,58 @@ SEC_DESC *make_sec_desc(TALLOC_CTX *ctx, uint16 revision, if(dacl && ((dst->dacl = dup_sec_acl(ctx, dacl)) == NULL)) goto error_exit; - + offset = 0; /* * Work out the linearization sizes. */ - if (dst->owner_sid != NULL) { if (offset == 0) - offset = SD_HEADER_SIZE; + offset = SEC_DESC_HEADER_SIZE; - dst->off_owner_sid = offset; offset += ((sid_size(dst->owner_sid) + 3) & ~3); } if (dst->grp_sid != NULL) { if (offset == 0) - offset = SD_HEADER_SIZE; + offset = SEC_DESC_HEADER_SIZE; - dst->off_grp_sid = offset; offset += ((sid_size(dst->grp_sid) + 3) & ~3); } if (dst->sacl != NULL) { - if (offset == 0) - offset = SD_HEADER_SIZE; + offset_acl = SEC_DESC_HEADER_SIZE; - dst->off_sacl = offset; - offset += ((dst->sacl->size + 3) & ~3); + dst->off_sacl = offset_acl; + offset_acl += ((dst->sacl->size + 3) & ~3); + offset += dst->sacl->size; + offset_sid += dst->sacl->size; } if (dst->dacl != NULL) { - if (offset == 0) - offset = SD_HEADER_SIZE; + if (offset_acl == 0) + offset_acl = SEC_DESC_HEADER_SIZE; - dst->off_dacl = offset; - offset += ((dst->dacl->size + 3) & ~3); + dst->off_dacl = offset_acl; + offset_acl += ((dst->dacl->size + 3) & ~3); + offset += dst->dacl->size; + offset_sid += dst->dacl->size; } - *sd_size = (size_t)((offset == 0) ? SD_HEADER_SIZE : offset); + *sd_size = (size_t)((offset == 0) ? SEC_DESC_HEADER_SIZE : offset); + + dst->off_owner_sid = offset_sid; + + if (dst->owner_sid != NULL) + dst->off_grp_sid = offset_sid + sid_size(dst->owner_sid); + else + dst->off_grp_sid = offset_sid; + return dst; error_exit: @@ -599,6 +725,8 @@ BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) { uint32 old_offset; uint32 max_offset = 0; /* after we're done, move offset to end */ + uint32 tmp_offset = 0; + SEC_DESC *psd; if (ppsd == NULL) @@ -656,10 +784,15 @@ BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) return False; } + tmp_offset = ps->data_offset; + ps->data_offset = psd->off_owner_sid; + if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth)) return False; if(!prs_align(ps)) return False; + + ps->data_offset = tmp_offset; } max_offset = MAX(max_offset, prs_offset(ps)); @@ -674,10 +807,15 @@ BOOL sec_io_desc(char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) return False; } + tmp_offset = ps->data_offset; + ps->data_offset = psd->off_grp_sid; + if(!smb_io_dom_sid("grp_sid", psd->grp_sid, ps, depth)) return False; if(!prs_align(ps)) return False; + + ps->data_offset = tmp_offset; } max_offset = MAX(max_offset, prs_offset(ps)); @@ -803,3 +941,85 @@ BOOL sec_io_desc_buf(char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth return True; } + +/******************************************************************* + adds new SID with its permissions to SEC_DESC +********************************************************************/ + +NTSTATUS sec_desc_add_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, uint32 mask, size_t *sd_size) +{ + SEC_DESC *sd = 0; + SEC_ACL *dacl = 0; + SEC_ACE *ace = 0; + NTSTATUS status; + + *sd_size = 0; + + if (!ctx || !psd || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER; + + status = sec_ace_add_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid, mask); + + if (!NT_STATUS_IS_OK(status)) + return status; + + if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace))) + return NT_STATUS_UNSUCCESSFUL; + + if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid, + psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size))) + return NT_STATUS_UNSUCCESSFUL; + + *psd = sd; + sd = 0; + return NT_STATUS_OK; +} + +/******************************************************************* + modify SID's permissions at SEC_DESC +********************************************************************/ + +NTSTATUS sec_desc_mod_sid(SEC_DESC *sd, DOM_SID *sid, uint32 mask) +{ + NTSTATUS status; + + if (!sd || !sid) return NT_STATUS_INVALID_PARAMETER; + + status = sec_ace_mod_sid(sd->dacl->ace, sd->dacl->num_aces, sid, mask); + + if (!NT_STATUS_IS_OK(status)) + return status; + + return NT_STATUS_OK; +} + +/******************************************************************* + delete SID from SEC_DESC +********************************************************************/ + +NTSTATUS sec_desc_del_sid(TALLOC_CTX *ctx, SEC_DESC **psd, DOM_SID *sid, size_t *sd_size) +{ + SEC_DESC *sd = 0; + SEC_ACL *dacl = 0; + SEC_ACE *ace = 0; + NTSTATUS status; + + *sd_size = 0; + + if (!ctx || !psd[0] || !sid || !sd_size) return NT_STATUS_INVALID_PARAMETER; + + status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->ace, &psd[0]->dacl->num_aces, sid); + + if (!NT_STATUS_IS_OK(status)) + return status; + + if (!(dacl = make_sec_acl(ctx, psd[0]->dacl->revision, psd[0]->dacl->num_aces, ace))) + return NT_STATUS_UNSUCCESSFUL; + + if (!(sd = make_sec_desc(ctx, psd[0]->revision, psd[0]->owner_sid, + psd[0]->grp_sid, psd[0]->sacl, dacl, sd_size))) + return NT_STATUS_UNSUCCESSFUL; + + *psd = sd; + sd = 0; + return NT_STATUS_OK; +} |