Print this page
13066 Want crontab -u
Change-ID: I3dc2251dbbcc721aeff25a9dde21a24271c927bc


   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  26 /*        All Rights Reserved   */
  27 
  28 /*
  29  * Copyright 2019 OmniOS Community Edition (OmniOSce) Association.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/stat.h>
  34 #include <sys/types.h>
  35 #include <sys/wait.h>
  36 #include <errno.h>
  37 #include <signal.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <string.h>
  41 #include <fcntl.h>
  42 #include <ctype.h>
  43 #include <pwd.h>
  44 #include <unistd.h>
  45 #include <locale.h>
  46 #include <nl_types.h>
  47 #include <langinfo.h>
  48 #include <libintl.h>
  49 #include <security/pam_appl.h>


  55 #if defined(XPG4)
  56 #define VIPATH  "/usr/xpg4/bin/vi"
  57 #elif defined(XPG6)
  58 #define VIPATH  "/usr/xpg6/bin/vi"
  59 #else
  60 #define _XPG_NOTDEFINED
  61 #define VIPATH  "vi"
  62 #endif
  63 
  64 #define TMPFILE         "_cron"         /* prefix for tmp file */
  65 #define CRMODE          0600    /* mode for creating crontabs */
  66 
  67 #define BADCREATE       \
  68         "can't create your crontab file in the crontab directory."
  69 #define BADOPEN         "can't open your crontab file."
  70 #define BADSHELL        \
  71         "because your login shell isn't /usr/bin/sh, you can't use cron."
  72 #define WARNSHELL       "warning: commands will be executed using /usr/bin/sh\n"
  73 #define BADUSAGE        \
  74         "usage:\n"                      \
  75         "\tcrontab [file]\n"            \
  76         "\tcrontab -e [username]\n"     \
  77         "\tcrontab -l [username]\n"     \
  78         "\tcrontab -r [username]"
  79 #define INVALIDUSER     "you are not a valid user (no entry in /etc/passwd)."
  80 #define NOTALLOWED      "you are not authorized to use cron.  Sorry."
  81 #define NOTROOT         \
  82         "you must be super-user to access another user's crontab file"
  83 #define AUDITREJECT     "The audit context for your shell has not been set."
  84 #define EOLN            "unexpected end of line."
  85 #define UNEXPECT        "unexpected character found in line."
  86 #define OUTOFBOUND      "number out of bounds."
  87 #define OVERFLOW        "too many elements."
  88 #define ERRSFND         "errors detected in input, no crontab file generated."
  89 #define ED_ERROR        \
  90         "     The editor indicates that an error occurred while you were\n"\
  91         "     editing the crontab data - usually a minor typing error.\n\n"
  92 #define BADREAD         "error reading your crontab file"
  93 #define ED_PROMPT       \
  94         "     Edit again, to ensure crontab information is intact (%s/%s)?\n"\
  95         "     ('%s' will discard edits.)"
  96 #define NAMETOOLONG     "login name too long"
  97 #define BAD_TZ  "Timezone unrecognized in: %s"
  98 #define BAD_SHELL       "Invalid shell specified: %s"


 119 
 120 int
 121 main(int argc, char **argv)
 122 {
 123         int     c, r;
 124         int     rflag   = 0;
 125         int     lflag   = 0;
 126         int     eflag   = 0;
 127         int     errflg  = 0;
 128         char *pp;
 129         FILE *fp, *tmpfp;
 130         struct stat stbuf;
 131         struct passwd *pwp;
 132         time_t omodtime;
 133         char *editor;
 134         uid_t ruid;
 135         pid_t pid;
 136         int stat_loc;
 137         int ret;
 138         char real_login[UNAMESIZE];

 139         int tmpfd = -1;
 140         pam_handle_t *pamh;
 141         int pam_error;
 142         char *buf;
 143         size_t buflen;
 144 
 145         (void) setlocale(LC_ALL, "");
 146 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 147 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it weren't */
 148 #endif
 149         (void) textdomain(TEXT_DOMAIN);
 150 
 151         if (init_yes() < 0) {
 152                 (void) fprintf(stderr, gettext(ERR_MSG_INIT_YES),
 153                     strerror(errno));
 154                 exit(1);
 155         }
 156 
 157         while ((c = getopt(argc, argv, "elr")) != EOF)
 158                 switch (c) {
 159                         case 'e':
 160                                 eflag++;
 161                                 break;
 162                         case 'l':
 163                                 lflag++;
 164                                 break;
 165                         case 'r':
 166                                 rflag++;
 167                                 break;



 168                         case '?':
 169                                 errflg++;
 170                                 break;
 171                 }

 172 



 173         if (eflag + lflag + rflag > 1)
 174                 errflg++;
 175 
 176         argc -= optind;
 177         argv += optind;





 178         if (errflg || argc > 1)
 179                 crabort(BADUSAGE);
 180 
 181         ruid = getuid();
 182         if ((pwp = getpwuid(ruid)) == NULL)
 183                 crabort(INVALIDUSER);
 184 
 185         if (strlcpy(real_login, pwp->pw_name, sizeof (real_login))
 186             >= sizeof (real_login))
 187                 crabort(NAMETOOLONG);

 188 
 189         if ((eflag || lflag || rflag) && argc == 1) {
 190                 if ((pwp = getpwnam(*argv)) == NULL)
 191                         crabort(INVALIDUSER);
 192 
 193                 if (!cron_admin(real_login)) {
 194                         if (pwp->pw_uid != ruid)
 195                                 crabort(NOTROOT);
 196                         else
 197                                 pp = getuser(ruid);
 198                 } else
 199                         pp = *argv++;
 200         } else {



 201                 pp = getuser(ruid);
 202         }
 203 
 204         if (pp == NULL) {
 205                 if (per_errno == 2)
 206                         crabort(BADSHELL);
 207                 else
 208                         crabort(INVALIDUSER);
 209         }
 210         if (strlcpy(login, pp, sizeof (login)) >= sizeof (login))
 211                 crabort(NAMETOOLONG);
 212         if (!allowed(login, CRONALLOW, CRONDENY))
 213                 crabort(NOTALLOWED);
 214 
 215         /* Do account validation check */
 216         pam_error = pam_start("cron", pp, NULL, &pamh);
 217         if (pam_error != PAM_SUCCESS) {
 218                 crabort((char *)pam_strerror(pamh, pam_error));
 219         }
 220         pam_error = pam_acct_mgmt(pamh, PAM_SILENT);




   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  26 /*        All Rights Reserved   */
  27 
  28 /*
  29  * Copyright 2020 OmniOS Community Edition (OmniOSce) Association.
  30  */
  31 
  32 #include <sys/types.h>
  33 #include <sys/stat.h>
  34 #include <sys/types.h>
  35 #include <sys/wait.h>
  36 #include <errno.h>
  37 #include <signal.h>
  38 #include <stdio.h>
  39 #include <stdlib.h>
  40 #include <string.h>
  41 #include <fcntl.h>
  42 #include <ctype.h>
  43 #include <pwd.h>
  44 #include <unistd.h>
  45 #include <locale.h>
  46 #include <nl_types.h>
  47 #include <langinfo.h>
  48 #include <libintl.h>
  49 #include <security/pam_appl.h>


  55 #if defined(XPG4)
  56 #define VIPATH  "/usr/xpg4/bin/vi"
  57 #elif defined(XPG6)
  58 #define VIPATH  "/usr/xpg6/bin/vi"
  59 #else
  60 #define _XPG_NOTDEFINED
  61 #define VIPATH  "vi"
  62 #endif
  63 
  64 #define TMPFILE         "_cron"         /* prefix for tmp file */
  65 #define CRMODE          0600    /* mode for creating crontabs */
  66 
  67 #define BADCREATE       \
  68         "can't create your crontab file in the crontab directory."
  69 #define BADOPEN         "can't open your crontab file."
  70 #define BADSHELL        \
  71         "because your login shell isn't /usr/bin/sh, you can't use cron."
  72 #define WARNSHELL       "warning: commands will be executed using /usr/bin/sh\n"
  73 #define BADUSAGE        \
  74         "usage:\n"                      \
  75         "\tcrontab [-u username] [file]\n"              \
  76         "\tcrontab [-u username] { -e | -l | -r }\n"    \
  77         "\tcrontab { -e | -l | -r } [username]"

  78 #define INVALIDUSER     "you are not a valid user (no entry in /etc/passwd)."
  79 #define NOTALLOWED      "you are not authorized to use cron.  Sorry."
  80 #define NOTROOT         \
  81         "you must be super-user to access another user's crontab file"
  82 #define AUDITREJECT     "The audit context for your shell has not been set."
  83 #define EOLN            "unexpected end of line."
  84 #define UNEXPECT        "unexpected character found in line."
  85 #define OUTOFBOUND      "number out of bounds."
  86 #define OVERFLOW        "too many elements."
  87 #define ERRSFND         "errors detected in input, no crontab file generated."
  88 #define ED_ERROR        \
  89         "     The editor indicates that an error occurred while you were\n"\
  90         "     editing the crontab data - usually a minor typing error.\n\n"
  91 #define BADREAD         "error reading your crontab file"
  92 #define ED_PROMPT       \
  93         "     Edit again, to ensure crontab information is intact (%s/%s)?\n"\
  94         "     ('%s' will discard edits.)"
  95 #define NAMETOOLONG     "login name too long"
  96 #define BAD_TZ  "Timezone unrecognized in: %s"
  97 #define BAD_SHELL       "Invalid shell specified: %s"


 118 
 119 int
 120 main(int argc, char **argv)
 121 {
 122         int     c, r;
 123         int     rflag   = 0;
 124         int     lflag   = 0;
 125         int     eflag   = 0;
 126         int     errflg  = 0;
 127         char *pp;
 128         FILE *fp, *tmpfp;
 129         struct stat stbuf;
 130         struct passwd *pwp;
 131         time_t omodtime;
 132         char *editor;
 133         uid_t ruid;
 134         pid_t pid;
 135         int stat_loc;
 136         int ret;
 137         char real_login[UNAMESIZE];
 138         char *user = NULL;
 139         int tmpfd = -1;
 140         pam_handle_t *pamh;
 141         int pam_error;
 142         char *buf;
 143         size_t buflen;
 144 
 145         (void) setlocale(LC_ALL, "");
 146 #if !defined(TEXT_DOMAIN)       /* Should be defined by cc -D */
 147 #define TEXT_DOMAIN "SYS_TEST"  /* Use this only if it wasn't */
 148 #endif
 149         (void) textdomain(TEXT_DOMAIN);
 150 
 151         if (init_yes() < 0) {
 152                 (void) fprintf(stderr, gettext(ERR_MSG_INIT_YES),
 153                     strerror(errno));
 154                 exit(1);
 155         }
 156 
 157         while ((c = getopt(argc, argv, "elru:")) != EOF) {
 158                 switch (c) {
 159                         case 'e':
 160                                 eflag++;
 161                                 break;
 162                         case 'l':
 163                                 lflag++;
 164                                 break;
 165                         case 'r':
 166                                 rflag++;
 167                                 break;
 168                         case 'u':
 169                                 user = optarg;
 170                                 break;
 171                         case '?':
 172                                 errflg++;
 173                                 break;
 174                 }
 175         }
 176 
 177         argc -= optind;
 178         argv += optind;
 179 
 180         if (eflag + lflag + rflag > 1)
 181                 errflg++;
 182 
 183         if ((eflag || lflag || rflag) && argc > 0) {
 184                 if (user != NULL)
 185                         errflg++;
 186                 else
 187                         user = *argv;
 188         }
 189 
 190         if (errflg || argc > 1)
 191                 crabort(BADUSAGE);
 192 
 193         ruid = getuid();
 194         if ((pwp = getpwuid(ruid)) == NULL)
 195                 crabort(INVALIDUSER);
 196 
 197         if (strlcpy(real_login, pwp->pw_name, sizeof (real_login))
 198             >= sizeof (real_login)) {
 199                 crabort(NAMETOOLONG);
 200         }
 201 
 202         if (user != NULL) {
 203                 if ((pwp = getpwnam(user)) == NULL)
 204                         crabort(INVALIDUSER);
 205 
 206                 if (!cron_admin(real_login)) {
 207                         if (pwp->pw_uid != ruid)
 208                                 crabort(NOTROOT);
 209                         else
 210                                 pp = getuser(ruid);


 211                 } else {
 212                         pp = user;
 213                 }
 214         } else {
 215                 pp = getuser(ruid);
 216         }
 217 
 218         if (pp == NULL) {
 219                 if (per_errno == 2)
 220                         crabort(BADSHELL);
 221                 else
 222                         crabort(INVALIDUSER);
 223         }
 224         if (strlcpy(login, pp, sizeof (login)) >= sizeof (login))
 225                 crabort(NAMETOOLONG);
 226         if (!allowed(login, CRONALLOW, CRONDENY))
 227                 crabort(NOTALLOWED);
 228 
 229         /* Do account validation check */
 230         pam_error = pam_start("cron", pp, NULL, &pamh);
 231         if (pam_error != PAM_SUCCESS) {
 232                 crabort((char *)pam_strerror(pamh, pam_error));
 233         }
 234         pam_error = pam_acct_mgmt(pamh, PAM_SILENT);