9 #define USE_KADM5_API_VERSION 2
10 #include <kadm5/admin.h>
15 #include "tcl_kadm5.h"
22 /* XXX This should probably be in the hash table like server_handle */
23 static krb5_context context;
25 static struct flagval krb5_flags_array[] = {
26 {"KRB5_KDB_DISALLOW_POSTDATED", KRB5_KDB_DISALLOW_POSTDATED},
27 {"KRB5_KDB_DISALLOW_FORWARDABLE", KRB5_KDB_DISALLOW_FORWARDABLE},
28 {"KRB5_KDB_DISALLOW_TGT_BASED", KRB5_KDB_DISALLOW_TGT_BASED},
29 {"KRB5_KDB_DISALLOW_RENEWABLE", KRB5_KDB_DISALLOW_RENEWABLE},
30 {"KRB5_KDB_DISALLOW_PROXIABLE", KRB5_KDB_DISALLOW_PROXIABLE},
31 {"KRB5_KDB_DISALLOW_DUP_SKEY", KRB5_KDB_DISALLOW_DUP_SKEY},
32 {"KRB5_KDB_DISALLOW_ALL_TIX", KRB5_KDB_DISALLOW_ALL_TIX},
33 {"KRB5_KDB_REQUIRES_PRE_AUTH", KRB5_KDB_REQUIRES_PRE_AUTH},
34 {"KRB5_KDB_REQUIRES_HW_AUTH", KRB5_KDB_REQUIRES_HW_AUTH},
35 {"KRB5_KDB_REQUIRES_PWCHANGE", KRB5_KDB_REQUIRES_PWCHANGE},
36 {"KRB5_KDB_DISALLOW_SVR", KRB5_KDB_DISALLOW_SVR},
37 {"KRB5_KDB_PWCHANGE_SERVICE", KRB5_KDB_PWCHANGE_SERVICE}
40 static struct flagval aux_attributes[] = {
41 {"KADM5_POLICY", KADM5_POLICY}
44 static struct flagval principal_mask_flags[] = {
45 {"KADM5_PRINCIPAL", KADM5_PRINCIPAL},
46 {"KADM5_PRINC_EXPIRE_TIME", KADM5_PRINC_EXPIRE_TIME},
47 {"KADM5_PW_EXPIRATION", KADM5_PW_EXPIRATION},
48 {"KADM5_LAST_PWD_CHANGE", KADM5_LAST_PWD_CHANGE},
49 {"KADM5_ATTRIBUTES", KADM5_ATTRIBUTES},
50 {"KADM5_MAX_LIFE", KADM5_MAX_LIFE},
51 {"KADM5_MOD_TIME", KADM5_MOD_TIME},
52 {"KADM5_MOD_NAME", KADM5_MOD_NAME},
53 {"KADM5_KVNO", KADM5_KVNO},
54 {"KADM5_MKVNO", KADM5_MKVNO},
55 {"KADM5_AUX_ATTRIBUTES", KADM5_AUX_ATTRIBUTES},
56 {"KADM5_POLICY", KADM5_POLICY},
57 {"KADM5_POLICY_CLR", KADM5_POLICY_CLR},
58 {"KADM5_MAX_RLIFE", KADM5_MAX_RLIFE},
59 {"KADM5_LAST_SUCCESS", KADM5_LAST_SUCCESS},
60 {"KADM5_LAST_FAILED", KADM5_LAST_FAILED},
61 {"KADM5_FAIL_AUTH_COUNT", KADM5_FAIL_AUTH_COUNT},
62 {"KADM5_KEY_DATA", KADM5_KEY_DATA},
63 {"KADM5_TL_DATA", KADM5_TL_DATA},
64 {"KADM5_PRINCIPAL_NORMAL_MASK", KADM5_PRINCIPAL_NORMAL_MASK}
67 static struct flagval policy_mask_flags[] = {
68 {"KADM5_POLICY", KADM5_POLICY},
69 {"KADM5_PW_MAX_LIFE", KADM5_PW_MAX_LIFE},
70 {"KADM5_PW_MIN_LIFE", KADM5_PW_MIN_LIFE},
71 {"KADM5_PW_MIN_LENGTH", KADM5_PW_MIN_LENGTH},
72 {"KADM5_PW_MIN_CLASSES", KADM5_PW_MIN_CLASSES},
73 {"KADM5_PW_HISTORY_NUM", KADM5_PW_HISTORY_NUM},
74 {"KADM5_REF_COUNT", KADM5_REF_COUNT}
77 static struct flagval config_mask_flags[] = {
78 {"KADM5_CONFIG_REALM", KADM5_CONFIG_REALM},
79 {"KADM5_CONFIG_DBNAME", KADM5_CONFIG_DBNAME},
80 {"KADM5_CONFIG_MKEY_NAME", KADM5_CONFIG_MKEY_NAME},
81 {"KADM5_CONFIG_MAX_LIFE", KADM5_CONFIG_MAX_LIFE},
82 {"KADM5_CONFIG_MAX_RLIFE", KADM5_CONFIG_MAX_RLIFE},
83 {"KADM5_CONFIG_EXPIRATION", KADM5_CONFIG_EXPIRATION},
84 {"KADM5_CONFIG_FLAGS", KADM5_CONFIG_FLAGS},
85 {"KADM5_CONFIG_ADMIN_KEYTAB", KADM5_CONFIG_ADMIN_KEYTAB},
86 {"KADM5_CONFIG_STASH_FILE", KADM5_CONFIG_STASH_FILE},
87 {"KADM5_CONFIG_ENCTYPE", KADM5_CONFIG_ENCTYPE},
88 {"KADM5_CONFIG_ADBNAME", KADM5_CONFIG_ADBNAME},
89 {"KADM5_CONFIG_ADB_LOCKFILE", KADM5_CONFIG_ADB_LOCKFILE},
90 {"KADM5_CONFIG_ACL_FILE", KADM5_CONFIG_ACL_FILE},
91 {"KADM5_CONFIG_KADMIND_PORT", KADM5_CONFIG_KADMIND_PORT},
92 {"KADM5_CONFIG_ENCTYPES", KADM5_CONFIG_ENCTYPES},
93 {"KADM5_CONFIG_ADMIN_SERVER", KADM5_CONFIG_ADMIN_SERVER},
94 {"KADM5_CONFIG_DICT_FILE", KADM5_CONFIG_DICT_FILE},
95 {"KADM5_CONFIG_MKEY_FROM_KBD", KADM5_CONFIG_MKEY_FROM_KBD},
98 static struct flagval priv_flags[] = {
99 {"KADM5_PRIV_GET", KADM5_PRIV_GET},
100 {"KADM5_PRIV_ADD", KADM5_PRIV_ADD},
101 {"KADM5_PRIV_MODIFY", KADM5_PRIV_MODIFY},
102 {"KADM5_PRIV_DELETE", KADM5_PRIV_DELETE}
106 static char *arg_error = "wrong # args";
108 static Tcl_HashTable *struct_table = 0;
110 static int put_server_handle(Tcl_Interp *interp, void *handle, char **name)
112 int i = 1, newPtr = 0;
114 Tcl_HashEntry *entry;
116 if (! struct_table) {
117 if (! (struct_table =
118 malloc(sizeof(*struct_table)))) {
119 fprintf(stderr, "Out of memory!\n");
122 Tcl_InitHashTable(struct_table, TCL_STRING_KEYS);
127 * Handles from ovsec_kadm_init() and kadm5_init() should not
128 * be mixed during unit tests, but the API would happily
129 * accept them. Making the hash entry names different in
130 * tcl_kadm.c and tcl_ovsec_kadm.c ensures that GET_HANDLE
131 * will fail if presented a handle from the other API.
133 sprintf(buf, "kadm5_handle%d", i);
134 entry = Tcl_CreateHashEntry(struct_table, buf, &newPtr);
138 Tcl_SetHashValue(entry, handle);
145 static int get_server_handle(Tcl_Interp *interp, const char *name,
148 Tcl_HashEntry *entry;
150 if(!strcasecmp(name, "null"))
153 if (! (struct_table &&
154 (entry = Tcl_FindHashEntry(struct_table, name)))) {
155 if (strncmp(name, "ovsec_kadm_handle", 17) == 0)
156 Tcl_AppendResult(interp, "ovsec_kadm handle "
157 "specified for kadm5 api: ", name, 0);
159 Tcl_AppendResult(interp, "unknown server handle ", name, 0);
162 *handle = (void *) Tcl_GetHashValue(entry);
167 static int remove_server_handle(Tcl_Interp *interp, const char *name)
169 Tcl_HashEntry *entry;
171 if (! (struct_table &&
172 (entry = Tcl_FindHashEntry(struct_table, name)))) {
173 Tcl_AppendResult(interp, "unknown server handle ", name, 0);
177 Tcl_SetHashValue(entry, NULL);
181 #define GET_HANDLE(num_args, ignored) \
182 void *server_handle; \
183 const char *whoami = argv[0]; \
185 if (argc != num_args + 1) { \
186 Tcl_AppendResult(interp, whoami, ": ", arg_error, 0); \
191 if ((ltcl_ret = get_server_handle(interp, argv[0], &server_handle)) \
198 static Tcl_HashTable *create_flag_table(struct flagval *flags, int size)
200 Tcl_HashTable *table;
201 Tcl_HashEntry *entry;
204 if (! (table = (Tcl_HashTable *) malloc(sizeof(Tcl_HashTable)))) {
205 fprintf(stderr, "Out of memory!\n");
209 Tcl_InitHashTable(table, TCL_STRING_KEYS);
211 for (i = 0; i < size; i++) {
214 if (! (entry = Tcl_CreateHashEntry(table, flags[i].name, &newPtr))) {
215 fprintf(stderr, "Out of memory!\n");
219 Tcl_SetHashValue(entry, &flags[i].val);
226 static Tcl_DString *unparse_str(char *in_str)
230 if (! (str = malloc(sizeof(*str)))) {
231 fprintf(stderr, "Out of memory!\n");
235 Tcl_DStringInit(str);
238 Tcl_DStringAppend(str, "null", -1);
241 Tcl_DStringAppend(str, in_str, -1);
249 static int parse_str(Tcl_Interp *interp, const char *in_str, char **out_str)
254 else if (! strcasecmp(in_str, "null")) {
258 *out_str = (char *) in_str;
264 static void set_ok(Tcl_Interp *interp, char *string)
266 Tcl_SetResult(interp, "OK", TCL_STATIC);
267 Tcl_AppendElement(interp, "KADM5_OK");
268 Tcl_AppendElement(interp, string);
273 static Tcl_DString *unparse_err(kadm5_ret_t code)
276 const char *error_string;
277 Tcl_DString *dstring;
280 case KADM5_FAILURE: code_string = "KADM5_FAILURE"; break;
281 case KADM5_AUTH_GET: code_string = "KADM5_AUTH_GET"; break;
282 case KADM5_AUTH_ADD: code_string = "KADM5_AUTH_ADD"; break;
283 case KADM5_AUTH_MODIFY:
284 code_string = "KADM5_AUTH_MODIFY"; break;
285 case KADM5_AUTH_DELETE:
286 code_string = "KADM5_AUTH_DELETE"; break;
287 case KADM5_AUTH_INSUFFICIENT:
288 code_string = "KADM5_AUTH_INSUFFICIENT"; break;
289 case KADM5_BAD_DB: code_string = "KADM5_BAD_DB"; break;
290 case KADM5_DUP: code_string = "KADM5_DUP"; break;
291 case KADM5_RPC_ERROR: code_string = "KADM5_RPC_ERROR"; break;
292 case KADM5_NO_SRV: code_string = "KADM5_NO_SRV"; break;
293 case KADM5_BAD_HIST_KEY:
294 code_string = "KADM5_BAD_HIST_KEY"; break;
295 case KADM5_NOT_INIT: code_string = "KADM5_NOT_INIT"; break;
296 case KADM5_INIT: code_string = "KADM5_INIT"; break;
297 case KADM5_BAD_PASSWORD:
298 code_string = "KADM5_BAD_PASSWORD"; break;
299 case KADM5_UNK_PRINC: code_string = "KADM5_UNK_PRINC"; break;
300 case KADM5_UNK_POLICY: code_string = "KADM5_UNK_POLICY"; break;
301 case KADM5_BAD_MASK: code_string = "KADM5_BAD_MASK"; break;
302 case KADM5_BAD_CLASS: code_string = "KADM5_BAD_CLASS"; break;
303 case KADM5_BAD_LENGTH: code_string = "KADM5_BAD_LENGTH"; break;
304 case KADM5_BAD_POLICY: code_string = "KADM5_BAD_POLICY"; break;
305 case KADM5_BAD_HISTORY: code_string = "KADM5_BAD_HISTORY"; break;
306 case KADM5_BAD_PRINCIPAL:
307 code_string = "KADM5_BAD_PRINCIPAL"; break;
308 case KADM5_BAD_AUX_ATTR:
309 code_string = "KADM5_BAD_AUX_ATTR"; break;
310 case KADM5_PASS_Q_TOOSHORT:
311 code_string = "KADM5_PASS_Q_TOOSHORT"; break;
312 case KADM5_PASS_Q_CLASS:
313 code_string = "KADM5_PASS_Q_CLASS"; break;
314 case KADM5_PASS_Q_DICT:
315 code_string = "KADM5_PASS_Q_DICT"; break;
316 case KADM5_PASS_REUSE: code_string = "KADM5_PASS_REUSE"; break;
317 case KADM5_PASS_TOOSOON:
318 code_string = "KADM5_PASS_TOOSOON"; break;
319 case KADM5_POLICY_REF:
320 code_string = "KADM5_POLICY_REF"; break;
321 case KADM5_PROTECT_PRINCIPAL:
322 code_string = "KADM5_PROTECT_PRINCIPAL"; break;
323 case KADM5_BAD_SERVER_HANDLE:
324 code_string = "KADM5_BAD_SERVER_HANDLE"; break;
325 case KADM5_BAD_STRUCT_VERSION:
326 code_string = "KADM5_BAD_STRUCT_VERSION"; break;
327 case KADM5_OLD_STRUCT_VERSION:
328 code_string = "KADM5_OLD_STRUCT_VERSION"; break;
329 case KADM5_NEW_STRUCT_VERSION:
330 code_string = "KADM5_NEW_STRUCT_VERSION"; break;
331 case KADM5_BAD_API_VERSION:
332 code_string = "KADM5_BAD_API_VERSION"; break;
333 case KADM5_OLD_LIB_API_VERSION:
334 code_string = "KADM5_OLD_LIB_API_VERSION"; break;
335 case KADM5_OLD_SERVER_API_VERSION:
336 code_string = "KADM5_OLD_SERVER_API_VERSION"; break;
337 case KADM5_NEW_LIB_API_VERSION:
338 code_string = "KADM5_NEW_LIB_API_VERSION"; break;
339 case KADM5_NEW_SERVER_API_VERSION:
340 code_string = "KADM5_NEW_SERVER_API_VERSION"; break;
341 case KADM5_SECURE_PRINC_MISSING:
342 code_string = "KADM5_SECURE_PRINC_MISSING"; break;
343 case KADM5_NO_RENAME_SALT:
344 code_string = "KADM5_NO_RENAME_SALT"; break;
345 case KADM5_BAD_CLIENT_PARAMS:
346 code_string = "KADM5_BAD_CLIENT_PARAMS"; break;
347 case KADM5_BAD_SERVER_PARAMS:
348 code_string = "KADM5_BAD_SERVER_PARAMS"; break;
349 case KADM5_AUTH_LIST:
350 code_string = "KADM5_AUTH_LIST"; break;
351 case KADM5_AUTH_CHANGEPW:
352 code_string = "KADM5_AUTH_CHANGEPW"; break;
353 case KADM5_GSS_ERROR: code_string = "KADM5_GSS_ERROR"; break;
354 case KADM5_BAD_TL_TYPE: code_string = "KADM5_BAD_TL_TYPE"; break;
355 case KADM5_MISSING_CONF_PARAMS:
356 code_string = "KADM5_MISSING_CONF_PARAMS"; break;
357 case KADM5_BAD_SERVER_NAME:
358 code_string = "KADM5_BAD_SERVER_NAME"; break;
359 case KADM5_MISSING_KRB5_CONF_PARAMS:
360 code_string = "KADM5_MISSING_KRB5_CONF_PARAMS"; break;
363 case OSA_ADB_DUP: code_string = "OSA_ADB_DUP"; break;
364 case OSA_ADB_NOENT: code_string = "ENOENT"; break;
365 case OSA_ADB_DBINIT: code_string = "OSA_ADB_DBINIT"; break;
366 case OSA_ADB_BAD_POLICY: code_string = "Bad policy name"; break;
367 case OSA_ADB_BAD_PRINC: code_string = "Bad principal name"; break;
368 case OSA_ADB_BAD_DB: code_string = "Invalid database."; break;
369 case OSA_ADB_XDR_FAILURE: code_string = "OSA_ADB_XDR_FAILURE"; break;
370 case OSA_ADB_BADLOCKMODE: code_string = "OSA_ADB_BADLOCKMODE"; break;
371 case OSA_ADB_CANTLOCK_DB: code_string = "OSA_ADB_CANTLOCK_DB"; break;
372 case OSA_ADB_NOTLOCKED: code_string = "OSA_ADB_NOTLOCKED"; break;
373 case OSA_ADB_NOLOCKFILE: code_string = "OSA_ADB_NOLOCKFILE"; break;
374 case OSA_ADB_NOEXCL_PERM: code_string = "OSA_ADB_NOEXCL_PERM"; break;
376 case KRB5_KDB_INUSE: code_string = "KRB5_KDB_INUSE"; break;
377 case KRB5_KDB_UK_SERROR: code_string = "KRB5_KDB_UK_SERROR"; break;
378 case KRB5_KDB_UK_RERROR: code_string = "KRB5_KDB_UK_RERROR"; break;
379 case KRB5_KDB_UNAUTH: code_string = "KRB5_KDB_UNAUTH"; break;
380 case KRB5_KDB_NOENTRY: code_string = "KRB5_KDB_NOENTRY"; break;
381 case KRB5_KDB_ILL_WILDCARD: code_string = "KRB5_KDB_ILL_WILDCARD"; break;
382 case KRB5_KDB_DB_INUSE: code_string = "KRB5_KDB_DB_INUSE"; break;
383 case KRB5_KDB_DB_CHANGED: code_string = "KRB5_KDB_DB_CHANGED"; break;
384 case KRB5_KDB_TRUNCATED_RECORD:
385 code_string = "KRB5_KDB_TRUNCATED_RECORD"; break;
386 case KRB5_KDB_RECURSIVELOCK:
387 code_string = "KRB5_KDB_RECURSIVELOCK"; break;
388 case KRB5_KDB_NOTLOCKED: code_string = "KRB5_KDB_NOTLOCKED"; break;
389 case KRB5_KDB_BADLOCKMODE: code_string = "KRB5_KDB_BADLOCKMODE"; break;
390 case KRB5_KDB_DBNOTINITED: code_string = "KRB5_KDB_DBNOTINITED"; break;
391 case KRB5_KDB_DBINITED: code_string = "KRB5_KDB_DBINITED"; break;
392 case KRB5_KDB_ILLDIRECTION: code_string = "KRB5_KDB_ILLDIRECTION"; break;
393 case KRB5_KDB_NOMASTERKEY: code_string = "KRB5_KDB_NOMASTERKEY"; break;
394 case KRB5_KDB_BADMASTERKEY: code_string = "KRB5_KDB_BADMASTERKEY"; break;
395 case KRB5_KDB_INVALIDKEYSIZE:
396 code_string = "KRB5_KDB_INVALIDKEYSIZE"; break;
397 case KRB5_KDB_CANTREAD_STORED:
398 code_string = "KRB5_KDB_CANTREAD_STORED"; break;
399 case KRB5_KDB_BADSTORED_MKEY:
400 code_string = "KRB5_KDB_BADSTORED_MKEY"; break;
401 case KRB5_KDB_CANTLOCK_DB: code_string = "KRB5_KDB_CANTLOCK_DB"; break;
402 case KRB5_KDB_DB_CORRUPT: code_string = "KRB5_KDB_DB_CORRUPT"; break;
404 case KRB5_PARSE_ILLCHAR: code_string = "KRB5_PARSE_ILLCHAR"; break;
405 case KRB5_PARSE_MALFORMED: code_string = "KRB5_PARSE_MALFORMED"; break;
406 case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN: code_string = "KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN"; break;
407 case KRB5_REALM_UNKNOWN: code_string = "KRB5_REALM_UNKNOWN"; break;
408 case KRB5_KDC_UNREACH: code_string = "KRB5_KDC_UNREACH"; break;
409 case KRB5_KDCREP_MODIFIED: code_string = "KRB5_KDCREP_MODIFIED"; break;
410 case KRB5KRB_AP_ERR_BAD_INTEGRITY: code_string = "KRB5KRB_AP_ERR_BAD_INTEGRITY"; break;
411 case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN: code_string = "KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN"; break;
412 case KRB5_CONFIG_BADFORMAT: code_string = "KRB5_CONFIG_BADFORMAT"; break;
414 case KRB5_CC_NOTFOUND: code_string = "KRB5_CC_NOTFOUND"; break;
415 case KRB5_FCC_NOFILE: code_string = "KRB5_FCC_NOFILE"; break;
417 case EINVAL: code_string = "EINVAL"; break;
418 case ENOENT: code_string = "ENOENT"; break;
421 fprintf(stderr, "**** CODE %ld (%s) ***\n", (long) code,
422 error_message (code));
423 code_string = "UNKNOWN";
427 error_string = error_message(code);
429 if (! (dstring = (Tcl_DString *) malloc(sizeof(Tcl_DString)))) {
430 fprintf(stderr, "Out of memory!\n");
431 exit(1); /* XXX Do we really want to exit? Ok if this is */
432 /* just a test program, but what about if it gets */
433 /* used for other things later? */
436 Tcl_DStringInit(dstring);
438 if (! (Tcl_DStringAppendElement(dstring, "ERROR") &&
439 Tcl_DStringAppendElement(dstring, code_string) &&
440 Tcl_DStringAppendElement(dstring, error_string))) {
441 fprintf(stderr, "Out of memory!\n");
450 static void stash_error(Tcl_Interp *interp, krb5_error_code code)
452 Tcl_DString *dstring = unparse_err(code);
453 Tcl_DStringResult(interp, dstring);
454 Tcl_DStringFree(dstring);
458 static Tcl_DString *unparse_key_data(krb5_key_data *key_data, int n_key_data)
464 if (! (str = malloc(sizeof(*str)))) {
465 fprintf(stderr, "Out of memory!\n");
469 Tcl_DStringInit(str);
470 for (i = 0; i < n_key_data; i++) {
471 krb5_key_data *key = &key_data[i];
473 Tcl_DStringStartSublist(str);
474 sprintf(buf, "%d", key->key_data_type[0]);
475 Tcl_DStringAppendElement(str, buf);
476 sprintf(buf, "%d", key->key_data_ver > 1 ?
477 key->key_data_type[1] : -1);
478 Tcl_DStringAppendElement(str, buf);
479 if (key->key_data_contents[0]) {
481 for (j = 0; j < key->key_data_length[0]; j++) {
482 sprintf(buf + 2*(j+1), "%02x",
483 key->key_data_contents[0][j]);
486 Tcl_DStringAppendElement(str, buf);
487 Tcl_DStringEndSublist(str);
493 static Tcl_DString *unparse_tl_data(krb5_tl_data *tl_data, int n_tl_data)
498 if (! (str = malloc(sizeof(*str)))) {
499 fprintf(stderr, "Out of memory!\n");
503 Tcl_DStringInit(str);
504 Tcl_DStringStartSublist(str);
505 for (; tl_data; tl_data = tl_data->tl_data_next) {
506 Tcl_DStringStartSublist(str);
507 sprintf(buf, "%d", tl_data->tl_data_type);
508 Tcl_DStringAppendElement(str, buf);
509 sprintf(buf, "%d", tl_data->tl_data_length);
510 Tcl_DStringAppendElement(str, buf);
511 Tcl_DStringAppend(str, " ", 1);
512 Tcl_DStringAppend(str, (char *) tl_data->tl_data_contents,
513 tl_data->tl_data_length);
514 Tcl_DStringEndSublist(str);
516 Tcl_DStringEndSublist(str);
521 static Tcl_DString *unparse_flags(struct flagval *array, int size,
527 if (! (str = malloc(sizeof(*str)))) {
528 fprintf(stderr, "Out of memory!\n");
532 Tcl_DStringInit(str);
534 for (i = 0; i < size; i++) {
535 if (flags & array[i].val) {
536 Tcl_DStringAppendElement(str, array[i].name);
544 static int parse_flags(Tcl_Interp *interp, Tcl_HashTable *table,
545 struct flagval *array, int size, const char *str,
548 int tmp, argc, i, retcode = TCL_OK;
550 Tcl_HashEntry *entry;
552 if (Tcl_GetInt(interp, str, &tmp) == TCL_OK) {
556 Tcl_ResetResult(interp);
558 if (Tcl_SplitList(interp, str, &argc, &argv) != TCL_OK) {
563 table = create_flag_table(array, size);
568 for (i = 0; i < argc; i++) {
569 if (! (entry = Tcl_FindHashEntry(table, argv[i]))) {
570 Tcl_AppendResult(interp, "unknown krb5 flag ", argv[i], 0);
574 *flags |= *(krb5_flags *) Tcl_GetHashValue(entry);
577 Tcl_Free((char *) argv);
581 static Tcl_DString *unparse_privs(krb5_flags flags)
583 return unparse_flags(priv_flags, sizeof(priv_flags) /
584 sizeof(struct flagval), flags);
588 static Tcl_DString *unparse_krb5_flags(krb5_flags flags)
590 return unparse_flags(krb5_flags_array, sizeof(krb5_flags_array) /
591 sizeof(struct flagval), flags);
594 static int parse_krb5_flags(Tcl_Interp *interp, const char *str,
598 static Tcl_HashTable *table = 0;
601 if ((tcl_ret = parse_flags(interp, table, krb5_flags_array,
602 sizeof(krb5_flags_array) /
603 sizeof(struct flagval),
604 str, &tmp)) != TCL_OK) {
612 static Tcl_DString *unparse_aux_attributes(krb5_int32 flags)
614 return unparse_flags(aux_attributes, sizeof(aux_attributes) /
615 sizeof(struct flagval), flags);
619 static int parse_aux_attributes(Tcl_Interp *interp, const char *str,
623 static Tcl_HashTable *table = 0;
626 if ((tcl_ret = parse_flags(interp, table, aux_attributes,
627 sizeof(aux_attributes) /
628 sizeof(struct flagval),
629 str, &tmp)) != TCL_OK) {
637 static int parse_principal_mask(Tcl_Interp *interp, const char *str,
641 static Tcl_HashTable *table = 0;
644 if ((tcl_ret = parse_flags(interp, table, principal_mask_flags,
645 sizeof(principal_mask_flags) /
646 sizeof(struct flagval),
647 str, &tmp)) != TCL_OK) {
655 static int parse_policy_mask(Tcl_Interp *interp, const char *str,
659 static Tcl_HashTable *table = 0;
662 if ((tcl_ret = parse_flags(interp, table, policy_mask_flags,
663 sizeof(policy_mask_flags) /
664 sizeof(struct flagval),
665 str, &tmp)) != TCL_OK) {
674 static Tcl_DString *unparse_principal_ent(kadm5_principal_ent_t princ,
677 Tcl_DString *str, *tmp_dstring;
680 krb5_error_code krb5_ret;
682 if (! (str = malloc(sizeof(*str)))) {
683 fprintf(stderr, "Out of memory!\n");
687 Tcl_DStringInit(str);
689 tmp = 0; /* It looks to me from looking at the library source */
690 /* code for krb5_parse_name that the pointer passed into */
691 /* it should be initialized to 0 if I want it do be */
692 /* allocated automatically. */
693 if (mask & KADM5_PRINCIPAL) {
694 krb5_ret = krb5_unparse_name(context, princ->principal, &tmp);
696 /* XXX Do we want to return an error? Not sure. */
697 Tcl_DStringAppendElement(str, "[unparseable principal]");
700 Tcl_DStringAppendElement(str, tmp);
704 Tcl_DStringAppendElement(str, "null");
706 sprintf(buf, "%d", princ->princ_expire_time);
707 Tcl_DStringAppendElement(str, buf);
709 sprintf(buf, "%d", princ->last_pwd_change);
710 Tcl_DStringAppendElement(str, buf);
712 sprintf(buf, "%d", princ->pw_expiration);
713 Tcl_DStringAppendElement(str, buf);
715 sprintf(buf, "%d", princ->max_life);
716 Tcl_DStringAppendElement(str, buf);
719 if (mask & KADM5_MOD_NAME) {
720 if ((krb5_ret = krb5_unparse_name(context, princ->mod_name, &tmp))) {
722 Tcl_DStringAppendElement(str, "[unparseable principal]");
725 Tcl_DStringAppendElement(str, tmp);
729 Tcl_DStringAppendElement(str, "null");
731 sprintf(buf, "%d", princ->mod_date);
732 Tcl_DStringAppendElement(str, buf);
734 if (mask & KADM5_ATTRIBUTES) {
735 tmp_dstring = unparse_krb5_flags(princ->attributes);
736 Tcl_DStringAppendElement(str, tmp_dstring->string);
737 Tcl_DStringFree(tmp_dstring);
740 Tcl_DStringAppendElement(str, "null");
742 sprintf(buf, "%d", princ->kvno);
743 Tcl_DStringAppendElement(str, buf);
745 sprintf(buf, "%d", princ->mkvno);
746 Tcl_DStringAppendElement(str, buf);
748 /* XXX This may be dangerous, because the contents of the policy */
749 /* field are undefined if the POLICY bit isn't set. However, I */
750 /* think it's a bug for the field not to be null in that case */
751 /* anyway, so we should assume that it will be null so that we'll */
752 /* catch it if it isn't. */
754 tmp_dstring = unparse_str(princ->policy);
755 Tcl_DStringAppendElement(str, tmp_dstring->string);
756 Tcl_DStringFree(tmp_dstring);
759 tmp_dstring = unparse_aux_attributes(princ->aux_attributes);
760 Tcl_DStringAppendElement(str, tmp_dstring->string);
761 Tcl_DStringFree(tmp_dstring);
764 sprintf(buf, "%d", princ->max_renewable_life);
765 Tcl_DStringAppendElement(str, buf);
767 sprintf(buf, "%d", princ->last_success);
768 Tcl_DStringAppendElement(str, buf);
770 sprintf(buf, "%d", princ->last_failed);
771 Tcl_DStringAppendElement(str, buf);
773 sprintf(buf, "%d", princ->fail_auth_count);
774 Tcl_DStringAppendElement(str, buf);
776 sprintf(buf, "%d", princ->n_key_data);
777 Tcl_DStringAppendElement(str, buf);
779 sprintf(buf, "%d", princ->n_tl_data);
780 Tcl_DStringAppendElement(str, buf);
782 tmp_dstring = unparse_key_data(princ->key_data, princ->n_key_data);
783 Tcl_DStringAppendElement(str, tmp_dstring->string);
784 Tcl_DStringFree(tmp_dstring);
787 tmp_dstring = unparse_tl_data(princ->tl_data, princ->n_tl_data);
788 Tcl_DStringAppendElement(str, tmp_dstring->string);
789 Tcl_DStringFree(tmp_dstring);
795 static int parse_keysalts(Tcl_Interp *interp, const char *list,
796 krb5_key_salt_tuple **keysalts,
799 const char **argv, **argv1 = NULL;
800 int i, tmp, argc, argc1, retcode;
806 if ((retcode = Tcl_SplitList(interp, list, &argc, &argv)) != TCL_OK) {
809 if (argc != num_keysalts) {
810 sprintf(interp->result, "%d keysalts specified, "
811 "but num_keysalts is %d", argc, num_keysalts);
815 *keysalts = (krb5_key_salt_tuple *)
816 malloc(sizeof(krb5_key_salt_tuple)*num_keysalts);
817 for (i = 0; i < num_keysalts; i++) {
818 if ((retcode = Tcl_SplitList(interp, argv[i], &argc1, &argv1)) !=
823 sprintf(interp->result, "wrong # fields in keysalt "
824 "(%d should be 2)", argc1);
828 /* XXX this used to be argv1[1] too! */
829 if ((retcode = Tcl_GetInt(interp, argv1[0], &tmp))
831 Tcl_AppendElement(interp, "while parsing ks_enctype");
835 (*keysalts)[i].ks_enctype = tmp;
836 if ((retcode = Tcl_GetInt(interp, argv1[1], &tmp))
838 Tcl_AppendElement(interp, "while parsing ks_salttype");
841 (*keysalts)[i].ks_salttype = tmp;
843 Tcl_Free((char *) argv1);
849 Tcl_Free((char *) argv1);
851 Tcl_Free((char *) argv);
855 static int parse_key_data(Tcl_Interp *interp, const char *list,
856 krb5_key_data **key_data,
864 if (n_key_data != 0) {
865 sprintf(interp->result, "0 key_datas specified, "
866 "but n_key_data is %d", n_key_data);
873 if ((retcode = Tcl_SplitList(interp, list, &argc, &argv)) != TCL_OK) {
876 if (argc != n_key_data) {
877 sprintf(interp->result, "%d key_datas specified, "
878 "but n_key_data is %d", argc, n_key_data);
884 sprintf(interp->result, "cannot parse key_data yet");
890 Tcl_Free((char *) argv);
894 static int parse_tl_data(Tcl_Interp *interp, const char *list,
898 krb5_tl_data *tl, *tl2;
899 const char **argv, **argv1 = NULL;
900 int i, tmp, argc, argc1, retcode;
904 if (n_tl_data != 0) {
905 sprintf(interp->result, "0 tl_datas specified, "
906 "but n_tl_data is %d", n_tl_data);
913 if ((retcode = Tcl_SplitList(interp, list, &argc, &argv)) != TCL_OK) {
916 if (argc != n_tl_data) {
917 sprintf(interp->result, "%d tl_datas specified, "
918 "but n_tl_data is %d", argc, n_tl_data);
924 for (i = 0; i < n_tl_data; i++) {
925 tl2 = (krb5_tl_data *) malloc(sizeof(krb5_tl_data));
926 memset(tl2, 0, sizeof(krb5_tl_data));
927 tl2->tl_data_next = tl;
932 for (i = 0; i < n_tl_data; i++) {
933 if ((retcode = Tcl_SplitList(interp, argv[i], &argc1, &argv1)) !=
938 sprintf(interp->result, "wrong # fields in tl_data "
939 "(%d should be 3)", argc1);
943 if ((retcode = Tcl_GetInt(interp, argv1[0], &tmp))
945 Tcl_AppendElement(interp, "while parsing tl_data_type");
949 tl->tl_data_type = tmp;
950 if ((retcode = Tcl_GetInt(interp, argv1[1], &tmp))
952 Tcl_AppendElement(interp, "while parsing tl_data_length");
956 tl->tl_data_length = tmp;
957 if (tl->tl_data_length != strlen(argv1[2])) {
958 sprintf(interp->result, "specified length %d does not "
959 "match length %lu of string \"%s\"", tmp,
960 (unsigned long) strlen(argv1[2]), argv1[2]);
964 tl->tl_data_contents = (krb5_octet *) malloc(tmp+1);
965 strcpy((char *) tl->tl_data_contents, argv1[2]);
967 Tcl_Free((char *) argv1);
969 tl = tl->tl_data_next;
972 sprintf(interp->result, "tl is not NULL!");
980 Tcl_Free((char *) argv1);
982 Tcl_Free((char *) argv);
986 static int parse_config_params(Tcl_Interp *interp, char *list,
987 kadm5_config_params *params)
989 static Tcl_HashTable *table = 0;
990 const char **argv = NULL;
991 int tmp, argc, retcode;
993 memset(params, 0, sizeof(kadm5_config_params));
997 if ((retcode = Tcl_SplitList(interp, list, &argc, &argv)) != TCL_OK) {
1002 sprintf(interp->result,
1003 "wrong # args in config params structure (%d should be 20)",
1005 retcode = TCL_ERROR;
1009 if ((retcode = parse_flags(interp, table, config_mask_flags,
1010 sizeof(config_mask_flags) /
1011 sizeof(struct flagval),
1012 argv[0], &tmp)) != TCL_OK) {
1017 if ((retcode = parse_str(interp, argv[1], ¶ms->realm)) != TCL_OK) {
1018 Tcl_AppendElement(interp, "while parsing realm name");
1019 retcode = TCL_ERROR;
1022 if ((retcode = Tcl_GetInt(interp, argv[2], &tmp))
1024 Tcl_AppendElement(interp, "while parsing kadmind_port");
1025 retcode = TCL_ERROR;
1028 params->kadmind_port = tmp;
1029 if ((retcode = parse_str(interp, argv[3], ¶ms->admin_server))
1031 Tcl_AppendElement(interp, "while parsing profile name");
1032 retcode = TCL_ERROR;
1035 if ((retcode = parse_str(interp, argv[4], ¶ms->dbname)) != TCL_OK) {
1036 Tcl_AppendElement(interp, "while parsing profile name");
1037 retcode = TCL_ERROR;
1040 if ((retcode = parse_str(interp, argv[5], ¶ms->admin_dbname)) != TCL_OK) {
1041 Tcl_AppendElement(interp, "while parsing admin_dbname name");
1042 retcode = TCL_ERROR;
1045 /* Ignore argv[6], which used to set the admin_lockfile field. */
1046 if ((retcode = parse_str(interp, argv[7], ¶ms->admin_keytab)) != TCL_OK) {
1047 Tcl_AppendElement(interp, "while parsing admin_keytab name");
1048 retcode = TCL_ERROR;
1051 if ((retcode = parse_str(interp, argv[8], ¶ms->acl_file)) != TCL_OK) {
1052 Tcl_AppendElement(interp, "while parsing acl_file name");
1053 retcode = TCL_ERROR;
1056 if ((retcode = parse_str(interp, argv[9], ¶ms->dict_file)) != TCL_OK) {
1057 Tcl_AppendElement(interp, "while parsing dict_file name");
1058 retcode = TCL_ERROR;
1061 if ((retcode = Tcl_GetInt(interp, argv[10], &tmp))
1063 Tcl_AppendElement(interp, "while parsing mkey_from_kbd");
1064 retcode = TCL_ERROR;
1067 params->mkey_from_kbd = tmp;
1068 if ((retcode = parse_str(interp, argv[11], ¶ms->stash_file)) != TCL_OK) {
1069 Tcl_AppendElement(interp, "while parsing stash_file name");
1070 retcode = TCL_ERROR;
1073 if ((retcode = parse_str(interp, argv[12], ¶ms->mkey_name)) != TCL_OK) {
1074 Tcl_AppendElement(interp, "while parsing mkey_name name");
1075 retcode = TCL_ERROR;
1078 if ((retcode = Tcl_GetInt(interp, argv[13], &tmp))
1080 Tcl_AppendElement(interp, "while parsing enctype");
1081 retcode = TCL_ERROR;
1084 params->enctype = tmp;
1085 if ((retcode = Tcl_GetInt(interp, argv[14], &tmp))
1087 Tcl_AppendElement(interp, "while parsing max_life");
1088 retcode = TCL_ERROR;
1091 params->max_life = tmp;
1092 if ((retcode = Tcl_GetInt(interp, argv[15], &tmp))
1094 Tcl_AppendElement(interp, "while parsing max_rlife");
1095 retcode = TCL_ERROR;
1098 params->max_rlife = tmp;
1099 if ((retcode = Tcl_GetInt(interp, argv[16], &tmp))
1101 Tcl_AppendElement(interp, "while parsing expiration");
1102 retcode = TCL_ERROR;
1105 params->expiration = tmp;
1106 if ((retcode = parse_krb5_flags(interp, argv[17], &tmp))
1108 Tcl_AppendElement(interp, "while parsing flags");
1109 retcode = TCL_ERROR;
1112 params->flags = tmp;
1113 if ((retcode = Tcl_GetInt(interp, argv[18], &tmp))
1115 Tcl_AppendElement(interp, "while parsing num_keysalts");
1116 retcode = TCL_ERROR;
1119 params->num_keysalts = tmp;
1120 if ((retcode = parse_keysalts(interp, argv[19], ¶ms->keysalts,
1121 params->num_keysalts)) != TCL_OK) {
1122 Tcl_AppendElement(interp, "while parsing keysalts");
1123 retcode = TCL_ERROR;
1131 static int parse_principal_ent(Tcl_Interp *interp, char *list,
1132 kadm5_principal_ent_t *out_princ)
1134 kadm5_principal_ent_t princ = 0;
1135 krb5_error_code krb5_ret;
1140 int retcode = TCL_OK;
1142 if ((tcl_ret = Tcl_SplitList(interp, list, &argc, &argv)) != TCL_OK) {
1146 if (argc != 12 && argc != 20) {
1147 sprintf(interp->result,
1148 "wrong # args in principal structure (%d should be 12 or 20)",
1150 retcode = TCL_ERROR;
1154 if (! (princ = malloc(sizeof *princ))) {
1155 fprintf(stderr, "Out of memory!\n");
1158 memset(princ, 0, sizeof(*princ));
1160 if ((krb5_ret = krb5_parse_name(context, argv[0], &princ->principal)) != 0) {
1161 stash_error(interp, krb5_ret);
1162 Tcl_AppendElement(interp, "while parsing principal");
1163 retcode = TCL_ERROR;
1168 * All of the numerical values parsed here are parsed into an
1169 * "int" and then assigned into the structure in case the actual
1170 * width of the field in the Kerberos structure is different from
1171 * the width of an integer.
1174 if ((tcl_ret = Tcl_GetInt(interp, argv[1], &tmp))
1176 Tcl_AppendElement(interp, "while parsing princ_expire_time");
1177 retcode = TCL_ERROR;
1180 princ->princ_expire_time = tmp;
1182 if ((tcl_ret = Tcl_GetInt(interp, argv[2], &tmp))
1184 Tcl_AppendElement(interp, "while parsing last_pwd_change");
1185 retcode = TCL_ERROR;
1188 princ->last_pwd_change = tmp;
1190 if ((tcl_ret = Tcl_GetInt(interp, argv[3], &tmp))
1192 Tcl_AppendElement(interp, "while parsing pw_expiration");
1193 retcode = TCL_ERROR;
1196 princ->pw_expiration = tmp;
1198 if ((tcl_ret = Tcl_GetInt(interp, argv[4], &tmp))
1200 Tcl_AppendElement(interp, "while parsing max_life");
1201 retcode = TCL_ERROR;
1204 princ->max_life = tmp;
1206 if ((krb5_ret = krb5_parse_name(context, argv[5], &princ->mod_name)) != 0) {
1207 stash_error(interp, krb5_ret);
1208 Tcl_AppendElement(interp, "while parsing mod_name");
1209 retcode = TCL_ERROR;
1213 if ((tcl_ret = Tcl_GetInt(interp, argv[6], &tmp))
1215 Tcl_AppendElement(interp, "while parsing mod_date");
1216 retcode = TCL_ERROR;
1219 princ->mod_date = tmp;
1221 if ((tcl_ret = parse_krb5_flags(interp, argv[7], &princ->attributes))
1223 Tcl_AppendElement(interp, "while parsing attributes");
1224 retcode = TCL_ERROR;
1228 if ((tcl_ret = Tcl_GetInt(interp, argv[8], &tmp))
1230 Tcl_AppendElement(interp, "while parsing kvno");
1231 retcode = TCL_ERROR;
1236 if ((tcl_ret = Tcl_GetInt(interp, argv[9], &tmp))
1238 Tcl_AppendElement(interp, "while parsing mkvno");
1239 retcode = TCL_ERROR;
1244 if ((tcl_ret = parse_str(interp, argv[10], &princ->policy)) != TCL_OK) {
1245 Tcl_AppendElement(interp, "while parsing policy");
1246 retcode = TCL_ERROR;
1249 if(princ->policy != NULL) {
1250 if(!(princ->policy = strdup(princ->policy))) {
1251 fprintf(stderr, "Out of memory!\n");
1256 if ((tcl_ret = parse_aux_attributes(interp, argv[11],
1257 &princ->aux_attributes)) != TCL_OK) {
1258 Tcl_AppendElement(interp, "while parsing aux_attributes");
1259 retcode = TCL_ERROR;
1263 if (argc == 12) goto finished;
1265 if ((tcl_ret = Tcl_GetInt(interp, argv[12], &tmp))
1267 Tcl_AppendElement(interp, "while parsing max_renewable_life");
1268 retcode = TCL_ERROR;
1271 princ->max_renewable_life = tmp;
1273 if ((tcl_ret = Tcl_GetInt(interp, argv[13], &tmp))
1275 Tcl_AppendElement(interp, "while parsing last_success");
1276 retcode = TCL_ERROR;
1279 princ->last_success = tmp;
1281 if ((tcl_ret = Tcl_GetInt(interp, argv[14], &tmp))
1283 Tcl_AppendElement(interp, "while parsing last_failed");
1284 retcode = TCL_ERROR;
1287 princ->last_failed = tmp;
1289 if ((tcl_ret = Tcl_GetInt(interp, argv[15], &tmp))
1291 Tcl_AppendElement(interp, "while parsing fail_auth_count");
1292 retcode = TCL_ERROR;
1295 princ->fail_auth_count = tmp;
1297 if ((tcl_ret = Tcl_GetInt(interp, argv[16], &tmp))
1299 Tcl_AppendElement(interp, "while parsing n_key_data");
1300 retcode = TCL_ERROR;
1303 princ->n_key_data = tmp;
1305 if ((tcl_ret = Tcl_GetInt(interp, argv[17], &tmp))
1307 Tcl_AppendElement(interp, "while parsing n_tl_data");
1308 retcode = TCL_ERROR;
1311 princ->n_tl_data = tmp;
1313 if ((tcl_ret = parse_key_data(interp, argv[18],
1315 princ->n_key_data)) != TCL_OK) {
1316 Tcl_AppendElement(interp, "while parsing key_data");
1317 retcode = TCL_ERROR;
1321 if ((tcl_ret = parse_tl_data(interp, argv[19],
1323 princ->n_tl_data)) != TCL_OK) {
1324 Tcl_AppendElement(interp, "while parsing tl_data");
1325 retcode = TCL_ERROR;
1330 Tcl_Free((char *) argv);
1336 static void free_principal_ent(kadm5_principal_ent_t *princ)
1338 krb5_free_principal(context, (*princ)->principal);
1339 krb5_free_principal(context, (*princ)->mod_name);
1344 static Tcl_DString *unparse_policy_ent(kadm5_policy_ent_t policy)
1346 Tcl_DString *str, *tmp_dstring;
1349 if (! (str = malloc(sizeof(*str)))) {
1350 fprintf(stderr, "Out of memory!\n");
1354 Tcl_DStringInit(str);
1356 tmp_dstring = unparse_str(policy->policy);
1357 Tcl_DStringAppendElement(str, tmp_dstring->string);
1358 Tcl_DStringFree(tmp_dstring);
1361 sprintf(buf, "%ld", policy->pw_min_life);
1362 Tcl_DStringAppendElement(str, buf);
1364 sprintf(buf, "%ld", policy->pw_max_life);
1365 Tcl_DStringAppendElement(str, buf);
1367 sprintf(buf, "%ld", policy->pw_min_length);
1368 Tcl_DStringAppendElement(str, buf);
1370 sprintf(buf, "%ld", policy->pw_min_classes);
1371 Tcl_DStringAppendElement(str, buf);
1373 sprintf(buf, "%ld", policy->pw_history_num);
1374 Tcl_DStringAppendElement(str, buf);
1376 sprintf(buf, "%ld", policy->policy_refcnt);
1377 Tcl_DStringAppendElement(str, buf);
1384 static int parse_policy_ent(Tcl_Interp *interp, char *list,
1385 kadm5_policy_ent_t *out_policy)
1387 kadm5_policy_ent_t policy = 0;
1392 int retcode = TCL_OK;
1394 if ((tcl_ret = Tcl_SplitList(interp, list, &argc, &argv)) != TCL_OK) {
1399 sprintf(interp->result, "wrong # args in policy structure (%d should be 7)",
1401 retcode = TCL_ERROR;
1405 if (! (policy = malloc(sizeof *policy))) {
1406 fprintf(stderr, "Out of memory!\n");
1410 if ((tcl_ret = parse_str(interp, argv[0], &policy->policy)) != TCL_OK) {
1411 Tcl_AppendElement(interp, "while parsing policy name");
1412 retcode = TCL_ERROR;
1416 if(policy->policy != NULL) {
1417 if (! (policy->policy = strdup(policy->policy))) {
1418 fprintf(stderr, "Out of memory!\n");
1424 * All of the numerical values parsed here are parsed into an
1425 * "int" and then assigned into the structure in case the actual
1426 * width of the field in the Kerberos structure is different from
1427 * the width of an integer.
1430 if ((tcl_ret = Tcl_GetInt(interp, argv[1], &tmp))
1432 Tcl_AppendElement(interp, "while parsing pw_min_life");
1433 retcode = TCL_ERROR;
1436 policy->pw_min_life = tmp;
1438 if ((tcl_ret = Tcl_GetInt(interp, argv[2], &tmp))
1440 Tcl_AppendElement(interp, "while parsing pw_max_life");
1441 retcode = TCL_ERROR;
1444 policy->pw_max_life = tmp;
1446 if ((tcl_ret = Tcl_GetInt(interp, argv[3], &tmp))
1448 Tcl_AppendElement(interp, "while parsing pw_min_length");
1449 retcode = TCL_ERROR;
1452 policy->pw_min_length = tmp;
1454 if ((tcl_ret = Tcl_GetInt(interp, argv[4], &tmp))
1456 Tcl_AppendElement(interp, "while parsing pw_min_classes");
1457 retcode = TCL_ERROR;
1460 policy->pw_min_classes = tmp;
1462 if ((tcl_ret = Tcl_GetInt(interp, argv[5], &tmp))
1464 Tcl_AppendElement(interp, "while parsing pw_history_num");
1465 retcode = TCL_ERROR;
1468 policy->pw_history_num = tmp;
1470 if ((tcl_ret = Tcl_GetInt(interp, argv[6], &tmp))
1472 Tcl_AppendElement(interp, "while parsing policy_refcnt");
1473 retcode = TCL_ERROR;
1476 policy->policy_refcnt = tmp;
1479 Tcl_Free((char *) argv);
1480 *out_policy = policy;
1485 static void free_policy_ent(kadm5_policy_ent_t *policy)
1491 static Tcl_DString *unparse_keytype(krb5_enctype enctype)
1496 if (! (str = malloc(sizeof(*str)))) {
1497 fprintf(stderr, "Out of memory!\n");
1501 Tcl_DStringInit(str);
1504 /* XXX is this right? */
1505 case ENCTYPE_NULL: Tcl_DStringAppend(str, "ENCTYPE_NULL", -1); break;
1506 case ENCTYPE_DES_CBC_CRC:
1507 Tcl_DStringAppend(str, "ENCTYPE_DES_CBC_CRC", -1); break;
1509 sprintf(buf, "UNKNOWN KEYTYPE (0x%x)", enctype);
1510 Tcl_DStringAppend(str, buf, -1);
1518 static Tcl_DString *unparse_keyblocks(krb5_keyblock *keyblocks, int num_keys)
1521 Tcl_DString *keytype;
1524 if (! (str = malloc(sizeof(*str)))) {
1525 fprintf(stderr, "Out of memory!\n");
1529 Tcl_DStringInit(str);
1531 for (j = 0; j < num_keys; j++) {
1532 krb5_keyblock *keyblock = &keyblocks[j];
1534 Tcl_DStringStartSublist(str);
1536 keytype = unparse_keytype(keyblock->enctype);
1537 Tcl_DStringAppendElement(str, keytype->string);
1538 Tcl_DStringFree(keytype);
1540 if (keyblock->length == 0) {
1541 Tcl_DStringAppendElement(str, "0x00");
1544 Tcl_DStringAppendElement(str, "0x");
1545 for (i = 0; i < keyblock->length; i++) {
1547 sprintf(buf, "%02x", (int) keyblock->contents[i]);
1548 Tcl_DStringAppend(str, buf, -1);
1552 Tcl_DStringEndSublist(str);
1559 enum init_type { INIT_NONE, INIT_PASS, INIT_CREDS };
1561 static int _tcl_kadm5_init_any(enum init_type init_type, ClientData clientData,
1562 Tcl_Interp *interp, int argc, const char *argv[])
1565 char *client_name, *pass, *service_name;
1567 krb5_ui_4 struct_version, api_version;
1568 const char *handle_var;
1569 void *server_handle;
1570 char *handle_name, *params_str;
1571 const char *whoami = argv[0];
1572 kadm5_config_params params;
1576 kadm5_init_krb5_context(&context);
1579 Tcl_AppendResult(interp, whoami, ": ", arg_error, 0);
1583 if (((tcl_ret = parse_str(interp, argv[0], &client_name)) != TCL_OK) ||
1584 ((tcl_ret = parse_str(interp, argv[1], &pass)) != TCL_OK) ||
1585 ((tcl_ret = parse_str(interp, argv[2], &service_name)) != TCL_OK) ||
1586 ((tcl_ret = parse_str(interp, argv[3], ¶ms_str)) != TCL_OK) ||
1587 ((tcl_ret = parse_config_params(interp, params_str, ¶ms))
1589 ((tcl_ret = Tcl_GetInt(interp, argv[4], (int *) &struct_version)) !=
1591 ((tcl_ret = Tcl_GetInt(interp, argv[5], (int *) &api_version)) !=
1596 handle_var = argv[6];
1598 if (! (handle_var && *handle_var)) {
1599 Tcl_SetResult(interp, "must specify server handle variable name",
1604 if (init_type == INIT_CREDS) {
1608 if ((ret = krb5_cc_default(context, &cc))) {
1609 stash_error(interp, ret);
1613 if ((ret = krb5_cc_resolve(context, pass, &cc))) {
1614 stash_error(interp, ret);
1619 ret = kadm5_init_with_creds(client_name, cc, service_name,
1620 ¶ms, struct_version,
1621 api_version, NULL, &server_handle);
1623 (void) krb5_cc_close(context, cc);
1625 ret = kadm5_init(client_name, pass, service_name, ¶ms,
1626 struct_version, api_version, NULL, &server_handle);
1628 if (ret != KADM5_OK) {
1629 stash_error(interp, ret);
1633 if ((tcl_ret = put_server_handle(interp, server_handle, &handle_name))
1638 if (! Tcl_SetVar(interp, handle_var, handle_name, TCL_LEAVE_ERR_MSG)) {
1642 set_ok(interp, "KADM5 API initialized.");
1646 static int tcl_kadm5_init(ClientData clientData, Tcl_Interp *interp,
1647 int argc, const char *argv[])
1649 return _tcl_kadm5_init_any(INIT_PASS, clientData, interp, argc, argv);
1652 static int tcl_kadm5_init_with_creds(ClientData clientData, Tcl_Interp *interp,
1653 int argc, const char *argv[])
1655 return _tcl_kadm5_init_any(INIT_CREDS, clientData, interp, argc, argv);
1658 static int tcl_kadm5_destroy(ClientData clientData, Tcl_Interp *interp,
1659 int argc, const char *argv[])
1666 ret = kadm5_destroy(server_handle);
1668 if (ret != KADM5_OK) {
1669 stash_error(interp, ret);
1673 if ((tcl_ret = remove_server_handle(interp, argv[-1])) != TCL_OK) {
1677 set_ok(interp, "KADM5 API deinitialized.");
1681 static int tcl_kadm5_create_principal(ClientData clientData,
1683 int argc, const char *argv[])
1687 int retcode = TCL_OK;
1689 kadm5_principal_ent_t princ = 0;
1698 if ((tcl_ret = parse_str(interp, argv[0], &princ_string)) != TCL_OK) {
1699 Tcl_AppendElement(interp, "while parsing principal");
1704 ((tcl_ret = parse_principal_ent(interp, princ_string, &princ))
1709 if ((tcl_ret = parse_principal_mask(interp, argv[1], &mask)) != TCL_OK) {
1714 if ((tcl_ret = parse_str(interp, argv[2], &pw)) != TCL_OK) {
1719 if ((tcl_ret = Tcl_GetBoolean(interp, argv[3], &override_qual)) !=
1727 ret = kadm5_create_principal(server_handle, princ, mask, pw,
1730 ret = kadm5_create_principal(server_handle, princ, mask, pw);
1733 if (ret != KADM5_OK) {
1734 stash_error(interp, ret);
1735 retcode = TCL_ERROR;
1739 set_ok(interp, "Principal created.");
1744 free_principal_ent(&princ);
1751 static int tcl_kadm5_delete_principal(ClientData clientData,
1753 int argc, const char *argv[])
1755 krb5_principal princ;
1756 krb5_error_code krb5_ret;
1763 if((tcl_ret = parse_str(interp, argv[0], &name)) != TCL_OK)
1766 if ((krb5_ret = krb5_parse_name(context, name, &princ))) {
1767 stash_error(interp, krb5_ret);
1768 Tcl_AppendElement(interp, "while parsing principal");
1771 } else princ = NULL;
1772 ret = kadm5_delete_principal(server_handle, princ);
1775 krb5_free_principal(context, princ);
1777 if (ret != KADM5_OK) {
1778 stash_error(interp, ret);
1782 set_ok(interp, "Principal deleted.");
1789 static int tcl_kadm5_modify_principal(ClientData clientData,
1791 int argc, const char *argv[])
1794 kadm5_principal_ent_t princ = 0;
1797 int retcode = TCL_OK;
1802 if ((tcl_ret = parse_str(interp, argv[0], &princ_string)) != TCL_OK) {
1803 Tcl_AppendElement(interp, "while parsing principal");
1808 ((tcl_ret = parse_principal_ent(interp, princ_string, &princ))
1813 if ((tcl_ret = parse_principal_mask(interp, argv[1], &mask)) != TCL_OK) {
1814 retcode = TCL_ERROR;
1818 ret = kadm5_modify_principal(server_handle, princ, mask);
1820 if (ret != KADM5_OK) {
1821 stash_error(interp, ret);
1822 retcode = TCL_ERROR;
1825 set_ok(interp, "Principal modified.");
1830 free_principal_ent(&princ);
1836 static int tcl_kadm5_rename_principal(ClientData clientData,
1838 int argc, const char *argv[])
1840 krb5_principal source, target;
1841 krb5_error_code krb5_ret;
1843 int retcode = TCL_OK;
1847 if ((krb5_ret = krb5_parse_name(context, argv[0], &source)) != 0) {
1848 stash_error(interp, krb5_ret);
1849 Tcl_AppendElement(interp, "while parsing source");
1853 if ((krb5_ret = krb5_parse_name(context, argv[1], &target)) != 0) {
1854 stash_error(interp, krb5_ret);
1855 Tcl_AppendElement(interp, "while parsing target");
1856 krb5_free_principal(context, source);
1860 ret = kadm5_rename_principal(server_handle, source, target);
1862 if (ret == KADM5_OK) {
1863 set_ok(interp, "Principal renamed.");
1866 stash_error(interp, ret);
1867 retcode = TCL_ERROR;
1870 krb5_free_principal(context, source);
1871 krb5_free_principal(context, target);
1877 static int tcl_kadm5_chpass_principal(ClientData clientData,
1879 int argc, const char *argv[])
1881 krb5_principal princ;
1886 krb5_error_code krb5_ret;
1887 int retcode = TCL_OK;
1892 if ((krb5_ret = krb5_parse_name(context, argv[0], &princ)) != 0) {
1893 stash_error(interp, krb5_ret);
1894 Tcl_AppendElement(interp, "while parsing principal name");
1898 if (parse_str(interp, argv[1], &pw) != TCL_OK) {
1899 Tcl_AppendElement(interp, "while parsing password");
1900 retcode = TCL_ERROR;
1905 if (Tcl_GetBoolean(interp, argv[2], &override_qual) != TCL_OK) {
1906 Tcl_AppendElement(interp, "while parsing override_qual");
1907 retcode = TCL_ERROR;
1911 ret = kadm5_chpass_principal(server_handle,
1912 princ, pw, override_qual);
1914 ret = kadm5_chpass_principal(server_handle, princ, pw);
1917 if (ret == KADM5_OK) {
1918 set_ok(interp, "Password changed.");
1922 stash_error(interp, ret);
1923 retcode = TCL_ERROR;
1927 krb5_free_principal(context, princ);
1933 static int tcl_kadm5_chpass_principal_util(ClientData clientData,
1935 int argc, const char *argv[])
1937 krb5_principal princ;
1942 char *pw_ret, *pw_ret_var;
1943 char msg_ret[1024], *msg_ret_var;
1944 krb5_error_code krb5_ret;
1946 int retcode = TCL_OK;
1950 if ((krb5_ret = krb5_parse_name(context, argv[0], &princ)) != 0) {
1951 stash_error(interp, krb5_ret);
1952 Tcl_AppendElement(interp, "while parsing principal name");
1956 if (parse_str(interp, argv[1], &new_pw) != TCL_OK) {
1957 Tcl_AppendElement(interp, "while parsing new password");
1958 retcode = TCL_ERROR;
1962 if (Tcl_GetBoolean(interp, argv[2], &override_qual) != TCL_OK) {
1963 Tcl_AppendElement(interp, "while parsing override_qual");
1964 retcode = TCL_ERROR;
1968 if (parse_str(interp, argv[3], &pw_ret_var) != TCL_OK) {
1969 Tcl_AppendElement(interp, "while parsing pw_ret variable name");
1970 retcode = TCL_ERROR;
1974 if (parse_str(interp, argv[4], &msg_ret_var) != TCL_OK) {
1975 Tcl_AppendElement(interp, "while parsing msg_ret variable name");
1976 retcode = TCL_ERROR;
1980 ret = kadm5_chpass_principal_util(server_handle, princ, new_pw,
1984 pw_ret_var ? &pw_ret : 0,
1985 msg_ret_var ? msg_ret : 0,
1986 msg_ret_var ? sizeof(msg_ret) : 0);
1988 if (ret == KADM5_OK) {
1990 (! Tcl_SetVar(interp, pw_ret_var, pw_ret,
1991 TCL_LEAVE_ERR_MSG))) {
1992 Tcl_AppendElement(interp, "while setting pw_ret variable");
1993 retcode = TCL_ERROR;
1997 (! Tcl_SetVar(interp, msg_ret_var, msg_ret,
1998 TCL_LEAVE_ERR_MSG))) {
1999 Tcl_AppendElement(interp,
2000 "while setting msg_ret variable");
2001 retcode = TCL_ERROR;
2004 set_ok(interp, "Password changed.");
2007 stash_error(interp, ret);
2008 retcode = TCL_ERROR;
2012 krb5_free_principal(context, princ);
2018 static int tcl_kadm5_randkey_principal(ClientData clientData,
2020 int argc, const char *argv[])
2022 krb5_principal princ;
2023 krb5_keyblock *keyblocks;
2025 char *keyblock_var, *num_var, buf[50];
2026 Tcl_DString *keyblock_dstring = 0;
2027 krb5_error_code krb5_ret;
2029 int retcode = TCL_OK;
2033 if ((krb5_ret = krb5_parse_name(context, argv[0], &princ)) != 0) {
2034 stash_error(interp, krb5_ret);
2035 Tcl_AppendElement(interp, "while parsing principal name");
2039 if (parse_str(interp, argv[1], &keyblock_var) != TCL_OK) {
2040 Tcl_AppendElement(interp, "while parsing keyblock variable name");
2041 retcode = TCL_ERROR;
2044 if (parse_str(interp, argv[2], &num_var) != TCL_OK) {
2045 Tcl_AppendElement(interp, "while parsing keyblock variable name");
2046 retcode = TCL_ERROR;
2050 ret = kadm5_randkey_principal(server_handle,
2051 princ, keyblock_var ? &keyblocks : 0,
2052 num_var ? &num_keys : 0);
2054 if (ret == KADM5_OK) {
2056 keyblock_dstring = unparse_keyblocks(keyblocks, num_keys);
2057 if (! Tcl_SetVar(interp, keyblock_var,
2058 keyblock_dstring->string,
2059 TCL_LEAVE_ERR_MSG)) {
2060 Tcl_AppendElement(interp,
2061 "while setting keyblock variable");
2062 retcode = TCL_ERROR;
2067 sprintf(buf, "%d", num_keys);
2068 if (! Tcl_SetVar(interp, num_var, buf,
2069 TCL_LEAVE_ERR_MSG)) {
2070 Tcl_AppendElement(interp,
2071 "while setting num_keys variable");
2074 set_ok(interp, "Key randomized.");
2077 stash_error(interp, ret);
2078 retcode = TCL_ERROR;
2082 krb5_free_principal(context, princ);
2083 if (keyblock_dstring) {
2084 Tcl_DStringFree(keyblock_dstring);
2085 free(keyblock_dstring);
2092 static int tcl_kadm5_get_principal(ClientData clientData, Tcl_Interp *interp,
2093 int argc, const const char *argv[])
2095 krb5_principal princ;
2096 kadm5_principal_ent_rec ent;
2097 Tcl_DString *ent_dstring = 0;
2100 krb5_error_code krb5_ret;
2102 kadm5_ret_t ret = -1;
2104 int retcode = TCL_OK;
2108 if((tcl_ret = parse_str(interp, argv[0], &name)) != TCL_OK)
2111 if ((krb5_ret = krb5_parse_name(context, name, &princ)) != 0) {
2112 stash_error(interp, krb5_ret);
2113 Tcl_AppendElement(interp, "while parsing principal name");
2116 } else princ = NULL;
2118 if ((tcl_ret = parse_str(interp, argv[1], &ent_var)) != TCL_OK) {
2119 Tcl_AppendElement(interp, "while parsing entry variable name");
2120 retcode = TCL_ERROR;
2123 if ((tcl_ret = parse_principal_mask(interp, argv[2], &mask)) != TCL_OK) {
2124 Tcl_AppendElement(interp, "while parsing principal mask");
2125 retcode = TCL_ERROR;
2129 ret = kadm5_get_principal(server_handle, princ, ent_var ? &ent : 0,
2132 if (ret == KADM5_OK) {
2134 ent_dstring = unparse_principal_ent(&ent, mask);
2135 if (! Tcl_SetVar(interp, ent_var, ent_dstring->string,
2136 TCL_LEAVE_ERR_MSG)) {
2137 Tcl_AppendElement(interp,
2138 "while setting entry variable");
2139 retcode = TCL_ERROR;
2142 set_ok(interp, "Principal retrieved.");
2146 stash_error(interp, ret);
2147 retcode = TCL_ERROR;
2152 Tcl_DStringFree(ent_dstring);
2156 krb5_free_principal(context, princ);
2157 if (ret == KADM5_OK && ent_var &&
2158 (ret = kadm5_free_principal_ent(server_handle, &ent)) &&
2159 (retcode == TCL_OK)) {
2160 stash_error(interp, ret);
2161 retcode = TCL_ERROR;
2166 static int tcl_kadm5_create_policy(ClientData clientData, Tcl_Interp *interp,
2167 int argc, const char *argv[])
2171 int retcode = TCL_OK;
2172 char *policy_string;
2173 kadm5_policy_ent_t policy = 0;
2178 if ((tcl_ret = parse_str(interp, argv[0], &policy_string)) != TCL_OK) {
2179 Tcl_AppendElement(interp, "while parsing policy");
2183 if (policy_string &&
2184 ((tcl_ret = parse_policy_ent(interp, policy_string, &policy))
2189 if ((tcl_ret = parse_policy_mask(interp, argv[1], &mask)) != TCL_OK) {
2194 ret = kadm5_create_policy(server_handle, policy, mask);
2196 if (ret != KADM5_OK) {
2197 stash_error(interp, ret);
2198 retcode = TCL_ERROR;
2202 set_ok(interp, "Policy created.");
2207 free_policy_ent(&policy);
2214 static int tcl_kadm5_delete_policy(ClientData clientData, Tcl_Interp *interp,
2215 int argc, const char *argv[])
2222 if (parse_str(interp, argv[0], &policy) != TCL_OK) {
2223 Tcl_AppendElement(interp, "while parsing policy name");
2227 ret = kadm5_delete_policy(server_handle, policy);
2229 if (ret != KADM5_OK) {
2230 stash_error(interp, ret);
2234 set_ok(interp, "Policy deleted.");
2241 static int tcl_kadm5_modify_policy(ClientData clientData, Tcl_Interp *interp,
2242 int argc, const char *argv[])
2244 char *policy_string;
2245 kadm5_policy_ent_t policy = 0;
2248 int retcode = TCL_OK;
2253 if ((tcl_ret = parse_str(interp, argv[0], &policy_string)) != TCL_OK) {
2254 Tcl_AppendElement(interp, "while parsing policy");
2258 if (policy_string &&
2259 ((tcl_ret = parse_policy_ent(interp, policy_string, &policy))
2264 if ((tcl_ret = parse_policy_mask(interp, argv[1], &mask)) != TCL_OK) {
2265 retcode = TCL_ERROR;
2269 ret = kadm5_modify_policy(server_handle, policy, mask);
2271 if (ret != KADM5_OK) {
2272 stash_error(interp, ret);
2273 retcode = TCL_ERROR;
2276 set_ok(interp, "Policy modified.");
2281 free_policy_ent(&policy);
2287 static int tcl_kadm5_get_policy(ClientData clientData, Tcl_Interp *interp,
2288 int argc, const char *argv[])
2290 kadm5_policy_ent_rec ent;
2291 Tcl_DString *ent_dstring = 0;
2295 int retcode = TCL_OK;
2299 if (parse_str(interp, argv[0], &policy) != TCL_OK) {
2300 Tcl_AppendElement(interp, "while parsing policy name");
2304 if (parse_str(interp, argv[1], &ent_var) != TCL_OK) {
2305 Tcl_AppendElement(interp, "while parsing entry variable name");
2309 ret = kadm5_get_policy(server_handle, policy, ent_var ? &ent : 0);
2311 if (ret == KADM5_OK) {
2313 ent_dstring = unparse_policy_ent(&ent);
2314 if (! Tcl_SetVar(interp, ent_var, ent_dstring->string,
2315 TCL_LEAVE_ERR_MSG)) {
2316 Tcl_AppendElement(interp,
2317 "while setting entry variable");
2318 retcode = TCL_ERROR;
2321 set_ok(interp, "Policy retrieved.");
2325 stash_error(interp, ret);
2326 retcode = TCL_ERROR;
2331 Tcl_DStringFree(ent_dstring);
2334 if (ent_var && ret == KADM5_OK &&
2335 (ret = kadm5_free_policy_ent(server_handle, &ent)) &&
2336 (retcode == TCL_OK)) {
2337 stash_error(interp, ret);
2338 retcode = TCL_ERROR;
2345 static int tcl_kadm5_free_principal_ent(ClientData clientData,
2347 int argc, const char *argv[])
2350 kadm5_principal_ent_t ent;
2355 if (parse_str(interp, argv[0], &ent_name) != TCL_OK) {
2356 Tcl_AppendElement(interp, "while parsing entry name");
2361 (ret = kadm5_free_principal_ent(server_handle, 0))) {
2362 stash_error(interp, ret);
2366 Tcl_HashEntry *entry;
2368 if (strncmp(ent_name, "principal", sizeof("principal")-1)) {
2369 Tcl_AppendResult(interp, "invalid principal handle \"",
2373 if (! struct_table) {
2374 if (! (struct_table = malloc(sizeof(*struct_table)))) {
2375 fprintf(stderr, "Out of memory!\n");
2378 Tcl_InitHashTable(struct_table, TCL_STRING_KEYS);
2381 if (! (entry = Tcl_FindHashEntry(struct_table, ent_name))) {
2382 Tcl_AppendResult(interp, "principal handle \"", ent_name,
2387 ent = (kadm5_principal_ent_t) Tcl_GetHashValue(entry);
2389 ret = kadm5_free_principal_ent(server_handle, ent);
2390 if (ret != KADM5_OK) {
2391 stash_error(interp, ret);
2394 Tcl_DeleteHashEntry(entry);
2396 set_ok(interp, "Principal freed.");
2401 static int tcl_kadm5_free_policy_ent(ClientData clientData,
2403 int argc, const char *argv[])
2406 kadm5_policy_ent_t ent;
2411 if (parse_str(interp, argv[0], &ent_name) != TCL_OK) {
2412 Tcl_AppendElement(interp, "while parsing entry name");
2417 (ret = kadm5_free_policy_ent(server_handle, 0))) {
2418 stash_error(interp, ret);
2422 Tcl_HashEntry *entry;
2424 if (strncmp(ent_name, "policy", sizeof("policy")-1)) {
2425 Tcl_AppendResult(interp, "invalid principal handle \"",
2429 if (! struct_table) {
2430 if (! (struct_table = malloc(sizeof(*struct_table)))) {
2431 fprintf(stderr, "Out of memory!\n");
2434 Tcl_InitHashTable(struct_table, TCL_STRING_KEYS);
2437 if (! (entry = Tcl_FindHashEntry(struct_table, ent_name))) {
2438 Tcl_AppendResult(interp, "policy handle \"", ent_name,
2443 ent = (kadm5_policy_ent_t) Tcl_GetHashValue(entry);
2445 if ((ret = kadm5_free_policy_ent(server_handle, ent)) != KADM5_OK) {
2446 stash_error(interp, ret);
2449 Tcl_DeleteHashEntry(entry);
2451 set_ok(interp, "Policy freed.");
2456 static int tcl_kadm5_get_privs(ClientData clientData, Tcl_Interp *interp,
2457 int argc, const char *argv[])
2459 const char *set_ret;
2466 if (parse_str(interp, argv[0], &priv_var) != TCL_OK) {
2467 Tcl_AppendElement(interp, "while parsing privs variable name");
2471 ret = kadm5_get_privs(server_handle, priv_var ? &privs : 0);
2473 if (ret == KADM5_OK) {
2475 Tcl_DString *str = unparse_privs(privs);
2476 set_ret = Tcl_SetVar(interp, priv_var, str->string,
2478 Tcl_DStringFree(str);
2481 Tcl_AppendElement(interp, "while setting priv variable");
2485 set_ok(interp, "Privileges retrieved.");
2489 stash_error(interp, ret);
2495 void Tcl_kadm5_init(Tcl_Interp *interp)
2499 Tcl_SetVar(interp, "KADM5_ADMIN_SERVICE",
2500 KADM5_ADMIN_SERVICE, TCL_GLOBAL_ONLY);
2501 Tcl_SetVar(interp, "KADM5_CHANGEPW_SERVICE",
2502 KADM5_CHANGEPW_SERVICE, TCL_GLOBAL_ONLY);
2503 (void) sprintf(buf, "%d", KADM5_STRUCT_VERSION);
2504 Tcl_SetVar(interp, "KADM5_STRUCT_VERSION", buf, TCL_GLOBAL_ONLY);
2505 (void) sprintf(buf, "%d", KADM5_API_VERSION_1);
2506 Tcl_SetVar(interp, "KADM5_API_VERSION_1", buf, TCL_GLOBAL_ONLY);
2507 (void) sprintf(buf, "%d", KADM5_API_VERSION_2);
2508 Tcl_SetVar(interp, "KADM5_API_VERSION_2", buf, TCL_GLOBAL_ONLY);
2509 (void) sprintf(buf, "%d", KADM5_API_VERSION_MASK);
2510 Tcl_SetVar(interp, "KADM5_API_VERSION_MASK", buf, TCL_GLOBAL_ONLY);
2511 (void) sprintf(buf, "%d", KADM5_STRUCT_VERSION_MASK);
2512 Tcl_SetVar(interp, "KADM5_STRUCT_VERSION_MASK", buf,
2515 Tcl_CreateCommand(interp, "kadm5_init", tcl_kadm5_init, 0, 0);
2516 Tcl_CreateCommand(interp, "kadm5_init_with_creds",
2517 tcl_kadm5_init_with_creds, 0, 0);
2518 Tcl_CreateCommand(interp, "kadm5_destroy", tcl_kadm5_destroy, 0,
2520 Tcl_CreateCommand(interp, "kadm5_create_principal",
2521 tcl_kadm5_create_principal, 0, 0);
2522 Tcl_CreateCommand(interp, "kadm5_delete_principal",
2523 tcl_kadm5_delete_principal, 0, 0);
2524 Tcl_CreateCommand(interp, "kadm5_modify_principal",
2525 tcl_kadm5_modify_principal, 0, 0);
2526 Tcl_CreateCommand(interp, "kadm5_rename_principal",
2527 tcl_kadm5_rename_principal, 0, 0);
2528 Tcl_CreateCommand(interp, "kadm5_chpass_principal",
2529 tcl_kadm5_chpass_principal, 0, 0);
2530 Tcl_CreateCommand(interp, "kadm5_chpass_principal_util",
2531 tcl_kadm5_chpass_principal_util, 0, 0);
2532 Tcl_CreateCommand(interp, "kadm5_randkey_principal",
2533 tcl_kadm5_randkey_principal, 0, 0);
2534 Tcl_CreateCommand(interp, "kadm5_get_principal",
2535 tcl_kadm5_get_principal, 0, 0);
2536 Tcl_CreateCommand(interp, "kadm5_create_policy",
2537 tcl_kadm5_create_policy, 0, 0);
2538 Tcl_CreateCommand(interp, "kadm5_delete_policy",
2539 tcl_kadm5_delete_policy, 0, 0);
2540 Tcl_CreateCommand(interp, "kadm5_modify_policy",
2541 tcl_kadm5_modify_policy, 0, 0);
2542 Tcl_CreateCommand(interp, "kadm5_get_policy",
2543 tcl_kadm5_get_policy, 0, 0);
2544 Tcl_CreateCommand(interp, "kadm5_free_principal_ent",
2545 tcl_kadm5_free_principal_ent, 0, 0);
2546 Tcl_CreateCommand(interp, "kadm5_free_policy_ent",
2547 tcl_kadm5_free_policy_ent, 0, 0);
2548 Tcl_CreateCommand(interp, "kadm5_get_privs",
2549 tcl_kadm5_get_privs, 0, 0);