Exemplo n.º 1
0
static krb5_error_code
fkt_add_entry(krb5_context context,
              krb5_keytab id,
              krb5_keytab_entry *entry)
{
    int ret;
    int fd;
    krb5_storage *sp;
    struct fkt_data *d = id->data;
    krb5_data keytab;
    int32_t len;

    fd = open (d->filename, O_RDWR | O_BINARY);
    if (fd < 0) {
        fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
        if (fd < 0) {
            ret = errno;
            krb5_set_error_string(context, "open(%s): %s", d->filename,
                                  strerror(ret));
            return ret;
        }
        ret = _krb5_xlock(context, fd, 1, d->filename);
        if (ret) {
            close(fd);
            return ret;
        }
        sp = krb5_storage_from_fd(fd);
        krb5_storage_set_eof_code(sp, KRB5_KT_END);
        ret = fkt_setup_keytab(context, id, sp);
        if(ret) {
            goto out;
        }
        storage_set_flags(context, sp, id->version);
    } else {
        int8_t pvno, tag;
        ret = _krb5_xlock(context, fd, 1, d->filename);
        if (ret) {
            close(fd);
            return ret;
        }
        sp = krb5_storage_from_fd(fd);
        krb5_storage_set_eof_code(sp, KRB5_KT_END);
        ret = krb5_ret_int8(sp, &pvno);
        if(ret) {
            /* we probably have a zero byte file, so try to set it up
                   properly */
            ret = fkt_setup_keytab(context, id, sp);
            if(ret) {
                krb5_set_error_string(context, "%s: keytab is corrupted: %s",
                                      d->filename, strerror(ret));
                goto out;
            }
            storage_set_flags(context, sp, id->version);
        } else {
            if(pvno != 5) {
                ret = KRB5_KEYTAB_BADVNO;
                krb5_set_error_string(context, "%s: %s",
                                      d->filename, strerror(ret));
                goto out;
            }
            ret = krb5_ret_int8 (sp, &tag);
            if (ret) {
                krb5_set_error_string(context, "%s: reading tag: %s",
                                      d->filename, strerror(ret));
                goto out;
            }
            id->version = tag;
            storage_set_flags(context, sp, id->version);
        }
    }

    {
        krb5_storage *emem;
        emem = krb5_storage_emem();
        if(emem == NULL) {
            ret = ENOMEM;
            krb5_set_error_string (context, "malloc: out of memory");
            goto out;
        }
        ret = krb5_kt_store_principal(context, emem, entry->principal);
        if(ret) {
            krb5_storage_free(emem);
            goto out;
        }
        ret = krb5_store_int32 (emem, entry->timestamp);
        if(ret) {
            krb5_storage_free(emem);
            goto out;
        }
        ret = krb5_store_int8 (emem, entry->vno % 256);
        if(ret) {
            krb5_storage_free(emem);
            goto out;
        }
        ret = krb5_kt_store_keyblock (context, emem, &entry->keyblock);
        if(ret) {
            krb5_storage_free(emem);
            goto out;
        }
        if ((d->flags & KRB5_KT_FL_JAVA) == 0) {
            ret = krb5_store_int32 (emem, entry->vno);
            if (ret) {
                krb5_storage_free(emem);
                goto out;
            }
        }

        ret = krb5_storage_to_data(emem, &keytab);
        krb5_storage_free(emem);
        if(ret)
            goto out;
    }

    while(1) {
        ret = krb5_ret_int32(sp, &len);
        if(ret == KRB5_KT_END) {
            len = keytab.length;
            break;
        }
        if(len < 0) {
            len = -len;
            if(len >= keytab.length) {
                krb5_storage_seek(sp, -4, SEEK_CUR);
                break;
            }
        }
        krb5_storage_seek(sp, len, SEEK_CUR);
    }
    ret = krb5_store_int32(sp, len);
    if(krb5_storage_write(sp, keytab.data, keytab.length) < 0)
        ret = errno;
    memset(keytab.data, 0, keytab.length);
    krb5_data_free(&keytab);
out:
    krb5_storage_free(sp);
    _krb5_xunlock(context, fd);
    close(fd);
    return ret;
}
Exemplo n.º 2
0
static void
print_entry(kadm5_server_context *server_context,
	    uint32_t ver,
	    time_t timestamp,
	    enum kadm_ops op,
	    uint32_t len,
	    krb5_storage *sp,
	    void *ctx)
{
    char t[256];
    int32_t mask;
    hdb_entry ent;
    krb5_principal source;
    char *name1, *name2;
    krb5_data data;
    krb5_context scontext = server_context->context;

    off_t end = krb5_storage_seek(sp, 0, SEEK_CUR) + len;

    krb5_error_code ret;

    strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));

    if((int)op < (int)kadm_get || (int)op > (int)kadm_nop) {
	printf("unknown op: %d\n", op);
	krb5_storage_seek(sp, end, SEEK_SET);
	return;
    }

    printf ("%s: ver = %u, timestamp = %s, len = %u\n",
	    op_names[op], ver, t, len);
    switch(op) {
    case kadm_delete:
	krb5_ret_principal(sp, &source);
	krb5_unparse_name(scontext, source, &name1);
	printf("    %s\n", name1);
	free(name1);
	krb5_free_principal(scontext, source);
	break;
    case kadm_rename:
	ret = krb5_data_alloc(&data, len);
	if (ret)
	    krb5_err (scontext, 1, ret, "kadm_rename: data alloc: %d", len);
	krb5_ret_principal(sp, &source);
	krb5_storage_read(sp, data.data, data.length);
	hdb_value2entry(scontext, &data, &ent);
	krb5_unparse_name(scontext, source, &name1);
	krb5_unparse_name(scontext, ent.principal, &name2);
	printf("    %s -> %s\n", name1, name2);
	free(name1);
	free(name2);
	krb5_free_principal(scontext, source);
	free_hdb_entry(&ent);
	break;
    case kadm_create:
	ret = krb5_data_alloc(&data, len);
	if (ret)
	    krb5_err (scontext, 1, ret, "kadm_create: data alloc: %d", len);
	krb5_storage_read(sp, data.data, data.length);
	ret = hdb_value2entry(scontext, &data, &ent);
	if(ret)
	    abort();
	mask = ~0;
	goto foo;
    case kadm_modify:
	ret = krb5_data_alloc(&data, len);
	if (ret)
	    krb5_err (scontext, 1, ret, "kadm_modify: data alloc: %d", len);
	krb5_ret_int32(sp, &mask);
	krb5_storage_read(sp, data.data, data.length);
	ret = hdb_value2entry(scontext, &data, &ent);
	if(ret)
	    abort();
    foo:
	if(ent.principal /* mask & KADM5_PRINCIPAL */) {
	    krb5_unparse_name(scontext, ent.principal, &name1);
	    printf("    principal = %s\n", name1);
	    free(name1);
	}
	if(mask & KADM5_PRINC_EXPIRE_TIME) {
	    if(ent.valid_end == NULL) {
		strlcpy(t, "never", sizeof(t));
	    } else {
		strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
			 localtime(ent.valid_end));
	    }
	    printf("    expires = %s\n", t);
	}
	if(mask & KADM5_PW_EXPIRATION) {
	    if(ent.pw_end == NULL) {
		strlcpy(t, "never", sizeof(t));
	    } else {
		strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
			 localtime(ent.pw_end));
	    }
	    printf("    password exp = %s\n", t);
	}
	if(mask & KADM5_LAST_PWD_CHANGE) {
	}
	if(mask & KADM5_ATTRIBUTES) {
	    unparse_flags(HDBFlags2int(ent.flags),
			  asn1_HDBFlags_units(), t, sizeof(t));
	    printf("    attributes = %s\n", t);
	}
	if(mask & KADM5_MAX_LIFE) {
	    if(ent.max_life == NULL)
		strlcpy(t, "for ever", sizeof(t));
	    else
		unparse_time(*ent.max_life, t, sizeof(t));
	    printf("    max life = %s\n", t);
	}
	if(mask & KADM5_MAX_RLIFE) {
	    if(ent.max_renew == NULL)
		strlcpy(t, "for ever", sizeof(t));
	    else
		unparse_time(*ent.max_renew, t, sizeof(t));
	    printf("    max rlife = %s\n", t);
	}
	if(mask & KADM5_MOD_TIME) {
	    printf("    mod time\n");
	}
	if(mask & KADM5_MOD_NAME) {
	    printf("    mod name\n");
	}
	if(mask & KADM5_KVNO) {
	    printf("    kvno = %d\n", ent.kvno);
	}
	if(mask & KADM5_MKVNO) {
	    printf("    mkvno\n");
	}
	if(mask & KADM5_AUX_ATTRIBUTES) {
	    printf("    aux attributes\n");
	}
	if(mask & KADM5_POLICY) {
	    printf("    policy\n");
	}
	if(mask & KADM5_POLICY_CLR) {
	    printf("    mod time\n");
	}
	if(mask & KADM5_LAST_SUCCESS) {
	    printf("    last success\n");
	}
	if(mask & KADM5_LAST_FAILED) {
	    printf("    last failed\n");
	}
	if(mask & KADM5_FAIL_AUTH_COUNT) {
	    printf("    fail auth count\n");
	}
	if(mask & KADM5_KEY_DATA) {
	    printf("    key data\n");
	}
	if(mask & KADM5_TL_DATA) {
	    printf("    tl data\n");
	}
	free_hdb_entry(&ent);
	break;
    case kadm_nop :
	break;
    default:
	abort();
    }
    krb5_storage_seek(sp, end, SEEK_SET);
}