1 /* 2 * Copyright (c) 1997-2001 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "kadmin_locl.h" 35 #include <parse_units.h> 36 37 RCSID("$Id: get.c,v 1.13 2001/05/07 05:31:43 assar Exp $"); 38 39 struct get_entry_data { 40 void (*header)(void); 41 void (*format)(kadm5_principal_ent_t); 42 }; 43 44 static void 45 print_entry_terse(kadm5_principal_ent_t princ) 46 { 47 char *p; 48 krb5_unparse_name(context, princ->principal, &p); 49 printf(" %s\n", p); 50 free(p); 51 } 52 53 static void 54 print_header_short(void) 55 { 56 printf("%-20s ", "Principal"); 57 58 printf("%-10s ", "Expires"); 59 60 printf("%-10s ", "PW-exp"); 61 62 printf("%-10s ", "PW-change"); 63 64 printf("%-9s ", "Max life"); 65 66 printf("%-9s ", "Max renew"); 67 68 printf("\n"); 69 } 70 71 static void 72 print_entry_short(kadm5_principal_ent_t princ) 73 { 74 char buf[1024]; 75 76 krb5_unparse_name_fixed_short(context, princ->principal, buf, sizeof(buf)); 77 printf("%-20s ", buf); 78 79 time_t2str(princ->princ_expire_time, buf, sizeof(buf), 0); 80 printf("%-10s ", buf); 81 82 time_t2str(princ->pw_expiration, buf, sizeof(buf), 0); 83 printf("%-10s ", buf); 84 85 time_t2str(princ->last_pwd_change, buf, sizeof(buf), 0); 86 printf("%-10s ", buf); 87 88 deltat2str(princ->max_life, buf, sizeof(buf)); 89 printf("%-9s ", buf); 90 91 deltat2str(princ->max_renewable_life, buf, sizeof(buf)); 92 printf("%-9s ", buf); 93 94 #if 0 95 time_t2str(princ->mod_date, buf, sizeof(buf), 0); 96 printf("%-10s ", buf); 97 98 krb5_unparse_name_fixed(context, princ->mod_name, buf, sizeof(buf)); 99 printf("%-24s", buf); 100 #endif 101 102 printf("\n"); 103 } 104 105 /* 106 * return 0 iff `salt' actually is the same as the current salt in `k' 107 */ 108 109 static int 110 cmp_salt (const krb5_salt *salt, const krb5_key_data *k) 111 { 112 if (salt->salttype != k->key_data_type[1]) 113 return 1; 114 if (salt->saltvalue.length != k->key_data_length[1]) 115 return 1; 116 return memcmp (salt->saltvalue.data, k->key_data_contents[1], 117 salt->saltvalue.length); 118 } 119 120 static void 121 print_entry_long(kadm5_principal_ent_t princ) 122 { 123 char buf[1024]; 124 int i; 125 krb5_salt def_salt; 126 127 krb5_unparse_name_fixed(context, princ->principal, buf, sizeof(buf)); 128 printf("%24s: %s\n", "Principal", buf); 129 time_t2str(princ->princ_expire_time, buf, sizeof(buf), 1); 130 printf("%24s: %s\n", "Principal expires", buf); 131 132 time_t2str(princ->pw_expiration, buf, sizeof(buf), 1); 133 printf("%24s: %s\n", "Password expires", buf); 134 135 time_t2str(princ->last_pwd_change, buf, sizeof(buf), 1); 136 printf("%24s: %s\n", "Last password change", buf); 137 138 deltat2str(princ->max_life, buf, sizeof(buf)); 139 printf("%24s: %s\n", "Max ticket life", buf); 140 141 deltat2str(princ->max_renewable_life, buf, sizeof(buf)); 142 printf("%24s: %s\n", "Max renewable life", buf); 143 printf("%24s: %d\n", "Kvno", princ->kvno); 144 printf("%24s: %d\n", "Mkvno", princ->mkvno); 145 printf("%24s: %s\n", "Policy", princ->policy ? princ->policy : "none"); 146 time_t2str(princ->last_success, buf, sizeof(buf), 1); 147 printf("%24s: %s\n", "Last successful login", buf); 148 time_t2str(princ->last_failed, buf, sizeof(buf), 1); 149 printf("%24s: %s\n", "Last failed login", buf); 150 printf("%24s: %d\n", "Failed login count", princ->fail_auth_count); 151 time_t2str(princ->mod_date, buf, sizeof(buf), 1); 152 printf("%24s: %s\n", "Last modified", buf); 153 if(princ->mod_name != NULL) { 154 krb5_unparse_name_fixed(context, princ->mod_name, buf, sizeof(buf)); 155 printf("%24s: %s\n", "Modifier", buf); 156 } 157 attributes2str (princ->attributes, buf, sizeof(buf)); 158 printf("%24s: %s\n", "Attributes", buf); 159 160 printf("%24s: ", "Keytypes(salttype[(salt-value)])"); 161 162 krb5_get_pw_salt (context, princ->principal, &def_salt); 163 164 for (i = 0; i < princ->n_key_data; ++i) { 165 krb5_key_data *k = &princ->key_data[i]; 166 krb5_error_code ret; 167 char *e_string, *s_string, *salt; 168 169 ret = krb5_enctype_to_string (context, 170 k->key_data_type[0], 171 &e_string); 172 if (ret) 173 asprintf (&e_string, "unknown(%d)", k->key_data_type[0]); 174 175 ret = krb5_salttype_to_string (context, 176 k->key_data_type[0], 177 k->key_data_type[1], 178 &s_string); 179 if (ret) 180 asprintf (&s_string, "unknown(%d)", k->key_data_type[1]); 181 182 if (cmp_salt(&def_salt, k) == 0) 183 salt = strdup(""); 184 else if(k->key_data_length[1] == 0) 185 salt = strdup("()"); 186 else 187 asprintf (&salt, "(%.*s)", k->key_data_length[1], 188 (char *)k->key_data_contents[1]); 189 190 191 printf ("%s%s(%s%s)", (i != 0) ? ", " : "", e_string, s_string, salt); 192 free (e_string); 193 free (s_string); 194 free (salt); 195 } 196 krb5_free_salt (context, def_salt); 197 printf("\n\n"); 198 } 199 200 static int 201 do_get_entry(krb5_principal principal, void *data) 202 { 203 kadm5_principal_ent_rec princ; 204 krb5_error_code ret; 205 struct get_entry_data *e = data; 206 207 memset(&princ, 0, sizeof(princ)); 208 ret = kadm5_get_principal(kadm_handle, principal, 209 &princ, 210 KADM5_PRINCIPAL_NORMAL_MASK|KADM5_KEY_DATA); 211 if(ret) 212 return ret; 213 else { 214 if(e->header) { 215 (*e->header)(); 216 e->header = NULL; /* XXX only once */ 217 } 218 (e->format)(&princ); 219 kadm5_free_principal_ent(kadm_handle, &princ); 220 } 221 return 0; 222 } 223 224 static int 225 getit(const char *name, int terse_flag, int argc, char **argv) 226 { 227 int i; 228 krb5_error_code ret; 229 struct get_entry_data data; 230 struct getargs args[] = { 231 { "long", 'l', arg_flag, NULL, "long format" }, 232 { "short", 's', arg_flag, NULL, "short format" }, 233 { "terse", 't', arg_flag, NULL, "terse format" }, 234 }; 235 int num_args = sizeof(args) / sizeof(args[0]); 236 int optind = 0; 237 int long_flag = -1; 238 int short_flag = -1; 239 240 args[0].value = &long_flag; 241 args[1].value = &short_flag; 242 args[2].value = &terse_flag; 243 244 if(getarg(args, num_args, argc, argv, &optind)) 245 goto usage; 246 if(optind == argc) 247 goto usage; 248 249 if(long_flag == -1 && (short_flag == 1 || terse_flag == 1)) 250 long_flag = 0; 251 if(short_flag == -1 && (long_flag == 1 || terse_flag == 1)) 252 short_flag = 0; 253 if(terse_flag == -1 && (long_flag == 1 || short_flag == 1)) 254 terse_flag = 0; 255 if(long_flag == 0 && short_flag == 0 && terse_flag == 0) 256 short_flag = 1; 257 258 if(long_flag) { 259 data.format = print_entry_long; 260 data.header = NULL; 261 } else if(short_flag){ 262 data.format = print_entry_short; 263 data.header = print_header_short; 264 } else if(terse_flag) { 265 data.format = print_entry_terse; 266 data.header = NULL; 267 } 268 269 argc -= optind; 270 argv += optind; 271 272 for(i = 0; i < argc; i++) 273 ret = foreach_principal(argv[i], do_get_entry, "get", &data); 274 return 0; 275 usage: 276 arg_printusage (args, num_args, name, "principal..."); 277 return 0; 278 } 279 280 int 281 get_entry(int argc, char **argv) 282 { 283 return getit("get", 0, argc, argv); 284 } 285 286 int 287 list_princs(int argc, char **argv) 288 { 289 return getit("list", 1, argc, argv); 290 } 291