reformatted with indent + by hand
This commit is contained in:
244
visudo.c
244
visudo.c
@@ -22,13 +22,14 @@
|
|||||||
* 3959 Arbol CT (303) 447-8093
|
* 3959 Arbol CT (303) 447-8093
|
||||||
* Boulder, CO 80301-1752
|
* Boulder, CO 80301-1752
|
||||||
*
|
*
|
||||||
********************************************************************************
|
**************************************************************************
|
||||||
* visudo.c, sudo project
|
* visudo.c, sudo project
|
||||||
* David R. Hieb
|
* David R. Hieb
|
||||||
* March 18, 1991
|
* March 18, 1991
|
||||||
*
|
*
|
||||||
* edit, lock and parse the sudoers file in a fashion similiar to /etc/vipw.
|
* edit, lock and parse the sudoers file in a fashion similiar to /etc/vipw.
|
||||||
*******************************************************************************/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@@ -39,140 +40,157 @@
|
|||||||
|
|
||||||
#include "sudo.h"
|
#include "sudo.h"
|
||||||
|
|
||||||
extern FILE *yyin, *yyout;
|
extern FILE *yyin, *yyout;
|
||||||
extern int errno, yylineno;
|
extern int errno, yylineno;
|
||||||
|
|
||||||
char buffer[BUFSIZ];
|
char buffer[BUFSIZ];
|
||||||
char *sudoers = SUDOERS;
|
char *sudoers = SUDOERS;
|
||||||
int status = 0, err_line_no = 0;
|
int status = 0, err_line_no = 0;
|
||||||
char *sudoers_tmp_file = TMPSUDOERS;
|
char *sudoers_tmp_file = TMPSUDOERS;
|
||||||
FILE *sudoers_tmp_fp, *sudoers_fp;
|
FILE *sudoers_tmp_fp, *sudoers_fp;
|
||||||
|
|
||||||
void Exit()
|
void Exit()
|
||||||
{
|
{
|
||||||
fclose(sudoers_tmp_fp);
|
(void) fclose(sudoers_tmp_fp);
|
||||||
unlink(sudoers_tmp_file);
|
(void) unlink(sudoers_tmp_file);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
main(argc, argv)
|
main(argc, argv)
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
|
|
||||||
/* handle the signals */
|
/*
|
||||||
signal(SIGILL, Exit);
|
* handle the signals
|
||||||
signal(SIGTRAP, Exit);
|
*/
|
||||||
signal(SIGBUS, Exit);
|
(void) signal(SIGILL, Exit);
|
||||||
signal(SIGSEGV, Exit);
|
(void) signal(SIGTRAP, Exit);
|
||||||
signal(SIGTERM, Exit);
|
(void) signal(SIGBUS, Exit);
|
||||||
|
(void) signal(SIGSEGV, Exit);
|
||||||
|
(void) signal(SIGTERM, Exit);
|
||||||
|
|
||||||
signal(SIGHUP, SIG_IGN);
|
(void) signal(SIGHUP, SIG_IGN);
|
||||||
signal(SIGINT, SIG_IGN);
|
(void) signal(SIGINT, SIG_IGN);
|
||||||
signal(SIGQUIT, SIG_IGN);
|
(void) signal(SIGQUIT, SIG_IGN);
|
||||||
|
|
||||||
setbuf(stderr, NULL);
|
setbuf(stderr, NULL);
|
||||||
|
|
||||||
/* we only want root to be able to read/write the sudoers_tmp_file */
|
/*
|
||||||
umask(077);
|
* we only want root to be able to read/write the sudoers_tmp_file
|
||||||
|
*/
|
||||||
|
umask(077);
|
||||||
|
|
||||||
/* open the sudoers file read only */
|
/*
|
||||||
if ((sudoers_fp = fopen(sudoers, "r")) == NULL) {
|
* open the sudoers file read only
|
||||||
fprintf(stderr, "%s: ", *argv);
|
*/
|
||||||
perror(sudoers);
|
if ((sudoers_fp = fopen(sudoers, "r")) == NULL) {
|
||||||
Exit();
|
(void) fprintf(stderr, "%s: ", *argv);
|
||||||
|
perror(sudoers);
|
||||||
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open the temporary sudoers file with the correct flags */
|
/*
|
||||||
if ((fd = open(sudoers_tmp_file, O_WRONLY|O_CREAT|O_EXCL, 0600)) < 0) {
|
* open the temporary sudoers file with the correct flags
|
||||||
if (errno == EEXIST) {
|
*/
|
||||||
fprintf(stderr, "%s: sudoers file busy\n", *argv);
|
if ((fd = open(sudoers_tmp_file, O_WRONLY | O_CREAT | O_EXCL, 0600)) < 0) {
|
||||||
exit(1);
|
if (errno == EEXIST) {
|
||||||
}
|
(void) fprintf(stderr, "%s: sudoers file busy\n", *argv);
|
||||||
fprintf(stderr, "%s: ", *argv);
|
exit(1);
|
||||||
perror(sudoers_tmp_file);
|
}
|
||||||
exit(1);
|
(void) fprintf(stderr, "%s: ", *argv);
|
||||||
|
perror(sudoers_tmp_file);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get a STREAM file pointer to the temporary sudoers file */
|
/*
|
||||||
if ((sudoers_tmp_fp = fdopen(fd, "w")) == NULL) {
|
* get a STREAM file pointer to the temporary sudoers file
|
||||||
fprintf(stderr, "%s: ", *argv);
|
*/
|
||||||
perror(sudoers_tmp_file);
|
if ((sudoers_tmp_fp = fdopen(fd, "w")) == NULL) {
|
||||||
Exit();
|
(void) fprintf(stderr, "%s: ", *argv);
|
||||||
|
perror(sudoers_tmp_file);
|
||||||
|
Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* transfer the contents of the sudoers file to the temporary sudoers file */
|
/*
|
||||||
while (fgets(buffer, sizeof(buffer) - 1, sudoers_fp) != NULL) {
|
* transfer the contents of the sudoers file to the temporary sudoers file
|
||||||
fputs(buffer, sudoers_tmp_fp);
|
*/
|
||||||
|
while (fgets(buffer, sizeof(buffer) - 1, sudoers_fp) != NULL) {
|
||||||
|
fputs(buffer, sudoers_tmp_fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(sudoers_fp);
|
(void) fclose(sudoers_fp);
|
||||||
fclose(sudoers_tmp_fp);
|
(void) fclose(sudoers_tmp_fp);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* build strings in buffer to be executed by system() */
|
/*
|
||||||
sprintf(buffer, "%s +%d %s", EDITOR, err_line_no, sudoers_tmp_file);
|
* build strings in buffer to be executed by system()
|
||||||
|
*/
|
||||||
|
(void) sprintf(buffer, "%s +%d %s", EDITOR, err_line_no,
|
||||||
|
sudoers_tmp_file);
|
||||||
|
|
||||||
/* edit the file */
|
/* edit the file */
|
||||||
if (system(buffer) == 0) {
|
if (system(buffer) == 0) {
|
||||||
|
|
||||||
/* can't stat file */
|
/* can't stat file */
|
||||||
if (stat(sudoers_tmp_file, &sbuf) < 0) {
|
if (stat(sudoers_tmp_file, &sbuf) < 0) {
|
||||||
fprintf(stderr, "%s: can't stat temporary file, %s unchanged\n",
|
(void) fprintf(stderr, "%s: can't stat temporary file, %s unchanged\n",
|
||||||
sudoers, *argv);
|
sudoers, *argv);
|
||||||
Exit();
|
Exit();
|
||||||
}
|
}
|
||||||
/* file has size == 0 */
|
|
||||||
if (sbuf.st_size == 0) {
|
|
||||||
fprintf(stderr, "%s: bad temporary file, %s unchanged\n",
|
|
||||||
sudoers, *argv);
|
|
||||||
Exit();
|
|
||||||
}
|
|
||||||
/* re-open the sudoers file for parsing */
|
|
||||||
if ((sudoers_tmp_fp = fopen(sudoers_tmp_file, "r")) == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't re-open temporary file, %s unchanged\n",
|
|
||||||
sudoers, *argv);
|
|
||||||
Exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
yyin = sudoers_tmp_fp;
|
/* file has size == 0 */
|
||||||
yyout = stdout;
|
if (sbuf.st_size == 0) {
|
||||||
|
(void) fprintf(stderr, "%s: bad temporary file, %s unchanged\n",
|
||||||
/* parse the file */
|
sudoers, *argv);
|
||||||
if (yyparse()) {
|
Exit();
|
||||||
fprintf(stderr, "yyparse() failed\n");
|
}
|
||||||
Exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/* re-open the sudoers file for parsing */
|
||||||
* the first time we get an error, set status to yylineno which
|
if ((sudoers_tmp_fp = fopen(sudoers_tmp_file, "r")) == NULL) {
|
||||||
* will be the line number after the line with the error.
|
(void) fprintf(stderr, "%s: can't re-open temporary file, %s unchanged\n",
|
||||||
* then, if we have gotten an error, set err_line_no to the
|
sudoers, *argv);
|
||||||
* correct line so that when we edit the file err_line_no will
|
Exit();
|
||||||
* be correct. at this time we also reset status and yylineno
|
}
|
||||||
* to their default values so that the next time yyparse() is
|
yyin = sudoers_tmp_fp;
|
||||||
* called, they will be initialized correctly.
|
yyout = stdout;
|
||||||
*/
|
|
||||||
err_line_no = (status == 0) ? 0 : status - 1;
|
|
||||||
status = 0;
|
|
||||||
yylineno = 1;
|
|
||||||
|
|
||||||
fclose(sudoers_tmp_fp);
|
/* parse the file */
|
||||||
}
|
if (yyparse()) {
|
||||||
|
(void) fprintf(stderr, "yyparse() failed\n");
|
||||||
|
Exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* the first time we get an error, set status to yylineno which
|
||||||
|
* will be the line number after the line with the error. then,
|
||||||
|
* if we have gotten an error, set err_line_no to the correct
|
||||||
|
* line so that when we edit the file err_line_no will be
|
||||||
|
* correct. at this time we also reset status and yylineno to
|
||||||
|
* their default values so that the next time yyparse() is
|
||||||
|
* called, they will be initialized correctly.
|
||||||
|
*/
|
||||||
|
err_line_no = (status == 0) ? 0 : status - 1;
|
||||||
|
status = 0;
|
||||||
|
yylineno = 1;
|
||||||
|
|
||||||
|
(void) fclose(sudoers_tmp_fp);
|
||||||
|
}
|
||||||
} while (err_line_no);
|
} while (err_line_no);
|
||||||
|
|
||||||
/* once the temporary sudoers file is gramatically correct, we can
|
/*
|
||||||
* rename it to the real sudoers file.
|
* once the temporary sudoers file is gramatically correct, we can
|
||||||
*/
|
* rename it to the real sudoers file.
|
||||||
if (rename(sudoers_tmp_file, sudoers) != 0) {
|
*/
|
||||||
fprintf(stderr, "%s: ", *argv), perror("rename");
|
if (rename(sudoers_tmp_file, sudoers) != 0) {
|
||||||
}
|
(void) fprintf(stderr, "%s: ", *argv);
|
||||||
else {
|
perror("rename");
|
||||||
if (chmod(sudoers, 0400) != 0) {
|
} else {
|
||||||
perror("chmod: failed");
|
if (chmod(sudoers, 0400) != 0)
|
||||||
}
|
perror("chmod: failed");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user