1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   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 /*
  23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * A program to become another unix user or kerberos principal
  29  * to execute specified command.
  30  *
  31  * Usage: chg_usr_exec [-k kpassword ] <login> <commands>
  32  *              -k kpassword    Kerberos password if login is specified
  33  *                              to a kerberos principal.
  34  *              login           a unix user or kerberos principal
  35  *              command         Soaris command or executable file executed
  36  *                              by login.
  37  */
  38 
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #include <unistd.h>
  42 #include <string.h>
  43 #include <errno.h>
  44 #include <pwd.h>
  45 
  46 #define BUFSIZE 10240
  47 
  48 void
  49 usage(char *cmd)
  50 {
  51         (void) printf("\tUsage: %s [-k kpassword ] <login> <commands> ...\n",
  52             cmd);
  53         exit(1);
  54 }
  55 
  56 int
  57 main(int argc, char *argv[])
  58 {
  59         char *plogin = NULL;
  60         char cmds[BUFSIZE] = { 0 };
  61         char sep[] = " ";
  62         struct passwd *ppw = NULL;
  63         char *kpasswd = NULL;
  64         int c, i, len;
  65 
  66         while ((c = getopt(argc, argv, "k:")) != -1) {
  67                 switch (c) {
  68                         case 'k':
  69                                 kpasswd = optarg;
  70                                 break;
  71                         default:
  72                                 usage(argv[0]);
  73                                 break;
  74                 }
  75         }
  76 
  77         if ((argc-optind) < 2 || strlen(argv[optind]) == 0)
  78                 usage(argv[0]);
  79 
  80         len = 0;
  81         plogin = argv[optind];
  82         if (kpasswd) {
  83                 (void) snprintf(cmds, sizeof (cmds),
  84                     "echo %s | kinit %s > /dev/null && ", kpasswd, plogin);
  85                 len = strlen(cmds);
  86         }
  87 
  88         for (i = optind + 1; i < argc; i++) {
  89                 (void) snprintf(cmds+len, sizeof (cmds)-len,
  90                     "%s%s", argv[i], sep);
  91                 len += strlen(argv[i]) + strlen(sep);
  92         }
  93 
  94         if ((ppw = getpwnam(plogin)) == NULL) {
  95                 (void) printf("User(%s) isn't found,getpwnam() returns NULL",
  96                     plogin);
  97                 return (1);
  98         }
  99         if (setgid(ppw->pw_gid) != 0) {
 100                 perror("setgid");
 101                 return (errno);
 102         }
 103         if (setuid(ppw->pw_uid) != 0) {
 104                 perror("setuid");
 105                 return (errno);
 106         }
 107 
 108         if (execl("/usr/xpg4/bin/sh", "sh",  "-c", cmds, (char *)0) != 0) {
 109                 perror("execl");
 110                 return (errno);
 111         }
 112 
 113         return (0);
 114 }