kadm5_ret_t kadm5_c_get_principals(void *server_handle, const char *expression, char ***princs, int *count) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1024]; int32_t tmp; krb5_data reply; ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) return ENOMEM; krb5_store_int32(sp, kadm_get_princs); krb5_store_int32(sp, expression != NULL); if(expression) krb5_store_string(sp, expression); ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if (ret) return ret; ret = _kadm5_client_recv(context, &reply); if(ret) return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); ret = tmp; if(ret == 0) { int i; krb5_ret_int32(sp, &tmp); *princs = calloc(tmp + 1, sizeof(**princs)); if (*princs == NULL) { ret = ENOMEM; goto out; } for(i = 0; i < tmp; i++) krb5_ret_string(sp, &(*princs)[i]); *count = tmp; } out: krb5_storage_free(sp); krb5_data_free (&reply); return ret; }
kadm5_ret_t kadm5_c_chpass_principal(void *server_handle, krb5_principal princ, int keepold, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, const char *password) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1024]; int32_t tmp; krb5_data reply; /* * We should get around to implementing this... At the moment, the * the server side API is implemented but the wire protocol has not * been updated. */ if (n_ks_tuple > 0) return KADM5_KS_TUPLE_NOSUPP; ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) { krb5_clear_error_message(context->context); return ENOMEM; } krb5_store_int32(sp, kadm_chpass); krb5_store_principal(sp, princ); krb5_store_string(sp, password); krb5_store_int32(sp, keepold); /* extension */ ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if (ret) return ret; ret = _kadm5_client_recv(context, &reply); if(ret) return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { krb5_clear_error_message(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); krb5_clear_error_message(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; }
kadm5_ret_t kadm5_c_get_privs(void *server_handle, uint32_t *privs) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1024]; int32_t tmp; krb5_data reply; *privs = 0; ret = _kadm5_connect(server_handle); if (ret) return ret; krb5_data_zero(&reply); sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) { ret = krb5_enomem(context->context); goto out_keep_error; } ret = krb5_store_int32(sp, kadm_get_privs); if (ret) goto out; ret = _kadm5_client_send(context, sp); if (ret) goto out_keep_error; ret = _kadm5_client_recv(context, &reply); if (ret) goto out_keep_error; krb5_storage_free(sp); sp = krb5_storage_from_data(&reply); if (sp == NULL) { ret = krb5_enomem(context->context); goto out_keep_error; } ret = krb5_ret_int32(sp, &tmp); if (ret == 0) ret = tmp; if (ret == 0) krb5_ret_uint32(sp, privs); out: krb5_clear_error_message(context->context); out_keep_error: krb5_storage_free(sp); krb5_data_free (&reply); return ret; }
kadm5_ret_t kadm5_c_chpass_principal_with_key(void *server_handle, krb5_principal princ, int keepold, int n_key_data, krb5_key_data *key_data) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1024]; int32_t tmp; krb5_data reply; int i; ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) { krb5_clear_error_message(context->context); return ENOMEM; } krb5_store_int32(sp, kadm_chpass_with_key); krb5_store_principal(sp, princ); krb5_store_int32(sp, n_key_data); for (i = 0; i < n_key_data; ++i) kadm5_store_key_data (sp, &key_data[i]); krb5_store_int32(sp, keepold); /* extension */ ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if (ret) return ret; ret = _kadm5_client_recv(context, &reply); if(ret) return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { krb5_clear_error_message(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); krb5_clear_error_message(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; }
kadm5_ret_t kadm5_c_get_principal(void *server_handle, krb5_principal princ, kadm5_principal_ent_t out, uint32_t mask) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1024]; int32_t tmp; krb5_data reply; ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) { krb5_clear_error_message(context->context); return ENOMEM; } krb5_store_int32(sp, kadm_get); krb5_store_principal(sp, princ); krb5_store_int32(sp, mask); ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if(ret) return ret; ret = _kadm5_client_recv(context, &reply); if (ret) return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { krb5_clear_error_message(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); ret = tmp; krb5_clear_error_message(context->context); if(ret == 0) kadm5_ret_principal_ent(sp, out); krb5_storage_free(sp); krb5_data_free (&reply); return ret; }
kadm5_ret_t kadm5_c_chpass_principal(void *server_handle, krb5_principal princ, const char *password) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1024]; int32_t tmp; krb5_data reply; ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) { krb5_clear_error_message(context->context); return ENOMEM; } krb5_store_int32(sp, kadm_chpass); krb5_store_principal(sp, princ); krb5_store_string(sp, password); ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if (ret) return ret; ret = _kadm5_client_recv(context, &reply); if(ret) return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { krb5_clear_error_message(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); krb5_clear_error_message(context->context); krb5_storage_free(sp); krb5_data_free (&reply); return tmp; }
kadm5_ret_t kadm5_c_rename_principal(void *server_handle, krb5_principal source, krb5_principal target) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1024]; int32_t tmp; krb5_data reply; ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) return ENOMEM; krb5_store_int32(sp, kadm_rename); krb5_store_principal(sp, source); krb5_store_principal(sp, target); ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if (ret) return ret; ret = _kadm5_client_recv(context, &reply); if(ret) return ret; sp = krb5_storage_from_data (&reply); if (sp == NULL) { krb5_data_free (&reply); return ENOMEM; } krb5_ret_int32(sp, &tmp); ret = tmp; krb5_storage_free(sp); krb5_data_free (&reply); return ret; }
kadm5_ret_t kadm5_c_randkey_principal(void *server_handle, krb5_principal princ, krb5_boolean keepold, int n_ks_tuple, krb5_key_salt_tuple *ks_tuple, krb5_keyblock **new_keys, int *n_keys) { kadm5_client_context *context = server_handle; kadm5_ret_t ret; krb5_storage *sp; unsigned char buf[1536]; int32_t tmp; size_t i; krb5_data reply; ret = _kadm5_connect(server_handle); if(ret) return ret; sp = krb5_storage_from_mem(buf, sizeof(buf)); if (sp == NULL) { krb5_clear_error_message(context->context); return ENOMEM; } /* * NOTE WELL: This message is extensible. It currently consists of: * * - opcode (kadm_randkey) * - principal name (princ) * * followed by optional items, each of which must be present if * there are any items following them that are also present: * * - keepold boolean (whether to delete old kvnos) * - number of key/salt type tuples * - array of {enctype, salttype} * * Eventually we may add: * * - opaque string2key parameters (salt, rounds, ...) */ krb5_store_int32(sp, kadm_randkey); krb5_store_principal(sp, princ); if (keepold == TRUE || n_ks_tuple > 0) krb5_store_uint32(sp, keepold); if (n_ks_tuple > 0) krb5_store_uint32(sp, n_ks_tuple); for (i = 0; i < n_ks_tuple; i++) { krb5_store_int32(sp, ks_tuple[i].ks_enctype); krb5_store_int32(sp, ks_tuple[i].ks_salttype); } /* Future extensions go here */ ret = _kadm5_client_send(context, sp); krb5_storage_free(sp); if (ret) return ret; ret = _kadm5_client_recv(context, &reply); if(ret) return ret; sp = krb5_storage_from_data(&reply); if (sp == NULL) { krb5_clear_error_message(context->context); krb5_data_free (&reply); return ENOMEM; } krb5_clear_error_message(context->context); krb5_ret_int32(sp, &tmp); ret = tmp; if(ret == 0){ krb5_keyblock *k; krb5_ret_int32(sp, &tmp); if (tmp < 0) { ret = EOVERFLOW; goto out; } k = malloc(tmp * sizeof(*k)); if (k == NULL) { ret = ENOMEM; goto out; } for(i = 0; i < tmp; i++) krb5_ret_keyblock(sp, &k[i]); if (n_keys && new_keys) { *n_keys = tmp; *new_keys = k; } } out: krb5_storage_free(sp); krb5_data_free (&reply); return ret; }