Beispiel #1
0
static int sys_acl_set_file_tdb(vfs_handle_struct *handle,
                                const char *path,
                                SMB_ACL_TYPE_T type,
                                SMB_ACL_T theacl)
{
    SMB_STRUCT_STAT sbuf;
    struct db_context *db;
    int ret = -1;

    SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);

    if (lp_posix_pathnames()) {
        ret = vfs_lstat_smb_fname(handle->conn, path, &sbuf);
    } else {
        ret = vfs_stat_smb_fname(handle->conn, path, &sbuf);
    }

    if (ret == -1) {
        return -1;
    }

    ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle,
                                        path,
                                        type,
                                        theacl);
    if (ret == -1) {
        return -1;
    }

    acl_tdb_delete(handle, db, &sbuf);
    return 0;
}
Beispiel #2
0
static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path)
{

    SMB_STRUCT_STAT sbuf;
    struct db_context *db = acl_db;
    int ret = -1;

    if (lp_posix_pathnames()) {
        ret = vfs_lstat_smb_fname(handle->conn, path, &sbuf);
    } else {
        ret = vfs_stat_smb_fname(handle->conn, path, &sbuf);
    }

    if (ret == -1) {
        return -1;
    }

    ret = rmdir_acl_common(handle, path);
    if (ret == -1) {
        return -1;
    }

    acl_tdb_delete(handle, db, &sbuf);
    return 0;
}
Beispiel #3
0
static int rmdir_acl_tdb(vfs_handle_struct *handle, const char *path)
{

    SMB_STRUCT_STAT sbuf;
    struct db_context *db;
    int ret = -1;

    SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1);

    if (lp_posix_pathnames()) {
        ret = vfs_lstat_smb_fname(handle->conn, path, &sbuf);
    } else {
        ret = vfs_stat_smb_fname(handle->conn, path, &sbuf);
    }

    if (ret == -1) {
        return -1;
    }

    ret = SMB_VFS_NEXT_RMDIR(handle, path);
    if (ret == -1) {
        return -1;
    }

    acl_tdb_delete(handle, db, &sbuf);
    return 0;
}
Beispiel #4
0
static NTSTATUS get_acl_blob(TALLOC_CTX *ctx,
                             vfs_handle_struct *handle,
                             files_struct *fsp,
                             const char *name,
                             DATA_BLOB *pblob)
{
    uint8 id_buf[16];
    TDB_DATA data;
    struct file_id id;
    struct db_context *db;
    NTSTATUS status;
    SMB_STRUCT_STAT sbuf;

    SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context,
                            return NT_STATUS_INTERNAL_DB_CORRUPTION);

    ZERO_STRUCT(sbuf);

    if (fsp) {
        status = vfs_stat_fsp(fsp);
        sbuf = fsp->fsp_name->st;
    } else {
        int ret = vfs_stat_smb_fname(handle->conn, name, &sbuf);
        if (ret == -1) {
            status = map_nt_error_from_unix(errno);
        }
    }

    if (!NT_STATUS_IS_OK(status)) {
        return status;
    }

    id = vfs_file_id_from_sbuf(handle->conn, &sbuf);

    /* For backwards compatibility only store the dev/inode. */
    push_file_id_16((char *)id_buf, &id);

    if (db->fetch(db,
                  ctx,
                  make_tdb_data(id_buf, sizeof(id_buf)),
                  &data) == -1) {
        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    }

    pblob->data = data.dptr;
    pblob->length = data.dsize;

    DEBUG(10,("get_acl_blob: returned %u bytes from file %s\n",
              (unsigned int)data.dsize, name ));

    if (pblob->length == 0 || pblob->data == NULL) {
        return NT_STATUS_NOT_FOUND;
    }
    return NT_STATUS_OK;
}
Beispiel #5
0
static bool recycle_directory_exist(vfs_handle_struct *handle, const char *dname)
{
	SMB_STRUCT_STAT st;

	if (vfs_stat_smb_fname(handle->conn, dname, &st) == 0) {
		if (S_ISDIR(st.st_ex_mode)) {
			return True;
		}
	}

	return False;
}
Beispiel #6
0
static int smbacl4_GetFileOwner(struct connection_struct *conn,
                                const char *filename,
                                SMB_STRUCT_STAT *psbuf)
{
    memset(psbuf, 0, sizeof(SMB_STRUCT_STAT));

    /* Get the stat struct for the owner info. */
    if (vfs_stat_smb_fname(conn, filename, psbuf) != 0)
    {
        DEBUG(8, ("vfs_stat_smb_fname failed with error %s\n",
                  strerror(errno)));
        return -1;
    }

    return 0;
}
Beispiel #7
0
static int mkdir_acl_common(vfs_handle_struct *handle, const char *path, mode_t mode)
{
	int ret;
	NTSTATUS status;
	SMB_STRUCT_STAT sbuf;

	ret = vfs_stat_smb_fname(handle->conn, path, &sbuf);
	if (ret == -1 && errno == ENOENT) {
		struct security_descriptor *parent_desc = NULL;
		struct security_descriptor *psd = NULL;

		/* We're creating a new directory. */
		status = check_parent_acl_common(handle, path,
				SEC_DIR_ADD_SUBDIR, &parent_desc);
		if (!NT_STATUS_IS_OK(status)) {
			errno = map_errno_from_nt_status(status);
			return -1;
		}

		/* Cache the parent security descriptor for
		 * later use. We don't have an fsp here so
		 * use the handle. */

		/* Attach this to the conn, move from talloc_tos(). */
		psd = (struct security_descriptor *)talloc_move(handle->conn,
				&parent_desc);

		if (!psd) {
			return -1;
		}
		SMB_VFS_HANDLE_SET_DATA(handle, psd, free_sd_common,
			struct security_descriptor *, return -1);
	}

	return SMB_VFS_NEXT_MKDIR(handle, path, mode);
}
Beispiel #8
0
int solarisacl_sys_acl_set_file(vfs_handle_struct *handle,
				const char *name,
				SMB_ACL_TYPE_T type,
				SMB_ACL_T theacl)
{
	int ret = -1;
	struct stat_ex s;
	SOLARIS_ACL_T solaris_acl = NULL;
	int count;
	
	DEBUG(10, ("solarisacl_sys_acl_set_file called for file '%s'\n",
		   name));

	if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT)) {
		errno = EINVAL;
		DEBUG(10, ("invalid smb acl type given (%d).\n", type));
		goto done;
	}
	DEBUGADD(10, ("setting %s acl\n", 
		      ((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));

	if(!smb_acl_to_solaris_acl(theacl, &solaris_acl, &count, type)) {
		DEBUG(10, ("conversion smb_acl -> solaris_acl failed (%s).\n",
			   strerror(errno)));
                goto done;
	}

	/*
	 * if the file is a directory, there is extra work to do:
	 * since the solaris acl call stores both the access acl and 
	 * the default acl as provided, we have to get the acl part 
	 * that has not been specified in "type" from the file first 
	 * and concatenate it with the acl provided.
	 */
	if (vfs_stat_smb_fname(handle->conn, name, &s) != 0) {
		DEBUG(10, ("Error in stat call: %s\n", strerror(errno)));
		goto done;
	}
	if (S_ISDIR(s.st_ex_mode)) {
		SOLARIS_ACL_T other_acl; 
		int other_count;
		SMB_ACL_TYPE_T other_type;

		other_type = (type == SMB_ACL_TYPE_ACCESS) 
			? SMB_ACL_TYPE_DEFAULT
			: SMB_ACL_TYPE_ACCESS;
		DEBUGADD(10, ("getting acl from filesystem\n"));
		if (!solaris_acl_get_file(name, &other_acl, &other_count)) {
			DEBUG(10, ("error getting acl from directory\n"));
			goto done;
		}
		DEBUG(10, ("adding %s part of fs acl to given acl\n",
			   ((other_type == SMB_ACL_TYPE_ACCESS) 
			    ? "access"
			    : "default")));
		if (!solaris_add_to_acl(&solaris_acl, &count, other_acl,
					other_count, other_type)) 
		{
			DEBUG(10, ("error adding other acl.\n"));
			SAFE_FREE(other_acl);
			goto done;
		}
		SAFE_FREE(other_acl);
	}
	else if (type != SMB_ACL_TYPE_ACCESS) {
		errno = EINVAL;
		goto done;
	}

	if (!solaris_acl_sort(solaris_acl, count)) {
		DEBUG(10, ("resulting acl is not valid!\n"));
		goto done;
	}

	ret = acl(name, SETACL, count, solaris_acl);
	
 done:
	DEBUG(10, ("solarisacl_sys_acl_set_file %s.\n",
		   ((ret != 0) ? "failed" : "succeeded")));
	SAFE_FREE(solaris_acl);
	return ret;
}
Beispiel #9
0
static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
				files_struct *fsp,
				const char *name,
			        uint32_t security_info,
				struct security_descriptor **ppdesc)
{
	DATA_BLOB blob;
	NTSTATUS status;
	uint16_t hash_type;
	uint8_t hash[XATTR_SD_HASH_SIZE];
	uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
	struct security_descriptor *psd = NULL;
	struct security_descriptor *pdesc_next = NULL;

	if (fsp && name == NULL) {
		name = fsp->fsp_name->base_name;
	}

	DEBUG(10, ("get_nt_acl_internal: name=%s\n", name));

	/* Get the full underlying sd for the hash
	   or to return as backup. */
	if (fsp) {
		status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
				fsp,
				HASH_SECURITY_INFO,
				&pdesc_next);
	} else {
		status = SMB_VFS_NEXT_GET_NT_ACL(handle,
				name,
				HASH_SECURITY_INFO,
				&pdesc_next);
	}

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("get_nt_acl_internal: get_next_acl for file %s "
			"returned %s\n",
			name,
			nt_errstr(status)));
		return status;
	}

	status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("get_nt_acl_internal: get_acl_blob returned %s\n",
			nt_errstr(status)));
		psd = pdesc_next;
		goto out;
	}

	status = parse_acl_blob(&blob, &psd,
				&hash_type, &hash[0]);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("parse_acl_blob returned %s\n",
				nt_errstr(status)));
		psd = pdesc_next;
		goto out;
	}

	/* Ensure the hash type is one we know. */
	switch (hash_type) {
		case XATTR_SD_HASH_TYPE_NONE:
			/* No hash, just return blob sd. */
			goto out;
		case XATTR_SD_HASH_TYPE_SHA256:
			break;
		default:
			DEBUG(10, ("get_nt_acl_internal: ACL blob revision "
				"mismatch (%u) for file %s\n",
				(unsigned int)hash_type,
				name));
			TALLOC_FREE(psd);
			psd = pdesc_next;
			goto out;
	}


	status = hash_sd_sha256(pdesc_next, hash_tmp);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(psd);
		psd = pdesc_next;
		goto out;
	}

	if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
		/* Hash matches, return blob sd. */
		goto out;
	}

	/* Hash doesn't match, return underlying sd. */
	TALLOC_FREE(psd);
	psd = pdesc_next;

  out:

	if (psd != pdesc_next) {
		/* We're returning the blob, throw
 		 * away the filesystem SD. */
		TALLOC_FREE(pdesc_next);
	} else {
		SMB_STRUCT_STAT sbuf;
		SMB_STRUCT_STAT *psbuf = &sbuf;
		bool is_directory = false;
		/*
		 * We're returning the underlying ACL from the
		 * filesystem. If it's a directory, and has no
		 * inheritable ACE entries we have to fake them.
		 */
		if (fsp) {
			is_directory = fsp->is_directory;
			psbuf = &fsp->fsp_name->st;
		} else {
			if (vfs_stat_smb_fname(handle->conn,
						name,
						&sbuf) == 0) {
				is_directory = S_ISDIR(sbuf.st_ex_mode);
			}
		}
		if (is_directory &&
				!sd_has_inheritable_components(psd,
							true)) {
			add_directory_inheritable_components(handle,
							name,
							psbuf,
							psd);
		}
	}

	if (!(security_info & OWNER_SECURITY_INFORMATION)) {
		psd->owner_sid = NULL;
	}
	if (!(security_info & GROUP_SECURITY_INFORMATION)) {
		psd->group_sid = NULL;
	}
	if (!(security_info & DACL_SECURITY_INFORMATION)) {
		psd->dacl = NULL;
	}
	if (!(security_info & SACL_SECURITY_INFORMATION)) {
		psd->sacl = NULL;
	}

	TALLOC_FREE(blob.data);
	*ppdesc = psd;
	return NT_STATUS_OK;
}
Beispiel #10
0
static NTSTATUS get_nt_acl_internal(vfs_handle_struct *handle,
				files_struct *fsp,
				const char *name,
			        uint32_t security_info,
				struct security_descriptor **ppdesc)
{
	DATA_BLOB blob = data_blob_null;
	NTSTATUS status;
	uint16_t hash_type = XATTR_SD_HASH_TYPE_NONE;
	uint8_t hash[XATTR_SD_HASH_SIZE];
	uint8_t hash_tmp[XATTR_SD_HASH_SIZE];
	struct security_descriptor *psd = NULL;
	struct security_descriptor *pdesc_next = NULL;
	bool ignore_file_system_acl = lp_parm_bool(SNUM(handle->conn),
						ACL_MODULE_NAME,
						"ignore system acls",
						false);

	if (fsp && name == NULL) {
		name = fsp->fsp_name->base_name;
	}

	DEBUG(10, ("get_nt_acl_internal: name=%s\n", name));

	/* Get the full underlying sd for the hash
	   or to return as backup. */
	if (fsp) {
		status = SMB_VFS_NEXT_FGET_NT_ACL(handle,
				fsp,
				HASH_SECURITY_INFO,
				&pdesc_next);
	} else {
		status = SMB_VFS_NEXT_GET_NT_ACL(handle,
				name,
				HASH_SECURITY_INFO,
				&pdesc_next);
	}

	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("get_nt_acl_internal: get_next_acl for file %s "
			"returned %s\n",
			name,
			nt_errstr(status)));
		return status;
	}

	status = get_acl_blob(talloc_tos(), handle, fsp, name, &blob);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("get_nt_acl_internal: get_acl_blob returned %s\n",
			nt_errstr(status)));
		psd = pdesc_next;
		goto out;
	}

	status = parse_acl_blob(&blob, &psd,
				&hash_type, &hash[0]);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(10, ("parse_acl_blob returned %s\n",
				nt_errstr(status)));
		psd = pdesc_next;
		goto out;
	}

	/* Ensure the hash type is one we know. */
	switch (hash_type) {
		case XATTR_SD_HASH_TYPE_NONE:
			/* No hash, just return blob sd. */
			goto out;
		case XATTR_SD_HASH_TYPE_SHA256:
			break;
		default:
			DEBUG(10, ("get_nt_acl_internal: ACL blob revision "
				"mismatch (%u) for file %s\n",
				(unsigned int)hash_type,
				name));
			TALLOC_FREE(psd);
			psd = pdesc_next;
			goto out;
	}

	if (ignore_file_system_acl) {
		goto out;
	}

	status = hash_sd_sha256(pdesc_next, hash_tmp);
	if (!NT_STATUS_IS_OK(status)) {
		TALLOC_FREE(psd);
		psd = pdesc_next;
		goto out;
	}

	if (memcmp(&hash[0], &hash_tmp[0], XATTR_SD_HASH_SIZE) == 0) {
		/* Hash matches, return blob sd. */
		DEBUG(10, ("get_nt_acl_internal: blob hash "
			"matches for file %s\n",
			name ));
		goto out;
	}

	/* Hash doesn't match, return underlying sd. */
	TALLOC_FREE(psd);
	psd = pdesc_next;

  out:

	if (psd != pdesc_next) {
		/* We're returning the blob, throw
 		 * away the filesystem SD. */
		TALLOC_FREE(pdesc_next);
	} else {
		SMB_STRUCT_STAT sbuf;
		SMB_STRUCT_STAT *psbuf = &sbuf;
		bool is_directory = false;
		/*
		 * We're returning the underlying ACL from the
		 * filesystem. If it's a directory, and has no
		 * inheritable ACE entries we have to fake them.
		 */
		if (fsp) {
			status = vfs_stat_fsp(fsp);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}
			psbuf = &fsp->fsp_name->st;
		} else {
			int ret = vfs_stat_smb_fname(handle->conn,
						name,
						&sbuf);
			if (ret == -1) {
				return map_nt_error_from_unix(errno);
			}
		}
		is_directory = S_ISDIR(psbuf->st_ex_mode);

		if (ignore_file_system_acl) {
			TALLOC_FREE(pdesc_next);
			status = make_default_filesystem_acl(talloc_tos(),
						name,
						psbuf,
						&psd);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}
		} else {
			if (is_directory &&
				!sd_has_inheritable_components(psd,
							true)) {
				add_directory_inheritable_components(handle,
							name,
							psbuf,
							psd);
			}
			/* The underlying POSIX module always sets
			   the ~SEC_DESC_DACL_PROTECTED bit, as ACLs
			   can't be inherited in this way under POSIX.
			   Remove it for Windows-style ACLs. */
			psd->type &= ~SEC_DESC_DACL_PROTECTED;
		}
	}

	if (!(security_info & SECINFO_OWNER)) {
		psd->owner_sid = NULL;
	}
	if (!(security_info & SECINFO_GROUP)) {
		psd->group_sid = NULL;
	}
	if (!(security_info & SECINFO_DACL)) {
		psd->type &= ~SEC_DESC_DACL_PRESENT;
		psd->dacl = NULL;
	}
	if (!(security_info & SECINFO_SACL)) {
		psd->type &= ~SEC_DESC_SACL_PRESENT;
		psd->sacl = NULL;
	}

	TALLOC_FREE(blob.data);
	*ppdesc = psd;

	if (DEBUGLEVEL >= 10) {
		DEBUG(10,("get_nt_acl_internal: returning acl for %s is:\n",
			name ));
		NDR_PRINT_DEBUG(security_descriptor, psd);
	}

	return NT_STATUS_OK;
}