Adapt plugins to version I/O logging ABI 1.1
This commit is contained in:
@@ -423,8 +423,8 @@ policy_close(int exit_status, int error)
|
|||||||
static int
|
static int
|
||||||
io_open(unsigned int version, sudo_conv_t conversation,
|
io_open(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t sudo_printf, char * const settings[],
|
sudo_printf_t sudo_printf, char * const settings[],
|
||||||
char * const user_info[], int argc, char * const argv[],
|
char * const user_info[], char * const command_info[],
|
||||||
char * const user_env[])
|
int argc, char * const argv[], char * const user_env[])
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
@@ -148,37 +148,71 @@ io_nextid(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
build_idpath(char *pathbuf, size_t pathsize)
|
build_idpath(const char *iolog_dir, const char *sessid, char *pathbuf, size_t pathsize)
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
char *cp;
|
||||||
int i, len;
|
int i, len;
|
||||||
|
|
||||||
if (sudo_user.sessid[0] == '\0')
|
if (sessid[0] == '\0')
|
||||||
log_error(0, "tried to build a session id path without a session id");
|
log_error(0, "tried to build a session id path without a session id");
|
||||||
|
|
||||||
/*
|
/* Check whether or not we have a real session ID. */
|
||||||
* Path is of the form /var/log/sudo-io/00/00/01.
|
for (i = 0; i < 6; i++) {
|
||||||
*/
|
switch (sessid[i]) {
|
||||||
len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", def_iolog_dir,
|
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||||
sudo_user.sessid[0], sudo_user.sessid[1], sudo_user.sessid[2],
|
case '6': case '7': case '8': case '9': case 'A': case 'B':
|
||||||
sudo_user.sessid[3], sudo_user.sessid[4], sudo_user.sessid[5]);
|
case 'C': case 'D': case 'E': case 'F': case 'G': case 'H':
|
||||||
if (len <= 0 && len >= pathsize) {
|
case 'I': case 'J': case 'K': case 'L': case 'M': case 'N':
|
||||||
errno = ENAMETOOLONG;
|
case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T':
|
||||||
log_error(USE_ERRNO, "%s/%s", def_iolog_dir, sudo_user.sessid);
|
case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
|
||||||
}
|
break;
|
||||||
|
default:
|
||||||
/*
|
goto checked;
|
||||||
* Create the intermediate subdirs as needed.
|
|
||||||
*/
|
|
||||||
for (i = 6; i > 0; i -= 3) {
|
|
||||||
pathbuf[len - i] = '\0';
|
|
||||||
if (stat(pathbuf, &sb) != 0) {
|
|
||||||
if (mkdir(pathbuf, S_IRWXU) != 0)
|
|
||||||
log_error(USE_ERRNO, "Can't mkdir %s", pathbuf);
|
|
||||||
} else if (!S_ISDIR(sb.st_mode)) {
|
|
||||||
log_error(0, "%s: %s", pathbuf, strerror(ENOTDIR));
|
|
||||||
}
|
}
|
||||||
pathbuf[len - i] = '/';
|
}
|
||||||
|
checked:
|
||||||
|
if (i == 6 && sessid[6] == '\0') {
|
||||||
|
/* Path is of the form /var/log/sudo-io/00/00/01. */
|
||||||
|
len = snprintf(pathbuf, pathsize, "%s/%c%c/%c%c/%c%c", iolog_dir,
|
||||||
|
sessid[0], sessid[1], sessid[2], sessid[3], sessid[4], sessid[5]);
|
||||||
|
if (len <= 0 && len >= pathsize) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
log_error(USE_ERRNO, "%s/%s", iolog_dir, sessid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the intermediate subdirs as needed. */
|
||||||
|
for (i = 6; i > 0; i -= 3) {
|
||||||
|
pathbuf[len - i] = '\0';
|
||||||
|
if (stat(pathbuf, &sb) != 0) {
|
||||||
|
if (mkdir(pathbuf, S_IRWXU) != 0)
|
||||||
|
log_error(USE_ERRNO, "Can't mkdir %s", pathbuf);
|
||||||
|
} else if (!S_ISDIR(sb.st_mode)) {
|
||||||
|
log_error(0, "%s: %s", pathbuf, strerror(ENOTDIR));
|
||||||
|
}
|
||||||
|
pathbuf[len - i] = '/';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Not a session ID, just append dir + file. */
|
||||||
|
len = snprintf(pathbuf, pathsize, "%s/%s", iolog_dir, sessid);
|
||||||
|
if (len <= 0 && len >= pathsize) {
|
||||||
|
errno = ENAMETOOLONG;
|
||||||
|
log_error(USE_ERRNO, "%s/%s", iolog_dir, sessid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the intermediate subdirs as needed. */
|
||||||
|
cp = &pathbuf[strlen(iolog_dir)];
|
||||||
|
do {
|
||||||
|
*cp = '\0';
|
||||||
|
if (stat(pathbuf, &sb) != 0) {
|
||||||
|
if (mkdir(pathbuf, S_IRWXU) != 0)
|
||||||
|
log_error(USE_ERRNO, "Can't mkdir %s", pathbuf);
|
||||||
|
} else if (!S_ISDIR(sb.st_mode)) {
|
||||||
|
log_error(0, "%s: %s", pathbuf, strerror(ENOTDIR));
|
||||||
|
}
|
||||||
|
*cp++ = '/';
|
||||||
|
cp = strchr(cp, '/');
|
||||||
|
} while (cp != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(len);
|
return(len);
|
||||||
@@ -208,10 +242,12 @@ open_io_fd(char *pathbuf, int len, const char *suffix, int docompress)
|
|||||||
static int
|
static int
|
||||||
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
||||||
sudo_printf_t plugin_printf, char * const settings[],
|
sudo_printf_t plugin_printf, char * const settings[],
|
||||||
char * const user_info[], int argc, char * const argv[],
|
char * const user_info[], char * const command_info[],
|
||||||
char * const user_env[])
|
int argc, char * const argv[], char * const user_env[])
|
||||||
{
|
{
|
||||||
char pathbuf[PATH_MAX];
|
char pathbuf[PATH_MAX];
|
||||||
|
const char *iolog_dir, *iolog_file = NULL;
|
||||||
|
char * const *cur;
|
||||||
FILE *io_logfile;
|
FILE *io_logfile;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
@@ -224,14 +260,30 @@ sudoers_io_open(unsigned int version, sudo_conv_t conversation,
|
|||||||
if (argc == 0)
|
if (argc == 0)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
if (!def_log_input && !def_log_output && !def_use_pty)
|
/*
|
||||||
|
* Pull iolog_dir and iolog_file out of command_info, if present,
|
||||||
|
* falling back to policy module info if not.
|
||||||
|
*/
|
||||||
|
iolog_dir = def_iolog_dir;
|
||||||
|
for (cur = command_info; *cur != NULL; cur++) {
|
||||||
|
if (**cur != 'i')
|
||||||
|
continue;
|
||||||
|
if (strncmp(*cur, "iolog_file=", sizeof("iolog_file=") - 1) == 0) {
|
||||||
|
iolog_file = *cur + sizeof("iolog_file=") - 1;
|
||||||
|
} else if (strncmp(*cur, "iolog_dir=", sizeof("iolog_dir=") - 1) == 0) {
|
||||||
|
iolog_dir = *cur + sizeof("iolog_dir=") - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no I/O log file defined there is nothing to do. */
|
||||||
|
if (iolog_file == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Build a path containing the session id split into two-digit subdirs,
|
* Build a path containing the session id split into two-digit subdirs,
|
||||||
* so ID 000001 becomes /var/log/sudo-io/00/00/01.
|
* so ID 000001 becomes /var/log/sudo-io/00/00/01.
|
||||||
*/
|
*/
|
||||||
len = build_idpath(pathbuf, sizeof(pathbuf));
|
len = build_idpath(iolog_dir, iolog_file, pathbuf, sizeof(pathbuf));
|
||||||
if (len == -1)
|
if (len == -1)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@@ -499,8 +499,12 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
|
|||||||
validate_env_vars(sudo_user.env_vars);
|
validate_env_vars(sudo_user.env_vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ISSET(sudo_mode, (MODE_RUN| MODE_EDIT)) && (def_log_input || def_log_output))
|
if (ISSET(sudo_mode, (MODE_RUN| MODE_EDIT)) && (def_log_input || def_log_output)) {
|
||||||
io_nextid();
|
io_nextid();
|
||||||
|
command_info[info_len++] = fmt_string("iolog_dir", def_iolog_dir);
|
||||||
|
command_info[info_len++] = fmt_string("iolog_file", sudo_user.sessid);
|
||||||
|
}
|
||||||
|
|
||||||
log_allowed(validated);
|
log_allowed(validated);
|
||||||
if (ISSET(sudo_mode, MODE_CHECK))
|
if (ISSET(sudo_mode, MODE_CHECK))
|
||||||
rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
|
rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
|
||||||
|
Reference in New Issue
Block a user