135
135
* Uses file locking to avoid sequence number collisions.
138
io_nextid(char *iolog_dir, char sessid[7])
138
io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
141
141
char buf[32], *ep;
172
172
log_fatal(USE_ERRNO, _("unable to open %s"), pathbuf);
173
173
lock_file(fd, SUDO_LOCK);
175
/* Read seq number (base 36). */
176
nread = read(fd, buf, sizeof(buf));
179
log_fatal(USE_ERRNO, _("unable to read %s"), pathbuf);
180
id = strtoul(buf, &ep, 36);
181
if (buf == ep || id >= SESSID_MAX)
182
log_fatal(0, _("invalid sequence number %s"), pathbuf);
176
* If there is no seq file in iolog_dir and a fallback dir was
177
* specified, look for seq in the fallback dir. This is to work
178
* around a bug in sudo 1.8.5 and older where iolog_dir was not
179
* expanded before the sequence number was updated.
181
if (iolog_dir_fallback != NULL && fstat(fd, &sb) == 0 && sb.st_size == 0) {
182
char fallback[PATH_MAX];
184
len = snprintf(fallback, sizeof(fallback), "%s/seq",
186
if (len > 0 && len < sizeof(fallback)) {
187
int fd2 = open(fallback, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR);
189
nread = read(fd2, buf, sizeof(buf));
191
id = strtoul(buf, &ep, 36);
192
if (buf == ep || id >= SESSID_MAX)
200
/* Read current seq number (base 36). */
202
nread = read(fd, buf, sizeof(buf));
205
log_fatal(USE_ERRNO, _("unable to read %s"), pathbuf);
206
id = strtoul(buf, &ep, 36);
207
if (buf == ep || id >= SESSID_MAX)
208
log_fatal(0, _("invalid sequence number %s"), pathbuf);
198
225
sessid[6] = '\0';
200
227
/* Rewind and overwrite old seq file. */
201
if (lseek(fd, 0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7)
228
if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7)
202
229
log_fatal(USE_ERRNO, _("unable to write to %s"), pathbuf);
476
503
/* Get next session ID and convert it into a path. */
477
504
tofree = emalloc(sizeof(_PATH_SUDO_IO_LOGDIR) + sizeof(sessid) + 2);
478
505
memcpy(tofree, _PATH_SUDO_IO_LOGDIR, sizeof(_PATH_SUDO_IO_LOGDIR));
479
io_nextid(tofree, sessid);
506
io_nextid(tofree, NULL, sessid);
480
507
snprintf(tofree + sizeof(_PATH_SUDO_IO_LOGDIR), sizeof(sessid) + 2,
481
508
"%c%c/%c%c/%c%c", sessid[0], sessid[1], sessid[2], sessid[3],
482
509
sessid[4], sessid[5]);