]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/dird/ua_cmds.c
kes Extend new GUI api code to tree commands.
[bacula/bacula] / bacula / src / dird / ua_cmds.c
index 8e6bb272d9f1d1f24212e55e97921ac3e4e21bf4..b09f3f7edd05787eed54946a9b8e5aa6e5cb693f 100644 (file)
@@ -1,15 +1,7 @@
-/*
- *
- *   Bacula Director -- User Agent Commands
- *
- *     Kern Sibbald, September MM
- *
- *   Version $Id$
- */
 /*
    Bacula® - The Network Backup Solution
 
-   Copyright (C) 2000-2006 Free Software Foundation Europe e.V.
+   Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
 
    The main author of Bacula is Kern Sibbald, with contributions from
    many others, a complete list can be found in the file AUTHORS.
    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
    Switzerland, email:ftf@fsfeurope.org.
 */
-
+/*
+ *
+ *   Bacula Director -- User Agent Commands
+ *
+ *     Kern Sibbald, September MM
+ *
+ *   Version $Id$
+ */
 #include "bacula.h"
 #include "dird.h"
 
@@ -150,7 +150,9 @@ int do_a_command(UAContext *ua, const char *cmd)
 {
    unsigned int i;
    int len, stat;
+   bool ok = false;
    bool found = false;
+   BSOCK *user = ua->UA_sock;
 
    stat = 1;
 
@@ -171,15 +173,17 @@ int do_a_command(UAContext *ua, const char *cmd)
              !acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
             break;
          }
-         stat = (*commands[i].func)(ua, cmd);   /* go execute command */
+         if (ua->api) user->signal(BNET_CMD_BEGIN);
+         ok = (*commands[i].func)(ua, cmd);   /* go execute command */
          found = true;
          break;
       }
    }
    if (!found) {
-      bnet_fsend(ua->UA_sock, _("%s: is an illegal command.\n"), ua->argk[0]);
+      user->fsend(_("%s: is an invalid command.\n"), ua->argk[0]);
    }
-   return stat;
+   if (ua->api) user->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED);
+   return ok;
 }
 
 /*
@@ -194,6 +198,7 @@ void set_pool_dbr_defaults_in_media_dbr(MEDIA_DBR *mr, POOL_DBR *pr)
    mr->Recycle = pr->Recycle;
    mr->VolRetention = pr->VolRetention;
    mr->VolUseDuration = pr->VolUseDuration;
+   mr->RecyclePoolId = pr->RecyclePoolId;
    mr->MaxVolJobs = pr->MaxVolJobs;
    mr->MaxVolFiles = pr->MaxVolFiles;
    mr->MaxVolBytes = pr->MaxVolBytes;
@@ -220,7 +225,7 @@ static int add_cmd(UAContext *ua, const char *cmd)
 "creates database records without labeling the Volumes.\n"
 "You probably want to use the \"label\" command.\n\n"));
 
-   if (!open_db(ua)) {
+   if (!open_client_db(ua)) {
       return 1;
    }
 
@@ -384,10 +389,6 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
    JCR *jcr = NULL;
    char JobName[MAX_NAME_LENGTH];
 
-   if (!open_db(ua)) {
-      return 1;
-   }
-
    for (i=1; i<ua->argc; i++) {
       if (strcasecmp(ua->argk[i], NT_("jobid")) == 0) {
          uint32_t JobId;
@@ -423,30 +424,49 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
       }
 
    }
-   /* If we still do not have a jcr,
-    *   throw up a list and ask the user to select one.
-    */
-   if (!jcr) {
+   if (jcr) {
+      if (jcr->job && !acl_access_ok(ua, Job_ACL, jcr->job->name())) {
+         bsendmsg(ua, _("Unauthorized command from this console.\n"));
+         return 1;
+      }
+   } else {
+     /*
+      * If we still do not have a jcr,
+      *   throw up a list and ask the user to select one.
+      */
       char buf[1000];
+      int tjobs = 0;                  /* total # number jobs */
       /* Count Jobs running */
       foreach_jcr(jcr) {
          if (jcr->JobId == 0) {      /* this is us */
             continue;
          }
-         njobs++;
+         tjobs++;                    /* count of all jobs */
+         if (!acl_access_ok(ua, Job_ACL, jcr->job->name())) {
+            continue;               /* skip not authorized */
+         }
+         njobs++;                   /* count of authorized jobs */
       }
       endeach_jcr(jcr);
 
-      if (njobs == 0) {
-         bsendmsg(ua, _("No Jobs running.\n"));
+      if (njobs == 0) {            /* no authorized */
+         if (tjobs == 0) {
+            bsendmsg(ua, _("No Jobs running.\n"));
+         } else {
+            bsendmsg(ua, _("None of your jobs are running.\n"));
+         }
          return 1;
       }
+
       start_prompt(ua, _("Select Job:\n"));
       foreach_jcr(jcr) {
          char ed1[50];
          if (jcr->JobId == 0) {      /* this is us */
             continue;
          }
+         if (!acl_access_ok(ua, Job_ACL, jcr->job->name())) {
+            continue;               /* skip not authorized */
+         }
          bsnprintf(buf, sizeof(buf), _("JobId=%s Job=%s"), edit_int64(jcr->JobId, ed1), jcr->Job);
          add_prompt(ua, buf);
       }
@@ -463,7 +483,7 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
       sscanf(buf, "JobId=%d Job=%127s", &njobs, JobName);
       jcr = get_jcr_by_full_name(JobName);
       if (!jcr) {
-         bsendmsg(ua, _("Job %s not found.\n"), JobName);
+         bsendmsg(ua, _("Job \"%s\" not found.\n"), JobName);
          return 1;
       }
    }
@@ -479,6 +499,10 @@ static int cancel_cmd(UAContext *ua, const char *cmd)
  *   the setting of MaxVols and NumVols slightly differently
  *   depending on if we are creating the Pool or we are
  *   simply bringing it into agreement with the resource (updage).
+ *
+ * Caution : RecyclePoolId isn't setup in this function.
+ *           You can use set_pooldbr_recyclepoolid();
+ *
  */
 void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op)
 {
@@ -512,6 +536,62 @@ void set_pooldbr_from_poolres(POOL_DBR *pr, POOL *pool, e_pool_op op)
    }
 }
 
+/* set/update Pool.RecyclePoolId in Catalog */
+int update_pool_recyclepool(JCR *jcr, B_DB *db, POOL *pool)
+{
+   POOL_DBR  pr;
+
+   if (!pool->RecyclePool) {
+      return 1;
+   }
+
+   memset(&pr, 0, sizeof(POOL_DBR));
+   bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
+
+   if (!db_get_pool_record(jcr, db, &pr)) {
+      return -1;                       /* not exists in database */
+   }
+
+   set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE);
+
+   if (!set_pooldbr_recyclepoolid(jcr, db, &pr, pool)) {
+      return -1;                      /* error */
+   }
+
+   if (!db_update_pool_record(jcr, db, &pr)) {
+      return -1;                      /* error */
+   }
+   return 1;
+}
+
+/* set POOL_DBR.RecyclePoolId from Pool resource 
+ * works with set_pooldbr_from_poolres
+ */
+bool set_pooldbr_recyclepoolid(JCR *jcr, B_DB *db, POOL_DBR *pr, POOL *pool)
+{
+   POOL_DBR rpool;
+   bool ret = true;
+
+   if (pool->RecyclePool) {
+      memset(&rpool, 0, sizeof(POOL_DBR));
+
+      bstrncpy(rpool.Name, pool->RecyclePool->name(), sizeof(rpool.Name));
+      if (db_get_pool_record(jcr, db, &rpool)) {
+        pr->RecyclePoolId = rpool.PoolId;
+      } else {
+        Jmsg(jcr, M_WARNING, 0,
+        _("Can't set %s RecyclePool to %s, %s is not in database.\n" \
+          "Try to update it with 'update pool=%s'\n"),
+        pool->name(), rpool.Name, rpool.Name,pool->name());
+
+        ret = false;
+      }
+   } else {                    /* no RecyclePool used, set it to 0 */
+      pr->RecyclePoolId = 0;
+   }
+   return ret;
+}
+
 
 /*
  * Create a pool record from a given Pool resource
@@ -527,7 +607,7 @@ int create_pool(JCR *jcr, B_DB *db, POOL *pool, e_pool_op op)
 
    memset(&pr, 0, sizeof(POOL_DBR));
 
-   bstrncpy(pr.Name, pool->hdr.name, sizeof(pr.Name));
+   bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
 
    if (db_get_pool_record(jcr, db, &pr)) {
       /* Pool Exists */
@@ -556,7 +636,7 @@ static int create_cmd(UAContext *ua, const char *cmd)
 {
    POOL *pool;
 
-   if (!open_db(ua)) {
+   if (!open_client_db(ua)) {
       return 1;
    }
 
@@ -568,7 +648,7 @@ static int create_cmd(UAContext *ua, const char *cmd)
    switch (create_pool(ua->jcr, ua->db, pool, POOL_OP_CREATE)) {
    case 0:
       bsendmsg(ua, _("Error: Pool %s already exists.\n"
-               "Use update to change it.\n"), pool->hdr.name);
+               "Use update to change it.\n"), pool->name());
       break;
 
    case -1:
@@ -578,7 +658,7 @@ static int create_cmd(UAContext *ua, const char *cmd)
    default:
      break;
    }
-   bsendmsg(ua, _("Pool %s created.\n"), pool->hdr.name);
+   bsendmsg(ua, _("Pool %s created.\n"), pool->name());
    return 1;
 }
 
@@ -593,7 +673,7 @@ static int python_cmd(UAContext *ua, const char *cmd)
 {
    if (ua->argc >= 2 && strcasecmp(ua->argk[1], NT_("restart")) == 0) {
       term_python_interpreter();
-      init_python_interpreter(director->hdr.name
+      init_python_interpreter(director->name()
          director->scripts_directory, "DirStartUp");
       bsendmsg(ua, _("Python interpreter restarted.\n"));
    } else {
@@ -612,15 +692,15 @@ static int setip_cmd(UAContext *ua, const char *cmd)
 {
    CLIENT *client;
    char buf[1024];
-   if (!ua->cons || !acl_access_ok(ua, Client_ACL, ua->cons->hdr.name)) {
-      bsendmsg(ua, _("Illegal command from this console.\n"));
+   if (!ua->cons || !acl_access_ok(ua, Client_ACL, ua->cons->name())) {
+      bsendmsg(ua, _("Unauthorized command from this console.\n"));
       return 1;
    }
    LockRes();
-   client = (CLIENT *)GetResWithName(R_CLIENT, ua->cons->hdr.name);
+   client = (CLIENT *)GetResWithName(R_CLIENT, ua->cons->name());
 
    if (!client) {
-      bsendmsg(ua, _("Client \"%s\" not found.\n"), ua->cons->hdr.name);
+      bsendmsg(ua, _("Client \"%s\" not found.\n"), ua->cons->name());
       goto get_out;
    }
    if (client->address) {
@@ -630,7 +710,7 @@ static int setip_cmd(UAContext *ua, const char *cmd)
    sockaddr_to_ascii(&(ua->UA_sock->client_addr), buf, sizeof(buf));
    client->address = bstrdup(buf);
    bsendmsg(ua, _("Client \"%s\" address set to %s\n"),
-            client->hdr.name, client->address);
+            client->name(), client->address);
 get_out:
    UnlockRes();
    return 1;
@@ -658,12 +738,12 @@ static void do_en_disable_cmd(UAContext *ua, bool setting)
       return;
    }
 
-   if (!acl_access_ok(ua, Job_ACL, job->hdr.name)) {
-      bsendmsg(ua, _("Illegal command from this console.\n"));
+   if (!acl_access_ok(ua, Job_ACL, job->name())) {
+      bsendmsg(ua, _("Unauthorized command from this console.\n"));
       return;
    }
    job->enabled = setting;
-   bsendmsg(ua, _("Job \"%s\" %sabled\n"), job->hdr.name, setting?"en":"dis");
+   bsendmsg(ua, _("Job \"%s\" %sabled\n"), job->name(), setting?"en":"dis");
    return;
 }
 
@@ -717,7 +797,7 @@ static void do_client_setdebug(UAContext *ua, CLIENT *client, int level, int tra
    ua->jcr->client = client;
    /* Try to connect for 15 seconds */
    bsendmsg(ua, _("Connecting to Client %s at %s:%d\n"),
-      client->hdr.name, client->address, client->FDport);
+      client->name(), client->address, client->FDport);
    if (!connect_to_file_daemon(ua->jcr, 1, 15, 0)) {
       bsendmsg(ua, _("Failed to connect to Client.\n"));
       return;
@@ -824,7 +904,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd)
    int trace_flag = -1;
    int i;
 
-   if (!open_db(ua)) {
+   if (!open_client_db(ua)) {
       return 1;
    }
    Dmsg1(120, "setdebug:%s:\n", cmd);
@@ -958,7 +1038,7 @@ static int var_cmd(UAContext *ua, const char *cmd)
    POOLMEM *val = get_pool_memory(PM_FNAME);
    char *var;
 
-   if (!open_db(ua)) {
+   if (!open_client_db(ua)) {
       return 1;
    }
    for (var=ua->cmd; *var != ' '; ) {    /* skip command */
@@ -995,12 +1075,20 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
       if (strcasecmp(ua->argk[i], NT_("job")) == 0) {
          if (ua->argv[i]) {
             job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
+            if (job && !acl_access_ok(ua, Job_ACL, job->name())) {
+               bsendmsg(ua, _("No authorization for Job \"%s\"\n"), job->name());
+               return 1;
+            }
             continue;
          }
       }
       if (strcasecmp(ua->argk[i], NT_("fileset")) == 0) {
          if (ua->argv[i]) {
             fileset = (FILESET *)GetResWithName(R_FILESET, ua->argv[i]);
+            if (fileset && !acl_access_ok(ua, FileSet_ACL, fileset->name())) {
+               bsendmsg(ua, _("No authorization for FileSet \"%s\"\n"), fileset->name());
+               return 1;
+            }
             continue;
          }
       }
@@ -1026,6 +1114,10 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
          bsendmsg(ua, _("No job specified.\n"));
          return 1;
       }
+      if (!acl_access_ok(ua, Job_ACL, job->name())) {
+         bsendmsg(ua, _("No authorization for Job \"%s\"\n"), job->name());
+         return 1;
+      }
    }
    if (!client) {
       client = job->client;
@@ -1056,7 +1148,7 @@ static int estimate_cmd(UAContext *ua, const char *cmd)
    get_level_since_time(ua->jcr, since, sizeof(since));
 
    bsendmsg(ua, _("Connecting to Client %s at %s:%d\n"),
-      job->client->hdr.name, job->client->address, job->client->FDport);
+      job->client->name(), job->client->address, job->client->FDport);
    if (!connect_to_file_daemon(jcr, 1, 15, 0)) {
       bsendmsg(ua, _("Failed to connect to Client.\n"));
       return 1;
@@ -1131,7 +1223,7 @@ static int delete_cmd(UAContext *ua, const char *cmd)
       NT_("jobid"),
       NULL};
 
-   if (!open_db(ua)) {
+   if (!open_client_db(ua)) {
       return 1;
    }
 
@@ -1319,7 +1411,7 @@ static void do_mount_cmd(UAContext *ua, const char *command)
    int drive;
    int slot = -1;
 
-   if (!open_db(ua)) {
+   if (!open_client_db(ua)) {
       return;
    }
    Dmsg2(120, "%s: %s\n", command, ua->UA_sock->msg);
@@ -1407,14 +1499,14 @@ static int use_cmd(UAContext *ua, const char *cmd)
    }
    if (open_db(ua)) {
       bsendmsg(ua, _("Using Catalog name=%s DB=%s\n"),
-         ua->catalog->hdr.name, ua->catalog->db_name);
+         ua->catalog->name(), ua->catalog->db_name);
    }
    return 1;
 }
 
 int quit_cmd(UAContext *ua, const char *cmd)
 {
-   ua->quit = TRUE;
+   ua->quit = true;
    return 1;
 }
 
@@ -1465,7 +1557,7 @@ int wait_cmd(UAContext *ua, const char *cmd)
 
    uint32_t jobid = 0 ;
 
-   if (!open_db(ua)) {
+   if (!open_client_db(ua)) {
       bsendmsg(ua, _("ERR: Can't open db\n")) ;
       return 1;
    }
@@ -1602,6 +1694,85 @@ static int version_cmd(UAContext *ua, const char *cmd)
    return 1;
 }
 
+/* 
+ * This call explicitly checks for a catalog=xxx and
+ *  if given, opens that catalog.  It also checks for
+ *  client=xxx and if found, opens the catalog 
+ *  corresponding to that client. If we still don't 
+ *  have a catalog, look for a Job keyword and get the
+ *  catalog from its client record.
+ */
+bool open_client_db(UAContext *ua)
+{
+   int i;
+   CAT *catalog;
+   CLIENT *client;
+   JOB *job;
+
+   /* Try for catalog keyword */
+   i = find_arg_with_value(ua, NT_("catalog"));
+   if (i >= 0) {
+      if (!acl_access_ok(ua, Catalog_ACL, ua->argv[i])) {
+         bsendmsg(ua, _("No authorization for Catalog \"%s\"\n"), ua->argv[i]);
+         return false;
+      }
+      catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]);
+      if (catalog) {
+         if (ua->catalog && ua->catalog != catalog) {
+            close_db(ua);
+         }
+         ua->catalog = catalog;
+         return open_db(ua);
+      }
+   }
+
+   /* Try for client keyword */
+   i = find_arg_with_value(ua, NT_("client"));
+   if (i >= 0) {
+      if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
+         bsendmsg(ua, _("No authorization for Client \"%s\"\n"), ua->argv[i]);
+         return false;
+      }
+      client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
+      if (client) {
+         catalog = client->catalog;
+         if (ua->catalog && ua->catalog != catalog) {
+            close_db(ua);
+         }
+         if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
+            bsendmsg(ua, _("No authorization for Catalog \"%s\"\n"), catalog->name());
+            return false;
+         }
+         ua->catalog = catalog;
+         return open_db(ua);
+      }
+   }
+
+   /* Try for Job keyword */
+   i = find_arg_with_value(ua, NT_("job"));
+   if (i >= 0) {
+      if (!acl_access_ok(ua, Job_ACL, ua->argv[i])) {
+         bsendmsg(ua, _("No authorization for Job \"%s\"\n"), ua->argv[i]);
+         return false;
+      }
+      job = (JOB *)GetResWithName(R_JOB, ua->argv[i]);
+      if (job) {
+         catalog = job->client->catalog;
+         if (ua->catalog && ua->catalog != catalog) {
+            close_db(ua);
+         }
+         if (!acl_access_ok(ua, Catalog_ACL, catalog->name())) {
+            bsendmsg(ua, _("No authorization for Catalog \"%s\"\n"), catalog->name());
+            return false;
+         }
+         ua->catalog = catalog;
+         return open_db(ua);
+      }
+   }
+
+   return open_db(ua);
+}
+
 
 /*
  * Open the catalog database.
@@ -1627,7 +1798,7 @@ bool open_db(UAContext *ua)
                              ua->catalog->db_port, ua->catalog->db_socket,
                              ua->catalog->mult_db_connections);
    if (!ua->db || !db_open_database(ua->jcr, ua->db)) {
-      bsendmsg(ua, _("Could not open database \"%s\".\n"),
+      bsendmsg(ua, _("Could not open catalog database \"%s\".\n"),
                  ua->catalog->db_name);
       if (ua->db) {
          bsendmsg(ua, "%s", db_strerror(ua->db));
@@ -1636,6 +1807,7 @@ bool open_db(UAContext *ua)
       return false;
    }
    ua->jcr->db = ua->db;
+   bsendmsg(ua, _("Using Catalog \"%s\"\n"), ua->catalog->name()); 
    Dmsg1(150, "DB %s opened\n", ua->catalog->db_name);
    return true;
 }