diff options
author | Günther Deschner <gd@samba.org> | 2021-02-05 13:05:45 +0100 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2021-07-14 16:49:30 +0000 |
commit | 3c8254a2faf5c95fcdb08ad14ded38e284e5d6af (patch) | |
tree | 90183989136de265b64e1c2ac88fc921eeb34b1e /source3/lib/netapi | |
parent | 962c803947ce52c8950677af1abc8920b1d1bb28 (diff) | |
download | samba-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.c | 183 |
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; } |