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 }