Esempio n. 1
0
static int
prop_one (krb5_context context, HDB *db, hdb_entry *entry, void *v)
{
    krb5_error_code ret;
    krb5_storage *sp;
    krb5_data data;
    struct slave *slave = (struct slave *)v;

    ret = hdb_entry2value (context, entry, &data);
    if (ret)
	return ret;
    ret = krb5_data_realloc (&data, data.length + 4);
    if (ret) {
	krb5_data_free (&data);
	return ret;
    }
    memmove ((char *)data.data + 4, data.data, data.length - 4);
    sp = krb5_storage_from_data(&data);
    if (sp == NULL) {
	krb5_data_free (&data);
	return ENOMEM;
    }
    krb5_store_int32(sp, ONE_PRINC);
    krb5_storage_free(sp);

    ret = krb5_write_priv_message (context, slave->ac, &slave->fd, &data);
    krb5_data_free (&data);
    return ret;
}
Esempio n. 2
0
static int
dump_one (krb5_context context, HDB *db, hdb_entry_ex *entry, void *v)
{
    krb5_error_code ret;
    krb5_storage *dump = (krb5_storage *)v;
    krb5_storage *sp;
    krb5_data data;

    ret = hdb_entry2value (context, &entry->entry, &data);
    if (ret)
	return ret;
    ret = krb5_data_realloc (&data, data.length + 4);
    if (ret)
	goto done;
    memmove ((char *)data.data + 4, data.data, data.length - 4);
    sp = krb5_storage_from_data(&data);
    if (sp == NULL) {
	ret = ENOMEM;
	goto done;
    }
    ret = krb5_store_uint32(sp, ONE_PRINC);
    krb5_storage_free(sp);

    if (ret == 0)
        ret = krb5_store_data(dump, data);

done:
    krb5_data_free (&data);
    return ret;
}
Esempio n. 3
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_pac_add_buffer(krb5_context context, krb5_pac p,
		    uint32_t type, const krb5_data *data)
{
    krb5_error_code ret;
    void *ptr;
    size_t len, offset, header_end, old_end;
    uint32_t i;

    len = p->pac->numbuffers;

    ptr = realloc(p->pac,
		  sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * len));
    if (ptr == NULL)
	return krb5_enomem(context);

    p->pac = ptr;

    for (i = 0; i < len; i++)
	p->pac->buffers[i].offset_lo += PAC_INFO_BUFFER_SIZE;

    offset = p->data.length + PAC_INFO_BUFFER_SIZE;

    p->pac->buffers[len].type = type;
    p->pac->buffers[len].buffersize = data->length;
    p->pac->buffers[len].offset_lo = offset;
    p->pac->buffers[len].offset_hi = 0;

    old_end = p->data.length;
    len = p->data.length + data->length + PAC_INFO_BUFFER_SIZE;
    if (len < p->data.length) {
	krb5_set_error_message(context, EINVAL, "integer overrun");
	return EINVAL;
    }

    /* align to PAC_ALIGNMENT */
    len = ((len + PAC_ALIGNMENT - 1) / PAC_ALIGNMENT) * PAC_ALIGNMENT;

    ret = krb5_data_realloc(&p->data, len);
    if (ret) {
	krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
	return ret;
    }

    /*
     * make place for new PAC INFO BUFFER header
     */
    header_end = PACTYPE_SIZE + (PAC_INFO_BUFFER_SIZE * p->pac->numbuffers);
    memmove((unsigned char *)p->data.data + header_end + PAC_INFO_BUFFER_SIZE,
	    (unsigned char *)p->data.data + header_end ,
	    old_end - header_end);
    memset((unsigned char *)p->data.data + header_end, 0, PAC_INFO_BUFFER_SIZE);

    /*
     * copy in new data part
     */

    memcpy((unsigned char *)p->data.data + offset,
	   data->data, data->length);
    memset((unsigned char *)p->data.data + offset + data->length,
	   0, p->data.length - offset - data->length);

    p->pac->numbuffers += 1;

    return 0;
}
Esempio n. 4
0
static void
change (krb5_auth_context auth_context,
        krb5_principal admin_principal,
        uint16_t version,
        int s,
        struct sockaddr *sa,
        int sa_size,
        krb5_data *in_data)
{
    krb5_error_code ret;
    char *client = NULL, *admin = NULL;
    const char *pwd_reason;
    kadm5_config_params conf;
    void *kadm5_handle = NULL;
    krb5_principal principal = NULL;
    krb5_data *pwd_data = NULL;
    char *tmp;
    ChangePasswdDataMS chpw;

    memset (&conf, 0, sizeof(conf));
    memset(&chpw, 0, sizeof(chpw));

    if (version == KRB5_KPASSWD_VERS_CHANGEPW) {
        ret = krb5_copy_data(context, in_data, &pwd_data);
        if (ret) {
            krb5_warn (context, ret, "krb5_copy_data");
            reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED,
                        "out out memory copying password");
            return;
        }
        principal = admin_principal;
    } else if (version == KRB5_KPASSWD_VERS_SETPW) {
        size_t len;

        ret = decode_ChangePasswdDataMS(in_data->data, in_data->length,
                                        &chpw, &len);
        if (ret) {
            krb5_warn (context, ret, "decode_ChangePasswdDataMS");
            reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED,
                        "malformed ChangePasswdData");
            return;
        }


        ret = krb5_copy_data(context, &chpw.newpasswd, &pwd_data);
        if (ret) {
            krb5_warn (context, ret, "krb5_copy_data");
            reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_MALFORMED,
                        "out out memory copying password");
            goto out;
        }

        if (chpw.targname == NULL && chpw.targrealm != NULL) {
            krb5_warn (context, ret, "kadm5_init_with_password_ctx");
            reply_priv (auth_context, s, sa, sa_size,
                        KRB5_KPASSWD_MALFORMED,
                        "targrealm but not targname");
            goto out;
        }

        if (chpw.targname) {
            krb5_principal_data princ;

            princ.name = *chpw.targname;
            princ.realm = *chpw.targrealm;
            if (princ.realm == NULL) {
                ret = krb5_get_default_realm(context, &princ.realm);

                if (ret) {
                    krb5_warnx (context,
                                "kadm5_init_with_password_ctx: "
                                "failed to allocate realm");
                    reply_priv (auth_context, s, sa, sa_size,
                                KRB5_KPASSWD_SOFTERROR,
                                "failed to allocate realm");
                    goto out;
                }
            }
            ret = krb5_copy_principal(context, &princ, &principal);
            if (*chpw.targrealm == NULL)
                free(princ.realm);
            if (ret) {
                krb5_warn(context, ret, "krb5_copy_principal");
                reply_priv(auth_context, s, sa, sa_size,
                           KRB5_KPASSWD_HARDERROR,
                           "failed to allocate principal");
                goto out;
            }
        } else
            principal = admin_principal;
    } else {
        krb5_warnx (context, "kadm5_init_with_password_ctx: unknown proto");
        reply_priv (auth_context, s, sa, sa_size,
                    KRB5_KPASSWD_HARDERROR,
                    "Unknown protocol used");
        return;
    }

    ret = krb5_unparse_name (context, admin_principal, &admin);
    if (ret) {
        krb5_warn (context, ret, "unparse_name failed");
        reply_priv (auth_context, s, sa, sa_size,
                    KRB5_KPASSWD_HARDERROR, "out of memory error");
        goto out;
    }

    conf.realm = principal->realm;
    conf.mask |= KADM5_CONFIG_REALM;

    ret = kadm5_init_with_password_ctx(context,
                                       admin,
                                       NULL,
                                       KADM5_ADMIN_SERVICE,
                                       &conf, 0, 0,
                                       &kadm5_handle);
    if (ret) {
        krb5_warn (context, ret, "kadm5_init_with_password_ctx");
        reply_priv (auth_context, s, sa, sa_size, 2,
                    "Internal error");
        goto out;
    }

    ret = krb5_unparse_name(context, principal, &client);
    if (ret) {
        krb5_warn (context, ret, "unparse_name failed");
        reply_priv (auth_context, s, sa, sa_size,
                    KRB5_KPASSWD_HARDERROR, "out of memory error");
        goto out;
    }

    /*
     * Check password quality if not changing as administrator
     */

    if (krb5_principal_compare(context, admin_principal, principal) == TRUE) {

        pwd_reason = kadm5_check_password_quality (context, principal,
                     pwd_data);
        if (pwd_reason != NULL ) {
            krb5_warnx (context,
                        "%s didn't pass password quality check with error: %s",
                        client, pwd_reason);
            reply_priv (auth_context, s, sa, sa_size,
                        KRB5_KPASSWD_SOFTERROR, pwd_reason);
            goto out;
        }
        krb5_warnx (context, "Changing password for %s", client);
    } else {
        ret = _kadm5_acl_check_permission(kadm5_handle, KADM5_PRIV_CPW,
                                          principal);
        if (ret) {
            krb5_warn (context, ret,
                       "Check ACL failed for %s for changing %s password",
                       admin, client);
            reply_priv (auth_context, s, sa, sa_size,
                        KRB5_KPASSWD_HARDERROR, "permission denied");
            goto out;
        }
        krb5_warnx (context, "%s is changing password for %s", admin, client);
    }

    ret = krb5_data_realloc(pwd_data, pwd_data->length + 1);
    if (ret) {
        krb5_warn (context, ret, "malloc: out of memory");
        reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_HARDERROR,
                    "Internal error");
        goto out;
    }
    tmp = pwd_data->data;
    tmp[pwd_data->length - 1] = '\0';

    ret = kadm5_s_chpass_principal_cond (kadm5_handle, principal, tmp);
    krb5_free_data (context, pwd_data);
    pwd_data = NULL;
    if (ret) {
        const char *str = krb5_get_error_message(context, ret);
        krb5_warnx(context, "kadm5_s_chpass_principal_cond: %s", str);
        reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SOFTERROR,
                    str ? str : "Internal error");
        krb5_free_error_message(context, str);
        goto out;
    }
    reply_priv (auth_context, s, sa, sa_size, KRB5_KPASSWD_SUCCESS,
                "Password changed");
out:
    free_ChangePasswdDataMS(&chpw);
    if (principal != admin_principal)
        krb5_free_principal(context, principal);
    if (admin)
        free(admin);
    if (client)
        free(client);
    if (pwd_data)
        krb5_free_data(context, pwd_data);
    if (kadm5_handle)
        kadm5_destroy (kadm5_handle);
}