From 80cdf20fcc53799a0022760917481a6386e68cb4 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Mon, 19 May 2003 22:25:44 +0000 Subject: [PATCH] Restrict valid chars in Volume name + doc git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@521 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 4 ++-- bacula/src/dird/catreq.c | 1 + bacula/src/dird/newvol.c | 2 +- bacula/src/dird/protos.h | 43 ++++++++++++++++++++------------------ bacula/src/dird/ua_cmds.c | 3 +-- bacula/src/dird/ua_label.c | 43 +++++++++++++++++++++++++------------- 6 files changed, 57 insertions(+), 39 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index d069123d4c..1bcaa7a3f6 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -1,5 +1,5 @@ Kern's ToDo List - 14 May 2003 + 19 May 2003 Documentation to do: (any release a little bit at a time) - Document running a test version. @@ -20,7 +20,6 @@ Testing to do: (painful) For 1.31 release: - Document what characters can go into Volume names. -- Implement Volume name checking. - Default duration with no qualifier is sec should be 1 day - Getting the following on all directories on Win32 19-May-2003 01:14 tibs-fd: Could not access c:/cygwin/home/kern/rxvt: ERR=Permission denied @@ -871,3 +870,4 @@ Done: (see kernsdone for more) - When the FD errs (e.g. disk full) have a more graceful shutdown. - Make sure Bacula prunes/purges canceled and failed jobs too and all jobs with zero JobFiles. +- Implement Volume name checking. diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 3880aba72c..5ce9194cb2 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -246,6 +246,7 @@ next_volume: Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName, mr.VolStatus, sdmr.VolStatus); bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */ + unbash_spaces(mr.VolumeName); if (!db_get_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"), mr.VolumeName, db_strerror(jcr->db)); diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index 6edcb250f5..735253c17f 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -58,7 +58,7 @@ int newVolume(JCR *jcr, MEDIA_DBR *mr) mr->LabelDate = time(NULL); bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType)); bstrncpy(name, pr.LabelFormat, sizeof(name)); - if (strchr(name, (int)'%') != NULL) { + if (!is_volume_name_legal(NULL, name)) { Jmsg(jcr, M_ERROR, 0, _("Illegal character in Label Format\n")); goto bail_out; } diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index b1e1c68bce..4c57e6f7bc 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -48,13 +48,13 @@ extern char *level_to_str(int level); /* 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 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); /* job.c */ extern void set_jcr_defaults(JCR *jcr, JOB *job); @@ -67,7 +67,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); @@ -92,6 +92,9 @@ int get_pint(UAContext *ua, char *prompt); int get_yesno(UAContext *ua, char *prompt); void parse_ua_args(UAContext *ua); +/* ua_label.c */ +int is_volume_name_legal(UAContext *ua, char *name); + /* ua_output.c */ void prtit(void *ctx, char *msg); @@ -99,28 +102,28 @@ void prtit(void *ctx, char *msg); void bsendmsg(void *sock, char *fmt, ...); /* 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 *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 *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); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 30d2476c79..ac104bcadd 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -245,8 +245,7 @@ getVolName: } } /* Don't allow | in Volume name because it is the volume separator character */ - if (strchr(ua->cmd, '|')) { - bsendmsg(ua, _("Illegal character | in a volume name.\n")); + if (!is_volume_name_legal(ua, ua->cmd)) { goto getVolName; } if (strlen(ua->cmd) >= MAX_NAME_LENGTH-10) { diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index f2a90c8c13..c1982209be 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -41,7 +41,6 @@ typedef struct s_vol_list { /* Forward referenced functions */ static int do_label(UAContext *ua, char *cmd, int relabel); static void label_from_barcodes(UAContext *ua); -static int is_legal_volume_name(UAContext *ua, char *name); static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, POOL_DBR *pr, int relabel); static vol_list_t *get_slot_list_from_SD(UAContext *ua); @@ -173,8 +172,8 @@ static int do_label(UAContext *ua, char *cmd, int relabel) /* If relabel get name of Volume to relabel */ if (relabel) { /* Check for volume=OldVolume */ - i = find_arg(ua, "volume"); - if (i >= 0 && ua->argv[i]) { + i = find_arg_with_value(ua, "volume"); + if (i >= 0) { memset(&omr, 0, sizeof(omr)); bstrncpy(omr.VolumeName, ua->argv[i], sizeof(omr.VolumeName)); if (db_get_media_record(ua->jcr, ua->db, &omr)) { @@ -197,8 +196,8 @@ checkVol: } /* Check for name=NewVolume */ - i = find_arg(ua, "name"); - if (i >= 0 && ua->argv[i]) { + i = find_arg_with_value(ua, "name"); + if (i >= 0) { pm_strcpy(&ua->cmd, ua->argv[i]); goto checkName; } @@ -209,7 +208,7 @@ checkVol: return 1; } checkName: - if (!is_legal_volume_name(ua, ua->cmd)) { + if (!is_volume_name_legal(ua, ua->cmd)) { continue; } @@ -225,8 +224,8 @@ checkName: /* If autochanger, request slot */ if (store->autochanger) { - i = find_arg(ua, "slot"); - if (i >= 0 && ua->argv[i]) { + i = find_arg_with_value(ua, "slot"); + if (i >= 0) { mr.Slot = atoi(ua->argv[i]); } else if (!get_pint(ua, _("Enter slot (0 for none): "))) { return 1; @@ -384,21 +383,37 @@ bail_out: return; } -static int is_legal_volume_name(UAContext *ua, char *name) +/* + * Check if the Volume name has legal characters + * If ua is non-NULL send the message + */ +int is_volume_name_legal(UAContext *ua, char *name) { int len; + char *p; + char *accept = ":.-_"; + /* Restrict the characters permitted in the Volume name */ - if (strpbrk(name, "`~!@#$%^&*()[]{}|\\;'\"<>?,/")) { - bsendmsg(ua, _("Illegal character | in a volume name.\n")); + for (p=name; *p; p++) { + if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) { + continue; + } + if (ua) { + bsendmsg(ua, _("Illegal character \"%c\" in a volume name.\n"), *p); + } return 0; } len = strlen(name); if (len >= MAX_NAME_LENGTH) { - bsendmsg(ua, _("Volume name too long.\n")); + if (ua) { + bsendmsg(ua, _("Volume name too long.\n")); + } return 0; } if (len == 0) { - bsendmsg(ua, _("Volume name must be at least one character long.\n")); + if (ua) { + bsendmsg(ua, _("Volume name must be at least one character long.\n")); + } return 0; } return 1; @@ -504,7 +519,7 @@ static vol_list_t *get_slot_list_from_SD(UAContext *ua) continue; } Slot = atoi(sd->msg); - if (Slot <= 0 || !is_legal_volume_name(ua, p)) { + if (Slot <= 0 || !is_volume_name_legal(ua, p)) { continue; } -- 2.39.5