Additional postcat flags for debuging a corrupted queue
file (-s: skip to offset; -r: don't follow pointer records).
File: postcat/postcat.c.
+
+20211110
+
+ Minor edits of 20211107 postcat changes. File: postcat.c.
+
+ Regression prevention: added sanity check in the queue file
+ editing code. File: cleanup/cleanup_body_edit.c
+
+ Regression prevention: copied a queue file record typecheck
+ from the pickup daemon. Files: *qmgr/qmgr_message.c.
Wish list:
- Fix the body_edit_lockout safety: turn it on when editing,
- and turn if off when done.
+ proxy_read_maps needs a dedicated matcher that looks
+ inside pipemap:{}. Maybe steal some code from postconf.
Add a pointer to
http://mmogilvi.users.sourceforge.net/software/oauthbearer.html
<b>-r</b> Print records in file order, don't follow pointer records.
- This feature is available in Postfix 3.7 and later. IP "<b>-s</b> <i>off-</i>
- <i>set</i>" Skip to the specified queue file offset.
+ This feature is available in Postfix 3.7 and later.
- This feature is available in Postfix 2.0 and later.
+ <b>-s</b> <i>offset</i>
+ Skip to the specified queue file offset.
+
+ This feature is available in Postfix 3.7 and later.
- <b>-v</b> Enable verbose logging for debugging purposes. Multiple <b>-v</b>
+ <b>-v</b> Enable verbose logging for debugging purposes. Multiple <b>-v</b>
options make the software increasingly verbose.
<b>DIAGNOSTICS</b>
Directory with Postfix configuration files.
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
gram.
- The text below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
+ The text below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
more details including examples.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
figuration files.
<b><a href="postconf.5.html#import_environment">import_environment</a> (see 'postconf -d' output)</b>
- The list of environment parameters that a privileged Postfix
- process will import from a non-Postfix parent process, or
+ The list of environment parameters that a privileged Postfix
+ process will import from a non-Postfix parent process, or
name=value environment overrides.
<b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
Print records in file order, don't follow pointer records.
This feature is available in Postfix 3.7 and later.
-IP "\fB-s \fIoffset\fR"
+.IP "\fB\-s \fIoffset\fR"
Skip to the specified queue file offset.
-This feature is available in Postfix 2.0 and later.
+This feature is available in Postfix 3.7 and later.
.IP \fB\-v\fR
Enable verbose logging for debugging purposes. Multiple \fB\-v\fR
options make the software increasingly verbose.
CLEANUP_OUT_BUF(state, rec_type, buf);
curr_rp->write_offs = vstream_ftell(state->dst);
+ /*
+ * Sanity check.
+ */
+ if (curr_rp->len > 0
+ && curr_rp->write_offs > curr_rp->start + curr_rp->len)
+ msg_panic("%s: write past end of body segment", myname);
+
return (0);
}
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20211107"
+#define MAIL_RELEASE_DATE "20211113"
#define MAIL_VERSION_NUMBER "3.7"
#ifdef SNAPSHOT
char *dsn_orcpt = 0;
int n;
int have_log_client_attr = 0;
+ static const char env_rec_types[] = REC_TYPE_ENVELOPE REC_TYPE_EXTRACT;
+ static const char extra_rec_type[] = {REC_TYPE_XTRA, 0};
+ const char *expected_rec_types;
/*
* Initialize. No early returns or we have a memory leak.
* mailing lists.
*/
for (;;) {
+ expected_rec_types = env_rec_types;
if ((curr_offset = vstream_ftell(message->fp)) < 0)
msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp));
if (curr_offset == message->data_offset && curr_offset > 0) {
if (vstream_fseek(message->fp, message->data_size, SEEK_CUR) < 0)
msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
curr_offset += message->data_size;
+ expected_rec_types = extra_rec_type;
}
rec_type = rec_get_raw(message->fp, buf, 0, REC_FLAG_NONE);
start = vstring_str(buf);
message->queue_id);
break;
}
+ if (strchr(expected_rec_types, rec_type) == 0) {
+ msg_warn("Unexpected record type '%c' at offset %ld",
+ rec_type, (long) curr_offset);
+ rec_type = REC_TYPE_ERROR;
+ break;
+ }
if (rec_type == REC_TYPE_END) {
message->rflags |= QMGR_READ_FLAG_SEEN_ALL_NON_RCPT;
break;
*/
if (rec_type == REC_TYPE_ATTR) {
if ((error_text = split_nameval(start, &name, &value)) != 0) {
- msg_warn("%s: ignoring bad attribute: %s: %.200s",
+ msg_warn("%s: bad attribute record: %s: %.200s",
message->queue_id, error_text, start);
rec_type = REC_TYPE_ERROR;
break;
/* of taking the names literally.
/*
/* This feature is available in Postfix 2.0 and later.
-/*.IP \fB-r\fR
+/* .IP \fB-r\fR
/* Print records in file order, don't follow pointer records.
/*
/* This feature is available in Postfix 3.7 and later.
-/* IP "\fB-s \fIoffset\fR"
+/* .IP "\fB-s \fIoffset\fR"
/* Skip to the specified queue file offset.
/*
-/* This feature is available in Postfix 2.0 and later.
+/* This feature is available in Postfix 3.7 and later.
/* .IP \fB-v\fR
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
/* options make the software increasingly verbose.
/*
* See if this is a plausible file.
*/
- if (start_offset == 0 && (flags & PC_FLAG_RAW) == 0
- && (ch = VSTREAM_GETC(fp)) != VSTREAM_EOF) {
+ if (start_offset == 0 && (ch = VSTREAM_GETC(fp)) != VSTREAM_EOF) {
if (!strchr(REC_TYPE_ENVELOPE, ch)) {
msg_warn("%s: input is not a valid queue file", VSTREAM_PATH(fp));
return;
flags |= PC_FLAG_RAW;
break;
case 's':
- if (!alldig(optarg) || (start_offset = atol(optarg)) <= 0)
+ if (!alldig(optarg) || (start_offset = atol(optarg)) < 0)
msg_fatal("bad offset: %s", optarg);
break;
case 'v':
char *dsn_orcpt = 0;
int n;
int have_log_client_attr = 0;
+ static const char env_rec_types[] = REC_TYPE_ENVELOPE REC_TYPE_EXTRACT;
+ static const char extra_rec_type[] = {REC_TYPE_XTRA, 0};
+ const char *expected_rec_types;
/*
* Initialize. No early returns or we have a memory leak.
* mailing lists.
*/
for (;;) {
+ expected_rec_types = env_rec_types;
if ((curr_offset = vstream_ftell(message->fp)) < 0)
msg_fatal("vstream_ftell %s: %m", VSTREAM_PATH(message->fp));
if (curr_offset == message->data_offset && curr_offset > 0) {
if (vstream_fseek(message->fp, message->data_size, SEEK_CUR) < 0)
msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
curr_offset += message->data_size;
+ expected_rec_types = extra_rec_type;
}
rec_type = rec_get_raw(message->fp, buf, 0, REC_FLAG_NONE);
start = vstring_str(buf);
message->queue_id);
break;
}
+ if (strchr(expected_rec_types, rec_type) == 0) {
+ msg_warn("Unexpected record type '%c' at offset %ld",
+ rec_type, (long) curr_offset);
+ rec_type = REC_TYPE_ERROR;
+ break;
+ }
if (rec_type == REC_TYPE_END) {
message->rflags |= QMGR_READ_FLAG_SEEN_ALL_NON_RCPT;
break;
*/
if (rec_type == REC_TYPE_ATTR) {
if ((error_text = split_nameval(start, &name, &value)) != 0) {
- msg_warn("%s: ignoring bad attribute: %s: %.200s",
+ msg_warn("%s: bad attribute record: %s: %.200s",
message->queue_id, error_text, start);
rec_type = REC_TYPE_ERROR;
break;