Index: include/asterisk/manager.h
===================================================================
--- include/asterisk/manager.h	(revision 85537)
+++ include/asterisk/manager.h	(working copy)
@@ -62,6 +62,7 @@
 #define EVENT_FLAG_CONFIG		(1 << 7) /* Ability to modify configurations */
 #define EVENT_FLAG_DTMF  		(1 << 8) /* Ability to read DTMF events */
 #define EVENT_FLAG_REPORTING		(1 << 9) /* Reporting events such as rtcp sent */
+#define EVENT_FLAG_CALL_SAFE		(1 << 10) /*< Limited/Safe call origination */
 /* Export manager structures */
 #define AST_MAX_MANHEADERS 128
 
Index: main/manager.c
===================================================================
--- main/manager.c	(revision 85537)
+++ main/manager.c	(working copy)
@@ -161,6 +161,7 @@
 	struct eventqent *last_ev;	/*!< last event processed. */
 	int writetimeout;	/*!< Timeout for ast_carefulwrite() */
 	AST_LIST_ENTRY(mansession) list;
+	char context[AST_MAX_CONTEXT];	/*!<context for safe calls origination */
 };
 
 #define NEW_EVENT(m)	(AST_LIST_NEXT(m->last_ev, eq_next))
@@ -183,6 +184,7 @@
 	int displayconnects;	/*!< XXX unused */
 	int keep;	/*!< mark entries created on a reload */
 	AST_RWLIST_ENTRY(ast_manager_user) list;
+	char context[AST_MAX_CONTEXT];
 };
 
 /*! \brief list of users found in the config file */
@@ -319,6 +321,7 @@
 	{ EVENT_FLAG_CONFIG, "config" },
 	{ EVENT_FLAG_DTMF, "dtmf" },
 	{ EVENT_FLAG_REPORTING, "reporting" },
+	{ EVENT_FLAG_CALL_SAFE, "safe_call" },
 	{ -1, "all" },
 	{ 0, "none" },
 };
@@ -1008,6 +1011,8 @@
 					ast_log(LOG_WARNING, "Invalid writetimeout value '%s' at line %d\n", v->value, v->lineno);
 				else
 					s->writetimeout = val;
+			} else if (!strcasecmp(v->name, "context")) {
+				ast_copy_string(s->context, v->value, sizeof(s->context));
 			}
 		}
 		break;
@@ -2003,6 +2008,18 @@
 		astman_send_error(s, m, "Channel not specified");
 		return 0;
 	}
+	if ( !(s->writeperm | EVENT_FLAG_CALL) ) {
+		/* A local channel might allow calling an arbitrary context. 
+		 * Forbit it until we know how to handle it.
+		 */
+		if (!strncmp(name, "Local", sizeof("Local"))) {
+			astman_send_error(s, m, "Local channel not allowed for safe_call");
+			return 0;
+		}
+		/* Caller has only EVENT_FLAG_CALL_SAFE permissions */
+		context = s->context;
+		app = "";
+	}
 	if (!ast_strlen_zero(priority) && (sscanf(priority, "%d", &pi) != 1)) {
 		if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
 			astman_send_error(s, m, "Invalid priority\n");
@@ -3317,7 +3334,7 @@
 		ast_manager_register2("GetConfigJSON", EVENT_FLAG_CONFIG, action_getconfigjson, "Retrieve configuration (JSON format)", mandescr_getconfigjson);
 		ast_manager_register2("UpdateConfig", EVENT_FLAG_CONFIG, action_updateconfig, "Update basic configuration", mandescr_updateconfig);
 		ast_manager_register2("Redirect", EVENT_FLAG_CALL, action_redirect, "Redirect (transfer) a call", mandescr_redirect );
-		ast_manager_register2("Originate", EVENT_FLAG_CALL, action_originate, "Originate Call", mandescr_originate);
+		ast_manager_register2("Originate", EVENT_FLAG_CALL | EVENT_FLAG_CALL_SAFE, action_originate, "Originate Call", mandescr_originate);
 		ast_manager_register2("Command", EVENT_FLAG_COMMAND, action_command, "Execute Asterisk CLI Command", mandescr_command );
 		ast_manager_register2("ExtensionState", EVENT_FLAG_CALL, action_extensionstate, "Check Extension Status", mandescr_extensionstate );
 		ast_manager_register2("AbsoluteTimeout", EVENT_FLAG_CALL, action_timeout, "Set Absolute Timeout", mandescr_timeout );
@@ -3460,9 +3477,11 @@
 				if (user->write)
 					ast_free(user->write);
 				user->write = ast_strdup(var->value);
-			}  else if (!strcasecmp(var->name, "displayconnects") )
+			}  else if (!strcasecmp(var->name, "displayconnects") ) {
 				user->displayconnects = ast_true(var->value);
-			else {
+			} else if (!strcasecmp(var->name, "context") ) {
+				ast_copy_string(user->context, var->name, sizeof(user->context));
+			} else {
 				ast_debug(1, "%s is an unknown option.\n", var->name);
 			}
 			var = var->next;
Index: configs/manager.conf.sample
===================================================================
--- configs/manager.conf.sample	(revision 85537)
+++ configs/manager.conf.sample	(working copy)
@@ -73,3 +73,9 @@
 ; Authorization for various classes 
 ;read = system,call,log,verbose,command,agent,user,config,dtmf,reporting
 ;write = system,call,log,verbose,command,agent,user,config,dtmf,reporting
+
+; Joe is only allowed to place calls from context dialplan-joe:
+;[joe]
+;secret= = joe-s-secret
+;context = dialplan-joe
+;write = safe_call
