summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/include/rpc_secdes.h113
-rw-r--r--source3/include/smb.h6
-rw-r--r--source3/libads/ldap.c129
-rw-r--r--source3/rpc_parse/parse_sec.c266
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;
+}