]> git.sur5r.net Git - bacula/bacula/commitdiff
- Add default Console resource in src/dird/bacula-dir.conf.in with
authorNicolas Boichat <nicolas@boichat.ch>
Sun, 22 Aug 2004 17:37:46 +0000 (17:37 +0000)
committerNicolas Boichat <nicolas@boichat.ch>
Sun, 22 Aug 2004 17:37:46 +0000 (17:37 +0000)
  access restricted to commands used by tray-monitor: status and
  .status.
- Add default Director ressource in src/filed/bacula-fd.conf.in and
  src/stored/bacula-sd.conf.in with Monitor directive enabled.
- Add .status dir [current|last] command to dird.
- Add Monitor directive in fd/sd configuration file (restrict
  access to status and .status commands).

@meno: I made some changes in src/filed/authenticate.c and
  src/stored/authenticate.c, which must be adapted to your new
  authentication code. Please contact me if you have any questions.

git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1549 91ce42f0-d328-0410-95d8-f526ca767f89

17 files changed:
bacula/src/dird/bacula-dir.conf.in
bacula/src/dird/ua_dotcmds.c
bacula/src/dird/ua_status.c
bacula/src/filed/authenticate.c
bacula/src/filed/bacula-fd.conf.in
bacula/src/filed/filed.h
bacula/src/filed/filed_conf.c
bacula/src/filed/filed_conf.h
bacula/src/filed/job.c
bacula/src/jcr.h
bacula/src/stored/authenticate.c
bacula/src/stored/bacula-sd.conf.in
bacula/src/stored/dircmd.c
bacula/src/stored/stored_conf.c
bacula/src/stored/stored_conf.h
bacula/src/tray-monitor/tray-monitor.c
bacula/src/tray-monitor/tray-monitor.conf.in

index fe51c4b156804e2ec93f606963414b198ff38369..ed9b17082b685a3dce87fdc023fa64aff57aac4f 100644 (file)
@@ -219,3 +219,14 @@ Pool {
   Volume Retention = 365 days         # one year
   Accept Any Volume = yes             # write on any volume in the pool
 }
+
+#
+# Restricted console used by tray-monitor to get the status of the director
+#
+Console {
+  Name = Monitor
+  Password = "@mon_dir_password@"
+  CommandACL = status, .status
+  ClientACL = 
+  StorageACL = 
+}
\ No newline at end of file
index d22fe6af9a9a56742fee6ad1170f9f10d292fa9d..98c9c53de091797bcf4cff8519bb8042c1419606 100644 (file)
@@ -45,6 +45,7 @@ extern const char *client_backups;
 extern int qmessagescmd(UAContext *ua, const char *cmd);
 extern int quit_cmd(UAContext *ua, const char *cmd);
 extern int qhelp_cmd(UAContext *ua, const char *cmd);
+extern int qstatus_cmd(UAContext *ua, const char *cmd);
 
 /* Forward referenced functions */
 static int diecmd(UAContext *ua, const char *cmd);
@@ -70,6 +71,7 @@ static struct cmdstruct commands[] = {
  { N_(".types"),      typescmd,     NULL},
  { N_(".backups"),    backupscmd,   NULL},
  { N_(".levels"),     levelscmd,    NULL},
+ { N_(".status"),     qstatus_cmd,  NULL},
  { N_(".storage"),    storagecmd,   NULL},
  { N_(".defaults"),   defaultscmd,  NULL},
  { N_(".messages"),   qmessagescmd, NULL},
index 9acb7fd0e5fe857b4f15bc4431040ed52cc65ad0..0383a8c3fdc2e523b7d93f6ed0438c4fdf412352 100644 (file)
@@ -42,6 +42,53 @@ static void do_client_status(UAContext *ua, CLIENT *client);
 static void do_director_status(UAContext *ua);
 static void do_all_status(UAContext *ua);
 
+static char OKqstatus[]   = "2000 OK .status\n";
+static char DotStatusJob[] = "JobId=%d JobStatus=%c JobErrors=%d\n";
+
+/*
+ * .status command
+ */
+int qstatus_cmd(UAContext *ua, const char *cmd)
+{
+   JCR* njcr;
+   s_last_job* job;
+   
+   if (!open_db(ua)) {
+      return 1;
+   }
+   Dmsg1(20, "status:%s:\n", cmd);
+
+   if ((ua->argc != 3) || (strcasecmp(ua->argk[1], "dir"))) {
+      bsendmsg(ua, "2900 Bad .status command, missing arguments.\n");
+      return 1;
+   }
+   
+   if (strcasecmp(ua->argk[2], "current") == 0) {
+      bsendmsg(ua, OKqstatus, ua->argk[2]);
+      lock_jcr_chain();
+      foreach_jcr(njcr) {
+         if (njcr->JobId != 0) {
+            bsendmsg(ua, DotStatusJob, njcr->JobId, njcr->JobStatus, njcr->JobErrors);
+         }
+         free_locked_jcr(njcr);
+      }
+      unlock_jcr_chain();
+   }
+   else if (strcasecmp(ua->argk[2], "last") == 0) {
+      bsendmsg(ua, OKqstatus, ua->argk[2]);
+      if ((last_jobs) && (last_jobs->size() > 0)) {
+         job = (s_last_job*)last_jobs->last();
+         bsendmsg(ua, DotStatusJob, job->JobId, job->JobStatus, job->Errors);
+      }
+   }
+   else {
+      bsendmsg(ua, "2900 Bad .status command, wrong argument.\n");
+      return 1;
+   }
+  
+   return 1;
+}
+
 /*
  * status command
  */
index ec3acb05e8ef4022d43e8556153fb6afdf4a6dcc..5e63ba028835c094bc723a7dec4aa3937cfddf84 100644 (file)
@@ -36,7 +36,7 @@ static char Dir_sorry[] = "2999 No go\n";
 /********************************************************************* 
  *
  */
-static int authenticate(int rcode, BSOCK *bs)
+static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
 {
    POOLMEM *dirname;
    DIRRES *director;
@@ -85,6 +85,7 @@ static int authenticate(int rcode, BSOCK *bs)
    }
    stop_bsock_timer(tid);
    free_pool_memory(dirname);
+   jcr->director = director;
    return (director != NULL);
 }
 
@@ -100,7 +101,7 @@ int authenticate_director(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
 
-   if (!authenticate(R_DIRECTOR, dir)) {
+   if (!authenticate(R_DIRECTOR, dir, jcr)) {
       bnet_fsend(dir, "%s", Dir_sorry);
       Emsg0(M_FATAL, 0, _("Unable to authenticate Director\n"));
       bmicrosleep(5, 0);
index e83250e8c9aabfb6d800a581bb243307ef2e06b0..cb23806638929d39c472f470cc0bf4cd74f6fe3b 100644 (file)
@@ -15,6 +15,16 @@ Director {
   Password = "@fd_password@"
 }
 
+#
+# Restricted Director, used by tray-monitor to get the
+#   status of the file daemon
+#
+Director {
+  Name = @hostname@-mon
+  Password = "@mon_fd_password@"
+  Monitor = yes
+}
+
 #
 # "Global" File daemon configuration specifications
 #
index 99c3045e7c15a413be2a3093d80e1dc62be779e6..451d601bcdcb456b65821d50ae7d525a73cd0cac 100644 (file)
  */
 
 #define FILE_DAEMON 1
+#include "filed_conf.h"
 #include "findlib/find.h"
 #include "jcr.h"
 #include "protos.h"                   /* file daemon prototypes */
-#include "filed_conf.h"
 #ifdef HAVE_LIBZ
 #include <zlib.h>                     /* compression headers */
 #else
index 319eef943fd5dfc17f92ba20b076535df4423a52..aaa3b33707c5888f441377568048e1480c5fee06 100644 (file)
@@ -105,6 +105,7 @@ static RES_ITEM dir_items[] = {
    {"password",    store_password, ITEM(res_dir.password),  0, ITEM_REQUIRED, 0},
    {"address",     store_str,      ITEM(res_dir.address),   0, 0, 0},
    {"enablessl",   store_yesno,    ITEM(res_dir.enable_ssl),1, ITEM_DEFAULT, 0},
+   {"monitor",     store_yesno,    ITEM(res_dir.monitor),   1, ITEM_DEFAULT, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
 
index ce1f4a8c848ccea798d6bcdaed25d61df7441d4f..f1d9fa5210e30b50b7fad5742d05f7d3b5982c5a 100644 (file)
@@ -51,6 +51,7 @@ struct DIRRES {
    char *password;                    /* Director password */
    char *address;                     /* Director address or zero */
    int enable_ssl;                    /* Use SSL for this Director */
+   int monitor;                       /* Have only access to status and .status functions */
 };
 
 struct CLIENT {
index 86bdfab4bc818c0b10b265bf8877f414b537a5cb..d9a43a7659e4d6749f8d7de4140f802b998b7c8e 100644 (file)
@@ -67,31 +67,32 @@ static void set_options(findFOPTS *fo, const char *opts);
 struct s_cmds {
    const char *cmd;
    int (*func)(JCR *);
+   int monitoraccess; /* specify if monitors have access to this function */
 };
 
 /*  
  * The following are the recognized commands from the Director. 
  */
 static struct s_cmds cmds[] = {
-   {"backup",       backup_cmd},
-   {"cancel",       cancel_cmd},
-   {"setdebug=",    setdebug_cmd},
-   {"estimate",     estimate_cmd},
-   {"exclude",      exclude_cmd},
-   {"Hello",        hello_cmd},
-   {"include",      include_cmd},
-   {"fileset",      fileset_cmd},
-   {"JobId=",       job_cmd},
-   {"level = ",     level_cmd},
-   {"restore",      restore_cmd},
-   {"session",      session_cmd},
-   {"status",       status_cmd},
-   {".status",      qstatus_cmd},
-   {"storage ",     storage_cmd},
-   {"verify",       verify_cmd},
-   {"bootstrap",    bootstrap_cmd},
-   {"RunBeforeJob", runbefore_cmd},
-   {"RunAfterJob",  runafter_cmd},
+   {"backup",       backup_cmd,    0},
+   {"cancel",       cancel_cmd,    0},
+   {"setdebug=",    setdebug_cmd,  0},
+   {"estimate",     estimate_cmd,  0},
+   {"exclude",      exclude_cmd,   0},
+   {"Hello",        hello_cmd,     1},
+   {"include",      include_cmd,   0},
+   {"fileset",      fileset_cmd,   0},
+   {"JobId=",       job_cmd,       0},
+   {"level = ",     level_cmd,     0},
+   {"restore",      restore_cmd,   0},
+   {"session",      session_cmd,   0},
+   {"status",       status_cmd,    1},
+   {".status",      qstatus_cmd,   1},
+   {"storage ",     storage_cmd,   0},
+   {"verify",       verify_cmd,    0},
+   {"bootstrap",    bootstrap_cmd, 0},
+   {"RunBeforeJob", runbefore_cmd, 0},
+   {"RunAfterJob",  runafter_cmd,  0},
    {NULL,      NULL}                  /* list terminator */
 };
 
@@ -109,6 +110,7 @@ static char runafter[]    = "RunAfterJob %s\n";
 /* Responses sent to Director */
 static char errmsg[]      = "2999 Invalid command\n";
 static char no_auth[]     = "2998 No Authorization\n";
+static char illegal_cmd[] = "2997 Illegal command for a Director with Monitor directive enabled\n";
 static char OKinc[]       = "2000 OK include\n";
 static char OKest[]       = "2000 OK estimate files=%u bytes=%s\n";
 static char OKexc[]       = "2000 OK exclude\n";
@@ -185,30 +187,37 @@ void *handle_client_request(void *dirp)
 
       /* Read command */
       if (bnet_recv(dir) < 0) {
-        break;                       /* connection terminated */
+         break;               /* connection terminated */
       }
       dir->msg[dir->msglen] = 0;
       Dmsg1(100, "<dird: %s", dir->msg);
       found = false;
       for (i=0; cmds[i].cmd; i++) {
-        if (strncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd)) == 0) {
-           if (!jcr->authenticated && cmds[i].func != hello_cmd) {
-              bnet_fsend(dir, no_auth);
-              break;
-           }
-           found = true;                /* indicate command found */
+         if (strncmp(cmds[i].cmd, dir->msg, strlen(cmds[i].cmd)) == 0) {
+            found = true;         /* indicate command found */
+            if (!jcr->authenticated && cmds[i].func != hello_cmd) {
+               bnet_fsend(dir, no_auth);
+               bnet_sig(dir, BNET_EOD);
+               break;
+            }
+            if ((jcr->authenticated) && (!cmds[i].monitoraccess) && (jcr->director->monitor)) {
+               Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd);
+               bnet_fsend(dir, illegal_cmd);
+               bnet_sig(dir, BNET_EOD);
+               break;
+            }
             Dmsg1(100, "Executing %s command.\n", cmds[i].cmd);
-           if (!cmds[i].func(jcr)) {    /* do command */
-              quit = true;              /* error or fully terminated,  get out */
+            if (!cmds[i].func(jcr)) {         /* do command */
+               quit = true;         /* error or fully terminated,      get out */
                Dmsg0(20, "Quit command loop due to command error or Job done.\n");
-           }
-           break;
-        }
+            }
+            break;
+         }
       }
-      if (!found) {                  /* command not found */
-        bnet_fsend(dir, errmsg);
-        quit = true;
-        break;
+      if (!found) {              /* command not found */
+         bnet_fsend(dir, errmsg);
+         quit = true;
+         break;
       }
    }
 
index 9b267a4235d6aeecd5a0ce3915ae963fde447377..7c142ddd864ded3a397f1411cf8115d3c0da43e6 100644 (file)
@@ -206,6 +206,7 @@ struct JCR {
    pthread_t heartbeat_id;            /* id of heartbeat thread */
    volatile BSOCK *hb_bsock;          /* duped SD socket */
    POOLMEM *RunAfterJob;              /* Command to run after job */
+   DIRRES* director;                  /* Director resource */
 #endif /* FILE_DAEMON */
 
 
@@ -237,7 +238,8 @@ struct JCR {
    bool no_attributes;                /* set if no attributes wanted */
    bool spool_data;                   /* set to spool data */
    int CurVol;                        /* Current Volume count */
-
+   DIRRES* director;                  /* Director resource */
+   
    uint32_t FileId;                   /* Last file id inserted */
 
    /* Parmaters for Open Read Session */
index 2cd2110c5b00598139cddbe3cddf3e747a529ab9..bf8f0f45163e1a2b0fc9b214184940602d91160a 100644 (file)
@@ -37,7 +37,7 @@ static char OK_hello[]  = "3000 OK Hello\n";
  *
  *
  */
-static int authenticate(int rcode, BSOCK *bs)
+static int authenticate(int rcode, BSOCK *bs, JCR* jcr)
 {
    POOLMEM *dirname;
    DIRRES *director = NULL;
@@ -89,6 +89,7 @@ static int authenticate(int rcode, BSOCK *bs)
    }
    stop_bsock_timer(tid);
    free_pool_memory(dirname);
+   jcr->director = director;
    return 1;
 }
 
@@ -108,7 +109,7 @@ int authenticate_director(JCR *jcr)
 {
    BSOCK *dir = jcr->dir_bsock;
 
-   if (!authenticate(R_DIRECTOR, dir)) {
+   if (!authenticate(R_DIRECTOR, dir, jcr)) {
       bnet_fsend(dir, "%s", Dir_sorry);
       Emsg1(M_ERROR, 0, _("Unable to authenticate Director at %s.\n"), dir->who);
       bmicrosleep(5, 0);
index 1b58851c65ebbbc7595c6ca4534a84374efbabf0..43482b447ed22510b9f69040e2bc74f512997a6f 100644 (file)
@@ -26,6 +26,16 @@ Director {
   Password = "@sd_password@"
 }
 
+#
+# Restricted Director, used by tray-monitor to get the
+#   status of the storage daemon
+#
+Director {
+  Name = @hostname@-mon
+  Password = "@mon_sd_password@"
+  Monitor = yes
+}
+
 #
 # Devices supported by this Storage daemon
 # To connect, the Director's bacula-dir.conf must have the
index 40c43f1648bb751d9bfb571913309b0d11601833..500c8485cd7d00695f8b6fd2767dfdc7a3941f82 100644 (file)
@@ -54,7 +54,7 @@ extern struct s_last_job last_job;
 /* Static variables */
 static char derrmsg[]       = "3900 Invalid command\n";
 static char OKsetdebug[]   = "3000 OK setdebug=%d\n";
-
+static char illegal_cmd[] = "3997 Illegal command for a Director with Monitor directive enabled\n";
 
 /* Imported functions */
 extern void terminate_child();
@@ -82,25 +82,26 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname,
 struct s_cmds {
    const char *cmd;
    int (*func)(JCR *jcr);
+   int monitoraccess; /* specify if monitors have access to this function */
 };
 
 /*  
  * The following are the recognized commands from the Director. 
  */
 static struct s_cmds cmds[] = {
-   {"JobId=",    job_cmd},            /* start Job */
-   {"setdebug=", setdebug_cmd},       /* set debug level */
-   {"cancel",    cancel_cmd},
-   {"label",     label_cmd},          /* label a tape */
-   {"relabel",   relabel_cmd},        /* relabel a tape */
-   {"mount",     mount_cmd},
-   {"unmount",   unmount_cmd},
-   {"status",    status_cmd},
-   {".status",   qstatus_cmd},
-   {"autochanger", autochanger_cmd},
-   {"release",   release_cmd},
-   {"readlabel", readlabel_cmd},
-   {NULL,       NULL}                /* list terminator */
+   {"JobId=",    job_cmd,       0},     /* start Job */
+   {"setdebug=", setdebug_cmd,  0},     /* set debug level */
+   {"cancel",    cancel_cmd,    0},
+   {"label",     label_cmd,     0},     /* label a tape */
+   {"relabel",   relabel_cmd,   0},     /* relabel a tape */
+   {"mount",     mount_cmd,     0},
+   {"unmount",   unmount_cmd,   0},
+   {"status",    status_cmd,    1},
+   {".status",   qstatus_cmd,   1},
+   {"autochanger", autochanger_cmd, 0},
+   {"release",   release_cmd,   0},
+   {"readlabel", readlabel_cmd, 0},
+   {NULL,       NULL}                      /* list terminator */
 };
 
 
@@ -180,24 +181,30 @@ void *handle_connection_request(void *arg)
    for (quit=0; !quit;) {
       /* Read command */
       if ((bnet_stat = bnet_recv(bs)) <= 0) {
-        break;                       /* connection terminated */
+         break;               /* connection terminated */
       }
       Dmsg1(9, "<dird: %s\n", bs->msg);
       found = false;
       for (i=0; cmds[i].cmd; i++) {
-        if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
-           if (!cmds[i].func(jcr)) {    /* do command */
-              quit = true;              /* error, get out */
-               Dmsg1(90, "Command %s requsts quit\n", cmds[i].cmd);
-           }
-           found = true;            /* indicate command found */
-           break;
-        }
+        if (strncmp(cmds[i].cmd, bs->msg, strlen(cmds[i].cmd)) == 0) {
+           if ((!cmds[i].monitoraccess) && (jcr->director->monitor)) {
+              Dmsg1(100, "Command %s illegal.\n", cmds[i].cmd);
+              bnet_fsend(bs, illegal_cmd);
+              bnet_sig(bs, BNET_EOD);
+              break;
+           }
+           if (!cmds[i].func(jcr)) { /* do command */
+              quit = true; /* error, get out */
+              Dmsg1(90, "Command %s requsts quit\n", cmds[i].cmd);
+           }
+           found = true;            /* indicate command found */
+           break;
+        }
       }
       if (!found) {                  /* command not found */
-        bnet_fsend(bs, derrmsg);
-        quit = true;
-        break;
+        bnet_fsend(bs, derrmsg);
+        quit = true;
+        break;
       }
    }
    bnet_sig(bs, BNET_TERMINATE);
index 2e51bb20035e07c355bce74db7cb7ccea16037b3..25edf24b743ca2b3a447c18efa38ff77f46effb2 100644 (file)
@@ -76,6 +76,7 @@ static RES_ITEM dir_items[] = {
    {"description", store_str,      ITEM(res_dir.hdr.desc),   0, 0, 0},
    {"password",    store_password, ITEM(res_dir.password),   0, ITEM_REQUIRED, 0},
    {"enablessl",   store_yesno,    ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0},
+   {"monitor",     store_yesno,    ITEM(res_dir.monitor),   1, ITEM_DEFAULT, 0},
    {NULL, NULL, 0, 0, 0, 0} 
 };
 
index d2bef94658f130c5dfe2242d2f00f628f200d629..457dce7335afb2f61f81afcc4219b41ee04b3c80 100644 (file)
@@ -45,9 +45,10 @@ enum {
 struct DIRRES {
    RES  hdr;
 
-   char *password;                   /* Director password */
-   char *address;                    /* Director IP address or zero */
-   int enable_ssl;                   /* Use SSL with this Director */
+   char *password;                    /* Director password */
+   char *address;                     /* Director IP address or zero */
+   int enable_ssl;                    /* Use SSL with this Director */
+   int monitor;                       /* Have only access to status and .status functions */
 };
 
 
index a89c10d906dd36d48facc6619082c76025b148cd..6241ebe76037b71d73883009c60844503fa5c69f 100644 (file)
@@ -71,7 +71,6 @@ void changeStatus(monitoritem* item, stateenum status);
 void changeStatusMessage(monitoritem* item, const char *fmt,...);
 
 /* Callbacks */
-static void TrayIconDaemonChanged(GtkWidget *widget, monitoritem* data);
 static void TrayIconActivate(GtkWidget *widget, gpointer data);
 static void TrayIconExit(unsigned int activateTime, unsigned int button);
 static void TrayIconPopupMenu(unsigned int button, unsigned int activateTime);
@@ -592,9 +591,9 @@ int docmd(monitoritem* item, const char* command, GSList** list) {
          str = g_string_sized_new(64);
          g_string_printf(str, "ERR=%s\n", item->D_sock->msg);
          g_slist_append(*list, str);
-         item->D_sock = NULL;
          changeStatus(NULL, error);
          changeStatusMessage(item, "Authentication error : %s", item->D_sock->msg);
+         item->D_sock = NULL;
          return 0;
       }
    
index bbeccaf3c3291644b19da142df510556d87ffb5c..3c451666f24bb60cbec03a9da18f0e961f806185 100644 (file)
@@ -3,19 +3,27 @@
 #
 
 Monitor {
-  Name = @hostname@-dir
+  Name = @hostname@-mon
 }
    
 Client {
   Name = @hostname@-fd
   Address = @hostname@
   FDPort = @fd_port@
-  Password = "@fd_password@"          # password for FileDaemon
+  Password = "@mon_fd_password@"          # password for FileDaemon
 }
 
 Storage {
   Name = @hostname@-sd
   Address = @hostname@
   SDPort = @sd_port@
-  Password = "@sd_password@"          # password for StorageDaemon
+  Password = "@mon_sd_password@"          # password for StorageDaemon
+}
+
+Director {
+  ConsoleName = Monitor
+  Name = @hostname@-dir
+  DIRport = @dir_port@
+  address = @hostname@
+  Password = "@mon_dir_password@"             # password for Director
 }
\ No newline at end of file