Beispiel #1
0
SEC_DESC_BUF *dup_sec_desc_buf(TALLOC_CTX *ctx, SEC_DESC_BUF *src)
{
	if(src == NULL)
		return NULL;

	return make_sec_desc_buf( ctx, src->sd_size, src->sd);
}
Beispiel #2
0
NTSTATUS se_create_child_secdesc_buf(TALLOC_CTX *ctx,
					SEC_DESC_BUF **ppsdb,
					const SEC_DESC *parent_ctr,
					bool container)
{
	NTSTATUS status;
	size_t size = 0;
	SEC_DESC *sd = NULL;

	*ppsdb = NULL;
	status = se_create_child_secdesc(ctx,
					&sd,
					&size,
					parent_ctr,
					parent_ctr->owner_sid,
					parent_ctr->group_sid,
					container);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	*ppsdb = make_sec_desc_buf(ctx, size, sd);
	if (!*ppsdb) {
		return NT_STATUS_NO_MEMORY;
	}
	return NT_STATUS_OK;
}
Beispiel #3
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);
}
Beispiel #4
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;
}
Beispiel #5
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;
}