diff --git a/usr.bin/calendar/Makefile b/usr.bin/calendar/Makefile index 2a51b3319a39..56665231db4c 100644 --- a/usr.bin/calendar/Makefile +++ b/usr.bin/calendar/Makefile @@ -6,7 +6,7 @@ PROG= calendar SRCS= calendar.c locale.c events.c dates.c parsedata.c io.c day.c \ ostern.c paskha.c pom.c sunpos.c -LIBADD= m +LIBADD= m util INTER= de_AT.ISO_8859-15 de_DE.ISO8859-1 fr_FR.ISO8859-1 \ hr_HR.ISO8859-2 hu_HU.ISO8859-2 pt_BR.ISO8859-1 \ pt_BR.UTF-8 ru_RU.KOI8-R ru_RU.UTF-8 uk_UA.KOI8-U diff --git a/usr.bin/calendar/calendar.c b/usr.bin/calendar/calendar.c index a9e6c19e9a0d..a2d015fa791e 100644 --- a/usr.bin/calendar/calendar.c +++ b/usr.bin/calendar/calendar.c @@ -44,9 +44,11 @@ static char sccsid[] = "@(#)calendar.c 8.3 (Berkeley) 3/25/94"; #include __FBSDID("$FreeBSD$"); +#include #include #include #include +#include #include #include #include @@ -68,7 +70,7 @@ static time_t f_time = 0; double UTCOffset = UTCOFFSET_NOTSET; int EastLongitude = LONGITUDE_NOTSET; #ifdef WITH_ICONV -const char *outputEncoding; +const char *outputEncoding = NULL; #endif static void usage(void) __dead2; @@ -84,12 +86,6 @@ main(int argc, char *argv[]) struct tm tp1, tp2; (void)setlocale(LC_ALL, ""); -#ifdef WITH_ICONV - /* save the information about the encoding used in the terminal */ - outputEncoding = strdup(nl_langinfo(CODESET)); - if (outputEncoding == NULL) - errx(1, "cannot allocate memory"); -#endif while ((ch = getopt(argc, argv, "-A:aB:D:dF:f:l:t:U:W:?")) != -1) switch (ch) { @@ -218,15 +214,33 @@ main(int argc, char *argv[]) if (doall) while ((pw = getpwent()) != NULL) { - (void)setegid(pw->pw_gid); - (void)initgroups(pw->pw_name, pw->pw_gid); - (void)seteuid(pw->pw_uid); - if (!chdir(pw->pw_dir)) + pid_t pid; + + if (chdir(pw->pw_dir) == -1) + continue; + pid = fork(); + if (pid < 0) + err(1, "fork"); + if (pid == 0) { + login_cap_t *lc; + + lc = login_getpwclass(pw); + if (setusercontext(lc, pw, pw->pw_uid, + LOGIN_SETALL) != 0) + errx(1, "setusercontext"); cal(); - (void)seteuid(0); + exit(0); + } } - else + else { +#ifdef WITH_ICONV + /* Save the information about the encoding used in the terminal. */ + outputEncoding = strdup(nl_langinfo(CODESET)); + if (outputEncoding == NULL) + errx(1, "cannot allocate memory"); +#endif cal(); + } exit(0); } diff --git a/usr.bin/calendar/io.c b/usr.bin/calendar/io.c index 191c86bd7706..f363289878b9 100644 --- a/usr.bin/calendar/io.c +++ b/usr.bin/calendar/io.c @@ -290,16 +290,24 @@ cal_parse(FILE *in, FILE *out) if (buf[0] == '\0') continue; - /* Parse special definitions: LANG, Easter, Paskha etc */ + /* + * Setting LANG in user's calendar was an old workaround + * for 'calendar -a' being run with C locale to properly + * print user's calendars in their native languages. + * Now that 'calendar -a' does fork with setusercontext(), + * and does not run iconv(), this variable has little use. + */ if (strncmp(buf, "LANG=", 5) == 0) { (void)setlocale(LC_ALL, buf + 5); d_first = (*nl_langinfo(D_MD_ORDER) == 'd'); #ifdef WITH_ICONV - set_new_encoding(); + if (!doall) + set_new_encoding(); #endif setnnames(); continue; } + /* Parse special definitions: Easter, Paskha etc */ REPLACE("Easter=", 7, neaster); REPLACE("Paskha=", 7, npaskha); REPLACE("ChineseNewYear=", 15, ncny); @@ -445,7 +453,6 @@ opencalout(void) void closecal(FILE *fp) { - uid_t uid; struct stat sbuf; int nread, pdes[2], status; char buf[1024]; @@ -470,19 +477,6 @@ closecal(FILE *fp) (void)close(pdes[0]); } (void)close(pdes[1]); - uid = geteuid(); - if (setuid(getuid()) < 0) { - warnx("setuid failed"); - _exit(1); - } - if (setgid(getegid()) < 0) { - warnx("setgid failed"); - _exit(1); - } - if (setuid(uid) < 0) { - warnx("setuid failed"); - _exit(1); - } execl(_PATH_SENDMAIL, "sendmail", "-i", "-t", "-F", "\"Reminder Service\"", (char *)NULL); warn(_PATH_SENDMAIL);