Example #1
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;
}
Example #2
0
bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
			  const struct nt_user_token *token )
{
	SEC_DESC *sec_desc;
	NTSTATUS status;
	WERROR err;

	/* use the default security check if the backend has not defined its
	 * own */

	if (key->ops && key->ops->reg_access_check) {
		return key->ops->reg_access_check(key->name, requested,
						  granted, token);
	}

	err = regkey_get_secdesc(talloc_tos(), key, &sec_desc);

	if (!W_ERROR_IS_OK(err)) {
		return false;
	}

	se_map_generic( &requested, &reg_generic_map );

	status =se_access_check(sec_desc, token, requested, granted);
	TALLOC_FREE(sec_desc);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}

	return NT_STATUS_IS_OK(status);
}
void security_acl_map_generic(struct security_acl *sa,
				const struct generic_mapping *mapping)
{
	unsigned int i;

	if (!sa) {
		return;
	}

	for (i = 0; i < sa->num_aces; i++) {
		se_map_generic(&sa->aces[i].access_mask, mapping);
	}
}
bool regkey_access_check( REGISTRY_KEY *key, uint32 requested, uint32 *granted,
			  const struct nt_user_token *token )
{
	SEC_DESC *sec_desc;
	NTSTATUS status;
	WERROR err;
	TALLOC_CTX *mem_ctx;

	/* use the default security check if the backend has not defined its
	 * own */

	if (key->ops && key->ops->reg_access_check) {
		return key->ops->reg_access_check(key->name, requested,
						  granted, token);
	}

	/*
	 * The secdesc routines can't yet cope with a NULL talloc ctx sanely.
	 */

	if (!(mem_ctx = talloc_init("regkey_access_check"))) {
		return false;
	}

	err = regkey_get_secdesc(mem_ctx, key, &sec_desc);

	if (!W_ERROR_IS_OK(err)) {
		TALLOC_FREE(mem_ctx);
		return false;
	}

	se_map_generic( &requested, &reg_generic_map );

	status =se_access_check(sec_desc, token, requested, granted);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(mem_ctx);
		return false;
	}

	TALLOC_FREE(mem_ctx);
	return NT_STATUS_IS_OK(status);
}
Example #5
0
bool regkey_access_check(struct registry_key_handle *key, uint32 requested,
			 uint32 *granted,
			 const struct security_token *token )
{
	struct security_descriptor *sec_desc;
	NTSTATUS status;
	WERROR err;

	/* root free-pass, like we have on all other pipes like samr, lsa, etc. */
	if (geteuid() == sec_initial_uid()) {
		*granted = REG_KEY_ALL;
		return true;
	}

	/* use the default security check if the backend has not defined its
	 * own */

	if (key->ops && key->ops->reg_access_check) {
		return key->ops->reg_access_check(key->name, requested,
						  granted, token);
	}

	err = regkey_get_secdesc(talloc_tos(), key, &sec_desc);

	if (!W_ERROR_IS_OK(err)) {
		return false;
	}

	se_map_generic( &requested, &reg_generic_map );

	status =se_access_check(sec_desc, token, requested, granted);
	TALLOC_FREE(sec_desc);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}

	return NT_STATUS_IS_OK(status);
}
Example #6
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;
}
Example #7
0
static bool smbacl4_fill_ace4(
    const struct smb_filename *filename,
    smbacl4_vfs_params *params,
    uid_t ownerUID,
    gid_t ownerGID,
    const struct security_ace *ace_nt, /* input */
    SMB_ACE4PROP_T *ace_v4 /* output */
)
{
    DEBUG(10, ("got ace for %s\n", sid_string_dbg(&ace_nt->trustee)));

    memset(ace_v4, 0, sizeof(SMB_ACE4PROP_T));

    /* only ACCESS|DENY supported right now */
    ace_v4->aceType = ace_nt->type;

    ace_v4->aceFlags = map_windows_ace_flags_to_nfs4_ace_flags(
                           ace_nt->flags);

    /* remove inheritance flags on files */
    if (VALID_STAT(filename->st) &&
            !S_ISDIR(filename->st.st_ex_mode)) {
        DEBUG(10, ("Removing inheritance flags from a file\n"));
        ace_v4->aceFlags &= ~(SMB_ACE4_FILE_INHERIT_ACE|
                              SMB_ACE4_DIRECTORY_INHERIT_ACE|
                              SMB_ACE4_NO_PROPAGATE_INHERIT_ACE|
                              SMB_ACE4_INHERIT_ONLY_ACE);
    }

    ace_v4->aceMask = ace_nt->access_mask &
                      (SEC_STD_ALL | SEC_FILE_ALL);

    se_map_generic(&ace_v4->aceMask, &file_generic_mapping);

    if (ace_v4->aceFlags!=ace_nt->flags)
        DEBUG(9, ("ace_v4->aceFlags(0x%x)!=ace_nt->flags(0x%x)\n",
                  ace_v4->aceFlags, ace_nt->flags));

    if (ace_v4->aceMask!=ace_nt->access_mask)
        DEBUG(9, ("ace_v4->aceMask(0x%x)!=ace_nt->access_mask(0x%x)\n",
                  ace_v4->aceMask, ace_nt->access_mask));

    if (dom_sid_equal(&ace_nt->trustee, &global_sid_World)) {
        ace_v4->who.special_id = SMB_ACE4_WHO_EVERYONE;
        ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
    } else if (params->mode!=e_special &&
               dom_sid_equal(&ace_nt->trustee,
                             &global_sid_Creator_Owner)) {
        DEBUG(10, ("Map creator owner\n"));
        ace_v4->who.special_id = SMB_ACE4_WHO_OWNER;
        ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
        /* A non inheriting creator owner entry has no effect. */
        ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE;
        if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)
                && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) {
            return false;
        }
    } else if (params->mode!=e_special &&
               dom_sid_equal(&ace_nt->trustee,
                             &global_sid_Creator_Group)) {
        DEBUG(10, ("Map creator owner group\n"));
        ace_v4->who.special_id = SMB_ACE4_WHO_GROUP;
        ace_v4->flags |= SMB_ACE4_ID_SPECIAL;
        /* A non inheriting creator group entry has no effect. */
        ace_v4->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE;
        if (!(ace_v4->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)
                && !(ace_v4->aceFlags & SMB_ACE4_FILE_INHERIT_ACE)) {
            return false;
        }
    } else {
        uid_t uid;
        gid_t gid;

        if (sid_to_gid(&ace_nt->trustee, &gid)) {
            ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
            ace_v4->who.gid = gid;
        } else if (sid_to_uid(&ace_nt->trustee, &uid)) {
            ace_v4->who.uid = uid;
        } else {
            DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
                      "convert %s to uid or gid\n",
                      filename->base_name,
                      sid_string_dbg(&ace_nt->trustee)));
            return false;
        }
    }

    return true; /* OK */
}
Example #8
0
NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call,
				     TALLOC_CTX *mem_ctx,
				     uint32_t access_desired,
				     struct lsa_policy_state **_state)
{
	struct auth_session_info *session_info = dce_call->conn->auth_state.session_info;
	enum security_user_level security_level;
	struct lsa_policy_state *state;
	struct ldb_result *dom_res;
	const char *dom_attrs[] = {
		"objectSid", 
		"objectGUID", 
		"nTMixedDomain",
		"fSMORoleOwner",
		NULL
	};
	char *p;
	int ret;

	state = talloc_zero(mem_ctx, struct lsa_policy_state);
	if (!state) {
		return NT_STATUS_NO_MEMORY;
	}

	/* make sure the sam database is accessible */
	state->sam_ldb = samdb_connect(state,
				       dce_call->event_ctx,
				       dce_call->conn->dce_ctx->lp_ctx,
				       dce_call->conn->auth_state.session_info,
				       dce_call->conn->remote_address,
				       0);
	if (state->sam_ldb == NULL) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	/* and the privilege database */
	state->pdb = privilege_connect(state, dce_call->conn->dce_ctx->lp_ctx);
	if (state->pdb == NULL) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}

	/* work out the domain_dn - useful for so many calls its worth
	   fetching here */
	state->domain_dn = ldb_get_default_basedn(state->sam_ldb);
	if (!state->domain_dn) {
		return NT_STATUS_NO_MEMORY;		
	}

	/* work out the forest root_dn - useful for so many calls its worth
	   fetching here */
	state->forest_dn = ldb_get_root_basedn(state->sam_ldb);
	if (!state->forest_dn) {
		return NT_STATUS_NO_MEMORY;		
	}

	ret = ldb_search(state->sam_ldb, mem_ctx, &dom_res,
			 state->domain_dn, LDB_SCOPE_BASE, dom_attrs, NULL);
	if (ret != LDB_SUCCESS) {
		return NT_STATUS_INVALID_SYSTEM_SERVICE;
	}
	if (dom_res->count != 1) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->domain_sid = samdb_result_dom_sid(state, dom_res->msgs[0], "objectSid");
	if (!state->domain_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->domain_guid = samdb_result_guid(dom_res->msgs[0], "objectGUID");

	state->mixed_domain = ldb_msg_find_attr_as_uint(dom_res->msgs[0], "nTMixedDomain", 0);
	
	talloc_free(dom_res);

	state->domain_name = lpcfg_sam_name(dce_call->conn->dce_ctx->lp_ctx);

	state->domain_dns = ldb_dn_canonical_string(state, state->domain_dn);
	if (!state->domain_dns) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}
	p = strchr(state->domain_dns, '/');
	if (p) {
		*p = '\0';
	}

	state->forest_dns = ldb_dn_canonical_string(state, state->forest_dn);
	if (!state->forest_dns) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}
	p = strchr(state->forest_dns, '/');
	if (p) {
		*p = '\0';
	}

	/* work out the builtin_dn - useful for so many calls its worth
	   fetching here */
	state->builtin_dn = samdb_search_dn(state->sam_ldb, state, state->domain_dn, "(objectClass=builtinDomain)");
	if (!state->builtin_dn) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	/* work out the system_dn - useful for so many calls its worth
	   fetching here */
	state->system_dn = samdb_search_dn(state->sam_ldb, state,
					   state->domain_dn, "(&(objectClass=container)(cn=System))");
	if (!state->system_dn) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->builtin_sid = dom_sid_parse_talloc(state, SID_BUILTIN);
	if (!state->builtin_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->nt_authority_sid = dom_sid_parse_talloc(state, SID_NT_AUTHORITY);
	if (!state->nt_authority_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->creator_owner_domain_sid = dom_sid_parse_talloc(state, SID_CREATOR_OWNER_DOMAIN);
	if (!state->creator_owner_domain_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->world_domain_sid = dom_sid_parse_talloc(state, SID_WORLD_DOMAIN);
	if (!state->world_domain_sid) {
		return NT_STATUS_NO_SUCH_DOMAIN;		
	}

	state->sd = sddl_decode(state, DCESRV_LSA_POLICY_SD_SDDL,
				state->domain_sid);
	if (state->sd == NULL) {
		return NT_STATUS_NO_MEMORY;
	}
	state->sd->dacl->revision = SECURITY_ACL_REVISION_NT4;

	se_map_generic(&access_desired, &dcesrv_lsa_policy_mapping);
	security_acl_map_generic(state->sd->dacl, &dcesrv_lsa_policy_mapping);

	security_level = security_session_user_level(session_info, NULL);
	if (security_level >= SECURITY_SYSTEM) {
		/*
		 * The security descriptor doesn't allow system,
		 * but we want to allow system via ncalrpc as root.
		 */
		state->access_mask = access_desired;
		if (state->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
			state->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
			state->access_mask |= LSA_POLICY_ALL_ACCESS;
		}
	} else {
		NTSTATUS status;

		status = se_access_check(state->sd,
					 session_info->security_token,
					 access_desired,
					 &state->access_mask);
		if (!NT_STATUS_IS_OK(status)) {
			DEBUG(2,("%s: access desired[0x%08X] rejected[0x%08X] - %s\n",
				 __func__,
				 (unsigned)access_desired,
				 (unsigned)state->access_mask,
				 nt_errstr(status)));
			return status;
		}
	}

	DEBUG(10,("%s: access desired[0x%08X] granted[0x%08X] - success.\n",
		  __func__,
		 (unsigned)access_desired,
		 (unsigned)state->access_mask));

	*_state = state;

	return NT_STATUS_OK;
}