diff --git a/tools/crm_attribute.c b/tools/crm_attribute.c
index 7cb277426b..60ded8d818 100644
--- a/tools/crm_attribute.c
+++ b/tools/crm_attribute.c
@@ -1,355 +1,362 @@
 
 /*
  * Copyright (C) 2004 Andrew Beekhof <andrew@beekhof.net>
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * General Public License for more details.
  *
  * You should have received a copy of the GNU General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
 #include <crm_internal.h>
 
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <libgen.h>
 #include <time.h>
 
 #include <sys/param.h>
 #include <sys/types.h>
 
 #include <crm/crm.h>
 #include <crm/msg_xml.h>
 #include <crm/common/xml.h>
 #include <crm/common/ipc.h>
 #include <crm/common/util.h>
 #include <crm/cluster.h>
 
 #include <crm/cib.h>
 #include <crm/attrd.h>
 #include <sys/utsname.h>
 
 gboolean BE_QUIET = FALSE;
 char command = 'G';
 
-char *dest_uname = NULL;
+const char *dest_uname = NULL;
 char *dest_node = NULL;
 char *set_name = NULL;
 char *attr_id = NULL;
 char *attr_name = NULL;
 char *attr_pattern = NULL;
 const char *type = NULL;
 const char *rsc_id = NULL;
 const char *attr_value = NULL;
 const char *attr_default = NULL;
 const char *set_type = NULL;
 
 /* *INDENT-OFF* */
 static struct crm_option long_options[] = {
     /* Top-level Options */
     {"help",    0, 0, '?', "\tThis text"},
     {"version", 0, 0, '$', "\tVersion information"  },
     {"verbose", 0, 0, 'V', "\tIncrease debug output"},
     {"quiet",   0, 0, 'q', "\tPrint only the value on stdout\n"},
 
     {"name",    1, 0, 'n', "Name of the attribute/option to operate on"},
     {"pattern", 1, 0, 'P', "Pattern matching names of attributes (only with -v/-D and -l reboot)"},
 
     {"-spacer-",    0, 0, '-', "\nCommands:"},
     {"query",       0, 0, 'G', "\tQuery the current value of the attribute/option"},
     {"update",      1, 0, 'v', "Update the value of the attribute/option"},
     {"delete",      0, 0, 'D', "\tDelete the attribute/option"},
 
     {"-spacer-",    0, 0, '-', "\nAdditional Options:"},
     {"node",        1, 0, 'N', "Set an attribute for the named node (instead of a cluster option).  See also: -l"},
     {"type",        1, 0, 't', "Which part of the configuration to update/delete/query the option in"},
     {"-spacer-",    0, 0, '-', "\t\t\tValid values: crm_config, rsc_defaults, op_defaults, tickets"},
     {"lifetime",    1, 0, 'l', "Lifetime of the node attribute"},
     {"-spacer-",    0, 0, '-', "\t\t\tValid values: reboot, forever"},
     {"utilization", 0, 0, 'z', "Set an utilization attribute for the node."},
     {"set-name",    1, 0, 's', "(Advanced) The attribute set in which to place the value"},
     {"id",	    1, 0, 'i', "\t(Advanced) The ID used to identify the attribute"},
     {"default",     1, 0, 'd', "(Advanced) The default value to display if none is found in the configuration"},
 
     {"inhibit-policy-engine", 0, 0, '!', NULL, 1},
 
     /* legacy */
     {"quiet",       0, 0, 'Q', NULL, 1},
     {"node-uname",  1, 0, 'U', NULL, 1},
     {"node-uuid",   1, 0, 'u', NULL, 1},
     {"get-value",   0, 0, 'G', NULL, 1},
     {"delete-attr", 0, 0, 'D', NULL, 1},
     {"attr-value",  1, 0, 'v', NULL, 1},
     {"attr-name",   1, 0, 'n', NULL, 1},
     {"attr-id",     1, 0, 'i', NULL, 1},
 
     {"-spacer-",	1, 0, '-', "\nExamples:", pcmk_option_paragraph},
     {"-spacer-",	1, 0, '-', "Add a new node attribute called 'location' with the value of 'office' for host 'myhost':", pcmk_option_paragraph},
     {"-spacer-",	1, 0, '-', " crm_attribute --node myhost --name location --update office", pcmk_option_example},
     {"-spacer-",	1, 0, '-', "Query the value of the 'location' node attribute for host 'myhost':", pcmk_option_paragraph},
     {"-spacer-",	1, 0, '-', " crm_attribute --node myhost --name location --query", pcmk_option_example},
     {"-spacer-",	1, 0, '-', "Change the value of the 'location' node attribute for host 'myhost':", pcmk_option_paragraph},
     {"-spacer-",	1, 0, '-', " crm_attribute --node myhost --name location --update backoffice", pcmk_option_example},
     {"-spacer-",	1, 0, '-', "Delete the 'location' node attribute for host 'myhost':", pcmk_option_paragraph},
     {"-spacer-",	1, 0, '-', " crm_attribute --node myhost --name location --delete", pcmk_option_example},
     {"-spacer-",	1, 0, '-', "Query the value of the cluster-delay cluster option:", pcmk_option_paragraph},
     {"-spacer-",	1, 0, '-', " crm_attribute --type crm_config --name cluster-delay --query", pcmk_option_example},
     {"-spacer-",	1, 0, '-', "Query the value of the cluster-delay cluster option. Only print the value:", pcmk_option_paragraph},
     {"-spacer-",	1, 0, '-', " crm_attribute --type crm_config --name cluster-delay --query --quiet", pcmk_option_example},
 
     {0, 0, 0, 0}
 };
 /* *INDENT-ON* */
 
 int
 main(int argc, char **argv)
 {
     cib_t *the_cib = NULL;
     int rc = pcmk_ok;
 
     int cib_opts = cib_sync_call;
     int argerr = 0;
     int flag;
 
     int option_index = 0;
     int is_remote_node = 0;
 
     crm_log_cli_init("crm_attribute");
     crm_set_options(NULL, "<command> -n <attribute> [options]", long_options,
                     "Manage node's attributes and cluster options."
                     "\n\nAllows node attributes and cluster options to be queried, modified and deleted.\n");
 
     if (argc < 2) {
         crm_help('?', EX_USAGE);
     }
 
     while (1) {
         flag = crm_get_option(argc, argv, &option_index);
         if (flag == -1)
             break;
 
         switch (flag) {
             case 'V':
                 crm_bump_log_level(argc, argv);
                 break;
             case '$':
             case '?':
                 crm_help(flag, EX_OK);
                 break;
             case 'G':
                 command = flag;
                 attr_value = optarg;
                 break;
             case 'D':
             case 'v':
                 command = flag;
                 attr_value = optarg;
                 crm_log_args(argc, argv);
                 break;
             case 'q':
             case 'Q':
                 BE_QUIET = TRUE;
                 break;
             case 'U':
             case 'N':
                 dest_uname = strdup(optarg);
                 break;
             case 'u':
                 dest_node = strdup(optarg);
                 break;
             case 's':
                 set_name = strdup(optarg);
                 break;
             case 'l':
             case 't':
                 type = optarg;
                 break;
             case 'z':
                 type = XML_CIB_TAG_NODES;
                 set_type = XML_TAG_UTILIZATION;
                 break;
             case 'n':
                 attr_name = strdup(optarg);
                 break;
             case 'P':
                 attr_pattern = strdup(optarg);
                 break;
             case 'i':
                 attr_id = strdup(optarg);
                 break;
             case 'r':
                 rsc_id = optarg;
                 break;
             case 'd':
                 attr_default = optarg;
                 break;
             case '!':
                 crm_warn("Inhibiting notifications for this update");
                 cib_opts |= cib_inhibit_notify;
                 break;
             default:
                 printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag);
                 ++argerr;
                 break;
         }
     }
 
     if (optind < argc) {
         printf("non-option ARGV-elements: ");
         while (optind < argc)
             printf("%s ", argv[optind++]);
         printf("\n");
     }
 
     if (optind > argc) {
         ++argerr;
     }
 
     if (argerr) {
         crm_help('?', EX_USAGE);
     }
 
     the_cib = cib_new();
     rc = the_cib->cmds->signon(the_cib, crm_system_name, cib_command);
 
     if (rc != pcmk_ok) {
         fprintf(stderr, "Error signing on to the CIB service: %s\n", pcmk_strerror(rc));
         return crm_exit(rc);
     }
 
     if (type == NULL && dest_uname != NULL) {
 	    type = "forever";
     }
 
     if (safe_str_eq(type, "reboot")) {
         type = XML_CIB_TAG_STATUS;
 
     } else if (safe_str_eq(type, "forever")) {
         type = XML_CIB_TAG_NODES;
     }
 
     if (type == NULL && dest_uname == NULL) {
         /* we're updating cluster options - don't populate dest_node */
         type = XML_CIB_TAG_CRMCONFIG;
 
     } else if (safe_str_eq(type, XML_CIB_TAG_CRMCONFIG)) {
     } else if (safe_str_neq(type, XML_CIB_TAG_TICKETS)) {
         if (dest_uname == NULL) {
-            dest_uname = get_node_name(0);
+            /* If we are being called from a resource agent via the cluster,
+             * the correct local node name will be passed as an environment
+             * variable. Otherwise, we have to ask the cluster.
+             */
+            dest_uname = getenv("OCF_RESKEY_" CRM_META "_" XML_LRM_ATTR_TARGET);
+            if (dest_uname == NULL) {
+                dest_uname = get_local_node_name();
+            }
         }
 
         rc = query_node_uuid(the_cib, dest_uname, &dest_node, &is_remote_node);
         if (pcmk_ok != rc) {
             fprintf(stderr, "Could not map name=%s to a UUID\n", dest_uname);
             the_cib->cmds->signoff(the_cib);
             cib_delete(the_cib);
             return crm_exit(rc);
         }
     }
 
     if ((command == 'D') && (attr_name == NULL) && (attr_pattern == NULL)) {
         fprintf(stderr, "Error: must specify attribute name or pattern to delete\n");
         return crm_exit(1);
     }
 
     if (attr_pattern) {
         if (((command != 'v') && (command != 'D'))
             || safe_str_neq(type, XML_CIB_TAG_STATUS)) {
 
             fprintf(stderr, "Error: pattern can only be used with till-reboot update or delete\n");
             return crm_exit(1);
         }
         command = 'u';
         free(attr_name);
         attr_name = attr_pattern;
     }
 
     if (((command == 'v') || (command == 'D') || (command == 'u'))
         && safe_str_eq(type, XML_CIB_TAG_STATUS)
         && pcmk_ok == attrd_update_delegate(NULL, command, dest_uname, attr_name,
                                             attr_value, type, set_name, NULL, NULL,
                                             is_remote_node?attrd_opt_remote:attrd_opt_none)) {
         crm_info("Update %s=%s sent via attrd", attr_name, command == 'D' ? "<none>" : attr_value);
 
     } else if (command == 'D') {
         rc = delete_attr_delegate(the_cib, cib_opts, type, dest_node, set_type, set_name,
                                   attr_id, attr_name, attr_value, TRUE, NULL);
 
         if (rc == -ENXIO) {
             /* Nothing to delete...
              * which means it's not there...
              * which is what the admin wanted
              */
             rc = pcmk_ok;
         } else if (rc != -EINVAL && safe_str_eq(crm_system_name, "crm_failcount")) {
             char *now_s = NULL;
             time_t now = time(NULL);
 
             now_s = crm_itoa(now);
             update_attr_delegate(the_cib, cib_sync_call, XML_CIB_TAG_CRMCONFIG, NULL, NULL, NULL,
                                  NULL, "last-lrm-refresh", now_s, TRUE, NULL, NULL);
             free(now_s);
         }
 
     } else if (command == 'v') {
         CRM_LOG_ASSERT(type != NULL);
         CRM_LOG_ASSERT(attr_name != NULL);
         CRM_LOG_ASSERT(attr_value != NULL);
 
         rc = update_attr_delegate(the_cib, cib_opts, type, dest_node, set_type, set_name,
                                   attr_id, attr_name, attr_value, TRUE, NULL, is_remote_node ? "remote" : NULL);
 
     } else {                    /* query */
 
         char *read_value = NULL;
 
         rc = read_attr_delegate(the_cib, type, dest_node, set_type, set_name,
                                 attr_id, attr_name, &read_value, TRUE, NULL);
 
         if (rc == -ENXIO && attr_default) {
             read_value = strdup(attr_default);
             rc = pcmk_ok;
         }
 
         crm_info("Read %s=%s %s%s",
                  attr_name, crm_str(read_value), set_name ? "in " : "", set_name ? set_name : "");
 
         if (rc == -EINVAL) {
             rc = pcmk_ok;
 
         } else if (BE_QUIET == FALSE) {
             fprintf(stdout, "%s%s %s%s %s%s value=%s\n",
                     type ? "scope=" : "", type ? type : "",
                     attr_id ? "id=" : "", attr_id ? attr_id : "",
                     attr_name ? "name=" : "", attr_name ? attr_name : "",
                     read_value ? read_value : "(null)");
 
         } else if (read_value != NULL) {
             fprintf(stdout, "%s\n", read_value);
         }
         free(read_value);
     }
 
     if (rc == -EINVAL) {
         printf("Please choose from one of the matches above and supply the 'id' with --attr-id\n");
 
     } else if (rc != pcmk_ok) {
         fprintf(stderr, "Error performing operation: %s\n", pcmk_strerror(rc));
     }
 
     the_cib->cmds->signoff(the_cib);
     cib_delete(the_cib);
     return crm_exit(rc);
 }