1 /*
   2  * Copyright 1995-2002 Sun Microsystems, Inc.  All rights reserved.
   3  * Use is subject to license terms.
   4  *
   5  * Copyright 2013 Nexenta Systems. All rights reserved.
   6  */
   7 
   8 /*
   9  * Test client for kwarnd.  This program is not shipped on the binary
  10  * release. This code was taken and modified from gssdtest.c
  11  */
  12 
  13 #include <stdio.h>
  14 #include <strings.h>
  15 #include <ctype.h>
  16 #include <stdlib.h>
  17 #include "kwarnd.h"
  18 #include <rpc/rpc.h>
  19 
  20 #define LOOP_COUNTER  100
  21 
  22 #define OCTAL_MACRO "%03.3o."
  23 #define MALLOC(n) malloc(n)
  24 #define CALLOC(n, s) calloc((n), (s))
  25 #define FREE(x, n) free(x)
  26 
  27 static void instructs(void);
  28 static void usage(void);
  29 static int parse_input_line(char *, int *, char ***);
  30 extern uid_t getuid(void);
  31 
  32 static void _kwarnd_add_warning(int, char **);
  33 static void _kwarnd_del_warning(int, char **);
  34 
  35 static int do_kwarndtest(char *buf);
  36 
  37 extern OM_UINT32 kwarn_add_warning();
  38 extern OM_UINT32 kwarn_del_warning();
  39 
  40 static int read_line(char *buf, int size)
  41 {
  42         int len;
  43 
  44         /* read the next line. If cntl-d, return with zero char count */
  45         printf(gettext("\n> "));
  46 
  47         if (fgets(buf, size, stdin) == NULL)
  48                 return (0);
  49 
  50         len = strlen(buf);
  51         buf[--len] = '\0';
  52         return (len);
  53 }
  54 
  55 int
  56 main()
  57 {
  58         char buf[512];
  59         int len, ret;
  60 
  61         /* Print out usage and instructions to start off the session */
  62 
  63         instructs();
  64         usage();
  65 
  66         /*
  67          * Loop, repeatedly calling parse_input_line() to get the
  68          * next line and parse it into argc and argv. Act on the
  69          * arguements found on the line.
  70          */
  71 
  72         do {
  73                 len = read_line(buf, 512);
  74                 if (len)
  75                         ret = do_kwarndtest(buf);
  76         } while (len && !ret);
  77 
  78         return (0);
  79 }
  80 
  81 static int
  82 do_kwarndtest(char *buf)
  83 {
  84         int argc;
  85         char **argv, **argv_array;
  86 
  87         char *cmd;
  88 
  89         argv = 0;
  90 
  91         if (parse_input_line(buf, &argc, &argv) == 0) {
  92                 printf(gettext("\n"));
  93                 return (1);
  94         }
  95 
  96         if (argc == 0) {
  97                 usage();
  98                 FREE(argv, (argc+1)*sizeof (char *));
  99                 return (0);
 100         }
 101 
 102         /*
 103          * remember argv_array address, which is memory calloc'd by
 104          * parse_input_line, so it can be free'd at the end of the loop.
 105          */
 106 
 107         argv_array = argv;
 108 
 109         cmd = argv[0];
 110 
 111         argc--;
 112         argv++;
 113 
 114         if (strcmp(cmd, "kwarn_add_warning") == 0 ||
 115             strcmp(cmd, "add") == 0) {
 116                 _kwarnd_add_warning(argc, argv);
 117         } else if (strcmp(cmd, "kwarn_del_warning") == 0 ||
 118             strcmp(cmd, "delete") == 0) {
 119                 _kwarnd_del_warning(argc, argv);
 120         } else if (strcmp(cmd, "exit") == 0) {
 121                 printf(gettext("\n"));
 122                 FREE(argv_array, (argc+2) * sizeof (char *));
 123                 return (1);
 124         } else
 125                 usage();
 126 
 127         /* free argv array */
 128 
 129         FREE(argv_array, (argc+2) * sizeof (char *));
 130         return (0);
 131 }
 132 
 133 static void
 134 _kwarnd_add_warning(int argc, char **argv)
 135 {
 136         OM_UINT32 status;
 137         time_t  exptime;
 138         time_t  now;
 139 
 140         /* set up the arguments specified in the input parameters */
 141 
 142         if (argc == 0) {
 143                 usage();
 144                 return;
 145         }
 146 
 147         if (argc != 2) {
 148                 usage();
 149                 return;
 150         }
 151 
 152         time(&now);
 153         exptime = atol(argv[1]);
 154         exptime = now + exptime;
 155 
 156         status = kwarn_add_warning(argv[0], exptime);
 157 
 158         if (status == 0) {
 159                 printf(gettext("\nadd of credential\n\n"));
 160                 printf(gettext("warning message successful for \"%s\"\n\n"),
 161                     argv[0]);
 162         } else {
 163                 printf(gettext("server ret err (octal) %o (%s)\n"),
 164                     status, gettext("add warning error"));
 165         }
 166 
 167         return;
 168 
 169 }
 170 
 171 static void
 172 _kwarnd_del_warning(int argc, char **argv)
 173 {
 174         OM_UINT32 status;
 175 
 176         if (argc != 1) {
 177                 usage();
 178                 return;
 179         }
 180 
 181         status = kwarn_del_warning(argv[0]);
 182 
 183         if (status == 0) {
 184                 printf(gettext("delete of principal warning message"
 185                     "for %s successful"),
 186                     argv[0]);
 187         } else {
 188                 printf(gettext("delete of principal %s unsuccessful\n\n"),
 189                     argv[0]);
 190         }
 191 }
 192 
 193 static void
 194 instructs(void)
 195 {
 196         fprintf(stderr,
 197             gettext(
 198 "\nThis program will test kwarnd.  kwarnd must be running as root. Enter\n"
 199 "the desired command and the principal to be added/deleted. If adding a\n"
 200 "principal, also include the expiration time in seconds.\n"));
 201 }
 202 
 203 static void
 204 usage(void)
 205 {
 206         fprintf(stderr,
 207             gettext(
 208             "\nusage:\t[kwarn_add_warning | add] (principal) (exptime)\n"
 209             "\t[kwarn_del_warning | delete] (principal)\n"
 210             "\texit\n\n"));
 211 }
 212 
 213 /* Copied from parse_argv(), then modified */
 214 
 215 static int
 216 parse_input_line(char *input_line, int *argc, char ***argv)
 217 {
 218         const char nil = '\0';
 219         char *chptr;
 220         int chr_cnt;
 221         int arg_cnt = 0;
 222         int ch_was_space = 1;
 223         int ch_is_space;
 224 
 225         chr_cnt = strlen(input_line);
 226 
 227         /* Count the arguments in the input_line string */
 228 
 229         *argc = 1;
 230 
 231         for (chptr = &input_line[0]; *chptr != nil; chptr++) {
 232                 ch_is_space = isspace(*chptr);
 233                 if (ch_is_space && !ch_was_space) {
 234                         (*argc)++;
 235                 }
 236                 ch_was_space = ch_is_space;
 237         }
 238 
 239         if (ch_was_space) {
 240                 (*argc)--;
 241         }       /* minus trailing spaces */
 242 
 243         /* Now that we know how many args calloc the argv array */
 244 
 245         *argv = (char **)CALLOC((*argc)+1, sizeof (char *));
 246         chptr = (char *)(&input_line[0]);
 247 
 248         for (ch_was_space = 1; *chptr != nil; chptr++) {
 249                 ch_is_space = isspace(*chptr);
 250                 if (ch_is_space) {
 251                         *chptr = nil;   /* replace each space with nil  */
 252                 } else if (ch_was_space) {      /* begining of word? */
 253                         (*argv)[arg_cnt++] = chptr;     /* new argument ? */
 254                 }
 255 
 256                 ch_was_space = ch_is_space;
 257         }
 258 
 259         return (chr_cnt);
 260 }