Exemple #1
0
static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
				struct security_descriptor **ppdesc,
				uint16_t *p_hash_type,
				uint8_t hash[XATTR_SD_HASH_SIZE])
{
	TALLOC_CTX *ctx = talloc_tos();
	struct xattr_NTACL xacl;
	enum ndr_err_code ndr_err;
	size_t sd_size;

	ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
			(ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);

	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
			ndr_errstr(ndr_err)));
		return ndr_map_error2ntstatus(ndr_err);;
	}

	switch (xacl.version) {
		case 2:
			*ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
					xacl.info.sd_hs2->sd->type | SEC_DESC_SELF_RELATIVE,
					xacl.info.sd_hs2->sd->owner_sid,
					xacl.info.sd_hs2->sd->group_sid,
					xacl.info.sd_hs2->sd->sacl,
					xacl.info.sd_hs2->sd->dacl,
					&sd_size);
			/* No hash - null out. */
			*p_hash_type = XATTR_SD_HASH_TYPE_NONE;
			memset(hash, '\0', XATTR_SD_HASH_SIZE);
			break;
		case 3:
			*ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION,
					xacl.info.sd_hs3->sd->type | SEC_DESC_SELF_RELATIVE,
					xacl.info.sd_hs3->sd->owner_sid,
					xacl.info.sd_hs3->sd->group_sid,
					xacl.info.sd_hs3->sd->sacl,
					xacl.info.sd_hs3->sd->dacl,
					&sd_size);
			*p_hash_type = xacl.info.sd_hs3->hash_type;
			/* Current version 3. */
			memcpy(hash, xacl.info.sd_hs3->hash, XATTR_SD_HASH_SIZE);
			break;
		default:
			return NT_STATUS_REVISION_MISMATCH;
	}

	TALLOC_FREE(xacl.info.sd);

	return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
}
Exemple #2
0
SEC_DESC *get_share_security_default( TALLOC_CTX *ctx, size_t *psize, uint32 def_access)
{
	uint32_t sa;
	SEC_ACE ace;
	SEC_ACL *psa = NULL;
	SEC_DESC *psd = NULL;
	uint32 spec_access = def_access;

	se_map_generic(&spec_access, &file_generic_mapping);

	sa = (def_access | spec_access );
	init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 0);

	if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, 1, &ace)) != NULL) {
		psd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
				    SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL,
				    psa, psize);
	}

	if (!psd) {
		DEBUG(0,("get_share_security: Failed to make SEC_DESC.\n"));
		return NULL;
	}

	return psd;
}
Exemple #3
0
SEC_DESC *make_standard_sec_desc(TALLOC_CTX *ctx, const DOM_SID *owner_sid, const DOM_SID *grp_sid,
				 SEC_ACL *dacl, size_t *sd_size)
{
	return make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
			     SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL,
			     dacl, sd_size);
}
Exemple #4
0
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;

	if (!ctx || !psd[0] || !sid || !sd_size)
		return NT_STATUS_INVALID_PARAMETER;

	*sd_size = 0;
	
	status = sec_ace_del_sid(ctx, &ace, psd[0]->dacl->aces, &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]->type, psd[0]->owner_sid, 
		psd[0]->group_sid, psd[0]->sacl, dacl, sd_size)))
		return NT_STATUS_UNSUCCESSFUL;

	*psd = sd;
	 sd  = 0;
	return NT_STATUS_OK;
}
SEC_DESC *build_sec_desc(struct ace_entry *dacl, struct ace_entry *sacl, 
			 char *owner_sid, char *group_sid)
{
	struct dom_sid the_owner_sid, the_group_sid;
	SEC_ACL *the_dacl, *the_sacl;
	SEC_DESC *result;
	size_t size;

	/* Build up bits of security descriptor */

	char_to_sid(&the_owner_sid, owner_sid);
	char_to_sid(&the_group_sid, group_sid);

	the_dacl = build_acl(dacl);
	the_sacl = build_acl(sacl);

	result =  make_sec_desc(SEC_DESC_REVISION, 
				SEC_DESC_SELF_RELATIVE | SEC_DESC_DACL_PRESENT,
				&the_owner_sid, &the_group_sid, 
				the_sacl, the_dacl, &size);

	free_sec_acl(&the_dacl);
	free_sec_acl(&the_sacl);

	return result;
}
Exemple #6
0
static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf,
					   smbacl4_vfs_params *params,
					   uint32_t security_info,
					   TALLOC_CTX *mem_ctx,
					   struct security_descriptor **ppdesc,
					   struct SMB4ACL_T *theacl)
{
	int good_aces = 0;
	struct dom_sid sid_owner, sid_group;
	size_t sd_size = 0;
	struct security_ace *nt_ace_list = NULL;
	struct security_acl *psa = NULL;
	TALLOC_CTX *frame = talloc_stackframe();
	bool ok;

	if (theacl==NULL) {
		TALLOC_FREE(frame);
		return NT_STATUS_ACCESS_DENIED; /* special because we
						 * need to think through
						 * the null case.*/
	}

	uid_to_sid(&sid_owner, sbuf->st_ex_uid);
	gid_to_sid(&sid_group, sbuf->st_ex_gid);

	ok = smbacl4_nfs42win(frame, params, theacl, &sid_owner, &sid_group,
			      S_ISDIR(sbuf->st_ex_mode),
			      &nt_ace_list, &good_aces);
	if (!ok) {
		DEBUG(8,("smbacl4_nfs42win failed\n"));
		TALLOC_FREE(frame);
		return map_nt_error_from_unix(errno);
	}

	psa = make_sec_acl(frame, NT4_ACL_REVISION, good_aces, nt_ace_list);
	if (psa == NULL) {
		DEBUG(2,("make_sec_acl failed\n"));
		TALLOC_FREE(frame);
		return NT_STATUS_NO_MEMORY;
	}

	DEBUG(10,("after make sec_acl\n"));
	*ppdesc = make_sec_desc(
		mem_ctx, SD_REVISION, smbacl4_get_controlflags(theacl),
		(security_info & SECINFO_OWNER) ? &sid_owner : NULL,
		(security_info & SECINFO_GROUP) ? &sid_group : NULL,
		NULL, psa, &sd_size);
	if (*ppdesc==NULL) {
		DEBUG(2,("make_sec_desc failed\n"));
		TALLOC_FREE(frame);
		return NT_STATUS_NO_MEMORY;
	}

	DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with "
		   "sd_size %d\n",
		   (int)ndr_size_security_descriptor(*ppdesc, 0)));

	TALLOC_FREE(frame);
	return NT_STATUS_OK;
}
Exemple #7
0
SEC_DESC *dup_sec_desc(TALLOC_CTX *ctx, const SEC_DESC *src)
{
	size_t dummy;

	if(src == NULL)
		return NULL;

	return make_sec_desc( ctx, src->revision, src->type,
				src->owner_sid, src->group_sid, src->sacl,
				src->dacl, &dummy);
}
Exemple #8
0
SEC_DESC_BUF *sec_desc_merge(TALLOC_CTX *ctx, SEC_DESC_BUF *new_sdb, SEC_DESC_BUF *old_sdb)
{
	DOM_SID *owner_sid, *group_sid;
	SEC_DESC_BUF *return_sdb;
	SEC_ACL *dacl, *sacl;
	SEC_DESC *psd = NULL;
	uint16 secdesc_type;
	size_t secdesc_size;

	/* Copy over owner and group sids.  There seems to be no flag for
	   this so just check the pointer values. */

	owner_sid = new_sdb->sd->owner_sid ? new_sdb->sd->owner_sid :
		old_sdb->sd->owner_sid;

	group_sid = new_sdb->sd->group_sid ? new_sdb->sd->group_sid :
		old_sdb->sd->group_sid;
	
	secdesc_type = new_sdb->sd->type;

	/* Ignore changes to the system ACL.  This has the effect of making
	   changes through the security tab audit button not sticking. 
	   Perhaps in future Samba could implement these settings somehow. */

	sacl = NULL;
	secdesc_type &= ~SEC_DESC_SACL_PRESENT;

	/* Copy across discretionary ACL */

	if (secdesc_type & SEC_DESC_DACL_PRESENT) {
		dacl = new_sdb->sd->dacl;
	} else {
		dacl = old_sdb->sd->dacl;
	}

	/* Create new security descriptor from bits */

	psd = make_sec_desc(ctx, new_sdb->sd->revision, secdesc_type,
			    owner_sid, group_sid, sacl, dacl, &secdesc_size);

	return_sdb = make_sec_desc_buf(ctx, secdesc_size, psd);

	return(return_sdb);
}
Exemple #9
0
struct security_descriptor* svcctl_gen_service_sd(TALLOC_CTX *mem_ctx)
{
	struct security_descriptor *sd = NULL;
	struct security_acl *theacl = NULL;
	struct security_ace ace[4];
	size_t sd_size;
	size_t i = 0;

	/* Basic access for everyone */
	init_sec_ace(&ace[i++], &global_sid_World,
		SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_READ_ACCESS, 0);

	init_sec_ace(&ace[i++], &global_sid_Builtin_Power_Users,
			SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_EXECUTE_ACCESS, 0);

	init_sec_ace(&ace[i++], &global_sid_Builtin_Server_Operators,
		SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_ALL_ACCESS, 0);
	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
		SEC_ACE_TYPE_ACCESS_ALLOWED, SERVICE_ALL_ACCESS, 0);

	/* Create the security descriptor */
	theacl = make_sec_acl(mem_ctx,
			      NT4_ACL_REVISION,
			      i,
			      ace);
	if (theacl == NULL) {
		return NULL;
	}

	sd = make_sec_desc(mem_ctx,
			   SECURITY_DESCRIPTOR_REVISION_1,
			   SEC_DESC_SELF_RELATIVE,
			   NULL,
			   NULL,
			   NULL,
			   theacl,
			   &sd_size);
	if (sd == NULL) {
		return NULL;
	}

	return sd;
}
Exemple #10
0
static WERROR construct_registry_sd(TALLOC_CTX *ctx, struct security_descriptor **psd)
{
	struct security_ace ace[3];
	size_t i = 0;
	struct security_descriptor *sd;
	struct security_acl *theacl;
	size_t sd_size;

	/* basic access for Everyone */

	init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
		     REG_KEY_READ, 0);

	/* Full Access 'BUILTIN\Administrators' */

	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
		     SEC_ACE_TYPE_ACCESS_ALLOWED, REG_KEY_ALL, 0);

	/* Full Access 'NT Authority\System' */

	init_sec_ace(&ace[i++], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
		     REG_KEY_ALL, 0);

	/* create the security descriptor */

	theacl = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace);
	if (theacl == NULL) {
		return WERR_NOMEM;
	}

	sd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
			   &global_sid_Builtin_Administrators,
			   &global_sid_System, NULL, theacl,
			   &sd_size);
	if (sd == NULL) {
		return WERR_NOMEM;
	}

	*psd = sd;
	return WERR_OK;
}
Exemple #11
0
static SEC_DESC* parse_acl_string(TALLOC_CTX *mem_ctx, const char *szACL, size_t *sd_size )
{
	SEC_DESC *sd = NULL;
	SEC_ACE *ace;
	SEC_ACL *acl;
	int num_ace;
	const char *pacl;
	int i;
	
	if ( !szACL )
		return NULL;

	pacl = szACL;
	num_ace = count_chars( pacl, ',' ) + 1;
	
	if ( !(ace = TALLOC_ZERO_ARRAY( mem_ctx, SEC_ACE, num_ace )) ) 
		return NULL;
	
	for ( i=0; i<num_ace; i++ ) {
		char *end_acl = strchr_m( pacl, ',' );
		fstring acl_string;

		strncpy( acl_string, pacl, MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1) );
		acl_string[MIN( PTR_DIFF( end_acl, pacl ), sizeof(fstring)-1)] = '\0';
		
		if ( !parse_ace( &ace[i], acl_string ) )
			return NULL;

		pacl = end_acl;
		pacl++;
	}
	
	if ( !(acl = make_sec_acl( mem_ctx, NT4_ACL_REVISION, num_ace, ace )) )
		return NULL;
		
	sd = make_sec_desc( mem_ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, 
		NULL, NULL, NULL, acl, sd_size);

	return sd;
}
Exemple #12
0
static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob,
				uint32 security_info,
				struct security_descriptor **ppdesc)
{
	TALLOC_CTX *ctx = talloc_tos();
	struct xattr_NTACL xacl;
	enum ndr_err_code ndr_err;
	size_t sd_size;

	ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl,
			(ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL);

	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
		DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n",
			ndr_errstr(ndr_err)));
		return ndr_map_error2ntstatus(ndr_err);;
	}

	if (xacl.version != 2) {
		return NT_STATUS_REVISION_MISMATCH;
	}

	*ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_hs->sd->type | SEC_DESC_SELF_RELATIVE,
			(security_info & OWNER_SECURITY_INFORMATION)
			? xacl.info.sd_hs->sd->owner_sid : NULL,
			(security_info & GROUP_SECURITY_INFORMATION)
			? xacl.info.sd_hs->sd->group_sid : NULL,
			(security_info & SACL_SECURITY_INFORMATION)
			? xacl.info.sd_hs->sd->sacl : NULL,
			(security_info & DACL_SECURITY_INFORMATION)
			? xacl.info.sd_hs->sd->dacl : NULL,
			&sd_size);

	TALLOC_FREE(xacl.info.sd);

	return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
}
Exemple #13
0
static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx,
						SMB_STRUCT_STAT *psbuf)
{
	struct dom_sid owner_sid, group_sid;
	size_t sd_size;
	struct security_ace *pace = NULL;
	struct security_acl *pacl = NULL;

	uid_to_sid(&owner_sid, psbuf->st_uid);
	gid_to_sid(&group_sid, psbuf->st_gid);

	pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2);
	if (!pace) {
		return NULL;
	}

	init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
			SEC_RIGHTS_FILE_ALL, 0);
	init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED,
			SEC_RIGHTS_FILE_ALL, 0);

	pacl = make_sec_acl(mem_ctx,
				NT4_ACL_REVISION,
				2,
				pace);
	if (!pacl) {
		return NULL;
	}
	return make_sec_desc(mem_ctx,
			SECURITY_DESCRIPTOR_REVISION_1,
			SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
			&owner_sid,
			&group_sid,
			NULL,
                        pacl,
			&sd_size);
}
Exemple #14
0
WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
				      struct spoolss_security_descriptor **secdesc)
{
	struct security_ace ace[7];	/* max number of ace entries */
	int i = 0;
	uint32_t sa;
	struct security_acl *psa = NULL;
	struct security_descriptor *psd = NULL;
	struct dom_sid adm_sid;
	size_t sd_size;

	/* Create an ACE where Everyone is allowed to print */

	sa = PRINTER_ACE_PRINT;
	init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
		     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);

	/* Add the domain admins group if we are a DC */

	if ( IS_DC ) {
		struct dom_sid domadmins_sid;

		sid_compose(&domadmins_sid, get_global_sam_sid(),
			    DOMAIN_RID_ADMINS);

		sa = PRINTER_ACE_FULL_CONTROL;
		init_sec_ace(&ace[i++], &domadmins_sid,
			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
		init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
	}
	else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
		sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);

		sa = PRINTER_ACE_FULL_CONTROL;
		init_sec_ace(&ace[i++], &adm_sid,
			SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
			SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
		init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
			sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
	}

	/* add BUILTIN\Administrators as FULL CONTROL */

	sa = PRINTER_ACE_FULL_CONTROL;
	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
	init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
		SEC_ACE_TYPE_ACCESS_ALLOWED,
		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);

	/* add BUILTIN\Print Operators as FULL CONTROL */

	sa = PRINTER_ACE_FULL_CONTROL;
	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
		SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
		SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
	init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
		SEC_ACE_TYPE_ACCESS_ALLOWED,
		sa, SEC_ACE_FLAG_CONTAINER_INHERIT);

	/* Make the security descriptor owned by the BUILTIN\Administrators */

	/* The ACL revision number in rpc_secdesc.h differs from the one
	   created by NT when setting ACE entries in printer
	   descriptors.  NT4 complains about the property being edited by a
	   NT5 machine. */

	if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
		psd = make_sec_desc(mem_ctx,
				    SD_REVISION,
				    SEC_DESC_SELF_RELATIVE,
				    &global_sid_Builtin_Administrators,
				    &global_sid_Builtin_Administrators,
				    NULL,
				    psa,
				    &sd_size);
	}

	if (psd == NULL) {
		DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
		return WERR_NOMEM;
	}

	DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
		 (unsigned int)sd_size));

	*secdesc = psd;

	return WERR_OK;
}
Exemple #15
0
SEC_DESC_BUF *se_create_child_secdesc(TALLOC_CTX *ctx, SEC_DESC *parent_ctr, 
				      bool child_container)
{
	SEC_DESC_BUF *sdb;
	SEC_DESC *sd;
	SEC_ACL *new_dacl, *the_acl;
	SEC_ACE *new_ace_list = NULL;
	unsigned int new_ace_list_ndx = 0, i;
	size_t size;

	/* Currently we only process the dacl when creating the child.  The
	   sacl should also be processed but this is left out as sacls are
	   not implemented in Samba at the moment.*/

	the_acl = parent_ctr->dacl;

	if (the_acl->num_aces) {
		if (!(new_ace_list = TALLOC_ARRAY(ctx, SEC_ACE, the_acl->num_aces))) 
			return NULL;
	} else {
		new_ace_list = NULL;
	}

	for (i = 0; i < the_acl->num_aces; i++) {
		SEC_ACE *ace = &the_acl->aces[i];
		SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
		uint8 new_flags = 0;
		bool inherit = False;

		/* The OBJECT_INHERIT_ACE flag causes the ACE to be
		   inherited by non-container children objects.  Container
		   children objects will inherit it as an INHERIT_ONLY
		   ACE. */

		if (ace->flags & SEC_ACE_FLAG_OBJECT_INHERIT) {

			if (!child_container) {
				new_flags |= SEC_ACE_FLAG_OBJECT_INHERIT;
			} else {
				new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
			}

			inherit = True;
		}

		/* The CONAINER_INHERIT_ACE flag means all child container
		   objects will inherit and use the ACE. */

		if (ace->flags & SEC_ACE_FLAG_CONTAINER_INHERIT) {
			if (!child_container) {
				inherit = False;
			} else {
				new_flags |= SEC_ACE_FLAG_CONTAINER_INHERIT;
			}
		}

		/* The INHERIT_ONLY_ACE is not used by the se_access_check()
		   function for the parent container, but is inherited by
		   all child objects as a normal ACE. */

		if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
			/* Move along, nothing to see here */
		}

		/* The SEC_ACE_FLAG_NO_PROPAGATE_INHERIT flag means the ACE
		   is inherited by child objects but not grandchildren
		   objects.  We clear the object inherit and container
		   inherit flags in the inherited ACE. */

		if (ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
			new_flags &= ~(SEC_ACE_FLAG_OBJECT_INHERIT |
				       SEC_ACE_FLAG_CONTAINER_INHERIT);
		}

		/* Add ACE to ACE list */

		if (!inherit)
			continue;

		init_sec_access(&new_ace->access_mask, ace->access_mask);
		init_sec_ace(new_ace, &ace->trustee, ace->type,
			     new_ace->access_mask, new_flags);

		DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
			  " inherited as %s:%d/0x%02x/0x%08x\n",
			  sid_string_dbg(&ace->trustee),
			  ace->type, ace->flags, ace->access_mask,
			  sid_string_dbg(&ace->trustee),
			  new_ace->type, new_ace->flags,
			  new_ace->access_mask));

		new_ace_list_ndx++;
	}

	/* Create child security descriptor to return */
	
	new_dacl = make_sec_acl(ctx, ACL_REVISION, new_ace_list_ndx, new_ace_list);

	/* Use the existing user and group sids.  I don't think this is
	   correct.  Perhaps the user and group should be passed in as
	   parameters by the caller? */

	sd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1,
			   SEC_DESC_SELF_RELATIVE,
			   parent_ctr->owner_sid,
			   parent_ctr->group_sid,
			   parent_ctr->sacl,
			   new_dacl, &size);

	sdb = make_sec_desc_buf(ctx, size, sd);

	return sdb;
}
Exemple #16
0
BOOL parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd)
{
	size_t s_size = 0;
	const char *pacl = acl_str;
	int num_aces = 0;
	SEC_ACE *ace_list = NULL;
	SEC_ACL *psa = NULL;
	SEC_DESC *psd = NULL;
	size_t sd_size = 0;
	int i;

	*ppsd = NULL;

	/* If the acl string is blank return "Everyone:R" */
	if (!*acl_str) {
		SEC_DESC *default_psd = get_share_security_default(ctx, &s_size, GENERIC_READ_ACCESS);
		if (!default_psd) {
			return False;
		}
		*ppsd = default_psd;
		return True;
	}

	num_aces = 1;

	/* Add the number of ',' characters to get the number of aces. */
	num_aces += count_chars(pacl,',');

	ace_list = TALLOC_ARRAY(ctx, SEC_ACE, num_aces);
	if (!ace_list) {
		return False;
	}

	for (i = 0; i < num_aces; i++) {
		SEC_ACCESS sa;
		uint32 g_access;
		uint32 s_access;
		DOM_SID sid;
		fstring sidstr;
		uint8 type = SEC_ACE_TYPE_ACCESS_ALLOWED;

		if (!next_token(&pacl, sidstr, ":", sizeof(sidstr))) {
			DEBUG(0,("parse_usershare_acl: malformed usershare acl looking "
				"for ':' in string '%s'\n", pacl));
			return False;
		}

		if (!string_to_sid(&sid, sidstr)) {
			DEBUG(0,("parse_usershare_acl: failed to convert %s to sid.\n",
				sidstr ));
			return False;
		}

		switch (*pacl) {
			case 'F': /* Full Control, ie. R+W */
			case 'f': /* Full Control, ie. R+W */
				s_access = g_access = GENERIC_ALL_ACCESS;
				break;
			case 'R': /* Read only. */
			case 'r': /* Read only. */
				s_access = g_access = GENERIC_READ_ACCESS;
				break;
			case 'D': /* Deny all to this SID. */
			case 'd': /* Deny all to this SID. */
				type = SEC_ACE_TYPE_ACCESS_DENIED;
				s_access = g_access = GENERIC_ALL_ACCESS;
				break;
			default:
				DEBUG(0,("parse_usershare_acl: unknown acl type at %s.\n",
					pacl ));
				return False;
		}

		pacl++;
		if (*pacl && *pacl != ',') {
			DEBUG(0,("parse_usershare_acl: bad acl string at %s.\n",
				pacl ));
			return False;
		}
		pacl++; /* Go past any ',' */

		se_map_generic(&s_access, &file_generic_mapping);
		init_sec_access(&sa, g_access | s_access );
		init_sec_ace(&ace_list[i], &sid, type, sa, 0);
	}

	if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, num_aces, ace_list)) != NULL) {
		psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, NULL, NULL, NULL, psa, &sd_size);
	}

	if (!psd) {
		DEBUG(0,("parse_usershare_acl: Failed to make SEC_DESC.\n"));
		return False;
	}

	*ppsd = psd;
	return True;
}
Exemple #17
0
int psec_setsec(char *printer)
{
	DOM_SID user_sid, group_sid;
	SEC_ACE *ace_list = NULL;
	SEC_ACL *dacl = NULL;
	SEC_DESC *sd;
	SEC_DESC_BUF *sdb = NULL;
	int result = 0, num_aces = 0;
	fstring line, keystr, tdb_path;
	size_t size;
	prs_struct ps;
	TALLOC_CTX *mem_ctx = NULL;
	BOOL has_user_sid = False, has_group_sid = False;

	ZERO_STRUCT(ps);

	/* Open tdb for reading */

	slprintf(tdb_path, sizeof(tdb_path) - 1, "%s/ntdrivers.tdb", 
		 lp_lockdir());

	tdb = tdb_open(tdb_path, 0, 0, O_RDWR, 0600);

	if (!tdb) {
		printf("psec: failed to open nt drivers database: %s\n",
		       sys_errlist[errno]);
		result = 1;
		goto done;
	}

	/* Read owner and group sid */

	fgets(line, sizeof(fstring), stdin);
	if (line[0] != '\n') {
		string_to_sid(&user_sid, line);
		has_user_sid = True;
	}

	fgets(line, sizeof(fstring), stdin);
	if (line[0] != '\n') {
		string_to_sid(&group_sid, line);
		has_group_sid = True;
	}

	/* Read ACEs from standard input for discretionary ACL */

	while(fgets(line, sizeof(fstring), stdin)) {
		int ace_type, ace_flags;
		uint32 ace_mask;
		fstring sidstr;
		DOM_SID sid;
		SEC_ACCESS sa;

		if (sscanf(line, "%d %d 0x%x %s", &ace_type, &ace_flags, 
			   &ace_mask, sidstr) != 4) {
			continue;
		}

		string_to_sid(&sid, sidstr);
		
		ace_list = Realloc(ace_list, sizeof(SEC_ACE) * 
				   (num_aces + 1));
		
		init_sec_access(&sa, ace_mask);
		init_sec_ace(&ace_list[num_aces], &sid, ace_type, sa, 
			     ace_flags);

		num_aces++;
	}

	dacl = make_sec_acl(ACL_REVISION, num_aces, ace_list);
	free(ace_list);

	/* Create security descriptor */

	sd = make_sec_desc(SEC_DESC_REVISION,
			   has_user_sid ? &user_sid : NULL, 
			   has_group_sid ? &group_sid : NULL,
			   NULL, /* System ACL */
			   dacl, /* Discretionary ACL */
			   &size);

	free_sec_acl(&dacl);

	sdb = make_sec_desc_buf(size, sd);

	free_sec_desc(&sd);

	/* Write security descriptor to tdb */

	mem_ctx = talloc_init();

	if (!mem_ctx) {
		printf("memory allocation error\n");
		result = 1;
		goto done;
	}

	prs_init(&ps, (uint32)sec_desc_size(sdb->sec) + 
		 sizeof(SEC_DESC_BUF), 4, mem_ctx, MARSHALL);

	if (!sec_io_desc_buf("nt_printing_setsec", &sdb, &ps, 1)) {
		printf("sec_io_desc_buf failed\n");
		goto done;
	}

	slprintf(keystr, sizeof(keystr) - 1, "SECDESC/%s", printer);

	if (!tdb_prs_store(tdb, keystr, &ps)==0) {
		printf("Failed to store secdesc for %s\n", printer);
		goto done;
	}

 done:
	if (tdb) tdb_close(tdb);
	if (sdb) free_sec_desc_buf(&sdb);
	if (mem_ctx) talloc_destroy(mem_ctx);
	prs_mem_free(&ps);

	return result;
}
Exemple #18
0
static WERROR gp_reg_generate_sd(TALLOC_CTX *mem_ctx,
				 const struct dom_sid *sid,
				 struct security_descriptor **sd,
				 size_t *sd_size)
{
	struct security_ace ace[6];
	uint32_t mask;

	struct security_acl *theacl = NULL;

	uint8_t inherit_flags;

	mask = REG_KEY_ALL;
	init_sec_ace(&ace[0],
		     &global_sid_System,
		     SEC_ACE_TYPE_ACCESS_ALLOWED,
		     mask, 0);

	mask = REG_KEY_ALL;
	init_sec_ace(&ace[1],
		     &global_sid_Builtin_Administrators,
		     SEC_ACE_TYPE_ACCESS_ALLOWED,
		     mask, 0);

	mask = REG_KEY_READ;
	init_sec_ace(&ace[2],
		     sid ? sid : &global_sid_Authenticated_Users,
		     SEC_ACE_TYPE_ACCESS_ALLOWED,
		     mask, 0);

	inherit_flags = SEC_ACE_FLAG_OBJECT_INHERIT |
			SEC_ACE_FLAG_CONTAINER_INHERIT |
			SEC_ACE_FLAG_INHERIT_ONLY;

	mask = REG_KEY_ALL;
	init_sec_ace(&ace[3],
		     &global_sid_System,
		     SEC_ACE_TYPE_ACCESS_ALLOWED,
		     mask, inherit_flags);

	mask = REG_KEY_ALL;
	init_sec_ace(&ace[4],
		     &global_sid_Builtin_Administrators,
		     SEC_ACE_TYPE_ACCESS_ALLOWED,
		     mask, inherit_flags);

	mask = REG_KEY_READ;
	init_sec_ace(&ace[5],
		     sid ? sid : &global_sid_Authenticated_Users,
		     SEC_ACE_TYPE_ACCESS_ALLOWED,
		     mask, inherit_flags);

	theacl = make_sec_acl(mem_ctx, NT4_ACL_REVISION, 6, ace);
	W_ERROR_HAVE_NO_MEMORY(theacl);

	*sd = make_sec_desc(mem_ctx, SD_REVISION,
			    SEC_DESC_SELF_RELATIVE |
			    SEC_DESC_DACL_AUTO_INHERITED | /* really ? */
			    SEC_DESC_DACL_AUTO_INHERIT_REQ, /* really ? */
			    NULL, NULL, NULL,
			    theacl, sd_size);
	W_ERROR_HAVE_NO_MEMORY(*sd);

	return WERR_OK;
}
Exemple #19
0
NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx,
					SEC_DESC **ppsd,
					size_t *psize,
					const SEC_DESC *parent_ctr,
					const DOM_SID *owner_sid,
					const DOM_SID *group_sid,
					bool container)
{
	SEC_ACL *new_dacl = NULL, *the_acl = NULL;
	SEC_ACE *new_ace_list = NULL;
	unsigned int new_ace_list_ndx = 0, i;

	*ppsd = NULL;
	*psize = 0;

	/* Currently we only process the dacl when creating the child.  The
	   sacl should also be processed but this is left out as sacls are
	   not implemented in Samba at the moment.*/

	the_acl = parent_ctr->dacl;

	if (the_acl->num_aces) {
		if (2*the_acl->num_aces < the_acl->num_aces) {
			return NT_STATUS_NO_MEMORY;
		}

		if (!(new_ace_list = TALLOC_ARRAY(ctx, SEC_ACE,
						2*the_acl->num_aces))) {
			return NT_STATUS_NO_MEMORY;
		}
	} else {
		new_ace_list = NULL;
	}

	for (i = 0; i < the_acl->num_aces; i++) {
		const SEC_ACE *ace = &the_acl->aces[i];
		SEC_ACE *new_ace = &new_ace_list[new_ace_list_ndx];
		const DOM_SID *ptrustee = &ace->trustee;
		const DOM_SID *creator = NULL;
		uint8 new_flags = ace->flags;

		if (!is_inheritable_ace(ace, container)) {
			continue;
		}

		/* see the RAW-ACLS inheritance test for details on these rules */
		if (!container) {
			new_flags = 0;
		} else {
			new_flags &= ~SEC_ACE_FLAG_INHERIT_ONLY;

			if (!(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {
				new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
			}
			if (new_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT) {
				new_flags = 0;
			}
		}

		/* The CREATOR sids are special when inherited */
		if (sid_equal(ptrustee, &global_sid_Creator_Owner)) {
			creator = &global_sid_Creator_Owner;
			ptrustee = owner_sid;
		} else if (sid_equal(ptrustee, &global_sid_Creator_Group)) {
			creator = &global_sid_Creator_Group;
			ptrustee = group_sid;
		}

		if (creator && container &&
				(new_flags & SEC_ACE_FLAG_CONTAINER_INHERIT)) {

			/* First add the regular ACE entry. */
			init_sec_ace(new_ace, ptrustee, ace->type,
			     	ace->access_mask, 0);

			DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x"
				" inherited as %s:%d/0x%02x/0x%08x\n",
				sid_string_dbg(&ace->trustee),
				ace->type, ace->flags, ace->access_mask,
				sid_string_dbg(&new_ace->trustee),
				new_ace->type, new_ace->flags,
				new_ace->access_mask));

			new_ace_list_ndx++;

			/* Now add the extra creator ACE. */
			new_ace = &new_ace_list[new_ace_list_ndx];

			ptrustee = creator;
			new_flags |= SEC_ACE_FLAG_INHERIT_ONLY;
		} else if (container &&
				!(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) {
			ptrustee = &ace->trustee;
		}

		init_sec_ace(new_ace, ptrustee, ace->type,
			     ace->access_mask, new_flags);

		DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x "
			  " inherited as %s:%d/0x%02x/0x%08x\n",
			  sid_string_dbg(&ace->trustee),
			  ace->type, ace->flags, ace->access_mask,
			  sid_string_dbg(&ace->trustee),
			  new_ace->type, new_ace->flags,
			  new_ace->access_mask));

		new_ace_list_ndx++;
	}

	/* Create child security descriptor to return */
	if (new_ace_list_ndx) {
		new_dacl = make_sec_acl(ctx,
				NT4_ACL_REVISION,
				new_ace_list_ndx,
				new_ace_list);

		if (!new_dacl) {
			return NT_STATUS_NO_MEMORY;
		}
	}

	*ppsd = make_sec_desc(ctx,
			SECURITY_DESCRIPTOR_REVISION_1,
			SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT,
			owner_sid,
			group_sid,
			NULL,
			new_dacl,
			psize);
	if (!*ppsd) {
		return NT_STATUS_NO_MEMORY;
	}
	return NT_STATUS_OK;
}
Exemple #20
0
static size_t afs_to_nt_acl_common(struct afs_acl *afs_acl,
				   SMB_STRUCT_STAT *psbuf,
				   uint32 security_info,
				   struct security_descriptor **ppdesc)
{
	SEC_ACE *nt_ace_list;
	DOM_SID owner_sid, group_sid;
	SEC_ACL *psa = NULL;
	int good_aces;
	size_t sd_size;
	TALLOC_CTX *mem_ctx = talloc_tos();

	struct afs_ace *afs_ace;

	uid_to_sid(&owner_sid, psbuf->st_uid);
	gid_to_sid(&group_sid, psbuf->st_gid);

	if (afs_acl->num_aces) {
		nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces);

		if (nt_ace_list == NULL)
			return 0;
	} else {
		nt_ace_list = NULL;
	}

	afs_ace = afs_acl->acelist;
	good_aces = 0;

	while (afs_ace != NULL) {
		uint32_t nt_rights;
		uint8 flag = SEC_ACE_FLAG_OBJECT_INHERIT |
			SEC_ACE_FLAG_CONTAINER_INHERIT;

		if (afs_ace->type == SID_NAME_UNKNOWN) {
			DEBUG(10, ("Ignoring unknown name %s\n",
				   afs_ace->name));
			afs_ace = afs_ace->next;
			continue;
		}

		if (S_ISDIR(psbuf->st_mode))
			afs_to_nt_dir_rights(afs_ace->rights, &nt_rights,
					     &flag);
		else
			nt_rights = afs_to_nt_file_rights(afs_ace->rights);

		init_sec_ace(&nt_ace_list[good_aces++], &(afs_ace->sid),
			     SEC_ACE_TYPE_ACCESS_ALLOWED, nt_rights, flag);
		afs_ace = afs_ace->next;
	}

	psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION,
			   good_aces, nt_ace_list);
	if (psa == NULL)
		return 0;

	*ppdesc = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
				SEC_DESC_SELF_RELATIVE,
				(security_info & OWNER_SECURITY_INFORMATION)
				? &owner_sid : NULL,
				(security_info & GROUP_SECURITY_INFORMATION)
				? &group_sid : NULL,
				NULL, psa, &sd_size);

	return sd_size;
}
Exemple #21
0
static size_t afs_to_nt_acl(struct afs_acl *afs_acl, 
			    struct files_struct *fsp,
			    uint32 security_info,
			    struct security_descriptor **ppdesc)
{
	SEC_ACE *nt_ace_list;
	DOM_SID owner_sid, group_sid;
	SEC_ACCESS mask;
	SMB_STRUCT_STAT sbuf;
	SEC_ACL *psa = NULL;
	int good_aces;
	size_t sd_size;
	TALLOC_CTX *mem_ctx = main_loop_talloc_get();

	struct afs_ace *afs_ace;

	if (fsp->is_directory || fsp->fh->fd == -1) {
		/* Get the stat struct for the owner info. */
		if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) {
			return 0;
		}
	} else {
		if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) {
			return 0;
		}
	}

	uid_to_sid(&owner_sid, sbuf.st_uid);
	gid_to_sid(&group_sid, sbuf.st_gid);

	if (afs_acl->num_aces) {
		nt_ace_list = TALLOC_ARRAY(mem_ctx, SEC_ACE, afs_acl->num_aces);

		if (nt_ace_list == NULL)
			return 0;
	} else {
		nt_ace_list = NULL;
	}

	afs_ace = afs_acl->acelist;
	good_aces = 0;

	while (afs_ace != NULL) {
		uint32 nt_rights;
		uint8 flag = SEC_ACE_FLAG_OBJECT_INHERIT |
			SEC_ACE_FLAG_CONTAINER_INHERIT;

		if (afs_ace->type == SID_NAME_UNKNOWN) {
			DEBUG(10, ("Ignoring unknown name %s\n",
				   afs_ace->name));
			afs_ace = afs_ace->next;
			continue;
		}

		if (fsp->is_directory)
			afs_to_nt_dir_rights(afs_ace->rights, &nt_rights,
					     &flag);
		else
			nt_rights = afs_to_nt_file_rights(afs_ace->rights);

		init_sec_access(&mask, nt_rights);
		init_sec_ace(&nt_ace_list[good_aces++], &(afs_ace->sid),
			     SEC_ACE_TYPE_ACCESS_ALLOWED, mask, flag);
		afs_ace = afs_ace->next;
	}

	psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION,
			   good_aces, nt_ace_list);
	if (psa == NULL)
		return 0;

	
	*ppdesc = make_sec_desc(mem_ctx, SEC_DESC_REVISION,
				SEC_DESC_SELF_RELATIVE,
				(security_info & OWNER_SECURITY_INFORMATION)
				? &owner_sid : NULL,
				(security_info & GROUP_SECURITY_INFORMATION)
				? &group_sid : NULL,
				NULL, psa, &sd_size);

	return sd_size;
}