The branch, master has been updated via 5ab88dd s4-kdc: Remove unused etypes from sdb structure via b9f9936 s4-sdb: Generate etypes list out of keys list via 47f1058 s4-kdc: Sort encrytion keys in descending order of strength via fcbed30 s4-registry: properly initialize registry key to be added via RPC via f1bd44ac5 s4-registry: implement set value and delete value for RPC from dc17549 s3-modules: fix build warning in vfs shadow copy2 module
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 5ab88ddbb97b56875cc16284a5ce12ec35fc5880 Author: Andreas Schneider <a...@samba.org> Date: Sun Sep 25 20:37:29 2016 +0200 s4-kdc: Remove unused etypes from sdb structure Signed-off-by: Andreas Schneider <a...@samba.org> eviewed-by: Guenther Deschner <g...@samba.org> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Mon Sep 26 06:08:09 CEST 2016 on sn-devel-144 commit b9f993655170cd53e50dd0d454382ca45d69ef85 Author: Andreas Schneider <a...@samba.org> Date: Sun Sep 25 20:32:49 2016 +0200 s4-sdb: Generate etypes list out of keys list This etypes list is Heimdal specific. It doesn't make sense to allocate and fill it in db-glue. Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Guenther Deschner <g...@samba.org> commit 47f10584d7b5c51e0391ccf2d8ae4470c8416d8d Author: Andreas Schneider <a...@samba.org> Date: Thu Sep 8 10:50:58 2016 +0200 s4-kdc: Sort encrytion keys in descending order of strength Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Guenther Deschner <g...@samba.org> commit fcbed30a52746a45ea5dc93383d3c1d48d28fbcf Author: Chris Davis <cd.rat...@gmail.com> Date: Fri Jun 27 17:25:24 2014 -0700 s4-registry: properly initialize registry key to be added via RPC Signed-off-by: Chris Davis <cd.rat...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> commit f1bd44ac5088e4f8ea3ecdde96eef138317c0a9f Author: Chris Davis <cd.rat...@gmail.com> Date: Fri Jun 27 19:30:06 2014 -0700 s4-registry: implement set value and delete value for RPC Signed-off-by: Chris Davis <cd.rat...@gmail.com> Reviewed-by: Andreas Schneider <a...@samba.org> Reviewed-by: Michael Adam <ob...@samba.org> ----------------------------------------------------------------------- Summary of changes: source4/kdc/db-glue.c | 103 +++++++++++++++++++++++++++++++-------------- source4/kdc/sdb.c | 6 --- source4/kdc/sdb.h | 4 -- source4/kdc/sdb_to_hdb.c | 15 ++++--- source4/lib/registry/rpc.c | 63 ++++++++++++++++++++++++++- 5 files changed, 144 insertions(+), 47 deletions(-) Changeset truncated at 500 lines: diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index 91c34a2..ef750a8 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -196,6 +196,69 @@ static int samba_kdc_entry_destructor(struct samba_kdc_entry *p) return 0; } +/* + * Sort keys in descending order of strength. + * + * Explanaton from Greg Hudson: + * + * To encrypt tickets only the first returned key is used by the MIT KDC. The + * other keys just communicate support for session key enctypes, and aren't + * really used. The encryption key for the ticket enc part doesn't have + * to be of a type requested by the client. The session key enctype is chosen + * based on the client preference order, limited by the set of enctypes present + * in the server keys (unless the string attribute is set on the server + * principal overriding that set). + */ +static int samba_kdc_sort_encryption_keys(struct sdb_entry_ex *entry_ex) +{ + unsigned int i, j, idx = 0; + static const krb5_enctype etype_list[] = { + ENCTYPE_AES256_CTS_HMAC_SHA1_96, + ENCTYPE_AES128_CTS_HMAC_SHA1_96, + ENCTYPE_DES3_CBC_SHA1, + ENCTYPE_ARCFOUR_HMAC, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_MD4, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL + }; + size_t etype_len = ARRAY_SIZE(etype_list); + size_t keys_size = entry_ex->entry.keys.len; + struct sdb_key *keys = entry_ex->entry.keys.val; + struct sdb_key *sorted_keys; + + sorted_keys = calloc(keys_size, sizeof(struct sdb_key)); + if (sorted_keys == NULL) { + return -1; + } + + for (i = 0; i < etype_len; i++) { + for (j = 0; j < keys_size; j++) { + const struct sdb_key skey = keys[j]; + + /* Paranoia: Do not overflow the key_data array */ + if (idx > keys_size) { + return -1; + } + + if (KRB5_KEY_TYPE(&skey.key) == etype_list[i]) { + sorted_keys[idx] = skey; + idx++; + } + } + } + + /* Paranoia: Something went wrong during data copy */ + if (idx < keys_size) { + return -1; + } + + free(entry_ex->entry.keys.val); + entry_ex->entry.keys.val = sorted_keys; + + return 0; +} + static krb5_error_code samba_kdc_message2entry_keys(krb5_context context, struct samba_kdc_db_context *kdc_db_ctx, TALLOC_CTX *mem_ctx, @@ -588,6 +651,13 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context, out: if (ret != 0) { entry_ex->entry.keys.len = 0; + } else if (entry_ex->entry.keys.len > 0 && + entry_ex->entry.keys.val != NULL) { + ret = samba_kdc_sort_encryption_keys(entry_ex); + if (ret != 0) { + entry_ex->entry.keys.len = 0; + ret = ENOMEM; + } } if (entry_ex->entry.keys.len == 0 && entry_ex->entry.keys.val) { free(entry_ex->entry.keys.val); @@ -666,7 +736,6 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx; uint32_t userAccountControl; uint32_t msDS_User_Account_Control_Computed; - unsigned int i; krb5_error_code ret = 0; krb5_boolean is_computer = FALSE; @@ -1018,24 +1087,6 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context, goto out; } - entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes))); - if (entry_ex->entry.etypes == NULL) { - krb5_clear_error_message(context); - ret = ENOMEM; - goto out; - } - entry_ex->entry.etypes->len = entry_ex->entry.keys.len; - entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int)); - if (entry_ex->entry.etypes->val == NULL) { - krb5_clear_error_message(context); - ret = ENOMEM; - goto out; - } - for (i=0; i < entry_ex->entry.etypes->len; i++) { - entry_ex->entry.etypes->val[i] = KRB5_KEY_TYPE(&entry_ex->entry.keys.val[i].key); - } - - p->msg = talloc_steal(p, msg); out: @@ -1422,22 +1473,12 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context, entry_ex->entry.max_renew = NULL; - entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes))); - if (entry_ex->entry.etypes == NULL) { - krb5_clear_error_message(context); - ret = ENOMEM; - goto out; - } - entry_ex->entry.etypes->len = entry_ex->entry.keys.len; - entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int)); - if (entry_ex->entry.etypes->val == NULL) { + ret = samba_kdc_sort_encryption_keys(entry_ex); + if (ret != 0) { krb5_clear_error_message(context); ret = ENOMEM; goto out; } - for (i=0; i < entry_ex->entry.etypes->len; i++) { - entry_ex->entry.etypes->val[i] = KRB5_KEY_TYPE(&entry_ex->entry.keys.val[i].key); - } p->msg = talloc_steal(p, msg); diff --git a/source4/kdc/sdb.c b/source4/kdc/sdb.c index ca6b38d..2150150 100644 --- a/source4/kdc/sdb.c +++ b/source4/kdc/sdb.c @@ -92,12 +92,6 @@ void free_sdb_entry(struct sdb_entry *s) SAFE_FREE(s->valid_start); SAFE_FREE(s->valid_end); SAFE_FREE(s->pw_end); - if (s->etypes) { - if (s->etypes->len) { - free(s->etypes->val); - } - free(s->etypes); - } ZERO_STRUCTP(s); } diff --git a/source4/kdc/sdb.h b/source4/kdc/sdb.h index e4f2725..dbebb26 100644 --- a/source4/kdc/sdb.h +++ b/source4/kdc/sdb.h @@ -92,10 +92,6 @@ struct sdb_entry { unsigned int *max_life; unsigned int *max_renew; struct SDBFlags flags; - struct sdb_entry_etypes { - unsigned int len; - unsigned int *val; - } *etypes; }; struct sdb_entry_ex { diff --git a/source4/kdc/sdb_to_hdb.c b/source4/kdc/sdb_to_hdb.c index 7ec4046..66ee763 100644 --- a/source4/kdc/sdb_to_hdb.c +++ b/source4/kdc/sdb_to_hdb.c @@ -277,24 +277,29 @@ static int sdb_entry_to_hdb_entry(krb5_context context, sdb_flags_to_hdb_flags(&s->flags, &h->flags); - if (s->etypes) { + h->etypes = NULL; + if (h->keys.val != NULL) { h->etypes = malloc(sizeof(*h->etypes)); if (h->etypes == NULL) { rc = ENOMEM; goto error; } - h->etypes->len = s->etypes->len; + + h->etypes->len = s->keys.len; + h->etypes->val = calloc(h->etypes->len, sizeof(int)); if (h->etypes->val == NULL) { rc = ENOMEM; goto error; } + for (i = 0; i < h->etypes->len; i++) { - h->etypes->val[i] = s->etypes->val[i]; + Key k = h->keys.val[i]; + + h->etypes->val[i] = KRB5_KEY_TYPE(&(k.key)); } - } else { - h->etypes = NULL; } + h->generation = NULL; h->extensions = NULL; /* really sure ? FIXME */ diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index a8f8382..255bcbe 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -285,6 +285,56 @@ static WERROR rpc_get_value_by_name(TALLOC_CTX *mem_ctx, return r.out.result; } +static WERROR rpc_set_value(struct registry_key *key, const char *value_name, + uint32_t type, const DATA_BLOB data) +{ + struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); + struct winreg_SetValue r; + struct winreg_String name; + NTSTATUS status; + + name.name = value_name; + + ZERO_STRUCT(r); + r.in.handle = &mykeydata->pol; + r.in.name = name; + r.in.type = (enum winreg_Type)type; + r.in.data = data.data; + r.in.size = data.length; + + status = dcerpc_winreg_SetValue_r(mykeydata->binding_handle, key, &r); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("SetValue failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + return r.out.result; +} + +static WERROR rpc_del_value(TALLOC_CTX *mem_ctx, struct registry_key *key, + const char *value_name) +{ + struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); + struct winreg_DeleteValue r; + struct winreg_String name; + NTSTATUS status; + + name.name = value_name; + + ZERO_STRUCT(r); + r.in.handle = &mykeydata->pol; + r.in.value = name; + + status = dcerpc_winreg_DeleteValue_r(mykeydata->binding_handle, + mem_ctx, &r); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("DeleteValue failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + return r.out.result; +} + static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, const struct registry_key *parent, uint32_t n, @@ -338,10 +388,19 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, { struct winreg_CreateKey r; struct rpc_key *parentkd = talloc_get_type(parent, struct rpc_key); - struct rpc_key *rpck = talloc(mem_ctx, struct rpc_key); + struct rpc_key *rpck = talloc_zero(mem_ctx, struct rpc_key); NTSTATUS status; + if (rpck == NULL) { + return WERR_NOMEM; + } + + rpck->key.context = parentkd->key.context; + rpck->binding_handle = parentkd->binding_handle; + rpck->num_values = -1; + rpck->num_subkeys = -1; + ZERO_STRUCT(r); r.in.handle = &parentkd->pol; r.in.name.name = path; @@ -470,6 +529,8 @@ static struct registry_operations reg_backend_rpc = { .enum_key = rpc_get_subkey_by_index, .enum_value = rpc_get_value_by_index, .get_value = rpc_get_value_by_name, + .set_value = rpc_set_value, + .delete_value = rpc_del_value, .create_key = rpc_add_key, .delete_key = rpc_del_key, .get_key_info = rpc_get_info, -- Samba Shared Repository