diff options
author | Nadezhda Ivanova <nadezhda.ivanova@postpath.com> | 2009-09-21 14:26:15 -0700 |
---|---|---|
committer | Nadezhda Ivanova <nadezhda.ivanova@postpath.com> | 2009-09-21 14:26:15 -0700 |
commit | 13b979b03d86f3ae43dc5fd539fa5d3f22f579a0 (patch) | |
tree | 40e15be25f6b975e7c5b91f00fdf6030726e25e7 /source4 | |
parent | 025590e7a4758e86e7942642971b92fc6bab7a8e (diff) | |
parent | 1afc7c453c1d5f7e761e46cdc69900305a149820 (diff) | |
download | samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.tar.gz samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.tar.bz2 samba-13b979b03d86f3ae43dc5fd539fa5d3f22f579a0.zip |
Merge branch 'master' of git://git.samba.org/samba
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 2 | ||||
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/resolve_oids.c | 226 | ||||
-rw-r--r-- | source4/lib/ldb/common/ldb.c | 4 | ||||
-rw-r--r-- | source4/libnet/libnet_become_dc.c | 2 | ||||
-rw-r--r-- | source4/libnet/libnet_join.c | 286 | ||||
-rw-r--r-- | source4/libnet/libnet_vampire.c | 49 | ||||
-rw-r--r-- | source4/librpc/ndr/py_security.c | 5 | ||||
-rw-r--r-- | source4/librpc/ndr/py_security.h | 23 | ||||
-rw-r--r-- | source4/param/config.mk | 2 | ||||
-rw-r--r-- | source4/param/provision.c | 131 | ||||
-rw-r--r-- | source4/param/provision.h | 16 | ||||
-rw-r--r-- | source4/scripting/python/samba/provision.py | 117 | ||||
-rw-r--r-- | source4/scripting/python/samba/samdb.py | 4 | ||||
-rwxr-xr-x | source4/setup/domainlevel | 9 | ||||
-rwxr-xr-x | source4/setup/enableaccount | 10 | ||||
-rwxr-xr-x | source4/setup/newuser | 10 | ||||
-rwxr-xr-x | source4/setup/pwsettings | 9 | ||||
-rw-r--r-- | source4/setup/secrets_dc.ldif | 24 | ||||
-rw-r--r-- | source4/setup/secrets_dns.ldif | 11 | ||||
-rw-r--r-- | source4/setup/secrets_self_join.ldif | 13 | ||||
-rwxr-xr-x | source4/setup/setexpiry | 12 | ||||
-rwxr-xr-x | source4/setup/setpassword | 12 |
22 files changed, 618 insertions, 359 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index a04e52469d..a50e5b4a66 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -248,7 +248,7 @@ static int setup_kerberos_keys(struct setup_password_fields_io *io) char *name; char *saltbody; - name = talloc_strdup(io->ac, io->u.sAMAccountName); + name = strlower_talloc(io->ac, io->u.sAMAccountName); if (!name) { ldb_oom(ldb); return LDB_ERR_OPERATIONS_ERROR; diff --git a/source4/dsdb/samdb/ldb_modules/resolve_oids.c b/source4/dsdb/samdb/ldb_modules/resolve_oids.c index f4d9eba17a..053c2ec55f 100644 --- a/source4/dsdb/samdb/ldb_modules/resolve_oids.c +++ b/source4/dsdb/samdb/ldb_modules/resolve_oids.c @@ -21,6 +21,199 @@ #include "ldb_module.h" #include "dsdb/samdb/samdb.h" +static int resolve_oids_need_value(struct ldb_context *ldb, + struct dsdb_schema *schema, + const struct dsdb_attribute *a, + const struct ldb_val *valp) +{ + const struct dsdb_attribute *va = NULL; + const struct dsdb_class *vo = NULL; + const void *p2; + char *str = NULL; + + if (a->syntax->oMSyntax != 6) { + return LDB_ERR_COMPARE_FALSE; + } + + if (valp) { + p2 = memchr(valp->data, '.', valp->length); + } else { + p2 = NULL; + } + + if (!p2) { + return LDB_ERR_COMPARE_FALSE; + } + + switch (a->attributeID_id) { + case DRSUAPI_ATTRIBUTE_objectClass: + case DRSUAPI_ATTRIBUTE_subClassOf: + case DRSUAPI_ATTRIBUTE_auxiliaryClass: + case DRSUAPI_ATTRIBUTE_systemPossSuperiors: + case DRSUAPI_ATTRIBUTE_possSuperiors: + str = talloc_strndup(ldb, (char *)valp->data, valp->length); + if (!str) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + vo = dsdb_class_by_governsID_oid(schema, str); + talloc_free(str); + if (!vo) { + return LDB_ERR_COMPARE_FALSE; + } + return LDB_ERR_COMPARE_TRUE; + case DRSUAPI_ATTRIBUTE_systemMustContain: + case DRSUAPI_ATTRIBUTE_systemMayContain: + case DRSUAPI_ATTRIBUTE_mustContain: + case DRSUAPI_ATTRIBUTE_mayContain: + str = talloc_strndup(ldb, (char *)valp->data, valp->length); + if (!str) { + ldb_oom(ldb); + return LDB_ERR_OPERATIONS_ERROR; + } + va = dsdb_attribute_by_attributeID_oid(schema, str); + talloc_free(str); + if (!va) { + return LDB_ERR_COMPARE_FALSE; + } + return LDB_ERR_COMPARE_TRUE; + case DRSUAPI_ATTRIBUTE_governsID: + case DRSUAPI_ATTRIBUTE_attributeID: + case DRSUAPI_ATTRIBUTE_attributeSyntax: + return LDB_ERR_COMPARE_FALSE; + } + + return LDB_ERR_COMPARE_FALSE; +} + +static int resolve_oids_parse_tree_need(struct ldb_context *ldb, + struct dsdb_schema *schema, + const struct ldb_parse_tree *tree) +{ + int i; + const struct dsdb_attribute *a = NULL; + const char *attr; + const char *p1; + const void *p2; + const struct ldb_val *valp = NULL; + int ret; + + switch (tree->operation) { + case LDB_OP_AND: + case LDB_OP_OR: + for (i=0;i<tree->u.list.num_elements;i++) { + ret = resolve_oids_parse_tree_need(ldb, schema, + tree->u.list.elements[i]); + if (ret != LDB_ERR_COMPARE_FALSE) { + return ret; + } + } + return LDB_ERR_COMPARE_FALSE; + case LDB_OP_NOT: + return resolve_oids_parse_tree_need(ldb, schema, + tree->u.isnot.child); + case LDB_OP_EQUALITY: + case LDB_OP_GREATER: + case LDB_OP_LESS: + case LDB_OP_APPROX: + attr = tree->u.equality.attr; + valp = &tree->u.equality.value; + break; + case LDB_OP_SUBSTRING: + attr = tree->u.substring.attr; + break; + case LDB_OP_PRESENT: + attr = tree->u.present.attr; + break; + case LDB_OP_EXTENDED: + attr = tree->u.extended.attr; + valp = &tree->u.extended.value; + break; + default: + return LDB_ERR_COMPARE_FALSE; + } + + p1 = strchr(attr, '.'); + + if (valp) { + p2 = memchr(valp->data, '.', valp->length); + } else { + p2 = NULL; + } + + if (!p1 && !p2) { + return LDB_ERR_COMPARE_FALSE; + } + + if (p1) { + a = dsdb_attribute_by_attributeID_oid(schema, attr); + } else { + a = dsdb_attribute_by_lDAPDisplayName(schema, attr); + } + if (!a) { + return LDB_ERR_COMPARE_FALSE; + } + + if (!p2) { + return LDB_ERR_COMPARE_FALSE; + } + + if (a->syntax->oMSyntax != 6) { + return LDB_ERR_COMPARE_FALSE; + } + + return resolve_oids_need_value(ldb, schema, a, valp); +} + +static int resolve_oids_element_need(struct ldb_context *ldb, + struct dsdb_schema *schema, + const struct ldb_message_element *el) +{ + int i; + const struct dsdb_attribute *a = NULL; + const char *p1; + + p1 = strchr(el->name, '.'); + + if (p1) { + a = dsdb_attribute_by_attributeID_oid(schema, el->name); + } else { + a = dsdb_attribute_by_lDAPDisplayName(schema, el->name); + } + if (!a) { + return LDB_ERR_COMPARE_FALSE; + } + + for (i=0; i < el->num_values; i++) { + int ret; + ret = resolve_oids_need_value(ldb, schema, a, + &el->values[i]); + if (ret != LDB_ERR_COMPARE_FALSE) { + return ret; + } + } + + return LDB_ERR_COMPARE_FALSE; +} + +static int resolve_oids_message_need(struct ldb_context *ldb, + struct dsdb_schema *schema, + const struct ldb_message *msg) +{ + int i; + + for (i=0; i < msg->num_elements; i++) { + int ret; + ret = resolve_oids_element_need(ldb, schema, + &msg->elements[i]); + if (ret != LDB_ERR_COMPARE_FALSE) { + return ret; + } + } + + return LDB_ERR_COMPARE_FALSE; +} + static int resolve_oids_replace_value(struct ldb_context *ldb, struct dsdb_schema *schema, const struct dsdb_attribute *a, @@ -98,19 +291,22 @@ static int resolve_oids_parse_tree_replace(struct ldb_context *ldb, const char *p1; const void *p2; struct ldb_val *valp = NULL; + int ret; switch (tree->operation) { case LDB_OP_AND: case LDB_OP_OR: for (i=0;i<tree->u.list.num_elements;i++) { - resolve_oids_parse_tree_replace(ldb, schema, + ret = resolve_oids_parse_tree_replace(ldb, schema, tree->u.list.elements[i]); + if (ret != LDB_SUCCESS) { + return ret; + } } return LDB_SUCCESS; case LDB_OP_NOT: - resolve_oids_parse_tree_replace(ldb, schema, + return resolve_oids_parse_tree_replace(ldb, schema, tree->u.isnot.child); - return LDB_SUCCESS; case LDB_OP_EQUALITY: case LDB_OP_GREATER: case LDB_OP_LESS: @@ -275,6 +471,14 @@ static int resolve_oids_search(struct ldb_module *module, struct ldb_request *re return ldb_next_request(module, req); } + ret = resolve_oids_parse_tree_need(ldb, schema, + req->op.search.tree); + if (ret == LDB_ERR_COMPARE_FALSE) { + return ldb_next_request(module, req); + } else if (ret != LDB_ERR_COMPARE_TRUE) { + return ret; + } + ac = talloc(req, struct resolve_oids_context); if (ac == NULL) { ldb_oom(ldb); @@ -332,6 +536,14 @@ static int resolve_oids_add(struct ldb_module *module, struct ldb_request *req) return ldb_next_request(module, req); } + ret = resolve_oids_message_need(ldb, schema, + req->op.add.message); + if (ret == LDB_ERR_COMPARE_FALSE) { + return ldb_next_request(module, req); + } else if (ret != LDB_ERR_COMPARE_TRUE) { + return ret; + } + ac = talloc(req, struct resolve_oids_context); if (ac == NULL) { ldb_oom(ldb); @@ -385,6 +597,14 @@ static int resolve_oids_modify(struct ldb_module *module, struct ldb_request *re return ldb_next_request(module, req); } + ret = resolve_oids_message_need(ldb, schema, + req->op.mod.message); + if (ret == LDB_ERR_COMPARE_FALSE) { + return ldb_next_request(module, req); + } else if (ret != LDB_ERR_COMPARE_TRUE) { + return ret; + } + ac = talloc(req, struct resolve_oids_context); if (ac == NULL) { ldb_oom(ldb); diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index 613451a7c2..b75d837674 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -41,8 +41,8 @@ static int ldb_context_destructor(void *ptr) if (ldb->transaction_active) { ldb_debug(ldb, LDB_DEBUG_FATAL, - "A transaction is still active in ldb context [%p]", - ldb); + "A transaction is still active in ldb context [%p] on %s", + ldb, (const char *)ldb_get_opaque(ldb, "ldb_url")); } return 0; diff --git a/source4/libnet/libnet_become_dc.c b/source4/libnet/libnet_become_dc.c index c4e786c833..70dee9597b 100644 --- a/source4/libnet/libnet_become_dc.c +++ b/source4/libnet/libnet_become_dc.c @@ -2101,7 +2101,7 @@ static void becomeDC_drsuapi1_add_entry_send(struct libnet_BecomeDC_state *s) vd[0] = data_blob_talloc(vd, NULL, 4); if (composite_nomem(vd[0].data, c)) return; - SIVAL(vd[0].data, 0, DS_DC_FUNCTION_2008_R2); + SIVAL(vd[0].data, 0, DS_DC_FUNCTION_2008); vs[0].blob = &vd[0]; diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 86ad685c51..fc7de10506 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -33,6 +33,7 @@ #include "auth/credentials/credentials_krb5.h" #include "librpc/gen_ndr/ndr_samr_c.h" #include "param/param.h" +#include "param/provision.h" /* * complete a domain join, when joining to a AD domain: @@ -860,254 +861,6 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } -NTSTATUS libnet_set_join_secrets(struct libnet_context *ctx, - TALLOC_CTX *mem_ctx, - struct libnet_set_join_secrets *r) -{ - TALLOC_CTX *tmp_mem; - int ret, rtn; - struct ldb_context *ldb; - struct ldb_dn *base_dn; - struct ldb_message **msgs, *msg; - const char *sct; - const char * const attrs[] = { - "whenChanged", - "secret", - "priorSecret", - "priorChanged", - "krb5Keytab", - "privateKeytab", - NULL - }; - - tmp_mem = talloc_new(mem_ctx); - if (!tmp_mem) { - return NT_STATUS_NO_MEMORY; - } - - /* Open the secrets database */ - ldb = secrets_db_connect(tmp_mem, ctx->event_ctx, ctx->lp_ctx); - if (!ldb) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "Could not open secrets database"); - talloc_free(tmp_mem); - return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; - } - - /* - * now prepare the record for secrets.ldb - */ - sct = talloc_asprintf(tmp_mem, "%d", r->in.join_type); - if (!sct) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - msg = ldb_msg_new(tmp_mem); - if (!msg) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - base_dn = ldb_dn_new(tmp_mem, ldb, "cn=Primary Domains"); - if (!base_dn) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - msg->dn = ldb_dn_copy(tmp_mem, base_dn); - if ( ! ldb_dn_add_child_fmt(msg->dn, "flatname=%s", r->in.domain_name)) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "flatname", r->in.domain_name); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - if (r->in.realm) { - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "realm", r->in.realm); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } - - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "objectClass", "primaryDomain"); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "objectClass", "kerberosSecret"); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "secret", r->in.join_password); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "samAccountName", r->in.account_name); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - rtn = samdb_msg_add_string(ldb, tmp_mem, msg, "secureChannelType", sct); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - if (r->in.kvno) { - rtn = samdb_msg_add_uint(ldb, tmp_mem, msg, "msDS-KeyVersionNumber", - r->in.kvno); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } - - if (r->in.domain_sid) { - rtn = samdb_msg_add_dom_sid(ldb, tmp_mem, msg, "objectSid", - r->in.domain_sid); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } - - /* - * search for the secret record - * - remove the records we find - * - and fetch the old secret and store it under priorSecret - */ - ret = gendb_search(ldb, - tmp_mem, base_dn, - &msgs, attrs, - "(|" SECRETS_PRIMARY_DOMAIN_FILTER "(realm=%s))", - r->in.domain_name, r->in.realm); - if (ret == 0) { - rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "privateKeytab", "secrets.keytab"); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } else if (ret == -1) { - r->out.error_string - = talloc_asprintf(mem_ctx, - "Search for domain: %s and realm: %s failed: %s", - r->in.domain_name, r->in.realm, ldb_errstring(ldb)); - talloc_free(tmp_mem); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } else { - const struct ldb_val *private_keytab; - const struct ldb_val *krb5_main_keytab; - const struct ldb_val *prior_secret; - const struct ldb_val *prior_modified_time; - int i; - - for (i = 0; i < ret; i++) { - ldb_delete(ldb, msgs[i]->dn); - } - - prior_secret = ldb_msg_find_ldb_val(msgs[0], "secret"); - if (prior_secret) { - rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "priorSecret", prior_secret); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } - rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secret", r->in.join_password); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - prior_modified_time = ldb_msg_find_ldb_val(msgs[0], - "whenChanged"); - if (prior_modified_time) { - rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "priorWhenChanged", - prior_modified_time); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } - - rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "samAccountName", r->in.account_name); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - rtn = samdb_msg_set_string(ldb, tmp_mem, msg, "secureChannelType", sct); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - - /* We will want to keep the keytab names */ - private_keytab = ldb_msg_find_ldb_val(msgs[0], "privateKeytab"); - if (private_keytab) { - rtn = samdb_msg_set_value(ldb, tmp_mem, msg, "privateKeytab", private_keytab); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } - krb5_main_keytab = ldb_msg_find_ldb_val(msgs[0], "krb5Keytab"); - if (krb5_main_keytab) { - rtn = samdb_msg_set_value(ldb, tmp_mem, msg, - "krb5Keytab", krb5_main_keytab); - if (rtn == -1) { - r->out.error_string = NULL; - talloc_free(tmp_mem); - return NT_STATUS_NO_MEMORY; - } - } - } - - /* create the secret */ - ret = ldb_add(ldb, msg); - if (ret != 0) { - r->out.error_string = talloc_asprintf(mem_ctx, "Failed to create secret record %s", - ldb_dn_get_linearized(msg->dn)); - talloc_free(tmp_mem); - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - - return NT_STATUS_OK; -} - static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Join *r) @@ -1115,11 +868,12 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, NTSTATUS status; TALLOC_CTX *tmp_mem; struct libnet_JoinDomain *r2; - struct libnet_set_join_secrets *r3; + struct provision_store_self_join_settings *set_secrets; uint32_t acct_type = 0; const char *account_name; const char *netbios_name; - + const char *error_string; + r->out.error_string = NULL; tmp_mem = talloc_new(mem_ctx); @@ -1179,26 +933,26 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, return status; } - r3 = talloc(tmp_mem, struct libnet_set_join_secrets); - if (!r3) { + set_secrets = talloc(tmp_mem, struct provision_store_self_join_settings); + if (!set_secrets) { r->out.error_string = NULL; talloc_free(tmp_mem); return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(r3); - r3->in.domain_name = r2->out.domain_name; - r3->in.realm = r2->out.realm; - r3->in.account_name = account_name; - r3->in.netbios_name = netbios_name; - r3->in.join_type = r->in.join_type; - r3->in.join_password = r2->out.join_password; - r3->in.kvno = r2->out.kvno; - r3->in.domain_sid = r2->out.domain_sid; + ZERO_STRUCTP(set_secrets); + set_secrets->domain_name = r2->out.domain_name; + set_secrets->realm = r2->out.realm; + set_secrets->account_name = account_name; + set_secrets->netbios_name = netbios_name; + set_secrets->secure_channel_type = r->in.join_type; + set_secrets->machine_password = r2->out.join_password; + set_secrets->key_version_number = r2->out.kvno; + set_secrets->domain_sid = r2->out.domain_sid; - status = libnet_set_join_secrets(ctx, r3, r3); + status = provision_store_self_join(ctx, ctx->lp_ctx, ctx->event_ctx, set_secrets, &error_string); if (!NT_STATUS_IS_OK(status)) { - r->out.error_string = talloc_steal(mem_ctx, r3->out.error_string); + r->out.error_string = talloc_steal(mem_ctx, error_string); talloc_free(tmp_mem); return status; } @@ -1206,11 +960,11 @@ static NTSTATUS libnet_Join_primary_domain(struct libnet_context *ctx, /* move all out parameter to the callers TALLOC_CTX */ r->out.error_string = NULL; r->out.join_password = r2->out.join_password; - talloc_steal(mem_ctx, r2->out.join_password); + talloc_reparent(r2, mem_ctx, r2->out.join_password); r->out.domain_sid = r2->out.domain_sid; - talloc_steal(mem_ctx, r2->out.domain_sid); + talloc_reparent(r2, mem_ctx, r2->out.domain_sid); r->out.domain_name = r2->out.domain_name; - talloc_steal(mem_ctx, r2->out.domain_name); + talloc_reparent(r2, mem_ctx, r2->out.domain_name); talloc_free(tmp_mem); return NT_STATUS_OK; } diff --git a/source4/libnet/libnet_vampire.c b/source4/libnet/libnet_vampire.c index 327a64daea..19453a4d65 100644 --- a/source4/libnet/libnet_vampire.c +++ b/source4/libnet/libnet_vampire.c @@ -595,10 +595,11 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, struct libnet_Vampire *r) { struct libnet_JoinDomain *join; - struct libnet_set_join_secrets *set_secrets; + struct provision_store_self_join_settings *set_secrets; struct libnet_BecomeDC b; struct vampire_state *s; struct ldb_message *msg; + const char *error_string; int ldb_ret; uint32_t i; NTSTATUS status; @@ -709,40 +710,52 @@ NTSTATUS libnet_Vampire(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_DB_ERROR; } - /* commit the transaction - this commits all the changes in - the ldb from the whole vampire. Note that this commit + /* prepare the transaction - this prepares to commit all the changes in + the ldb from the whole vampire. Note that this triggers the writing of the linked attribute backlinks. */ - if (ldb_transaction_commit(s->ldb) != LDB_SUCCESS) { - printf("Failed to commit vampire transaction\n"); + if (ldb_transaction_prepare_commit(s->ldb) != LDB_SUCCESS) { + printf("Failed to prepare_commit vampire transaction\n"); return NT_STATUS_INTERNAL_DB_ERROR; } - set_secrets = talloc_zero(s, struct libnet_set_join_secrets); + set_secrets = talloc(s, struct provision_store_self_join_settings); if (!set_secrets) { + r->out.error_string = NULL; + talloc_free(s); return NT_STATUS_NO_MEMORY; } - - set_secrets->in.domain_name = join->out.domain_name; - set_secrets->in.realm = join->out.realm; - set_secrets->in.account_name = account_name; - set_secrets->in.netbios_name = netbios_name; - set_secrets->in.join_type = SEC_CHAN_BDC; - set_secrets->in.join_password = join->out.join_password; - set_secrets->in.kvno = join->out.kvno; - set_secrets->in.domain_sid = join->out.domain_sid; - status = libnet_set_join_secrets(ctx, set_secrets, set_secrets); + ZERO_STRUCTP(set_secrets); + set_secrets->domain_name = join->out.domain_name; + set_secrets->realm = join->out.realm; + set_secrets->account_name = account_name; + set_secrets->netbios_name = netbios_name; + set_secrets->secure_channel_type = SEC_CHAN_BDC; + set_secrets->machine_password = join->out.join_password; + set_secrets->key_version_number = join->out.kvno; + set_secrets->domain_sid = join->out.domain_sid; + + status = provision_store_self_join(ctx, ctx->lp_ctx, ctx->event_ctx, set_secrets, &error_string); if (!NT_STATUS_IS_OK(status)) { - r->out.error_string = talloc_steal(mem_ctx, set_secrets->out.error_string); + r->out.error_string = talloc_steal(mem_ctx, error_string); talloc_free(s); return status; } r->out.domain_name = talloc_steal(r, join->out.domain_name); r->out.domain_sid = talloc_steal(r, join->out.domain_sid); - talloc_free(s); + /* commit the transaction now we know the secrets were written + * out properly + */ + if (ldb_transaction_commit(s->ldb) != LDB_SUCCESS) { + printf("Failed to commit vampire transaction\n"); + return NT_STATUS_INTERNAL_DB_ERROR; + } + + talloc_free(s); + return NT_STATUS_OK; } diff --git a/source4/librpc/ndr/py_security.c b/source4/librpc/ndr/py_security.c index 02dc059f05..1b185a51b5 100644 --- a/source4/librpc/ndr/py_security.c +++ b/source4/librpc/ndr/py_security.c @@ -23,6 +23,11 @@ #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None #endif +PyObject *py_dom_sid_FromSid(struct dom_sid *sid) +{ + return py_talloc_reference(&dom_sid_Type, sid); +} + static void PyType_AddMethods(PyTypeObject *type, PyMethodDef *methods) { PyObject *dict; diff --git a/source4/librpc/ndr/py_security.h b/source4/librpc/ndr/py_security.h new file mode 100644 index 0000000000..9d200faf8e --- /dev/null +++ b/source4/librpc/ndr/py_security.h @@ -0,0 +1,23 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "libcli/security/security.h" + +/* a lone prototype for this function, because it's python */ +PyObject *py_dom_sid_FromSid(struct dom_sid *sid); diff --git a/source4/param/config.mk b/source4/param/config.mk index 6e5290b64d..45eb836bb4 100644 --- a/source4/param/config.mk +++ b/source4/param/config.mk @@ -13,7 +13,7 @@ PUBLIC_HEADERS += param/param.h PC_FILES += $(paramsrcdir)/samba-hostconfig.pc [SUBSYSTEM::PROVISION] -PRIVATE_DEPENDENCIES = LIBPYTHON pyldb pyparam_util +PRIVATE_DEPENDENCIES = LIBPYTHON pyldb pyparam_util python_dcerpc_security PROVISION_OBJ_FILES = $(paramsrcdir)/provision.o $(param_OBJ_FILES) diff --git a/source4/param/provision.c b/source4/param/provision.c index bbc6837a90..355af794d8 100644 --- a/source4/param/provision.c +++ b/source4/param/provision.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. Samba utility functions Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2008 - + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or @@ -20,15 +21,21 @@ #include "includes.h" #include "auth/auth.h" #include "lib/ldb_wrap.h" +#include "ldb/include/ldb.h" +#include "ldb_errors.h" #include "libcli/raw/libcliraw.h" #include "librpc/ndr/libndr.h" #include "param/param.h" #include "param/provision.h" +#include "param/secrets.h" #include <Python.h> +#include "lib/talloc/pytalloc.h" +#include "librpc/rpc/pyrpc.h" #include "scripting/python/modules.h" #include "lib/ldb/pyldb.h" #include "param/pyparam.h" +#include "librpc/ndr/py_security.h" NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct provision_settings *settings, @@ -144,3 +151,125 @@ NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, return NT_STATUS_OK; } + +extern void initldb(void); +extern void initsecurity(void); + +NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct tevent_context *event_ctx, + struct provision_store_self_join_settings *settings, + const char **error_string) +{ + int ret; + PyObject *provision_mod, *provision_dict, *provision_fn, *py_result, *parameters, *py_sid; + struct ldb_context *ldb; + TALLOC_CTX *tmp_mem = talloc_new(mem_ctx); + if (!tmp_mem) { + return NT_STATUS_NO_MEMORY; + } + + /* Open the secrets database */ + ldb = secrets_db_connect(tmp_mem, event_ctx, lp_ctx); + if (!ldb) { + *error_string + = talloc_asprintf(mem_ctx, + "Could not open secrets database"); + talloc_free(tmp_mem); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + ret = ldb_transaction_start(ldb); + + if (ret != LDB_SUCCESS) { + *error_string + = talloc_asprintf(mem_ctx, + "Could not start transaction on secrets database: %s", ldb_errstring(ldb)); + talloc_free(tmp_mem); + return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; + } + + py_load_samba_modules(); + Py_Initialize(); + py_update_path("bin"); /* FIXME: Can't assume this is always the case */ + initldb(); + initsecurity(); + provision_mod = PyImport_Import(PyString_FromString("samba.provision")); + + if (provision_mod == NULL) { + PyErr_Print(); + *error_string + = talloc_asprintf(mem_ctx, "Unable to import provision Python module."); + talloc_free(tmp_mem); + return NT_STATUS_UNSUCCESSFUL; + } + + provision_dict = PyModule_GetDict(provision_mod); + + if (provision_dict == NULL) { + *error_string + = talloc_asprintf(mem_ctx, "Unable to get dictionary for provision module"); + talloc_free(tmp_mem); + return NT_STATUS_UNSUCCESSFUL; + } + + provision_fn = PyDict_GetItemString(provision_dict, "secretsdb_self_join"); + if (provision_fn == NULL) { + PyErr_Print(); + *error_string + = talloc_asprintf(mem_ctx, "Unable to get provision_become_dc function"); + talloc_free(tmp_mem); + return NT_STATUS_UNSUCCESSFUL; + } + + parameters = PyDict_New(); + + PyDict_SetItemString(parameters, "secretsdb", + PyLdb_FromLdbContext(ldb)); + PyDict_SetItemString(parameters, "domain", + PyString_FromString(settings->domain_name)); + PyDict_SetItemString(parameters, "domain", + PyString_FromString(settings->domain_name)); + PyDict_SetItemString(parameters, "realm", + PyString_FromString(settings->realm)); + PyDict_SetItemString(parameters, "machinepass", + PyString_FromString(settings->machine_password)); + PyDict_SetItemString(parameters, "netbiosname", + PyString_FromString(settings->netbios_name)); + + py_sid = py_dom_sid_FromSid(settings->domain_sid); + + PyDict_SetItemString(parameters, "domainsid", + py_sid); + + PyDict_SetItemString(parameters, "secure_channel_type", + PyInt_FromLong(settings->secure_channel_type)); + + PyDict_SetItemString(parameters, "key_version_number", + PyInt_FromLong(settings->key_version_number)); + + py_result = PyEval_CallObjectWithKeywords(provision_fn, NULL, parameters); + + Py_DECREF(parameters); + + if (py_result == NULL) { + ldb_transaction_cancel(ldb); + talloc_free(tmp_mem); + + PyErr_Print(); + PyErr_Clear(); + return NT_STATUS_UNSUCCESSFUL; + } + + ret = ldb_transaction_commit(ldb); + if (ret != LDB_SUCCESS) { + *error_string + = talloc_asprintf(mem_ctx, + "Could not commit transaction on secrets database: %s", ldb_errstring(ldb)); + talloc_free(tmp_mem); + return NT_STATUS_INTERNAL_DB_ERROR; + } + + talloc_free(tmp_mem); + + return NT_STATUS_OK; +} diff --git a/source4/param/provision.h b/source4/param/provision.h index af9685d292..c3b3bb88d8 100644 --- a/source4/param/provision.h +++ b/source4/param/provision.h @@ -44,8 +44,24 @@ struct provision_result { struct loadparm_context *lp_ctx; }; +struct provision_store_self_join_settings { + const char *domain_name; + const char *realm; + const char *netbios_name; + const char *account_name; + enum netr_SchannelType secure_channel_type; + const char *machine_password; + int key_version_number; + struct dom_sid *domain_sid; +}; + NTSTATUS provision_bare(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct provision_settings *settings, struct provision_result *result); +NTSTATUS provision_store_self_join(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, + struct tevent_context *ev_ctx, + struct provision_store_self_join_settings *settings, + const char **error_string); + #endif /* _PROVISION_H_ */ diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 25cec4b143..2d3e04eac1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -44,7 +44,7 @@ from credentials import Credentials, DONT_USE_KERBEROS from auth import system_session, admin_session from samba import version, Ldb, substitute_var, valid_netbios_name from samba import check_all_substituted -from samba import DS_DOMAIN_FUNCTION_2000, DS_DC_FUNCTION_2008_R2 +from samba import DS_DOMAIN_FUNCTION_2000, DS_DOMAIN_FUNCTION_2008, DS_DC_FUNCTION_2008, DS_DC_FUNCTION_2008_R2 from samba.samdb import SamDB from samba.idmap import IDmapDB from samba.dcerpc import security @@ -54,14 +54,10 @@ from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, timestring from ms_schema import read_ms_schema from ms_display_specifiers import read_ms_ldif from signal import SIGTERM +from dcerpc.misc import SEC_CHAN_BDC, SEC_CHAN_WKSTA __docformat__ = "restructuredText" - -class ProvisioningError(ValueError): - pass - - def find_setup_dir(): """Find the setup directory used by provision.""" dirname = os.path.dirname(__file__) @@ -113,6 +109,11 @@ def get_config_descriptor(domain_sid): DEFAULTSITE = "Default-First-Site-Name" +# Exception classes + +class ProvisioningError(Exception): + """A generic provision error.""" + class InvalidNetbiosName(Exception): """A specified name was not a valid NetBIOS name.""" def __init__(self, name): @@ -355,7 +356,6 @@ def provision_paths_from_lp(lp, dnsdomain): """ paths = ProvisionPaths() paths.private_dir = lp.get("private dir") - paths.keytab = "secrets.keytab" paths.dns_keytab = "dns.keytab" paths.shareconf = os.path.join(paths.private_dir, "share.ldb") @@ -695,26 +695,83 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.transaction_commit() +def secretsdb_self_join(secretsdb, domain, + netbiosname, domainsid, machinepass, + realm=None, dnsdomain=None, + keytab_path=None, + key_version_number=1, + secure_channel_type=SEC_CHAN_WKSTA): + """Add domain join-specific bits to a secrets database. + + :param secretsdb: Ldb Handle to the secrets database + :param machinepass: Machine password + """ + attrs=["whenChanged", + "secret", + "priorSecret", + "priorChanged", + "krb5Keytab", + "privateKeytab"] + + + msg = ldb.Message(ldb.Dn(secretsdb, "flatname=%s,cn=Primary Domains" % domain)); + msg["secureChannelType"] = str(secure_channel_type) + msg["flatname"] = [domain] + msg["objectClass"] = ["top", "primaryDomain"] + if realm is not None: + if dnsdomain is None: + dnsdomain = realm.lower() + msg["objectClass"] = ["top", "primaryDomain", "kerberosSecret"] + msg["realm"] = realm + msg["saltPrincipal"] = "host/%s.%s@%s" % (netbiosname.lower(), dnsdomain.lower(), realm.upper()) + msg["msDS-KeyVersionNumber"] = [str(key_version_number)] + msg["privateKeytab"] = ["secrets.keytab"]; + + + msg["secret"] = [machinepass] + msg["samAccountName"] = ["%s$" % netbiosname] + msg["secureChannelType"] = [str(secure_channel_type)] + msg["objectSid"] = [ndr_pack(domainsid)] + + res = secretsdb.search(base="cn=Primary Domains", + attrs=attrs, + expression=("(&(|(flatname=%s)(realm=%s)(objectSid=%s))(objectclass=primaryDomain))" % (domain, realm, str(domainsid))), + scope=SCOPE_ONELEVEL) + + for del_msg in res: + if del_msg.dn is not msg.dn: + secretsdb.delete(del_msg.dn) + + res = secretsdb.search(base=msg.dn, attrs=attrs, scope=SCOPE_BASE) + if len(res) == 1: + msg["priorSecret"] = res[0]["secret"] + msg["priorWhenChanged"] = res[0]["whenChanged"] -def secretsdb_become_dc(secretsdb, setup_path, domain, realm, dnsdomain, - netbiosname, domainsid, keytab_path, samdb_url, - dns_keytab_path, dnspass, machinepass): - """Add DC-specific bits to a secrets database. + if res["privateKeytab"] is not None: + msg["privateKeytab"] = res[0]["privateKeytab"] + + if res["krb5Keytab"] is not None: + msg["krb5Keytab"] = res[0]["krb5Keytab"] + + for el in msg: + el.set_flags(ldb.FLAG_MOD_REPLACE) + secretsdb.modify(msg) + else: + secretsdb.add(msg) + + +def secretsdb_setup_dns(secretsdb, setup_path, realm, dnsdomain, + dns_keytab_path, dnspass): + """Add DNS specific bits to a secrets database. :param secretsdb: Ldb Handle to the secrets database :param setup_path: Setup path function :param machinepass: Machine password """ - setup_ldb(secretsdb, setup_path("secrets_dc.ldif"), { - "MACHINEPASS_B64": b64encode(machinepass), - "DOMAIN": domain, + setup_ldb(secretsdb, setup_path("secrets_dns.ldif"), { "REALM": realm, "DNSDOMAIN": dnsdomain, - "DOMAINSID": str(domainsid), - "SECRETS_KEYTAB": keytab_path, - "NETBIOSNAME": netbiosname, - "SAM_LDB": samdb_url, "DNS_KEYTAB": dns_keytab_path, "DNSPASS_B64": b64encode(dnspass), }) @@ -738,6 +795,7 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) + secrets_ldb.transaction_start() secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) if credentials is not None and credentials.authentication_requested(): @@ -873,9 +931,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, :note: This will wipe the main SAM database file! """ - domainFunctionality = DS_DOMAIN_FUNCTION_2000 - forestFunctionality = DS_DOMAIN_FUNCTION_2000 - domainControllerFunctionality = DS_DC_FUNCTION_2008_R2 + # Do NOT change these default values without discussion with the team and reslease manager. + domainFunctionality = DS_DOMAIN_FUNCTION_2008 + forestFunctionality = DS_DOMAIN_FUNCTION_2008 + domainControllerFunctionality = DS_DC_FUNCTION_2008 # Also wipes the database setup_samdb_partitions(path, setup_path, message=message, lp=lp, @@ -1275,16 +1334,18 @@ def provision(setup_dir, message, session_info, # Only make a zone file on the first DC, it should be replicated with DNS replication if serverrole == "domain controller": - secrets_ldb = Ldb(paths.secrets, session_info=session_info, - credentials=credentials, lp=lp) - secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, + secretsdb_self_join(secrets_ldb, domain=domain, realm=names.realm, + dnsdomain=names.dnsdomain, netbiosname=names.netbiosname, domainsid=domainsid, - keytab_path=paths.keytab, samdb_url=paths.samdb, + machinepass=machinepass, + secure_channel_type=SEC_CHAN_BDC) + + secretsdb_setup_dns(secrets_ldb, setup_path, + realm=names.realm, dnsdomain=names.dnsdomain, dns_keytab_path=paths.dns_keytab, - dnspass=dnspass, machinepass=machinepass, - dnsdomain=names.dnsdomain) + dnspass=dnspass) domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") assert isinstance(domainguid, str) @@ -1309,6 +1370,8 @@ def provision(setup_dir, message, session_info, realm=names.realm) message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf) + #Now commit the secrets.ldb to disk + secrets_ldb.transaction_commit() if provision_backend is not None: if ldap_backend_type == "fedora-ds": diff --git a/source4/scripting/python/samba/samdb.py b/source4/scripting/python/samba/samdb.py index 239dd6a6ea..39cf1d6c40 100644 --- a/source4/scripting/python/samba/samdb.py +++ b/source4/scripting/python/samba/samdb.py @@ -202,8 +202,8 @@ userPassword:: %s self.transaction_start() try: res = self.search(base=self.domain_dn(), scope=ldb.SCOPE_SUBTREE, - expression=filter, - attrs=["userAccountControl", "accountExpires"]) + expression=filter, + attrs=["userAccountControl", "accountExpires"]) assert(len(res) == 1) user_dn = res[0].dn diff --git a/source4/setup/domainlevel b/source4/setup/domainlevel index b49150ff2d..ceab735c8f 100755 --- a/source4/setup/domainlevel +++ b/source4/setup/domainlevel @@ -39,6 +39,7 @@ parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) +parser.add_option("-H", help="LDB URL for database or target server", type=str) parser.add_option("--quiet", help="Be quiet", action="store_true") parser.add_option("--forest", help="The forest function level (2000 | 2003 | 2008 | 2008_R2). We don't support the 2003 with mixed domains (NT4 DC support) level.", type=str) @@ -60,8 +61,12 @@ if len(args) == 0: lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) -samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), - credentials=creds, lp=lp) +if opts.H is not None: + url = opts.H +else: + url = lp.get("sam database") + +samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) domain_dn = SamDB.domain_dn(samdb) diff --git a/source4/setup/enableaccount b/source4/setup/enableaccount index 0ca5b39faa..f8f727c1ee 100755 --- a/source4/setup/enableaccount +++ b/source4/setup/enableaccount @@ -36,6 +36,7 @@ parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) +parser.add_option("-H", help="LDB URL for database or target server", type=str) parser.add_option("--filter", help="LDAP Filter to set password on", type=str) opts, args = parser.parse_args() @@ -54,6 +55,11 @@ if filter is None: lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) -samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), - credentials=creds, lp=lp) +if opts.H is not None: + url = opts.H +else: + url = lp.get("sam database") + +samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) + samdb.enable_account(filter) diff --git a/source4/setup/newuser b/source4/setup/newuser index 10af55a458..ef65d36dfb 100755 --- a/source4/setup/newuser +++ b/source4/setup/newuser @@ -37,6 +37,7 @@ parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) +parser.add_option("-H", help="LDB URL for database or target server", type=str) parser.add_option("--unixname", help="Unix Username", type=str) parser.add_option("--must-change-at-next-login", help="Force password to be changed on next login", action="store_true") @@ -58,6 +59,11 @@ if opts.unixname is None: lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) -samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), - credentials=creds, lp=lp) +if opts.H is not None: + url = opts.H +else: + url = lp.get("sam database") + +samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) + samdb.newuser(username, opts.unixname, password, force_password_change_at_next_login_req=opts.must_change_at_next_login) diff --git a/source4/setup/pwsettings b/source4/setup/pwsettings index 6a5e18ef59..0bb39d9757 100755 --- a/source4/setup/pwsettings +++ b/source4/setup/pwsettings @@ -39,6 +39,7 @@ parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) +parser.add_option("-H", help="LDB URL for database or target server", type=str) parser.add_option("--quiet", help="Be quiet", action="store_true") parser.add_option("--complexity", help="The password complexity (on | off | default). Default is 'on'", type=str) @@ -67,8 +68,12 @@ if len(args) == 0: lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) -samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), - credentials=creds, lp=lp) +if opts.H is not None: + url = opts.H +else: + url = lp.get("sam database") + +samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) domain_dn = SamDB.domain_dn(samdb) res = samdb.search(domain_dn, scope=ldb.SCOPE_BASE, diff --git a/source4/setup/secrets_dc.ldif b/source4/setup/secrets_dc.ldif deleted file mode 100644 index b8251eece5..0000000000 --- a/source4/setup/secrets_dc.ldif +++ /dev/null @@ -1,24 +0,0 @@ -dn: flatname=${DOMAIN},CN=Primary Domains -objectClass: top -objectClass: primaryDomain -objectClass: kerberosSecret -flatname: ${DOMAIN} -realm: ${REALM} -secret:: ${MACHINEPASS_B64} -secureChannelType: 6 -sAMAccountName: ${NETBIOSNAME}$ -msDS-KeyVersionNumber: 1 -objectSid: ${DOMAINSID} -privateKeytab: ${SECRETS_KEYTAB} - -#Update a keytab for the external DNS server to use -dn: servicePrincipalName=DNS/${DNSDOMAIN},CN=Principals -objectClass: top -objectClass: secret -objectClass: kerberosSecret -realm: ${REALM} -servicePrincipalName: DNS/${DNSDOMAIN} -msDS-KeyVersionNumber: 1 -privateKeytab: ${DNS_KEYTAB} -secret:: ${DNSPASS_B64} - diff --git a/source4/setup/secrets_dns.ldif b/source4/setup/secrets_dns.ldif new file mode 100644 index 0000000000..8a19733d19 --- /dev/null +++ b/source4/setup/secrets_dns.ldif @@ -0,0 +1,11 @@ +#Update a keytab for the external DNS server to use +dn: servicePrincipalName=DNS/${DNSDOMAIN},CN=Principals +objectClass: top +objectClass: secret +objectClass: kerberosSecret +realm: ${REALM} +servicePrincipalName: DNS/${DNSDOMAIN} +msDS-KeyVersionNumber: 1 +privateKeytab: ${DNS_KEYTAB} +secret:: ${DNSPASS_B64} + diff --git a/source4/setup/secrets_self_join.ldif b/source4/setup/secrets_self_join.ldif new file mode 100644 index 0000000000..22be0cab0b --- /dev/null +++ b/source4/setup/secrets_self_join.ldif @@ -0,0 +1,13 @@ +dn: flatname=${DOMAIN},CN=Primary Domains +objectClass: top +objectClass: primaryDomain +objectClass: kerberosSecret +flatname: ${DOMAIN} +realm: ${REALM} +secret:: ${MACHINEPASS_B64} +secureChannelType: 6 +sAMAccountName: ${NETBIOSNAME}$ +msDS-KeyVersionNumber: ${KEY_VERSION_NUMBER} +objectSid: ${DOMAINSID} +privateKeytab: ${SECRETS_KEYTAB} +saltPrincipal: ${SALT_PRINCIPAL} diff --git a/source4/setup/setexpiry b/source4/setup/setexpiry index 1572555b8c..2740326f2b 100755 --- a/source4/setup/setexpiry +++ b/source4/setup/setexpiry @@ -37,12 +37,15 @@ parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) +parser.add_option("-H", help="LDB URL for database or target server", type=str) parser.add_option("--filter", help="LDAP Filter to set password on", type=str) parser.add_option("--days", help="Days to expiry", type=int) parser.add_option("--noexpiry", help="Password does never expire", action="store_true") opts, args = parser.parse_args() +filter = opts.filter + if (len(args) == 0) and (filter is None): print "Either the username or '--filter' must be specified!" parser.print_usage() @@ -59,6 +62,11 @@ if filter is None: lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) -samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), - credentials=creds, lp=lp) +if opts.H is not None: + url = opts.H +else: + url = lp.get("sam database") + +samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) + samdb.setexpiry(filter, days*24*3600, no_expiry_req=opts.noexpiry) diff --git a/source4/setup/setpassword b/source4/setup/setpassword index d8a2a1144a..57772be7a7 100755 --- a/source4/setup/setpassword +++ b/source4/setup/setpassword @@ -38,6 +38,7 @@ parser.add_option_group(sambaopts) parser.add_option_group(options.VersionOptions(parser)) credopts = options.CredentialsOptions(parser) parser.add_option_group(credopts) +parser.add_option("-H", help="LDB URL for database or target server", type=str) parser.add_option("--filter", help="LDAP Filter to set password on", type=str) parser.add_option("--newpassword", help="Set password", type=str) parser.add_option("--must-change-at-next-login", help="Force password to be changed on next login", action="store_true") @@ -62,7 +63,12 @@ if filter is None: lp = sambaopts.get_loadparm() creds = credopts.get_credentials(lp) -samdb = SamDB(url=lp.get("sam database"), session_info=system_session(), - credentials=creds, lp=lp) -samdb.setpassword(filter, password, force_password_change_at_next_login=opts.must_change_at_next_login) +if opts.H is not None: + url = opts.H +else: + url = lp.get("sam database") + +samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp) + +samdb.setpassword(filter, password, force_password_change_at_next_login_req=opts.must_change_at_next_login) |