s3-pdb: Make ADS-type backends updates secrets.tdb.
[ira/wip.git] / source3 / passdb / pdb_ipa.c
index f118e6e49ef132f7545c430dde8c9681225e067e..74ac6774a47369a9ec25cdef7b57ae972b701c95 100644 (file)
 #include "libcli/security/dom_sid.h"
 #include "../librpc/ndr/libndr.h"
 #include "librpc/gen_ndr/samr.h"
+#include "secrets.h"
 
 #include "smbldap.h"
+#include "passdb/pdb_ldap.h"
+#include "passdb/pdb_ipa.h"
+#include "passdb/pdb_ldap_schema.h"
 
 #define IPA_KEYTAB_SET_OID "2.16.840.1.113730.3.8.3.1"
 #define IPA_MAGIC_ID_STR "999"
@@ -34,6 +38,8 @@
 #define LDAP_ATTRIBUTE_TRUST_TYPE "sambaTrustType"
 #define LDAP_ATTRIBUTE_TRUST_ATTRIBUTES "sambaTrustAttributes"
 #define LDAP_ATTRIBUTE_TRUST_DIRECTION "sambaTrustDirection"
+#define LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET "sambaTrustPosixOffset"
+#define LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE "sambaSupportedEncryptionTypes"
 #define LDAP_ATTRIBUTE_TRUST_PARTNER "sambaTrustPartner"
 #define LDAP_ATTRIBUTE_FLAT_NAME "sambaFlatName"
 #define LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING "sambaTrustAuthOutgoing"
@@ -363,6 +369,29 @@ static bool fill_pdb_trusted_domain(TALLOC_CTX *mem_ctx,
                return false;
        }
 
+       td->trust_posix_offset = talloc(td, uint32_t);
+       if (td->trust_posix_offset == NULL) {
+               return false;
+       }
+       res = get_uint32_t_from_ldap_msg(ldap_state, entry,
+                                        LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET,
+                                        td->trust_posix_offset);
+       if (!res) {
+               return false;
+       }
+
+       td->supported_enc_type = talloc(td, uint32_t);
+       if (td->supported_enc_type == NULL) {
+               return false;
+       }
+       res = get_uint32_t_from_ldap_msg(ldap_state, entry,
+                                        LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE,
+                                        td->supported_enc_type);
+       if (!res) {
+               return false;
+       }
+
+
        get_data_blob_from_ldap_msg(td, ldap_state, entry,
                                    LDAP_ATTRIBUTE_TRUST_FOREST_TRUST_INFO,
                                    &td->trust_forest_trust_info);
@@ -519,6 +548,26 @@ static NTSTATUS ipasam_set_trusted_domain(struct pdb_methods *methods,
                }
        }
 
+       if (td->trust_posix_offset != NULL) {
+               res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
+                                               &mods,
+                                               LDAP_ATTRIBUTE_TRUST_POSIX_OFFSET,
+                                               *td->trust_posix_offset);
+               if (!res) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+       }
+
+       if (td->supported_enc_type != NULL) {
+               res = smbldap_make_mod_uint32_t(priv2ld(ldap_state), entry,
+                                               &mods,
+                                               LDAP_ATTRIBUTE_SUPPORTED_ENC_TYPE,
+                                               *td->supported_enc_type);
+               if (!res) {
+                       return NT_STATUS_UNSUCCESSFUL;
+               }
+       }
+
        if (td->trust_auth_outgoing.data != NULL) {
                smbldap_make_mod_blob(priv2ld(ldap_state), entry, &mods,
                                      LDAP_ATTRIBUTE_TRUST_AUTH_OUTGOING,
@@ -636,7 +685,7 @@ static NTSTATUS ipasam_enum_trusted_domains(struct pdb_methods *methods,
        }
 
        *num_domains = 0;
-       if (!(*domains = TALLOC_ARRAY(mem_ctx, struct pdb_trusted_domain *, 1))) {
+       if (!(*domains = talloc_array(mem_ctx, struct pdb_trusted_domain *, 1))) {
                DEBUG(1, ("talloc failed\n"));
                return NT_STATUS_NO_MEMORY;
        }
@@ -684,7 +733,7 @@ static NTSTATUS ipasam_enum_trusteddoms(struct pdb_methods *methods,
                return NT_STATUS_OK;
        }
 
-       if (!(*domains = TALLOC_ARRAY(mem_ctx, struct trustdom_info *,
+       if (!(*domains = talloc_array(mem_ctx, struct trustdom_info *,
                                      *num_domains))) {
                DEBUG(1, ("talloc failed\n"));
                return NT_STATUS_NO_MEMORY;
@@ -693,7 +742,7 @@ static NTSTATUS ipasam_enum_trusteddoms(struct pdb_methods *methods,
        for (i = 0; i < *num_domains; i++) {
                struct trustdom_info *dom_info;
 
-               dom_info = TALLOC_P(*domains, struct trustdom_info);
+               dom_info = talloc(*domains, struct trustdom_info);
                if (dom_info == NULL) {
                        DEBUG(1, ("talloc failed\n"));
                        return NT_STATUS_NO_MEMORY;
@@ -717,9 +766,11 @@ static struct pdb_domain_info *pdb_ipasam_get_domain_info(struct pdb_methods *pd
                                                          TALLOC_CTX *mem_ctx)
 {
        struct pdb_domain_info *info;
-       NTSTATUS status;
        struct ldapsam_privates *ldap_state =
                        (struct ldapsam_privates *)pdb_methods->private_data;
+       char sid_buf[24];
+       DATA_BLOB sid_blob;
+       NTSTATUS status;
 
        info = talloc(mem_ctx, struct pdb_domain_info);
        if (info == NULL) {
@@ -738,9 +789,27 @@ static struct pdb_domain_info *pdb_ipasam_get_domain_info(struct pdb_methods *pd
        }
        strlower_m(info->dns_domain);
        info->dns_forest = talloc_strdup(info, info->dns_domain);
+
+       /* we expect a domain SID to have 4 sub IDs */
+       if (ldap_state->domain_sid.num_auths != 4) {
+               goto fail;
+       }
+
        sid_copy(&info->sid, &ldap_state->domain_sid);
 
-       status = GUID_from_string("testguid", &info->guid);
+       if (!sid_linearize(sid_buf, sizeof(sid_buf), &info->sid)) {
+               goto fail;
+       }
+
+       /* the first 8 bytes of the linearized SID are not random,
+        * so we skip them */
+       sid_blob.data = (uint8_t *) sid_buf + 8 ;
+       sid_blob.length = 16;
+
+       status = GUID_from_ndr_blob(&sid_blob, &info->guid);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto fail;
+       }
 
        return info;
 
@@ -973,7 +1042,6 @@ static NTSTATUS ipasam_add_posix_account_objectclass(struct ldapsam_privates *ld
 {
        int ret;
        LDAPMod **mods = NULL;
-       NTSTATUS status;
 
        smbldap_set_mod(&mods, LDAP_MOD_ADD,
                        "objectclass", "posixAccount");
@@ -995,7 +1063,7 @@ static NTSTATUS ipasam_add_posix_account_objectclass(struct ldapsam_privates *ld
        if (ret != LDAP_SUCCESS) {
                DEBUG(1, ("failed to modify/add user with uid = %s (dn = %s)\n",
                          username, dn));
-               return status;
+               return NT_STATUS_LDAP(ret);
        }
 
        return NT_STATUS_OK;
@@ -1007,7 +1075,6 @@ static NTSTATUS ipasam_add_ipa_group_objectclasses(struct ldapsam_privates *ldap
                                                   uint32_t has_objectclass)
 {
        LDAPMod **mods = NULL;
-       NTSTATUS status;
        int ret;
 
        if (!(has_objectclass & HAS_GROUPOFNAMES)) {
@@ -1051,7 +1118,7 @@ static NTSTATUS ipasam_add_ipa_group_objectclasses(struct ldapsam_privates *ldap
        if (ret != LDAP_SUCCESS) {
                DEBUG(1, ("failed to modify/add group %s (dn = %s)\n",
                          name, dn));
-               return status;
+               return NT_STATUS_LDAP(ret);
        }
 
        return NT_STATUS_OK;
@@ -1064,7 +1131,6 @@ static NTSTATUS ipasam_add_ipa_objectclasses(struct ldapsam_privates *ldap_state
                                             uint32_t has_objectclass)
 {
        LDAPMod **mods = NULL;
-       NTSTATUS status;
        int ret;
        char *princ;
 
@@ -1081,7 +1147,7 @@ static NTSTATUS ipasam_add_ipa_objectclasses(struct ldapsam_privates *ldap_state
                smbldap_set_mod(&mods, LDAP_MOD_ADD, LDAP_ATTRIBUTE_KRB_PRINCIPAL, princ);
        }
 
-       if (!(has_objectclass & HAS_KRB_PRINCIPAL_AUX)); {
+       if (!(has_objectclass & HAS_KRB_PRINCIPAL_AUX)) {
                smbldap_set_mod(&mods, LDAP_MOD_ADD,
                                LDAP_ATTRIBUTE_OBJECTCLASS,
                                LDAP_OBJ_KRB_PRINCIPAL_AUX);
@@ -1128,7 +1194,7 @@ static NTSTATUS ipasam_add_ipa_objectclasses(struct ldapsam_privates *ldap_state
                if (ret != LDAP_SUCCESS) {
                        DEBUG(1, ("failed to modify/add user with uid = %s (dn = %s)\n",
                                  name, dn));
-                       return status;
+                       return NT_STATUS_LDAP(ret);
                }
        }
 
@@ -1341,6 +1407,42 @@ static NTSTATUS ipasam_create_user(struct pdb_methods *pdb_methods,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS pdb_ipa_init_secrets(struct pdb_methods *m)
+{
+#if _SAMBA_BUILD_ == 4
+       struct pdb_domain_info *dom_info;
+       bool ret;
+
+       dom_info = pdb_ipasam_get_domain_info(m, m);
+       if (!dom_info) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+
+       secrets_clear_domain_protection(dom_info->name);
+       ret = secrets_store_domain_sid(dom_info->name,
+                                      &dom_info->sid);
+       if (!ret) {
+               goto done;
+       }
+       ret = secrets_store_domain_guid(dom_info->name,
+                                       &dom_info->guid);
+       if (!ret) {
+               goto done;
+       }
+       ret = secrets_mark_domain_protected(dom_info->name);
+       if (!ret) {
+               goto done;
+       }
+
+done:
+       TALLOC_FREE(dom_info);
+       if (!ret) {
+               return NT_STATUS_UNSUCCESSFUL;
+       }
+#endif
+       return NT_STATUS_OK;
+}
+
 static NTSTATUS pdb_init_IPA_ldapsam(struct pdb_methods **pdb_method, const char *location)
 {
        struct ldapsam_privates *ldap_state;
@@ -1392,6 +1494,12 @@ static NTSTATUS pdb_init_IPA_ldapsam(struct pdb_methods **pdb_method, const char
        (*pdb_method)->del_trusted_domain = ipasam_del_trusted_domain;
        (*pdb_method)->enum_trusted_domains = ipasam_enum_trusted_domains;
 
+       status = pdb_ipa_init_secrets(*pdb_method);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10, ("pdb_ipa_init_secrets failed!\n"));
+               return status;
+       }
+
        return NT_STATUS_OK;
 }