summaryrefslogtreecommitdiff
path: root/source3/lib/netapi
diff options
context:
space:
mode:
authorGünther Deschner <gd@samba.org>2021-02-05 13:05:45 +0100
committerGünther Deschner <gd@samba.org>2021-07-14 16:49:30 +0000
commit3c8254a2faf5c95fcdb08ad14ded38e284e5d6af (patch)
tree90183989136de265b64e1c2ac88fc921eeb34b1e /source3/lib/netapi
parent962c803947ce52c8950677af1abc8920b1d1bb28 (diff)
downloadsamba-3c8254a2faf5c95fcdb08ad14ded38e284e5d6af.tar.gz
s3-libnetapi: implement NetProvisionComputerAccount_l
Guenther Signed-off-by: Guenther Deschner <gd@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org>
Diffstat (limited to 'source3/lib/netapi')
-rw-r--r--source3/lib/netapi/joindomain.c183
1 files changed, 181 insertions, 2 deletions
diff --git a/source3/lib/netapi/joindomain.c b/source3/lib/netapi/joindomain.c
index 27cb84d01a9..dc873c194ad 100644
--- a/source3/lib/netapi/joindomain.c
+++ b/source3/lib/netapi/joindomain.c
@@ -30,6 +30,9 @@
#include "rpc_client/cli_pipe.h"
#include "secrets.h"
#include "libsmb/dsgetdcname.h"
+#include "../librpc/gen_ndr/ndr_ODJ.h"
+#include "lib/util/base64.h"
+#include "libnet/libnet_join_offline.h"
/****************************************************************
****************************************************************/
@@ -596,14 +599,190 @@ WERROR NetRenameMachineInDomain_l(struct libnetapi_ctx *ctx,
WERROR NetProvisionComputerAccount_r(struct libnetapi_ctx *ctx,
struct NetProvisionComputerAccount *r)
{
- return WERR_NOT_SUPPORTED;
+ return NetProvisionComputerAccount_l(ctx, r);
}
/****************************************************************
****************************************************************/
+static WERROR NetProvisionComputerAccount_backend(struct libnetapi_ctx *ctx,
+ struct NetProvisionComputerAccount *r,
+ TALLOC_CTX *mem_ctx,
+ struct ODJ_PROVISION_DATA **p)
+{
+ WERROR werr;
+ struct libnet_JoinCtx *j = NULL;
+ int use_kerberos = 0;
+ const char *username = NULL;
+
+ werr = libnet_init_JoinCtx(mem_ctx, &j);
+ if (!W_ERROR_IS_OK(werr)) {
+ return werr;
+ }
+
+ j->in.domain_name = talloc_strdup(j, r->in.domain);
+ if (j->in.domain_name == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ talloc_free(discard_const_p(char *, j->in.machine_name));
+ j->in.machine_name = talloc_strdup(j, r->in.machine_name);
+ if (j->in.machine_name == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ if (r->in.dcname) {
+ j->in.dc_name = talloc_strdup(j, r->in.dcname);
+ if (j->in.dc_name == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ if (r->in.machine_account_ou) {
+ j->in.account_ou = talloc_strdup(j, r->in.machine_account_ou);
+ if (j->in.account_ou == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ libnetapi_get_username(ctx, &username);
+ if (username == NULL) {
+ talloc_free(j);
+ return WERR_NERR_BADUSERNAME;
+ }
+
+ j->in.admin_account = talloc_strdup(j, username);
+ if (j->in.admin_account == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+
+ libnetapi_get_use_kerberos(ctx, &use_kerberos);
+ if (!use_kerberos) {
+ const char *password = NULL;
+
+ libnetapi_get_password(ctx, &password);
+ if (password == NULL) {
+ talloc_free(j);
+ return WERR_NERR_BADPASSWORD;
+ }
+ j->in.admin_password = talloc_strdup(j, password);
+ if (j->in.admin_password == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ j->in.use_kerberos = use_kerberos;
+ j->in.debug = true;
+ j->in.join_flags = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
+ WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
+
+ if (r->in.options & NETSETUP_PROVISION_REUSE_ACCOUNT) {
+ j->in.join_flags |= WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
+ }
+
+ if (r->in.options & NETSETUP_PROVISION_USE_DEFAULT_PASSWORD) {
+ j->in.join_flags |= WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
+ j->in.machine_password = talloc_strdup(j, r->in.machine_name);
+ if (j->in.machine_password == NULL) {
+ talloc_free(j);
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ j->in.provision_computer_account_only = true;
+
+ werr = libnet_Join(mem_ctx, j);
+ if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
+ libnetapi_set_error_string(ctx, "%s", j->out.error_string);
+ talloc_free(j);
+ return werr;
+ }
+
+ werr = libnet_odj_compose_ODJ_PROVISION_DATA(mem_ctx, j, p);
+ if (!W_ERROR_IS_OK(werr)) {
+ talloc_free(j);
+ return werr;
+ }
+
+ TALLOC_FREE(j);
+
+ return WERR_OK;
+}
+
WERROR NetProvisionComputerAccount_l(struct libnetapi_ctx *ctx,
struct NetProvisionComputerAccount *r)
{
- return WERR_NOT_SUPPORTED;
+ WERROR werr;
+ enum ndr_err_code ndr_err;
+ const char *b64_bin_data_str;
+ DATA_BLOB blob;
+ struct ODJ_PROVISION_DATA_serialized_ptr odj_provision_data;
+ struct ODJ_PROVISION_DATA *p;
+ TALLOC_CTX *mem_ctx = talloc_new(ctx);
+
+ if (r->in.provision_bin_data == NULL &&
+ r->in.provision_text_data == NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+ if (r->in.provision_bin_data != NULL &&
+ r->in.provision_text_data != NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+ if (r->in.provision_bin_data == NULL &&
+ r->in.provision_bin_data_size != NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+ if (r->in.provision_bin_data != NULL &&
+ r->in.provision_bin_data_size == NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+
+ if (r->in.domain == NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+
+ if (r->in.machine_name == NULL) {
+ return WERR_INVALID_PARAMETER;
+ }
+
+ werr = NetProvisionComputerAccount_backend(ctx, r, mem_ctx, &p);
+ if (!W_ERROR_IS_OK(werr)) {
+ talloc_free(mem_ctx);
+ return werr;
+ }
+
+ ZERO_STRUCT(odj_provision_data);
+
+ odj_provision_data.s.p = p;
+
+ ndr_err = ndr_push_struct_blob(&blob, ctx, &odj_provision_data,
+ (ndr_push_flags_fn_t)ndr_push_ODJ_PROVISION_DATA_serialized_ptr);
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ talloc_free(mem_ctx);
+ return W_ERROR(NERR_BadOfflineJoinInfo);
+ }
+
+ talloc_free(mem_ctx);
+
+ if (r->out.provision_text_data != NULL) {
+ b64_bin_data_str = base64_encode_data_blob(ctx, blob);
+ if (b64_bin_data_str == NULL) {
+ return WERR_NOT_ENOUGH_MEMORY;
+ }
+ *r->out.provision_text_data = b64_bin_data_str;
+ }
+
+ if (r->out.provision_bin_data != NULL &&
+ r->out.provision_bin_data_size != NULL) {
+ *r->out.provision_bin_data = blob.data;
+ *r->out.provision_bin_data_size = blob.length;
+ }
+
+ return werr;
}