Index: /branches/rel_avx_2_7_2/src/backend/sys_cmd.c
===================================================================
--- /branches/rel_avx_2_7_2/src/backend/sys_cmd.c	(revision 8849)
+++ /branches/rel_avx_2_7_2/src/backend/sys_cmd.c	(working copy)
@@ -40,6 +40,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <inttypes.h>
+#include <stdint.h>
 #include <poll.h>
 #include <sys/ioctl.h>
 #include <termios.h>
@@ -7017,3 +7018,129 @@
 }
 
 #undef AVX_IF_DESC_CMD_LENGTH
+
+enum {
+    AVX_EXAUTH_UNIX = 0,
+    AVX_EXAUTH_RADIUS,
+};
+
+typedef {
+    uint8_t type;
+    char host[64];
+    uint16_t port;
+} __avx_exauth_conf_t;
+
+#define AVX_NSS_CONF "/etc/nsswitch.conf"
+
+/* The PAM stacks with
+ * RADIUS authentication enabled appear like the following:
+ *
+ *     <type> [success=done default=ignore] pam_radius_auth.so
+ *     <type> [success=done default=bad] pam_unix.so
+ *
+ * With this setting, PAM will run the following flow:
+ *     1. First check RADIUS users.
+ *         - If user is met in RADIUS, return to the application
+ *           (done by "success=done").
+ *         - If not, go to the next step (done by "default=ignore").
+ *     2. Check UNIX users.
+ *         - It user is met in UNIX, return to the application.
+ *         - If not, abort the whole PAM authentication
+ *           (done by "default=bad").
+ *
+ * As a counterpart, the PAM stacks with RADIUS authentication
+ * disabled appear like the following:
+ *
+ *     <type> [success=done default=bad] pam_unix.so
+ */
+
+#define AVX_AUTH_PAM "/etc/pam.d/array-common-auth.pam"
+#define AVX_ACCT_PAM "/etc/pam.d/array-common-acct.pam"
+#define _AVX_PAM_FIRST_PASS "[success=done default=ignore]"
+#define _AVX_PAM_LAST_PASS "[success=done default=bad]"
+#define _AVX_PAM_USE_RADIUS "pam_radius_auth.so"
+#define _AVX_PAM_USE_UNIX "pam_unix.so"
+
+#define _AVX_WRITE_PAM_CONF(conf, type, BODY)                                  \
+    do {                                                                       \
+        FILE *fp = fopen(conf, "w");                                           \
+        if (!fp) {                                                             \
+            printf("Cannot open %s PAM conf\n", type);                         \
+            return -1;                                                         \
+        }                                                                      \
+        BODY fclose(fp);                                                       \
+    } while (0)
+
+#define _AVX_WRITE_PASS(type, ctrl, mod)                                       \
+    fprintf(fp, "%s %s %s", type, ctrl, mod)
+
+#define _AVX_WRITE_LF fprintf(fp, "\n")
+
+int exauth_on() {
+	_AVX_WRITE_PAM_CONF(
+        AVX_AUTH_PAM, "auth",
+        _AVX_WRITE_PASS("auth", _AVX_PAM_FIRST_PASS, _AVX_PAM_USE_RADIUS);
+        _AVX_WRITE_LF;
+        _AVX_WRITE_PASS("auth", _AVX_PAM_LAST_PASS, _AVX_PAM_USE_UNIX););
+
+    _AVX_WRITE_PAM_CONF(
+        AVX_ACCT_PAM, "account",
+        _AVX_WRITE_PASS("account", _AVX_PAM_FIRST_PASS, _AVX_PAM_USE_RADIUS);
+        _AVX_WRITE_LF;
+        _AVX_WRITE_PASS("account", _AVX_PAM_LAST_PASS, _AVX_PAM_USE_UNIX););
+
+    /* Activate NSS of RADIUS users */
+    system("sed -i '/^passwd:/s/$/ ato/' " AVX_NSS_CONF);
+    system("sed -i '/^shadow:/s/$/ ato/' " AVX_NSS_CONF);
+
+    sleep(1);
+    return 0;
+}
+
+int exauth_off() {
+    _AVX_WRITE_PAM_CONF(
+        AVX_AUTH_PAM, "auth",
+        _AVX_WRITE_PASS("auth", _AVX_PAM_LAST_PASS, _AVX_PAM_USE_UNIX););
+
+    _AVX_WRITE_PAM_CONF(
+        AVX_ACCT_PAM, "account",
+        _AVX_WRITE_PASS("account", _AVX_PAM_LAST_PASS, _AVX_PAM_USE_UNIX););
+
+    /* Deactivate NSS of RADIUS user */
+    system("sed -i '/^passwd:/s/ ato//g' " AVX_NSS_CONF);
+    system("sed -i '/^shadow:/s/ ato//g' " AVX_NSS_CONF);
+
+    sleep(1);
+    return 0;
+}
+
+#define AVX_RADIUS_CONF "/etc/pam_radius.conf"
+#define _AVX_RADIUS_TIMEOUT 3
+
+int set_radius_server(
+    char *host,
+    uint16_t port,
+    char *secret
+) {
+    FILE *fp = fopen(AVX_RADIUS_CONF, "w");
+    if(!fp) {
+        printf("Cannot open RADIUS server config\n");
+        return -1;
+    }
+
+    fprintf(fp, "%s:%d %s %d", host, port, secret, _AVX_RADIUS_TIMEOUT);
+
+    fclose(fp);
+
+    sleep(1);
+    return 0;
+}
+
+int unset_radius_server() {
+    system("rm -rf " AVX_RADIUS_CONF);
+    return 0;
+}
+
+char *write_exauth_conf() {
+    return NULL;
+}
Index: /branches/rel_avx_2_7_2/src/backend/sys_tool.c
===================================================================
--- /branches/rel_avx_2_7_2/src/backend/sys_tool.c	(revision 8849)
+++ /branches/rel_avx_2_7_2/src/backend/sys_tool.c	(working copy)
@@ -358,6 +358,11 @@
         CMD_NORMAL | CMD_ARRAYOS | CMD_GLOBAL,
         "#interface description"
     },
+    {
+        write_exauth_conf,
+        CMD_NORMAL | CMD_ARRAYOS | CMD_GLOBAL,
+        "#admin aaa configuration"
+    },
     /*last entry is empty*/
     {
         NULL,
Index: /branches/rel_avx_2_7_2/src/generator/commands.pm
===================================================================
--- /branches/rel_avx_2_7_2/src/generator/commands.pm	(revision 8849)
+++ /branches/rel_avx_2_7_2/src/generator/commands.pm	(working copy)
@@ -7239,6 +7239,145 @@
             optional => "NO",
         }, ],
     },
+    {
+        obj_type => "MENU",
+        name => "admin",
+        parent_menu => ".",
+        uniq_name => "root_admin",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL",
+        user_level => "CLI_LEVEL_CONFIG",
+        help_string => "Administration configuration",
+    },
+    {
+        obj_type => "MENU",
+        name => "aaa",
+        parent_menu => "root_admin",
+        uniq_name => "root_admin_aaa",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL",
+        user_level => "CLI_LEVEL_CONFIG",
+        help_string => "External authentication configuration",
+    },
+    {
+        obj_type => "MENU",
+        name => "server",
+        parent_menu => "root_admin_aaa",
+        uniq_name => "root_admin_server_aaa",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL",
+        user_level => "CLI_LEVEL_CONFIG",
+        help_string => "External authentication server configuration",
+    },
+    {
+        obj_type => "ITEM",
+        name => "es01",
+        menu => "root_admin_server_aaa",
+        help_string => "Configure external RADIUS authentication server",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_SPECIAL_LOG",
+        user_level => "CLI_LEVEL_CONFIG",
+        function_name => "set_radius_server",
+        function_args => [
+            {
+                type => "STRING",
+                help_string => "Host name or ip address",
+                optional => "NO",
+            },
+            {
+                type => "U16",
+                help_string => "Port",
+                optional => "NO",
+            },
+            {
+                type => "STRING",
+                help_string => "Secret",
+                optional => "YES",
+                default_value => "\"\"",
+            },
+        ],
+    },
+    {
+        obj_type => "MENU",
+        name => "admin",
+        parent_menu => "root_no",
+        uniq_name => "root_no_admin",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL",
+        user_level => "CLI_LEVEL_CONFIG",
+        help_string => "Delete administration configurations",
+    },
+	{
+        obj_type => "MENU",
+        name => "aaa",
+        parent_menu => "root_no_admin",
+        uniq_name => "root_no_admin_aaa_server",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL",
+        user_level => "CLI_LEVEL_ENABLE",
+        help_string => "Delete external authentication configurations",
+    },
+    {
+        obj_type => "MENU",
+        name => "server",
+        parent_menu => "root_no_admin_aaa_server",
+        uniq_name => "root_no_admin_aaa",
+        help_string => "Delete external authentication server",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL",
+        user_level => "CLI_LEVEL_CONFIG",
+    },
+	{
+        obj_type => "ITEM",
+        name => "es01",
+        menu => "root_no_admin_aaa",
+        help_string => "Delete external RADIUS authentication server",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL|CMD_SPECIAL_LOG",
+        user_level => "CLI_LEVEL_CONFIG",
+        function_name => "unset_radius_server",
+        function_args => [],
+    },
+    {
+        obj_type => "ITEM",
+        name => "on",
+        menu => "root_admin_aaa",
+        help_string => "Turn on external authentication",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL",
+        user_level => "CLI_LEVEL_CONFIG",
+        function_name => "exauth_on",
+        function_args => [],
+    },
+    {
+        obj_type => "ITEM",
+        name => "off",
+        menu => "root_admin_aaa",
+        help_string => "Turn off external authentication",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL",
+        user_level => "CLI_LEVEL_CONFIG",
+        function_name => "exauth_off",
+        function_args => [],
+    },
+    {
+        obj_type => "MENU",
+        name => "admin",
+        parent_menu => "root_show",
+        uniq_name => "root_show_admin",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL",
+        user_level => "CLI_LEVEL_ENABLE",
+        help_string => "Display administration configurations",
+    },
+    {
+        obj_type => "MENU",
+        name => "aaa",
+        parent_menu => "root_show_admin",
+        uniq_name => "root_show_admin_aaa",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL",
+        user_level => "CLI_LEVEL_ENABLE",
+        help_string => "Display external authentication configurations",
+    },
+    {
+        obj_type => "ITEM",
+        name => "all",
+        menu => "root_show_admin_aaa",
+        help_string => "Display all external authentication configurations",
+        cmd_attribute => "CMD_ARRAYOS|CMD_NORMAL|CMD_GLOBAL",
+        user_level => "CLI_LEVEL_ENABLE",
+        function_name => "show_exauth_all",
+        function_args => [],
+    },
 );
 
 # This method is required to expost the command table to the caller.
