]> git.sur5r.net Git - bacula/bacula/commitdiff
First cut Console ACLs
authorKern Sibbald <kern@sibbald.com>
Sat, 17 Jan 2004 14:10:22 +0000 (14:10 +0000)
committerKern Sibbald <kern@sibbald.com>
Sat, 17 Jan 2004 14:10:22 +0000 (14:10 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1014 91ce42f0-d328-0410-95d8-f526ca767f89

22 files changed:
bacula/kernstodo
bacula/src/console/authenticate.c
bacula/src/console/console.c
bacula/src/console/console_conf.c
bacula/src/console/console_conf.h
bacula/src/dird/Makefile.in
bacula/src/dird/bacula-dir.conf.in
bacula/src/dird/dird_conf.c
bacula/src/dird/dird_conf.h
bacula/src/dird/protos.h
bacula/src/dird/ua.h
bacula/src/dird/ua_acl.c [new file with mode: 0644]
bacula/src/dird/ua_cmds.c
bacula/src/dird/ua_output.c
bacula/src/dird/ua_select.c
bacula/src/gnome2-console/authenticate.c
bacula/src/gnome2-console/console.c
bacula/src/gnome2-console/console_conf.c
bacula/src/gnome2-console/console_conf.h
bacula/src/lib/alist.h
bacula/src/lib/lex.c
bacula/src/lib/parse_conf.c

index d8790bd7381c13d6130fcd367e951730508bf12c..9727a4b2bc18aa31287510d984793cbf9e526fd4 100644 (file)
@@ -58,6 +58,7 @@ For 1.33 Testing/Documentation:
 - Document Pool keyword for restore.
                 
 For 1.33
+- Implement alist processing for ACLs from Console.
 - Finish code passing files=nnn to restore start.
 - Add Console usr permissions -- do by adding regex filters for
   jobs, clients, storage, ...
index b6f0726a4cc4aa836ff14a104434250f4cbdc399..ab503db8f231a5d22d57414fbbb2d7cad3ced7ac 100644 (file)
@@ -47,21 +47,28 @@ static char OKhello[]   = "1000 OK:";
 /*
  * Authenticate Director
  */
-int authenticate_director(JCR *jcr, DIRRES *director, char *name)
+int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
 {
    BSOCK *dir = jcr->dir_bsock;
    int ssl_need = BNET_SSL_NONE;
    char bashed_name[MAX_NAME_LENGTH];
+   char *password;
 
    /* 
     * Send my name to the Director then do authentication
     */
-   bstrncpy(bashed_name, name, sizeof(bashed_name));
-   bash_spaces(bashed_name);
+   if (cons) {
+      bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name));
+      bash_spaces(bashed_name);
+      password = cons->password;
+   } else {
+      bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
+      password = director->password;
+   }
    bnet_fsend(dir, hello, bashed_name);
 
-   if (!cram_md5_get_auth(dir, director->password, ssl_need) || 
-       !cram_md5_auth(dir, director->password, ssl_need)) {
+   if (!cram_md5_get_auth(dir, password, ssl_need) || 
+       !cram_md5_auth(dir, password, ssl_need)) {
       sendit( _("Director authorization problem.\n"
             "Most likely the passwords do not agree.\n"));  
       return 0;
index 8ea78bbbad7833e7bf3e61b3fb78cfc998395c07..6436ab9a3549e23e4470ff775e47356b1fa3eedb 100644 (file)
@@ -51,7 +51,7 @@ extern int rl_catch_signals;
 #endif
 
 /* Imported functions */
-int authenticate_director(JCR *jcr, DIRRES *director, char *name);
+int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
 
 
 
@@ -404,13 +404,7 @@ try_again:
    LockRes();
    CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
    UnlockRes();
-   char *con_name;
-   if (cons) {
-      con_name = cons->hdr.name;
-   } else {
-      con_name = "*UserAgent*";
-   }
-   if (!authenticate_director(&jcr, dir, con_name)) {
+   if (!authenticate_director(&jcr, dir, cons)) {
       fprintf(stderr, "ERR=%s", UA_sock->msg);
       terminate_console(0);
       return 1;
index ef7eb4939982052896a7adc1bca07e7f33cac770..daeebc898b0d48ac832335896187e71524143a0f 100644 (file)
@@ -72,6 +72,7 @@ static struct res_items cons_items[] = {
    {"rcfile",      store_dir,      ITEM(res_cons.rc_file), 0, 0, 0},
    {"historyfile", store_dir,      ITEM(res_cons.hist_file), 0, 0, 0},
    {"requiressl",  store_yesno,    ITEM(res_cons.require_ssl), 1, ITEM_DEFAULT, 0},
+   {"password",    store_password, ITEM(res_cons.password), 0, ITEM_REQUIRED, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
 
@@ -81,7 +82,7 @@ static struct res_items dir_items[] = {
    {"name",        store_name,     ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,      ITEM(res_dir.hdr.desc), 0, 0, 0},
    {"dirport",     store_int,      ITEM(res_dir.DIRport),  0, ITEM_DEFAULT, 9101},
-   {"address",     store_str,      ITEM(res_dir.address),  0, ITEM_REQUIRED, 0},
+   {"address",     store_str,      ITEM(res_dir.address),  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},
    {NULL, NULL, NULL, 0, 0, 0} 
index e01c21bf78916fd4281f20ecf729954e5ac62760..0b9d52962c032b27ae39983e94acc62376b2e17b 100644 (file)
@@ -34,6 +34,7 @@ struct s_res_con {
    char *rc_file;                     /* startup file */
    char *hist_file;                   /* command history file */
    int require_ssl;                   /* Require SSL on all connections */
+   char *password;                    /* UA server password */
 };
 typedef struct s_res_con CONRES;
 
index 851d93d3365472ecd0a63d8ee4b20eb60d5aeddf..a306b014844b07298b477963e5dd0dc908bdad31 100644 (file)
@@ -29,7 +29,7 @@ SVRSRCS = dird.c admin.c authenticate.c \
          jobq.c mountreq.c msgchan.c next_vol.c newvol.c \
          recycle.c restore.c run_conf.c \
          scheduler.c sql_cmds.c \
-         ua_cmds.c ua_dotcmds.c \
+         ua_acl.c ua_cmds.c ua_dotcmds.c \
          ua_query.c \
          ua_input.c ua_label.c ua_output.c ua_prune.c \
          ua_purge.c ua_restore.c ua_run.c \
@@ -42,7 +42,7 @@ SVROBJS = dird.o admin.o authenticate.o \
          jobq.o mountreq.o msgchan.o next_vol.o newvol.o \
          recycle.o restore.o run_conf.o \
          scheduler.o sql_cmds.o \
-         ua_cmds.o ua_dotcmds.o \
+         ua_acl.o ua_cmds.o ua_dotcmds.o \
          ua_query.o \
          ua_input.o ua_label.o ua_output.o ua_prune.o \
          ua_purge.o ua_restore.o ua_run.o \
index bb56eacb042686fc4165c25db1564aa44fca56ad..a76448c7e706ed6d3931416aae3fa3d31dc78aac 100644 (file)
@@ -177,6 +177,11 @@ Catalog {
 #  and to the console
 Messages {
   Name = Standard
+#
+# NOTE! If you send to two email or more email addresses, you will need
+#  to replace the %r in the from field (-f part) with a single valid
+#  email address in both the mailcommand and the operatorcommand.
+#
   mailcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: %t %e of %c %l\" %r"
   operatorcommand = "@sbindir@/bsmtp -h @smtp_host@ -f \"\(Bacula\) %r\" -s \"Bacula: Intervention needed for %j\" %r"
   mail = @job_email@ = all, !skipped            
index 3f4303b8a5871a780f7e3cc12fcf4dda03006429..f41dce96e5d31066b13b56fc92fe985a9b6761e6 100644 (file)
@@ -64,6 +64,7 @@ extern void store_inc(LEX *lc, struct res_items *item, int index, int pass);
 void store_jobtype(LEX *lc, struct res_items *item, int index, int pass);
 void store_level(LEX *lc, struct res_items *item, int index, int pass);
 void store_replace(LEX *lc, struct res_items *item, int index, int pass);
+void store_acl(LEX *lc, struct res_items *item, int index, int pass);
 
 
 /* We build the current resource here as we are
@@ -113,6 +114,15 @@ static struct res_items con_items[] = {
    {"description", store_str,      ITEM(res_con.hdr.desc), 0, 0, 0},
    {"enablessl",   store_yesno,    ITEM(res_con.enable_ssl), 1, ITEM_DEFAULT, 0},
    {"password",    store_password, ITEM(res_con.password), 0, ITEM_REQUIRED, 0},
+   {"jobacl",      store_acl,      ITEM(res_con.ACL_lists), Job_ACL, 0, 0},
+   {"clientacl",   store_acl,      ITEM(res_con.ACL_lists), Client_ACL, 0, 0},
+   {"storageacl",  store_acl,      ITEM(res_con.ACL_lists), Storage_ACL, 0, 0},
+   {"scheduleacl", store_acl,      ITEM(res_con.ACL_lists), Schedule_ACL, 0, 0},
+   {"runacl",      store_acl,      ITEM(res_con.ACL_lists), Run_ACL, 0, 0},
+   {"poolacl",     store_acl,      ITEM(res_con.ACL_lists), Pool_ACL, 0, 0},
+   {"commandacl",  store_acl,      ITEM(res_con.ACL_lists), Command_ACL, 0, 0},
+   {"filesetacl",  store_acl,      ITEM(res_con.ACL_lists), FileSet_ACL, 0, 0},
+   {"catalogacl",  store_acl,      ITEM(res_con.ACL_lists), Catalog_ACL, 0, 0},
    {NULL, NULL, NULL, 0, 0, 0}
 };
 
@@ -250,16 +260,6 @@ static struct res_items sch_items[] = {
    {NULL, NULL, NULL, 0, 0, 0} 
 };
 
-/* Group resource -- not implemented
- *
- *   name         handler     value                 code flags    default_value
- */
-static struct res_items group_items[] = {
-   {"name",        store_name, ITEM(res_group.hdr.name), 0, ITEM_REQUIRED, 0},
-   {"description", store_str,  ITEM(res_group.hdr.desc), 0, 0, 0},
-   {NULL, NULL, NULL, 0, 0, 0} 
-};
-
 /* Pool resource
  *
  *   name            handler     value                        code flags default_value
@@ -323,7 +323,6 @@ struct s_res resources[] = {
    {"catalog",       cat_items,   R_CATALOG,   NULL},
    {"schedule",      sch_items,   R_SCHEDULE,  NULL},
    {"fileset",       fs_items,    R_FILESET,   NULL},
-   {"group",         group_items, R_GROUP,     NULL},
    {"pool",          pool_items,  R_POOL,      NULL},
    {"messages",      msgs_items,  R_MSGS,      NULL},
    {"counter",       counter_items, R_COUNTER, NULL},
@@ -402,7 +401,7 @@ char *level_to_str(int level)
    static char level_no[30];
    char *str = level_no;
 
-   sprintf(level_no, "%d", level);    /* default if not found */
+   bsnprintf(level_no, sizeof(level_no), "%d", level);    /* default if not found */
    for (i=0; joblevels[i].level_name; i++) {
       if (level == joblevels[i].level) {
         str = joblevels[i].level_name;
@@ -567,7 +566,7 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       if (res->res_sch.run) {
         int i;
         RUN *run = res->res_sch.run;
-        char buf[1000], num[10];
+        char buf[1000], num[30];
          sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
         if (!run) {
            break;
@@ -577,7 +576,7 @@ next_run:
          bstrncpy(buf, "      hour=", sizeof(buf));
         for (i=0; i<24; i++) {
            if (bit_is_set(i, run->hour)) {
-               sprintf(num, "%d ", i);
+               bsnprintf(num, sizeof(num), "%d ", i);
               bstrncat(buf, num, sizeof(buf));
            }
         }
@@ -586,7 +585,7 @@ next_run:
          bstrncpy(buf, "      mday=", sizeof(buf));
         for (i=0; i<31; i++) {
            if (bit_is_set(i, run->mday)) {
-               sprintf(num, "%d ", i);
+               bsnprintf(num, sizeof(num), "%d ", i);
               bstrncat(buf, num, sizeof(buf));
            }
         }
@@ -595,7 +594,7 @@ next_run:
          bstrncpy(buf, "      month=", sizeof(buf));
         for (i=0; i<12; i++) {
            if (bit_is_set(i, run->month)) {
-               sprintf(num, "%d ", i);
+               bsnprintf(num, sizeof(num), "%d ", i);
               bstrncat(buf, num, sizeof(buf));
            }
         }
@@ -604,7 +603,7 @@ next_run:
          bstrncpy(buf, "      wday=", sizeof(buf));
         for (i=0; i<7; i++) {
            if (bit_is_set(i, run->wday)) {
-               sprintf(num, "%d ", i);
+               bsnprintf(num, sizeof(num), "%d ", i);
               bstrncat(buf, num, sizeof(buf));
            }
         }
@@ -613,7 +612,7 @@ next_run:
          bstrncpy(buf, "      wom=", sizeof(buf));
         for (i=0; i<5; i++) {
            if (bit_is_set(i, run->wom)) {
-               sprintf(num, "%d ", i);
+               bsnprintf(num, sizeof(num), "%d ", i);
               bstrncat(buf, num, sizeof(buf));
            }
         }
@@ -622,7 +621,7 @@ next_run:
          bstrncpy(buf, "      woy=", sizeof(buf));
         for (i=0; i<54; i++) {
            if (bit_is_set(i, run->woy)) {
-               sprintf(num, "%d ", i);
+               bsnprintf(num, sizeof(num), "%d ", i);
               bstrncat(buf, num, sizeof(buf));
            }
         }
@@ -650,9 +649,6 @@ next_run:
          sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name);
       }
       break;
-   case R_GROUP:
-      sendit(sock, "Group: name=%s\n", res->res_group.hdr.name);
-      break;
    case R_POOL:
       sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name,
              res->res_pool.pool_type);
@@ -761,6 +757,12 @@ void free_resource(int type)
       if (res->res_con.password) {
         free(res->res_con.password);
       }
+      for (int i=0; i<Num_ACL; i++) {
+        if (res->res_con.ACL_lists[i]) {
+           delete res->res_con.ACL_lists[i];
+           res->res_con.ACL_lists[i] = NULL;
+        }
+      }
       break;
    case R_CLIENT:
       if (res->res_client.address) {
@@ -876,8 +878,6 @@ void free_resource(int type)
       free_msgs_res((MSGS *)res);  /* free message resource */
       res = NULL;
       break;
-   case R_GROUP:
-      break;
    default:
       printf("Unknown resource type %d in free_resource.\n", type);
    }
@@ -935,7 +935,6 @@ void save_resource(int type, struct res_items *items, int pass)
       case R_CONSOLE:
       case R_CATALOG:
       case R_STORAGE:
-      case R_GROUP:
       case R_POOL:
       case R_MSGS:
       case R_FILESET:
@@ -1037,9 +1036,6 @@ void save_resource(int type, struct res_items *items, int pass)
    case R_SCHEDULE:
       size = sizeof(SCHED);
       break;
-   case R_GROUP:
-      size = sizeof(GROUP);
-      break;
    case R_POOL:
       size = sizeof(POOL);
       break;
@@ -1150,6 +1146,34 @@ void store_replace(LEX *lc, struct res_items *item, int index, int pass)
    set_bit(index, res_all.hdr.item_present);
 }
 
+/* 
+ * Store ACL (access control list)
+ *
+ */
+void store_acl(LEX *lc, struct res_items *item, int index, int pass)
+{
+   int token;
+
+   for (;;) {
+      token = lex_get_token(lc, T_NAME);
+      if (pass == 1) {
+        if (((alist **)item->value)[item->code] == NULL) {   
+           ((alist **)item->value)[item->code] = new alist(10, owned_by_alist);
+//          Dmsg1(400, "Defined new ACL alist at %d\n", item->code);
+        }
+        ((alist **)item->value)[item->code]->append(bstrdup(lc->str));
+//       Dmsg2(400, "Appended to %d %s\n", item->code, lc->str);
+      }
+      token = lex_get_token(lc, T_ALL);
+      if (token == T_COMMA) {
+        continue;                    /* get another ACL */
+      }
+      break;
+   }
+   set_bit(index, res_all.hdr.item_present);
+}
+
+
 #ifdef old_deprecated_code
 /* 
  * Store backup/verify info for Job record 
index 604c8799839cc5a0ad7649a31e14e3624901e766..ee2f15847d55fbdfb0f62c327ed948d3d4988b0a 100644 (file)
 /*
  * Resource codes -- they must be sequential for indexing   
  */
-#define R_FIRST               1001
-
-#define R_DIRECTOR            1001
-#define R_CLIENT              1002
-#define R_JOB                 1003
-#define R_STORAGE             1004
-#define R_CATALOG             1005
-#define R_SCHEDULE            1006
-#define R_FILESET             1007
-#define R_GROUP               1008
-#define R_POOL                1009
-#define R_MSGS                1010
-#define R_COUNTER             1011
-#define R_CONSOLE             1012
-#define R_JOBDEFS             1013
-
-#define R_LAST                R_JOBDEFS    
+enum {
+   R_DIRECTOR = 1001,
+   R_CLIENT,
+   R_JOB,
+   R_STORAGE,
+   R_CATALOG,
+   R_SCHEDULE,
+   R_FILESET,
+   R_POOL,
+   R_MSGS,
+   R_COUNTER,
+   R_CONSOLE,
+   R_JOBDEFS
+};
+
+#define R_FIRST  R_DIRECTOR
+#define R_LAST   R_JOBDEFS    
 
 /*
  * Some resource attributes
@@ -106,6 +106,23 @@ struct DIRRES {
    utime_t SDConnectTimeout;          /* timeout in seconds */
 };
 
+
+/*
+ * Console ACL positions
+ */
+enum {
+   Job_ACL = 0,
+   Client_ACL,
+   Storage_ACL,
+   Schedule_ACL,
+   Run_ACL,
+   Pool_ACL,
+   Command_ACL,
+   FileSet_ACL,
+   Catalog_ACL,
+   Num_ACL                            /* keep last */
+};
+
 /* 
  *    Console Resource
  */
@@ -113,6 +130,7 @@ struct CONRES {
    RES   hdr;
    char *password;                    /* UA server password */
    int enable_ssl;                    /* Use SSL */
+   alist *ACL_lists[Num_ACL];         /* pointers to ACLs */
 };
 
 
@@ -261,14 +279,6 @@ struct SCHED {
    RUN *run;
 };
 
-/*
- *   Group Resource (not used)
- *
- */
-struct GROUP {
-   RES   hdr;
-};
-
 /*
  *   Counter Resource
  */
@@ -323,7 +333,6 @@ union URES {
    JOB        res_job;
    FILESET    res_fs;
    SCHED      res_sch;
-   GROUP      res_group;
    POOL       res_pool;
    MSGS       res_msgs;
    COUNTER    res_counter;
index 2eed7fdbaf17bbb3d46bf5875ce4e39292598cf8..87bc67d8e521a8d7ba6658b2f12635c9a4793b42 100644 (file)
@@ -62,7 +62,7 @@ int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp);
 
 /* fd_cmds.c */
 extern int connect_to_file_daemon(JCR *jcr, int retry_interval,
-                                  int max_retry_time, int verbose);
+                                 int max_retry_time, int verbose);
 extern int send_include_list(JCR *jcr);
 extern int send_exclude_list(JCR *jcr);
 extern int send_bootstrap_file(JCR *jcr);
@@ -70,7 +70,7 @@ extern int send_level_command(JCR *jcr);
 extern int get_attributes_and_put_in_catalog(JCR *jcr);
 extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId);
 extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname, 
-                          char *link, char *attr, int stream);
+                         char *link, char *attr, int stream);
 extern void get_level_since_time(JCR *jcr, char *since, int since_len);
 extern int send_run_before_and_after_commands(JCR *jcr);
 
@@ -94,7 +94,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf);
 
 /* msgchan.c */
 extern int connect_to_storage_daemon(JCR *jcr, int retry_interval,    
-                              int max_retry_time, int verbose);
+                             int max_retry_time, int verbose);
 extern int start_storage_daemon_job(JCR *jcr);
 extern int start_storage_daemon_message_thread(JCR *jcr);
 extern int bget_dirmsg(BSOCK *bs);
@@ -108,6 +108,10 @@ void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, char **reason)
 /* newvol.c */
 int newVolume(JCR *jcr, MEDIA_DBR *mr);
 
+/* ua_acl.c */
+bool acl_access_ok(UAContext *ua, int acl, char *item);
+bool acl_access_ok(UAContext *ua, int acl, char *item, int len);
+
 /* ua_cmds.c */
 int do_a_command(UAContext *ua, char *cmd);
 int do_a_dot_command(UAContext *ua, char *cmd);
@@ -142,28 +146,28 @@ JCR *create_control_jcr(char *base_name, int job_type);
 void free_ua_context(UAContext *ua);
 
 /* ua_select.c */
-STORE   *select_storage_resource(UAContext *ua);
-JOB     *select_job_resource(UAContext *ua);
-JOB     *select_restore_job_resource(UAContext *ua);
-CLIENT  *select_client_resource(UAContext *ua);
+STORE  *select_storage_resource(UAContext *ua);
+JOB    *select_job_resource(UAContext *ua);
+JOB    *select_restore_job_resource(UAContext *ua);
+CLIENT *select_client_resource(UAContext *ua);
 FILESET *select_fileset_resource(UAContext *ua);
-int     select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
-int     select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
-int     select_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int     select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
-
-void    start_prompt(UAContext *ua, char *msg);
-void    add_prompt(UAContext *ua, char *prompt);
-int     do_prompt(UAContext *ua, char *automsg, char *msg, char *prompt, int max_prompt);
-CAT    *get_catalog_resource(UAContext *ua);           
+int    select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr);
+int    select_media_dbr(UAContext *ua, MEDIA_DBR *mr);
+int    select_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int    select_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+
+void   start_prompt(UAContext *ua, char *msg);
+void   add_prompt(UAContext *ua, char *prompt);
+int    do_prompt(UAContext *ua, char *automsg, char *msg, char *prompt, int max_prompt);
+CAT    *get_catalog_resource(UAContext *ua);          
 STORE  *get_storage_resource(UAContext *ua, int use_default);
-int     get_media_type(UAContext *ua, char *MediaType, int max_media);
-int     get_pool_dbr(UAContext *ua, POOL_DBR *pr);
-int     get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
+int    get_media_type(UAContext *ua, char *MediaType, int max_media);
+int    get_pool_dbr(UAContext *ua, POOL_DBR *pr);
+int    get_client_dbr(UAContext *ua, CLIENT_DBR *cr);
 POOL   *get_pool_resource(UAContext *ua);
 POOL   *select_pool_resource(UAContext *ua);
 CLIENT *get_client_resource(UAContext *ua);
-int     get_job_dbr(UAContext *ua, JOB_DBR *jr);
+int    get_job_dbr(UAContext *ua, JOB_DBR *jr);
 
 int find_arg_keyword(UAContext *ua, char **list);
 int find_arg(UAContext *ua, char *keyword);
index 3a3b49dedf6c4732d42681f008ed0791815d5372..d2ded609b44d59e11a1e754e5c6811375e75f8db 100644 (file)
@@ -28,7 +28,6 @@
 #ifndef __UA_H_
 #define __UA_H_ 1
 
-
 struct UAContext {
    BSOCK *UA_sock;
    BSOCK *sd;
@@ -62,5 +61,4 @@ struct TREE_CTX {
    UAContext *ua;
 };
 
-
 #endif
diff --git a/bacula/src/dird/ua_acl.c b/bacula/src/dird/ua_acl.c
new file mode 100644 (file)
index 0000000..11a9053
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *
+ *   Bacula Director -- User Agent Access Control List (ACL) handling
+ *
+ *     Kern Sibbald, January MMIV  
+ *
+ *   Version  $Id$
+ */
+
+/*
+   Copyright (C) 2004 Kern Sibbald and John Walker
+
+   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 program 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 program; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+   MA 02111-1307, USA.
+
+ */
+
+#include "bacula.h"
+#include "dird.h"
+
+/*  
+ * Check if access is permitted to item in acl   
+ */
+bool acl_access_ok(UAContext *ua, int acl, char *item)
+{
+   return acl_access_ok(ua, acl, item, strlen(item));
+}
+
+
+bool acl_access_ok(UAContext *ua, int acl, char *item, int len)
+{
+   if (!ua->cons) {
+      Dmsg0(400, "Root cons access OK.\n");
+      return true;                   /* No cons resource -> root console OK for everything */
+   }
+   alist *list = ua->cons->ACL_lists[acl];
+   if (!list) {
+      return false;                  /* List empty, reject */
+   }
+   for (int i=0; i<list->size(); i++) {
+      if (strncasecmp(item, (char *)list->get(i), len) == 0) {
+         Dmsg3(400, "Found %s in %d %s\n", item, acl, (char *)list->get(i));
+        return true;
+      }
+   }
+   return false;
+}
index c71a1341b4ff8a1e8077217d68ef229e3379880d..b5ac957074701a0b482dffa27317921c41ded0a3 100644 (file)
@@ -129,12 +129,11 @@ int do_a_command(UAContext *ua, char *cmd)
 {
    unsigned int i;
    int len, stat;
-   int found;
+   bool found = false;
 
-   found = 0;
    stat = 1;
 
-   Dmsg1(120, "Command: %s\n", ua->UA_sock->msg);
+   Dmsg1(200, "Command: %s\n", ua->UA_sock->msg);
    if (ua->argc == 0) {
       return 1;
    }
@@ -142,15 +141,16 @@ int do_a_command(UAContext *ua, char *cmd)
    len = strlen(ua->argk[0]);
    for (i=0; i<comsize; i++) {    /* search for command */
       if (strncasecmp(ua->argk[0],  _(commands[i].key), len) == 0) {
+        if (!acl_access_ok(ua, Command_ACL, ua->argk[0], len)) {
+           break;
+        }
         stat = (*commands[i].func)(ua, cmd);   /* go execute command */
-        found = 1;
+        found = true;
         break;
       }
    }
    if (!found) {
-      pm_strcat(&ua->UA_sock->msg, _(": is an illegal command\n"));
-      ua->UA_sock->msglen = strlen(ua->UA_sock->msg);
-      bnet_send(ua->UA_sock);
+      bnet_fsend(ua->UA_sock, _("%s: is an illegal command.\n"), ua->argk[0]);
    }
    return stat;
 }
index 9725a6e47d28412e90c2ba0120f28f443051bd7a..d20a42fdc4778bdaa729e17845b52e25d5d9a2fa 100644 (file)
@@ -82,7 +82,6 @@ static struct showstruct reses[] = {
    {N_("catalogs"),   R_CATALOG},
    {N_("schedules"),  R_SCHEDULE},
    {N_("filesets"),   R_FILESET},
-   {N_("groups"),     R_GROUP},
    {N_("pools"),      R_POOL},
    {N_("messages"),   R_MSGS},
    {N_("all"),        -1},
index 1572bfa341f884cfdc25cc483020d0b44a141a35..c667a8f7d0801c29131293c49cd71b624e8d51ed 100644 (file)
@@ -149,7 +149,9 @@ STORE *select_storage_resource(UAContext *ua)
    start_prompt(ua, _("The defined Storage resources are:\n"));
    LockRes();
    foreach_res(store, R_STORAGE) {
-      add_prompt(ua, store->hdr.name);
+      if (acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+        add_prompt(ua, store->hdr.name);
+      }
    }
    UnlockRes();
    do_prompt(ua, _("Storage"),  _("Select Storage resource"), name, sizeof(name));
@@ -168,7 +170,9 @@ FILESET *select_fileset_resource(UAContext *ua)
    start_prompt(ua, _("The defined FileSet resources are:\n"));
    LockRes();
    foreach_res(fs, R_FILESET) {
-      add_prompt(ua, fs->hdr.name);
+      if (acl_access_ok(ua, FileSet_ACL, fs->hdr.name)) {
+        add_prompt(ua, fs->hdr.name);
+      }
    }
    UnlockRes();
    do_prompt(ua, _("FileSet"), _("Select FileSet resource"), name, sizeof(name));
@@ -188,15 +192,19 @@ CAT *get_catalog_resource(UAContext *ua)
 
    for (i=1; i<ua->argc; i++) {
       if (strcasecmp(ua->argk[i], _("catalog")) == 0 && ua->argv[i]) {
-        catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]);
-        break;
+        if (acl_access_ok(ua, Catalog_ACL, ua->argv[i])) {
+           catalog = (CAT *)GetResWithName(R_CATALOG, ua->argv[i]);
+           break;
+        }
       }
    }
    if (!catalog) {
       start_prompt(ua, _("The defined Catalog resources are:\n"));
       LockRes();
       foreach_res(catalog, R_CATALOG) {
-        add_prompt(ua, catalog->hdr.name);
+        if (acl_access_ok(ua, Catalog_ACL, catalog->hdr.name)) {
+           add_prompt(ua, catalog->hdr.name);
+        }
       }
       UnlockRes();
       do_prompt(ua, _("Catalog"),  _("Select Catalog resource"), name, sizeof(name));
@@ -217,7 +225,9 @@ JOB *select_job_resource(UAContext *ua)
    start_prompt(ua, _("The defined Job resources are:\n"));
    LockRes();
    foreach_res(job, R_JOB) {
-      add_prompt(ua, job->hdr.name);
+      if (acl_access_ok(ua, Job_ACL, job->hdr.name)) {
+        add_prompt(ua, job->hdr.name);
+      }
    }
    UnlockRes();
    do_prompt(ua, _("Job"), _("Select Job resource"), name, sizeof(name));
@@ -236,7 +246,7 @@ JOB *select_restore_job_resource(UAContext *ua)
    start_prompt(ua, _("The defined Restore Job resources are:\n"));
    LockRes();
    foreach_res(job, R_JOB) {
-      if (job->JobType == JT_RESTORE) {
+      if (job->JobType == JT_RESTORE && acl_access_ok(ua, Job_ACL, job->hdr.name)) {
         add_prompt(ua, job->hdr.name);
       }
    }
@@ -259,7 +269,9 @@ CLIENT *select_client_resource(UAContext *ua)
    start_prompt(ua, _("The defined Client resources are:\n"));
    LockRes();
    foreach_res(client, R_CLIENT) {
-      add_prompt(ua, client->hdr.name);
+      if (acl_access_ok(ua, Client_ACL, client->hdr.name)) {
+        add_prompt(ua, client->hdr.name);
+      }
    }
    UnlockRes();
    do_prompt(ua, _("Client"),  _("Select Client (File daemon) resource"), name, sizeof(name));
@@ -280,6 +292,9 @@ CLIENT *get_client_resource(UAContext *ua)
    for (i=1; i<ua->argc; i++) {
       if ((strcasecmp(ua->argk[i], _("client")) == 0 ||
            strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) {
+        if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
+           break;
+        }
         client = (CLIENT *)GetResWithName(R_CLIENT, ua->argv[i]);
         if (client) {
            return client;
@@ -314,6 +329,9 @@ int get_client_dbr(UAContext *ua, CLIENT_DBR *cr)
    for (i=1; i<ua->argc; i++) {
       if ((strcasecmp(ua->argk[i], _("client")) == 0 ||               
            strcasecmp(ua->argk[i], _("fd")) == 0) && ua->argv[i]) {
+        if (!acl_access_ok(ua, Client_ACL, ua->argv[i])) {
+           break;
+        }
         bstrncpy(cr->Name, ua->argv[i], sizeof(cr->Name));
         if (!db_get_client_record(ua->jcr, ua->db, cr)) {
             bsendmsg(ua, _("Could not find Client \"%s\": ERR=%s"), ua->argv[i],
@@ -356,7 +374,8 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr)
    start_prompt(ua, _("Defined Clients:\n"));
    for (i=0; i < num_clients; i++) {
       ocr.ClientId = ids[i];
-      if (!db_get_client_record(ua->jcr, ua->db, &ocr)) {
+      if (!db_get_client_record(ua->jcr, ua->db, &ocr) ||
+         !acl_access_ok(ua, Client_ACL, ocr.Name)) {
         continue;
       }
       add_prompt(ua, ocr.Name);
@@ -391,7 +410,8 @@ int select_client_dbr(UAContext *ua, CLIENT_DBR *cr)
 int get_pool_dbr(UAContext *ua, POOL_DBR *pr)
 {
    if (pr->Name[0]) {                /* If name already supplied */
-      if (db_get_pool_record(ua->jcr, ua->db, pr)) {
+      if (db_get_pool_record(ua->jcr, ua->db, pr) &&
+         acl_access_ok(ua, Pool_ACL, pr->Name)) { 
         return pr->PoolId;
       }
       bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), pr->Name, db_strerror(ua->db));
@@ -413,7 +433,8 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
    uint32_t *ids; 
 
    for (i=1; i<ua->argc; i++) {
-      if (strcasecmp(ua->argk[i], _("pool")) == 0 && ua->argv[i]) {
+      if (strcasecmp(ua->argk[i], _("pool")) == 0 && ua->argv[i] &&
+         acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
         bstrncpy(pr->Name, ua->argv[i], sizeof(pr->Name));
         if (!db_get_pool_record(ua->jcr, ua->db, pr)) {
             bsendmsg(ua, _("Could not find Pool \"%s\": ERR=%s"), ua->argv[i],
@@ -438,7 +459,8 @@ int select_pool_dbr(UAContext *ua, POOL_DBR *pr)
    start_prompt(ua, _("Defined Pools:\n"));
    for (i=0; i < num_pools; i++) {
       opr.PoolId = ids[i];
-      if (!db_get_pool_record(ua->jcr, ua->db, &opr)) {
+      if (!db_get_pool_record(ua->jcr, ua->db, &opr) ||
+         !acl_access_ok(ua, Pool_ACL, opr.Name)) {
         continue;
       }
       add_prompt(ua, opr.Name);
@@ -525,7 +547,9 @@ POOL *select_pool_resource(UAContext *ua)
    start_prompt(ua, _("The defined Pool resources are:\n"));
    LockRes();
    foreach_res(pool, R_POOL) {
-      add_prompt(ua, pool->hdr.name);
+      if (acl_access_ok(ua, Pool_ACL, pool->hdr.name)) {
+        add_prompt(ua, pool->hdr.name);
+      }
    }
    UnlockRes();
    do_prompt(ua, _("Pool"), _("Select Pool resource"), name, sizeof(name));
@@ -545,7 +569,7 @@ POOL *get_pool_resource(UAContext *ua)
    int i;
    
    i = find_arg_with_value(ua, "pool");
-   if (i >= 0) {
+   if (i >= 0 && acl_access_ok(ua, Pool_ACL, ua->argv[i])) {
       pool = (POOL *)GetResWithName(R_POOL, ua->argv[i]);
       if (pool) {
         return pool;
@@ -593,7 +617,7 @@ int get_job_dbr(UAContext *ua, JOB_DBR *jr)
         jr->JobId = 0;
         bstrncpy(jr->Job, ua->argv[i], sizeof(jr->Job));
       } else if (strcasecmp(ua->argk[i], _("jobid")) == 0 && ua->argv[i]) {
-        jr->JobId = atoi(ua->argv[i]);
+        jr->JobId = str_to_int64(ua->argv[i]);
       } else {
         continue;
       }
@@ -760,7 +784,7 @@ STORE *get_storage_resource(UAContext *ua, int use_default)
            break;
 
          } else if (strcasecmp(ua->argk[i], _("jobid")) == 0) {
-           jobid = atoi(ua->argv[i]);
+           jobid = str_to_int64(ua->argv[i]);
            if (jobid <= 0) {
                bsendmsg(ua, _("Expecting jobid=nn command, got: %s\n"), ua->argk[i]);
               return NULL;
@@ -784,13 +808,19 @@ STORE *get_storage_resource(UAContext *ua, int use_default)
        }
       }
    }
-
+   if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+      store = NULL;
+   }
+   
    if (!store && store_name) {
       store = (STORE *)GetResWithName(R_STORAGE, store_name);
       if (!store) {
          bsendmsg(ua, "Storage resource \"%s\": not found\n", store_name);
       }
    }
+   if (store && !acl_access_ok(ua, Storage_ACL, store->hdr.name)) {
+      store = NULL;
+   }
    /* No keywords found, so present a selection list */
    if (!store) {
       store = select_storage_resource(ua);
index 0aa3f7d3659c443395e8ea631d863814fbc5a859..aa0e440b5cb42ff0b429adc1070432889dc1ca71 100644 (file)
@@ -45,21 +45,28 @@ static char OKhello[]   = "1000 OK:";
 /*
  * Authenticate Director
  */
-int authenticate_director(JCR *jcr, DIRRES *director, char *name)
+int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons)
 {
    BSOCK *dir = jcr->dir_bsock;
    int ssl_need = BNET_SSL_NONE;
    char bashed_name[MAX_NAME_LENGTH];
+   char *password;
 
    /* 
     * Send my name to the Director then do authentication
     */
-   bstrncpy(bashed_name, name, sizeof(bashed_name));
-   bash_spaces(bashed_name);
+   if (cons) {
+      bstrncpy(bashed_name, cons->hdr.name, sizeof(bashed_name));
+      bash_spaces(bashed_name);
+      password = cons->password;
+   } else {
+      bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name));
+      password = director->password;
+   }
    bnet_fsend(dir, hello, bashed_name);
 
-   if (!cram_md5_get_auth(dir, director->password, ssl_need) || 
-       !cram_md5_auth(dir, director->password, ssl_need)) {
+   if (!cram_md5_get_auth(dir, password, ssl_need) || 
+       !cram_md5_auth(dir, password, ssl_need)) {
       printf(_("%s: Director authorization problem.\n"), my_name);
       set_text(_("Director authorization problem.\n"), -1);
       return 0;
index b7e76655fabffd1ceccc3df1c0cbbb731a760929..b0b9b2b9f6f171cde3d080a60ad9b47ebc39b9f4 100644 (file)
@@ -32,7 +32,7 @@
 #include "support.h"
 
 /* Imported functions */
-int authenticate_director(JCR *jcr, DIRRES *director, char *name);
+int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
        
 /* Exported variables */
 GtkWidget *app1;            /* application window */
@@ -172,7 +172,7 @@ int main(int argc, char *argv[])
 
    LockRes();
    ndir = 0;
-   for (dir=NULL; (dir = (DIRRES *)GetNextRes(R_DIRECTOR, (RES *)dir)); ) {
+   foreach_res(dir, R_DIRECTOR) {
       ndir++;
    }
    UnlockRes();
@@ -181,10 +181,6 @@ int main(int argc, char *argv[])
 Without that I don't how to speak to the Director :-(\n"), configfile);
    }
 
-   if (test_config) {
-      terminate_console(0);
-      exit(0);
-   }
 
 
    app1 = create_app1();
@@ -212,13 +208,17 @@ Without that I don't how to speak to the Director :-(\n"), configfile);
  */
 
    LockRes();
-   for (con = NULL; (con = (CONRES *)GetNextRes(R_CONSOLE, (RES *)con)); ) {
+   foreach_res(con, R_CONSOLE) {
+       if (!con->fontface) {
+          Dmsg1(400, "No fontface for %s\n", con->hdr.name);
+         continue;
+       }
        text_font = gdk_font_load(con->fontface);
        if (text_font == NULL) {
-           Dmsg2(404, "Load of requested ConsoleFont \"%s\" (%s) failed!\n",
+           Dmsg2(400, "Load of requested ConsoleFont \"%s\" (%s) failed!\n",
                  con->hdr.name, con->fontface);
        } else {
-           Dmsg2(404, "ConsoleFont \"%s\" (%s) loaded.\n",
+           Dmsg2(400, "ConsoleFont \"%s\" (%s) loaded.\n",
                  con->hdr.name, con->fontface);
           break;
        }          
@@ -226,7 +226,7 @@ Without that I don't how to speak to the Director :-(\n"), configfile);
    UnlockRes();
 
    if (text_font == NULL) {
-       Dmsg1(100, "Attempting to load fallback font %s\n",
+       Dmsg1(400, "Attempting to load fallback font %s\n",
               "-misc-fixed-medium-r-normal-*-*-130-*-*-c-*-iso8859-1");
        text_font = gdk_font_load("-misc-fixed-medium-r-normal-*-*-130-*-*-c-*-iso8859-1");
    }
@@ -237,6 +237,11 @@ Without that I don't how to speak to the Director :-(\n"), configfile);
    gtk_widget_modify_font (status1, font_desc);
    pango_font_description_free (font_desc);
 
+   if (test_config) {
+      terminate_console(0);
+      exit(0);
+   }
+
    initial = gtk_timeout_add(100, initial_connect_to_director, (gpointer)NULL);
 
    gtk_main();
@@ -401,13 +406,7 @@ int connect_to_director(gpointer data)
    LockRes();
    CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
    UnlockRes();
-   char *con_name;
-   if (cons) {
-      con_name = cons->hdr.name;
-   } else {
-      con_name = "*UserAgent*";
-   }
-   if (!authenticate_director(&jcr, dir, con_name)) {
+   if (!authenticate_director(&jcr, dir, cons)) {
       set_text(UA_sock->msg, UA_sock->msglen);
       return 0;
    }
index 7b5b1fbdd6d6e7fcf82f1457f90ac066671770e2..813e353ab556eedabe372ca56cc469ef811ad9b6 100644 (file)
@@ -8,14 +8,14 @@
  *   1. The generic lexical scanner in lib/lex.c and lib/lex.h
  *
  *   2. The generic config  scanner in lib/parse_config.c and 
- *      lib/parse_config.h.
- *      These files contain the parser code, some utility
- *      routines, and the common store routines (name, int,
- *      string).
+ *     lib/parse_config.h.
+ *     These files contain the parser code, some utility
+ *     routines, and the common store routines (name, int,
+ *     string).
  *
  *   3. The daemon specific file, which contains the Resource
- *      definitions as well as any specific store routines
- *      for the resource records.
+ *     definitions as well as any specific store routines
+ *     for the resource records.
  *
  *     Kern Sibbald, January MM, September MM
  *
@@ -71,7 +71,7 @@ static struct res_items dir_items[] = {
    {"description", store_str,      ITEM(res_dir.hdr.desc), 0, 0, 0},
    {"dirport",     store_int,      ITEM(res_dir.DIRport),  0, ITEM_DEFAULT, 9101},
    {"address",     store_str,      ITEM(res_dir.address),  0, ITEM_REQUIRED, 0},
-   {"password",    store_password, ITEM(res_dir.password), 0, ITEM_REQUIRED, 0},
+   {"password",    store_password, ITEM(res_dir.password), 0, 0, 0},
    {"enablessl", store_yesno,      ITEM(res_dir.enable_ssl), 1, ITEM_DEFAULT, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
@@ -79,7 +79,8 @@ static struct res_items dir_items[] = {
 static struct res_items con_items[] = {
    {"name",        store_name,     ITEM(con_dir.hdr.name), 0, ITEM_REQUIRED, 0},
    {"description", store_str,      ITEM(con_dir.hdr.desc), 0, 0, 0},
-   {"font",        store_str,      ITEM(con_dir.fontface), 0, ITEM_REQUIRED, 0},
+   {"font",        store_str,      ITEM(con_dir.fontface), 0, 0, 0},
+   {"password",    store_password, ITEM(con_dir.password), 0, ITEM_REQUIRED, 0},
    {"requiressl",  store_yesno,    ITEM(con_dir.require_ssl), 1, ITEM_DEFAULT, 0},
    {NULL, NULL, NULL, 0, 0, 0} 
 };
@@ -90,8 +91,8 @@ static struct res_items con_items[] = {
  */
 struct s_res resources[] = {
    {"director",      dir_items,   R_DIRECTOR,  NULL},
-   {"consolefont",   con_items,   R_CONSOLE,   NULL},
-   {NULL,            NULL,        0,           NULL}
+   {"console",       con_items,   R_CONSOLE,   NULL},
+   {NULL,           NULL,        0,           NULL}
 };
 
 
@@ -105,18 +106,18 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ...
       printf("No record for %d %s\n", type, res_to_str(type));
       return;
    }
-   if (type < 0) {                    /* no recursion */
+   if (type < 0) {                   /* no recursion */
       type = - type;
       recurse = 0;
    }
    switch (type) {
    case R_DIRECTOR:
       printf("Director: name=%s address=%s DIRport=%d\n", reshdr->name, 
-              res->res_dir.address, res->res_dir.DIRport);
+             res->res_dir.address, res->res_dir.DIRport);
       break;
    case R_CONSOLE:
       printf("Console: name=%s font face=%s\n", 
-             reshdr->name, NPRT(res->con_dir.fontface));
+            reshdr->name, NPRT(res->con_dir.fontface));
       break;
    default:
       printf("Unknown resource type %d\n", type);
@@ -156,12 +157,12 @@ void free_resource(int type)
    switch (type) {
    case R_DIRECTOR:
       if (res->res_dir.address) {
-         free(res->res_dir.address);
+        free(res->res_dir.address);
       }
       break;
    case R_CONSOLE:
       if (res->con_dir.fontface) {
-         free(res->con_dir.fontface);
+        free(res->con_dir.fontface);
       }
       break;
    default:
@@ -191,10 +192,10 @@ void save_resource(int type, struct res_items *items, int pass)
     */
    for (i=0; items[i].name; i++) {
       if (items[i].flags & ITEM_REQUIRED) {
-            if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
+           if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) {  
                Emsg2(M_ABORT, 0, "%s item is required in %s resource, but not found.\n",
-                 items[i].name, resources[rindex]);
-             }
+                items[i].name, resources[rindex]);
+            }
       }
    }
 
@@ -207,26 +208,26 @@ void save_resource(int type, struct res_items *items, int pass)
       switch (type) {
       /* Resources not containing a resource */
       case R_DIRECTOR:
-         break;
+        break;
 
       case R_CONSOLE:
-         break;
+        break;
 
       default:
          Emsg1(M_ERROR, 0, "Unknown resource type %d\n", type);
-         error = 1;
-         break;
+        error = 1;
+        break;
       }
       /* Note, the resoure name was already saved during pass 1,
        * so here, we can just release it.
        */
       if (res_all.res_dir.hdr.name) {
-         free(res_all.res_dir.hdr.name);
-         res_all.res_dir.hdr.name = NULL;
+        free(res_all.res_dir.hdr.name);
+        res_all.res_dir.hdr.name = NULL;
       }
       if (res_all.res_dir.hdr.desc) {
-         free(res_all.res_dir.hdr.desc);
-         res_all.res_dir.hdr.desc = NULL;
+        free(res_all.res_dir.hdr.desc);
+        res_all.res_dir.hdr.desc = NULL;
       }
       return;
    }
@@ -249,20 +250,20 @@ void save_resource(int type, struct res_items *items, int pass)
       res = (URES *)malloc(size);
       memcpy(res, &res_all, size);
       if (!resources[rindex].res_head) {
-         resources[rindex].res_head = (RES *)res; /* store first entry */
+        resources[rindex].res_head = (RES *)res; /* store first entry */
       } else {
-         RES *next;
-         /* Add new res to end of chain */
-         for (next=resources[rindex].res_head; next->next; next=next->next) {
-            if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
-               Emsg2(M_ERROR_TERM, 0,
+        RES *next;
+        /* Add new res to end of chain */
+        for (next=resources[rindex].res_head; next->next; next=next->next) {
+           if (strcmp(next->name, res->res_dir.hdr.name) == 0) {
+              Emsg2(M_ERROR_TERM, 0,
                   _("Attempt to define second %s resource named \"%s\" is not permitted.\n"),
-                  resources[rindex].name, res->res_dir.hdr.name);
-            }
-         }
-         next->next = (RES *)res;
+                 resources[rindex].name, res->res_dir.hdr.name);
+           }
+        }
+        next->next = (RES *)res;
          Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type),
-               res->res_dir.hdr.name);
+              res->res_dir.hdr.name);
       }
    }
 }
index b63d20ccc8221b21f573279b0db424f0a60706ec..c9dde14855956804053bb7a493524a12169e6297 100644 (file)
 /*
  * Resource codes -- they must be sequential for indexing   
  */
-#define R_FIRST                      1001
 
-#define R_DIRECTOR                   1001
-#define R_CONSOLE                    1002
+enum {
+   R_DIRECTOR = 1001,
+   R_CONSOLE,
+};
 
-#define R_LAST                       R_CONSOLE
+#define R_FIRST     R_DIRECTOR
+#define R_LAST     R_CONSOLE
 
 /*
  * Some resource attributes
@@ -42,6 +44,7 @@ typedef struct s_res_dir DIRRES;
 struct s_con_dir {
    RES  hdr;
    char *fontface;                   /* Console Font specification */
+   char *password;                   /* UA server password */
    int require_ssl;                  /* Require SSL on all connections */
 };
 typedef struct s_con_dir CONRES;
index 8b6755405b4c73eb2819a8b0722938f90e7d8619..bcce8abe9aa1b322921ff90d13a4b1ca52f180d9 100644 (file)
 
  */
 
+/* Second arg of init */
+enum {
+  owned_by_alist = true,
+  not_owned_by_alist = false
+};
+
+
 /* 
  * Array list -- much like a simplified STL vector
  *   array of pointers to inserted items
index 3b2a25bac364f0316deb181925c6ec2a25b98853..b2a99ea1c287d60f31bc8059db77088bfdb4db0d 100644 (file)
@@ -57,12 +57,13 @@ static void s_err(char *file, int line, LEX *lc, char *msg, ...)
    va_end(arg_ptr);
      
    if (lc->line_no > lc->begin_line_no) {
-      sprintf(more, _("Problem probably begins at Line %d.\n"), lc->begin_line_no);
+      bsnprintf(more, sizeof(more), 
+                _("Problem probably begins at line %d.\n"), lc->begin_line_no);
    } else {
       more[0] = 0;
    }
    e_msg(file, line, M_ERROR_TERM, 0, _("Config error: %s\n\
-            : Line %d, col %d of file %s\n%s\n%s"),
+            : line %d, col %d of file %s\n%s\n%s"),
       buf, lc->line_no, lc->col_no, lc->fname, lc->line, more);
 }
 
@@ -189,7 +190,7 @@ static void add_str(LEX *lf, int ch)
 {
    if (lf->str_len >= MAXSTRING-3) {
       Emsg3(M_ERROR_TERM, 0, _(
-            "Token too long, file: %s, line %d, begins at line %d\n"), 
+           _("Config token too long, file: %s, line %d, begins at line %d\n")), 
             lf->fname, lf->line_no, lf->begin_line_no);
    }
    lf->str[lf->str_len++] = ch;
@@ -253,19 +254,19 @@ char *lex_tok_to_str(int token)
 
 static uint32_t scan_pint(LEX *lf, char *str)
 {
-   double dval = 0;
+   int64_t val = 0;
    if (!is_a_number(str)) {
       scan_err1(lf, "expected a positive integer number, got: %s", str);
       /* NOT REACHED */
    } else {
       errno = 0;
-      dval = strtod(str, NULL);
-      if (errno != 0 || dval < 0) {
+      val = str_to_int64(str);
+      if (errno != 0 || val < 0) {
          scan_err1(lf, "expected a postive integer number, got: %s", str);
         /* NOT REACHED */
       }
    }
-   return (uint32_t)dval;
+   return (uint32_t)val;
 }
 
 /*       
@@ -508,7 +509,7 @@ lex_get_token(LEX *lf, int expect)
         break;
       }
       errno = 0;
-      lf->int32_val = (int32_t)strtod(lf->str, NULL);
+      lf->int32_val = (int32_t)str_to_int64(lf->str);
       if (errno != 0) {
          scan_err2(lf, "expected an integer number, got %s: %s",
               lex_tok_to_str(token), lf->str);
@@ -527,7 +528,7 @@ lex_get_token(LEX *lf, int expect)
         break;
       }
       errno = 0;
-      lf->int64_val = (int64_t)strtod(lf->str, NULL);
+      lf->int64_val = str_to_int64(lf->str);
       if (errno != 0) {
          scan_err2(lf, "expected an integer number, got %s: %s",
               lex_tok_to_str(token), lf->str);
index aa908f9b8a527465c4fb67c30da2286e49274a94..692ec0d219106fc81dc62eee17cf3dd1e6e4bfd8 100755 (executable)
@@ -214,10 +214,10 @@ void store_msgs(LEX *lc, struct res_items *item, int index, int pass)
            token = lex_get_token(lc, T_NAME);   /* scan destination */
            dest = check_pool_memory_size(dest, dest_len + lc->str_len + 2);
            if (dest[0] != 0) {
-               strcat(dest, " ");  /* separate multiple destinations with space */
+               pm_strcat(&dest, " ");  /* separate multiple destinations with space */
               dest_len++;
            }
-           strcat(dest, lc->str);
+           pm_strcat(&dest, lc->str);
            dest_len += lc->str_len;
             Dmsg2(100, "store_msgs newdest=%s: dest=%s:\n", lc->str, NPRT(dest));
            token = lex_get_token(lc, T_ALL);