diff options
-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; +} |