^samba.tests.dckeytab.samba.tests.dckeytab.DCKeytabTests.test_export_keytab_gmsa
^samba.tests.blackbox.gmsa.samba.tests.blackbox.gmsa.GMSABlackboxTest.test_gmsa_password_access
-^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_gmsa_can_authenticate_to_ldap_with_kerberos\(ad_dc:local\)$
-^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_gmsa_can_authenticate_to_ldap_without_kerberos\(ad_dc:local\)$
-^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_gmsa_can_perform_as_req_with_aes256\(ad_dc:local\)$
-^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_gmsa_can_perform_as_req_with_rc4\(ad_dc:local\)$
-^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_gmsa_can_perform_gensec_logon\(ad_dc:local\)$
-^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_gmsa_can_perform_netlogon\(ad_dc:local\)$
^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_retrieved_password\(ad_dc:local\)$
^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_retrieved_password_allowed\(ad_dc:local\)$
-^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_retrieved_password_denied\(ad_dc:local\)$
^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_retrieved_password_during_clock_skew_window_when_current_key_is_expired\(ad_dc:local\)$
^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_retrieved_password_during_clock_skew_window_when_current_key_is_valid\(ad_dc:local\)$
^samba.tests.krb5.gmsa_tests.samba.tests.krb5.gmsa_tests.GmsaTests.test_retrieved_password_during_clock_skew_window_when_next_key_is_expired\(ad_dc:local\)$
*/
#include "includes.h"
+#include "ldb.h"
+#include "ldb_errors.h"
#include "libcli/ldap/ldap_ndr.h"
#include "ldb_module.h"
#include "auth/auth.h"
+#include "dsdb/gmsa/util.h"
#include "dsdb/samdb/samdb.h"
#include "dsdb/samdb/ldb_modules/util.h"
#include "dsdb/samdb/ldb_modules/ridalloc.h"
#include "libcli/security/security.h"
+#include "librpc/gen_ndr/security.h"
#include "librpc/gen_ndr/ndr_security.h"
#include "ldb_wrap.h"
#include "param/param.h"
#include "libds/common/flag_mapping.h"
#include "system/network.h"
#include "librpc/gen_ndr/irpc.h"
+#include "lib/crypto/gmsa.h"
+#include "lib/util/data_blob.h"
#include "lib/util/smb_strtox.h"
+#include "lib/util/time.h"
#undef strcasecmp
/* used in "samldb_find_for_defaultObjectCategory" */
struct ldb_dn *dn, *res_dn;
+ /* the SID to be assigned to the resulting account */
+ const struct dom_sid *sid;
+
/* all the async steps necessary to complete the operation */
struct samldb_step *steps;
struct samldb_step *curstep;
return ldb_operr(ldb);
}
+ ac->sid = sid;
+
return samldb_next_step(ac);
}
return samldb_next_step(ac);
}
+static int samldb_gmsa_add(struct samldb_ctx *ac)
+{
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+ int ret = LDB_SUCCESS;
+ NTTIME current_time = 0;
+ const bool userPassword = dsdb_user_password_support(ac->module,
+ ac->msg,
+ ac->req);
+ bool ok;
+
+ ok = dsdb_gmsa_current_time(ldb, ¤t_time);
+ if (!ok) {
+ ret = ldb_operr(ldb);
+ goto out;
+ }
+
+ /* Remove any user‐specified passwords. */
+ dsdb_remove_password_related_attrs(ac->msg, userPassword);
+
+ /* Remove any user‐specified password IDs. */
+ ldb_msg_remove_attr(ac->msg, "msDS-ManagedPasswordId");
+ ldb_msg_remove_attr(ac->msg, "msDS-ManagedPasswordPreviousId");
+
+ {
+ DATA_BLOB pwd_id_blob = {};
+ DATA_BLOB password_blob = {};
+ struct gmsa_null_terminated_password *password = NULL;
+
+ /*
+ * The account must have a SID allocated for us to be able to
+ * derive its password.
+ */
+ if (ac->sid == NULL) {
+ ret = ldb_operr(ldb);
+ goto out;
+ }
+
+ /* Calculate the password and ID blobs. */
+ ret = gmsa_generate_blobs(ldb,
+ ac->msg,
+ current_time,
+ ac->sid,
+ &pwd_id_blob,
+ &password);
+ if (ret) {
+ goto out;
+ }
+
+ password_blob = (DATA_BLOB){.data = password->buf,
+ .length = GMSA_PASSWORD_LEN};
+
+ /* Add the new password blob. */
+ ret = ldb_msg_append_steal_value(ac->msg,
+ "clearTextPassword",
+ &password_blob,
+ 0);
+ if (ret) {
+ goto out;
+ }
+
+ /* Add the new password ID blob. */
+ ret = ldb_msg_append_steal_value(ac->msg,
+ "msDS-ManagedPasswordId",
+ &pwd_id_blob,
+ 0);
+ if (ret) {
+ goto out;
+ }
+ }
+
+ ret = samldb_next_step(ac);
+ if (ret) {
+ goto out;
+ }
+
+out:
+ return ret;
+}
+
static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
{
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
if (ret != LDB_SUCCESS) return ret;
}
+ if (dsdb_account_is_gmsa(ldb, ac->msg)) {
+ ret = samldb_add_step(ac, samldb_gmsa_add);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
+ }
+
/* check if we have a valid sAMAccountName */
ret = samldb_add_step(ac, samldb_check_sAMAccountName);
if (ret != LDB_SUCCESS) return ret;