LCOV - code coverage report
Current view: top level - source3/lib/netapi - joindomain.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 191 604 31.6 %
Date: 2024-01-11 09:59:51 Functions: 7 19 36.8 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  NetApi Join Support
       4             :  *  Copyright (C) Guenther Deschner 2007-2008
       5             :  *
       6             :  *  This program is free software; you can redistribute it and/or modify
       7             :  *  it under the terms of the GNU General Public License as published by
       8             :  *  the Free Software Foundation; either version 3 of the License, or
       9             :  *  (at your option) any later version.
      10             :  *
      11             :  *  This program is distributed in the hope that it will be useful,
      12             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  *  GNU General Public License for more details.
      15             :  *
      16             :  *  You should have received a copy of the GNU General Public License
      17             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include "includes.h"
      21             : #include "ads.h"
      22             : #include "librpc/gen_ndr/libnetapi.h"
      23             : #include "libcli/auth/libcli_auth.h"
      24             : #include "lib/netapi/netapi.h"
      25             : #include "lib/netapi/netapi_private.h"
      26             : #include "lib/netapi/libnetapi.h"
      27             : #include "librpc/gen_ndr/libnet_join.h"
      28             : #include "libnet/libnet_join.h"
      29             : #include "../librpc/gen_ndr/ndr_wkssvc_c.h"
      30             : #include "rpc_client/cli_pipe.h"
      31             : #include "secrets.h"
      32             : #include "libsmb/dsgetdcname.h"
      33             : #include "../librpc/gen_ndr/ndr_ODJ.h"
      34             : #include "lib/util/base64.h"
      35             : #include "libnet/libnet_join_offline.h"
      36             : #include "libcli/security/dom_sid.h"
      37             : 
      38             : /****************************************************************
      39             : ****************************************************************/
      40             : 
      41           2 : WERROR NetJoinDomain_l(struct libnetapi_ctx *mem_ctx,
      42             :                        struct NetJoinDomain *r)
      43             : {
      44           2 :         struct libnet_JoinCtx *j = NULL;
      45           0 :         struct libnetapi_private_ctx *priv;
      46           0 :         WERROR werr;
      47             : 
      48           2 :         priv = talloc_get_type_abort(mem_ctx->private_data,
      49             :                 struct libnetapi_private_ctx);
      50             : 
      51           2 :         if (!r->in.domain) {
      52           0 :                 return WERR_INVALID_PARAMETER;
      53             :         }
      54             : 
      55           2 :         werr = libnet_init_JoinCtx(mem_ctx, &j);
      56           2 :         W_ERROR_NOT_OK_RETURN(werr);
      57             : 
      58           2 :         j->in.domain_name = talloc_strdup(mem_ctx, r->in.domain);
      59           2 :         W_ERROR_HAVE_NO_MEMORY(j->in.domain_name);
      60             : 
      61           2 :         if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
      62           0 :                 NTSTATUS status;
      63           2 :                 struct netr_DsRGetDCNameInfo *info = NULL;
      64           2 :                 const char *dc = NULL;
      65           2 :                 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
      66             :                                  DS_WRITABLE_REQUIRED |
      67             :                                  DS_RETURN_DNS_NAME;
      68           2 :                 status = dsgetdcname(mem_ctx, priv->msg_ctx, r->in.domain,
      69             :                                      NULL, NULL, flags, &info);
      70           2 :                 if (!NT_STATUS_IS_OK(status)) {
      71           2 :                         libnetapi_set_error_string(mem_ctx,
      72             :                                 "%s", get_friendly_nt_error_msg(status));
      73           2 :                         return ntstatus_to_werror(status);
      74             :                 }
      75             : 
      76           0 :                 dc = strip_hostname(info->dc_unc);
      77           0 :                 j->in.dc_name = talloc_strdup(mem_ctx, dc);
      78           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.dc_name);
      79             :         }
      80             : 
      81           0 :         if (r->in.account_ou) {
      82           0 :                 j->in.account_ou = talloc_strdup(mem_ctx, r->in.account_ou);
      83           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.account_ou);
      84             :         }
      85             : 
      86           0 :         if (r->in.account) {
      87           0 :                 j->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
      88           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.admin_account);
      89             :         }
      90             : 
      91           0 :         if (r->in.password) {
      92           0 :                 j->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
      93           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.admin_password);
      94             :         }
      95             : 
      96           0 :         j->in.join_flags = r->in.join_flags;
      97           0 :         j->in.modify_config = true;
      98           0 :         j->in.debug = true;
      99             : 
     100           0 :         werr = libnet_Join(mem_ctx, j);
     101           0 :         if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
     102           0 :                 libnetapi_set_error_string(mem_ctx, "%s", j->out.error_string);
     103             :         }
     104           0 :         TALLOC_FREE(j);
     105             : 
     106           0 :         return werr;
     107             : }
     108             : 
     109             : /****************************************************************
     110             : ****************************************************************/
     111             : 
     112           0 : WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx,
     113             :                        struct NetJoinDomain *r)
     114             : {
     115           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     116           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     117           0 :         NTSTATUS status;
     118           0 :         WERROR werr;
     119           0 :         unsigned int old_timeout = 0;
     120           0 :         struct dcerpc_binding_handle *b;
     121           0 :         DATA_BLOB session_key;
     122             : 
     123           0 :         if (IS_DC) {
     124           0 :                 return WERR_NERR_SETUPDOMAINCONTROLLER;
     125             :         }
     126             : 
     127           0 :         werr = libnetapi_open_pipe(ctx, r->in.server,
     128             :                                    &ndr_table_wkssvc,
     129             :                                    &pipe_cli);
     130           0 :         if (!W_ERROR_IS_OK(werr)) {
     131           0 :                 goto done;
     132             :         }
     133             : 
     134           0 :         b = pipe_cli->binding_handle;
     135             : 
     136           0 :         if (r->in.password) {
     137             : 
     138           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     139           0 :                 if (!NT_STATUS_IS_OK(status)) {
     140           0 :                         werr = ntstatus_to_werror(status);
     141           0 :                         goto done;
     142             :                 }
     143             : 
     144           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     145             :                                                           r->in.password,
     146             :                                                           &session_key,
     147             :                                                           &encrypted_password);
     148           0 :                 if (!W_ERROR_IS_OK(werr)) {
     149           0 :                         goto done;
     150             :                 }
     151             :         }
     152             : 
     153           0 :         old_timeout = rpccli_set_timeout(pipe_cli, 600000);
     154             : 
     155           0 :         status = dcerpc_wkssvc_NetrJoinDomain2(b, talloc_tos(),
     156             :                                                r->in.server,
     157             :                                                r->in.domain,
     158             :                                                r->in.account_ou,
     159             :                                                r->in.account,
     160             :                                                encrypted_password,
     161             :                                                r->in.join_flags,
     162             :                                                &werr);
     163           0 :         if (!NT_STATUS_IS_OK(status)) {
     164           0 :                 werr = ntstatus_to_werror(status);
     165           0 :                 goto done;
     166             :         }
     167             : 
     168           0 :  done:
     169           0 :         if (pipe_cli && old_timeout) {
     170           0 :                 rpccli_set_timeout(pipe_cli, old_timeout);
     171             :         }
     172             : 
     173           0 :         return werr;
     174             : }
     175             : /****************************************************************
     176             : ****************************************************************/
     177             : 
     178           0 : WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx,
     179             :                          struct NetUnjoinDomain *r)
     180             : {
     181           0 :         struct libnet_UnjoinCtx *u = NULL;
     182           0 :         struct dom_sid domain_sid;
     183           0 :         const char *domain = NULL;
     184           0 :         WERROR werr;
     185           0 :         struct libnetapi_private_ctx *priv;
     186           0 :         const char *realm = lp_realm();
     187             : 
     188           0 :         priv = talloc_get_type_abort(mem_ctx->private_data,
     189             :                 struct libnetapi_private_ctx);
     190             : 
     191           0 :         if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
     192           0 :                 return WERR_NERR_SETUPNOTJOINED;
     193             :         }
     194             : 
     195           0 :         werr = libnet_init_UnjoinCtx(mem_ctx, &u);
     196           0 :         W_ERROR_NOT_OK_RETURN(werr);
     197             : 
     198           0 :         if (realm[0] != '\0') {
     199           0 :                 domain = realm;
     200             :         } else {
     201           0 :                 domain = lp_workgroup();
     202             :         }
     203             : 
     204           0 :         if (r->in.server_name) {
     205           0 :                 u->in.dc_name = talloc_strdup(mem_ctx, r->in.server_name);
     206           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
     207             :         } else {
     208           0 :                 NTSTATUS status;
     209           0 :                 struct netr_DsRGetDCNameInfo *info = NULL;
     210           0 :                 const char *dc = NULL;
     211           0 :                 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
     212             :                                  DS_WRITABLE_REQUIRED |
     213             :                                  DS_RETURN_DNS_NAME;
     214           0 :                 status = dsgetdcname(mem_ctx, priv->msg_ctx, domain,
     215             :                                      NULL, NULL, flags, &info);
     216           0 :                 if (!NT_STATUS_IS_OK(status)) {
     217           0 :                         libnetapi_set_error_string(mem_ctx,
     218             :                                 "failed to find DC for domain %s: %s",
     219             :                                 domain,
     220             :                                 get_friendly_nt_error_msg(status));
     221           0 :                         return ntstatus_to_werror(status);
     222             :                 }
     223             : 
     224           0 :                 dc = strip_hostname(info->dc_unc);
     225           0 :                 u->in.dc_name = talloc_strdup(mem_ctx, dc);
     226           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
     227             : 
     228           0 :                 u->in.domain_name = domain;
     229             :         }
     230             : 
     231           0 :         if (r->in.account) {
     232           0 :                 u->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
     233           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.admin_account);
     234             :         }
     235             : 
     236           0 :         if (r->in.password) {
     237           0 :                 u->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
     238           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.admin_password);
     239             :         }
     240             : 
     241           0 :         u->in.domain_name = domain;
     242           0 :         u->in.unjoin_flags = r->in.unjoin_flags;
     243           0 :         u->in.delete_machine_account = false;
     244           0 :         u->in.modify_config = true;
     245           0 :         u->in.debug = true;
     246             : 
     247           0 :         u->in.domain_sid = &domain_sid;
     248             : 
     249           0 :         werr = libnet_Unjoin(mem_ctx, u);
     250           0 :         if (!W_ERROR_IS_OK(werr) && u->out.error_string) {
     251           0 :                 libnetapi_set_error_string(mem_ctx, "%s", u->out.error_string);
     252             :         }
     253           0 :         TALLOC_FREE(u);
     254             : 
     255           0 :         return werr;
     256             : }
     257             : 
     258             : /****************************************************************
     259             : ****************************************************************/
     260             : 
     261           0 : WERROR NetUnjoinDomain_r(struct libnetapi_ctx *ctx,
     262             :                          struct NetUnjoinDomain *r)
     263             : {
     264           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     265           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     266           0 :         NTSTATUS status;
     267           0 :         WERROR werr;
     268           0 :         unsigned int old_timeout = 0;
     269           0 :         struct dcerpc_binding_handle *b;
     270           0 :         DATA_BLOB session_key;
     271             : 
     272           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     273             :                                    &ndr_table_wkssvc,
     274             :                                    &pipe_cli);
     275           0 :         if (!W_ERROR_IS_OK(werr)) {
     276           0 :                 goto done;
     277             :         }
     278             : 
     279           0 :         b = pipe_cli->binding_handle;
     280             : 
     281           0 :         if (r->in.password) {
     282             : 
     283           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     284           0 :                 if (!NT_STATUS_IS_OK(status)) {
     285           0 :                         werr = ntstatus_to_werror(status);
     286           0 :                         goto done;
     287             :                 }
     288             : 
     289           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     290             :                                                           r->in.password,
     291             :                                                           &session_key,
     292             :                                                           &encrypted_password);
     293           0 :                 if (!W_ERROR_IS_OK(werr)) {
     294           0 :                         goto done;
     295             :                 }
     296             :         }
     297             : 
     298           0 :         old_timeout = rpccli_set_timeout(pipe_cli, 60000);
     299             : 
     300           0 :         status = dcerpc_wkssvc_NetrUnjoinDomain2(b, talloc_tos(),
     301             :                                                  r->in.server_name,
     302             :                                                  r->in.account,
     303             :                                                  encrypted_password,
     304             :                                                  r->in.unjoin_flags,
     305             :                                                  &werr);
     306           0 :         if (!NT_STATUS_IS_OK(status)) {
     307           0 :                 werr = ntstatus_to_werror(status);
     308           0 :                 goto done;
     309             :         }
     310             : 
     311           0 :  done:
     312           0 :         if (pipe_cli && old_timeout) {
     313           0 :                 rpccli_set_timeout(pipe_cli, old_timeout);
     314             :         }
     315             : 
     316           0 :         return werr;
     317             : }
     318             : 
     319             : /****************************************************************
     320             : ****************************************************************/
     321             : 
     322           0 : WERROR NetGetJoinInformation_r(struct libnetapi_ctx *ctx,
     323             :                                struct NetGetJoinInformation *r)
     324             : {
     325           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     326           0 :         NTSTATUS status;
     327           0 :         WERROR werr;
     328           0 :         const char *buffer = NULL;
     329           0 :         struct dcerpc_binding_handle *b;
     330             : 
     331           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     332             :                                    &ndr_table_wkssvc,
     333             :                                    &pipe_cli);
     334           0 :         if (!W_ERROR_IS_OK(werr)) {
     335           0 :                 goto done;
     336             :         }
     337             : 
     338           0 :         b = pipe_cli->binding_handle;
     339             : 
     340           0 :         status = dcerpc_wkssvc_NetrGetJoinInformation(b, talloc_tos(),
     341             :                                                       r->in.server_name,
     342             :                                                       &buffer,
     343           0 :                                                       (enum wkssvc_NetJoinStatus *)r->out.name_type,
     344             :                                                       &werr);
     345           0 :         if (!NT_STATUS_IS_OK(status)) {
     346           0 :                 werr = ntstatus_to_werror(status);
     347           0 :                 goto done;
     348             :         }
     349             : 
     350           0 :         if (!W_ERROR_IS_OK(werr)) {
     351           0 :                 goto done;
     352             :         }
     353             : 
     354           0 :         *r->out.name_buffer = talloc_strdup(ctx, buffer);
     355           0 :         W_ERROR_HAVE_NO_MEMORY(*r->out.name_buffer);
     356             : 
     357           0 :  done:
     358           0 :         return werr;
     359             : }
     360             : 
     361             : /****************************************************************
     362             : ****************************************************************/
     363             : 
     364           0 : WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx,
     365             :                                struct NetGetJoinInformation *r)
     366             : {
     367           0 :         const char *realm = lp_realm();
     368             : 
     369           0 :         if ((lp_security() == SEC_ADS) && realm[0] != '\0') {
     370           0 :                 *r->out.name_buffer = talloc_strdup(ctx, realm);
     371             :         } else {
     372           0 :                 *r->out.name_buffer = talloc_strdup(ctx, lp_workgroup());
     373             :         }
     374           0 :         if (!*r->out.name_buffer) {
     375           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     376             :         }
     377             : 
     378           0 :         switch (lp_server_role()) {
     379           0 :                 case ROLE_DOMAIN_MEMBER:
     380             :                 case ROLE_DOMAIN_PDC:
     381             :                 case ROLE_DOMAIN_BDC:
     382             :                 case ROLE_IPA_DC:
     383           0 :                         *r->out.name_type = NetSetupDomainName;
     384           0 :                         break;
     385           0 :                 case ROLE_STANDALONE:
     386             :                 default:
     387           0 :                         *r->out.name_type = NetSetupWorkgroupName;
     388           0 :                         break;
     389             :         }
     390             : 
     391           0 :         return WERR_OK;
     392             : }
     393             : 
     394             : /****************************************************************
     395             : ****************************************************************/
     396             : 
     397           0 : WERROR NetGetJoinableOUs_l(struct libnetapi_ctx *ctx,
     398             :                            struct NetGetJoinableOUs *r)
     399             : {
     400             : #ifdef HAVE_ADS
     401           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     402           0 :         WERROR ret;
     403           0 :         NTSTATUS status;
     404           0 :         ADS_STATUS ads_status;
     405           0 :         ADS_STRUCT *ads = NULL;
     406           0 :         struct netr_DsRGetDCNameInfo *info = NULL;
     407           0 :         const char *dc = NULL;
     408           0 :         uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
     409             :                          DS_RETURN_DNS_NAME;
     410           0 :         struct libnetapi_private_ctx *priv;
     411           0 :         char **p;
     412           0 :         size_t s;
     413             : 
     414           0 :         priv = talloc_get_type_abort(ctx->private_data,
     415             :                 struct libnetapi_private_ctx);
     416             : 
     417           0 :         status = dsgetdcname(tmp_ctx, priv->msg_ctx, r->in.domain,
     418             :                              NULL, NULL, flags, &info);
     419           0 :         if (!NT_STATUS_IS_OK(status)) {
     420           0 :                 libnetapi_set_error_string(ctx, "%s",
     421             :                         get_friendly_nt_error_msg(status));
     422           0 :                 ret = ntstatus_to_werror(status);
     423           0 :                 goto out;
     424             :         }
     425             : 
     426           0 :         dc = strip_hostname(info->dc_unc);
     427             : 
     428           0 :         ads = ads_init(tmp_ctx,
     429           0 :                        info->domain_name,
     430           0 :                        info->domain_name,
     431             :                        dc,
     432             :                        ADS_SASL_PLAIN);
     433           0 :         if (!ads) {
     434           0 :                 ret = WERR_GEN_FAILURE;
     435           0 :                 goto out;
     436             :         }
     437             : 
     438           0 :         ADS_TALLOC_CONST_FREE(ads->auth.user_name);
     439           0 :         if (r->in.account) {
     440           0 :                 ads->auth.user_name = talloc_strdup(ads, r->in.account);
     441           0 :                 if (ads->auth.user_name == NULL) {
     442           0 :                         ret = WERR_NOT_ENOUGH_MEMORY;
     443           0 :                         goto out;
     444             :                 }
     445             :         } else {
     446           0 :                 const char *username = NULL;
     447             : 
     448           0 :                 libnetapi_get_username(ctx, &username);
     449           0 :                 if (username != NULL) {
     450           0 :                         ads->auth.user_name = talloc_strdup(ads, username);
     451           0 :                         if (ads->auth.user_name == NULL) {
     452           0 :                                 ret = WERR_NOT_ENOUGH_MEMORY;
     453           0 :                                 goto out;
     454             :                         }
     455             :                 }
     456             :         }
     457             : 
     458           0 :         ADS_TALLOC_CONST_FREE(ads->auth.password);
     459           0 :         if (r->in.password) {
     460           0 :                 ads->auth.password = talloc_strdup(ads, r->in.password);
     461           0 :                 if (ads->auth.password == NULL) {
     462           0 :                         ret = WERR_NOT_ENOUGH_MEMORY;
     463           0 :                         goto out;
     464             :                 }
     465             :         } else {
     466           0 :                 const char *password = NULL;
     467             : 
     468           0 :                 libnetapi_get_password(ctx, &password);
     469           0 :                 if (password != NULL) {
     470           0 :                         ads->auth.password = talloc_strdup(ads, password);
     471           0 :                         if (ads->auth.password == NULL) {
     472           0 :                                 ret = WERR_NOT_ENOUGH_MEMORY;
     473           0 :                                 goto out;
     474             :                         }
     475             :                 }
     476             :         }
     477             : 
     478           0 :         ads_status = ads_connect_user_creds(ads);
     479           0 :         if (!ADS_ERR_OK(ads_status)) {
     480           0 :                 ret = WERR_NERR_DEFAULTJOINREQUIRED;
     481           0 :                 goto out;
     482             :         }
     483             : 
     484           0 :         ads_status = ads_get_joinable_ous(ads, ctx, &p, &s);
     485           0 :         if (!ADS_ERR_OK(ads_status)) {
     486           0 :                 ret = WERR_NERR_DEFAULTJOINREQUIRED;
     487           0 :                 goto out;
     488             :         }
     489           0 :         *r->out.ous = discard_const_p(const char *, p);
     490           0 :         *r->out.ou_count = s;
     491             : 
     492           0 :         ret = WERR_OK;
     493           0 : out:
     494           0 :         TALLOC_FREE(tmp_ctx);
     495             : 
     496           0 :         return ret;
     497             : #else
     498           0 :         return WERR_NOT_SUPPORTED;
     499             : #endif
     500             : }
     501             : 
     502             : /****************************************************************
     503             : ****************************************************************/
     504             : 
     505           0 : WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx,
     506             :                            struct NetGetJoinableOUs *r)
     507             : {
     508           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     509           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     510           0 :         NTSTATUS status;
     511           0 :         WERROR werr;
     512           0 :         struct dcerpc_binding_handle *b;
     513           0 :         DATA_BLOB session_key;
     514             : 
     515           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     516             :                                    &ndr_table_wkssvc,
     517             :                                    &pipe_cli);
     518           0 :         if (!W_ERROR_IS_OK(werr)) {
     519           0 :                 goto done;
     520             :         }
     521             : 
     522           0 :         b = pipe_cli->binding_handle;
     523             : 
     524           0 :         if (r->in.password) {
     525             : 
     526           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     527           0 :                 if (!NT_STATUS_IS_OK(status)) {
     528           0 :                         werr = ntstatus_to_werror(status);
     529           0 :                         goto done;
     530             :                 }
     531             : 
     532           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     533             :                                                           r->in.password,
     534             :                                                           &session_key,
     535             :                                                           &encrypted_password);
     536           0 :                 if (!W_ERROR_IS_OK(werr)) {
     537           0 :                         goto done;
     538             :                 }
     539             :         }
     540             : 
     541           0 :         status = dcerpc_wkssvc_NetrGetJoinableOus2(b, talloc_tos(),
     542             :                                                    r->in.server_name,
     543             :                                                    r->in.domain,
     544             :                                                    r->in.account,
     545             :                                                    encrypted_password,
     546             :                                                    r->out.ou_count,
     547             :                                                    r->out.ous,
     548             :                                                    &werr);
     549           0 :         if (!NT_STATUS_IS_OK(status)) {
     550           0 :                 werr = ntstatus_to_werror(status);
     551           0 :                 goto done;
     552             :         }
     553             : 
     554           0 :  done:
     555           0 :         return werr;
     556             : }
     557             : 
     558             : /****************************************************************
     559             : ****************************************************************/
     560             : 
     561           0 : WERROR NetRenameMachineInDomain_r(struct libnetapi_ctx *ctx,
     562             :                                   struct NetRenameMachineInDomain *r)
     563             : {
     564           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     565           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     566           0 :         NTSTATUS status;
     567           0 :         WERROR werr;
     568           0 :         struct dcerpc_binding_handle *b;
     569           0 :         DATA_BLOB session_key;
     570             : 
     571           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     572             :                                    &ndr_table_wkssvc,
     573             :                                    &pipe_cli);
     574           0 :         if (!W_ERROR_IS_OK(werr)) {
     575           0 :                 goto done;
     576             :         }
     577             : 
     578           0 :         b = pipe_cli->binding_handle;
     579             : 
     580           0 :         if (r->in.password) {
     581             : 
     582           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     583           0 :                 if (!NT_STATUS_IS_OK(status)) {
     584           0 :                         werr = ntstatus_to_werror(status);
     585           0 :                         goto done;
     586             :                 }
     587             : 
     588           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     589             :                                                           r->in.password,
     590             :                                                           &session_key,
     591             :                                                           &encrypted_password);
     592           0 :                 if (!W_ERROR_IS_OK(werr)) {
     593           0 :                         goto done;
     594             :                 }
     595             :         }
     596             : 
     597           0 :         status = dcerpc_wkssvc_NetrRenameMachineInDomain2(b, talloc_tos(),
     598             :                                                           r->in.server_name,
     599             :                                                           r->in.new_machine_name,
     600             :                                                           r->in.account,
     601             :                                                           encrypted_password,
     602             :                                                           r->in.rename_options,
     603             :                                                           &werr);
     604           0 :         if (!NT_STATUS_IS_OK(status)) {
     605           0 :                 werr = ntstatus_to_werror(status);
     606           0 :                 goto done;
     607             :         }
     608             : 
     609           0 :  done:
     610           0 :         return werr;
     611             : }
     612             : 
     613             : /****************************************************************
     614             : ****************************************************************/
     615             : 
     616           0 : WERROR NetRenameMachineInDomain_l(struct libnetapi_ctx *ctx,
     617             :                                   struct NetRenameMachineInDomain *r)
     618             : {
     619           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetRenameMachineInDomain);
     620             : }
     621             : 
     622             : /****************************************************************
     623             : ****************************************************************/
     624             : 
     625           0 : WERROR NetProvisionComputerAccount_r(struct libnetapi_ctx *ctx,
     626             :                                      struct NetProvisionComputerAccount *r)
     627             : {
     628           0 :         return NetProvisionComputerAccount_l(ctx, r);
     629             : }
     630             : 
     631             : /****************************************************************
     632             : ****************************************************************/
     633             : 
     634          12 : static WERROR NetProvisionComputerAccount_backend(struct libnetapi_ctx *ctx,
     635             :                                                   struct NetProvisionComputerAccount *r,
     636             :                                                   TALLOC_CTX *mem_ctx,
     637             :                                                   struct ODJ_PROVISION_DATA **p)
     638             : {
     639           0 :         WERROR werr;
     640          12 :         struct libnet_JoinCtx *j = NULL;
     641          12 :         int use_kerberos = 0;
     642          12 :         const char *username = NULL;
     643             : 
     644          12 :         werr = libnet_init_JoinCtx(mem_ctx, &j);
     645          12 :         if (!W_ERROR_IS_OK(werr)) {
     646           0 :                 return werr;
     647             :         }
     648             : 
     649          12 :         j->in.domain_name = talloc_strdup(j, r->in.domain);
     650          12 :         if (j->in.domain_name == NULL) {
     651           0 :                 talloc_free(j);
     652           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     653             :         }
     654             : 
     655          12 :         talloc_free(discard_const_p(char *, j->in.machine_name));
     656          12 :         j->in.machine_name = talloc_strdup(j, r->in.machine_name);
     657          12 :         if (j->in.machine_name == NULL) {
     658           0 :                 talloc_free(j);
     659           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     660             :         }
     661             : 
     662          12 :         if (r->in.dcname) {
     663           4 :                 j->in.dc_name = talloc_strdup(j, r->in.dcname);
     664           4 :                 if (j->in.dc_name == NULL) {
     665           0 :                         talloc_free(j);
     666           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     667             :                 }
     668             :         }
     669             : 
     670          12 :         if (r->in.machine_account_ou) {
     671           0 :                 j->in.account_ou = talloc_strdup(j, r->in.machine_account_ou);
     672           0 :                 if (j->in.account_ou == NULL) {
     673           0 :                         talloc_free(j);
     674           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     675             :                 }
     676             :         }
     677             : 
     678          12 :         libnetapi_get_username(ctx, &username);
     679          12 :         if (username == NULL) {
     680           0 :                 talloc_free(j);
     681           0 :                 return WERR_NERR_BADUSERNAME;
     682             :         }
     683             : 
     684          12 :         j->in.admin_account = talloc_strdup(j, username);
     685          12 :         if (j->in.admin_account == NULL) {
     686           0 :                 talloc_free(j);
     687           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     688             :         }
     689             : 
     690          12 :         libnetapi_get_use_kerberos(ctx, &use_kerberos);
     691          12 :         if (!use_kerberos) {
     692          12 :                 const char *password = NULL;
     693             : 
     694          12 :                 libnetapi_get_password(ctx, &password);
     695          12 :                 if (password == NULL) {
     696           0 :                         talloc_free(j);
     697           0 :                         return WERR_NERR_BADPASSWORD;
     698             :                 }
     699          12 :                 j->in.admin_password = talloc_strdup(j, password);
     700          12 :                 if (j->in.admin_password == NULL) {
     701           0 :                         talloc_free(j);
     702           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     703             :                 }
     704             :         }
     705             : 
     706          12 :         j->in.use_kerberos = use_kerberos;
     707          12 :         j->in.debug = true;
     708          12 :         j->in.join_flags     = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
     709             :                                   WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
     710             : 
     711          12 :         if (r->in.options & NETSETUP_PROVISION_REUSE_ACCOUNT) {
     712           0 :                 j->in.join_flags |= WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
     713             :         }
     714             : 
     715          12 :         if (r->in.options & NETSETUP_PROVISION_USE_DEFAULT_PASSWORD) {
     716           6 :                 j->in.join_flags |= WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
     717           6 :                 j->in.machine_password = talloc_strdup(j, r->in.machine_name);
     718           6 :                 if (j->in.machine_password == NULL) {
     719           0 :                         talloc_free(j);
     720           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     721             :                 }
     722             :         }
     723             : 
     724          12 :         j->in.provision_computer_account_only = true;
     725             : 
     726          12 :         werr = libnet_Join(mem_ctx, j);
     727          12 :         if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
     728           0 :                 libnetapi_set_error_string(ctx, "%s", j->out.error_string);
     729           0 :                 talloc_free(j);
     730           0 :                 return werr;
     731             :         }
     732             : 
     733          12 :         werr = libnet_odj_compose_ODJ_PROVISION_DATA(mem_ctx, j, p);
     734          12 :         if (!W_ERROR_IS_OK(werr)) {
     735           0 :                 talloc_free(j);
     736           0 :                 return werr;
     737             :         }
     738             : 
     739          12 :         TALLOC_FREE(j);
     740             : 
     741          12 :         return WERR_OK;
     742             : }
     743             : 
     744          12 : WERROR NetProvisionComputerAccount_l(struct libnetapi_ctx *ctx,
     745             :                                      struct NetProvisionComputerAccount *r)
     746             : {
     747           0 :         WERROR werr;
     748           0 :         enum ndr_err_code ndr_err;
     749           0 :         const char *b64_bin_data_str;
     750           0 :         DATA_BLOB blob;
     751           0 :         struct ODJ_PROVISION_DATA_serialized_ptr odj_provision_data;
     752           0 :         struct ODJ_PROVISION_DATA *p;
     753          12 :         TALLOC_CTX *mem_ctx = talloc_new(ctx);
     754             : 
     755          12 :         if (r->in.provision_bin_data == NULL &&
     756          12 :             r->in.provision_text_data == NULL) {
     757           0 :                 return WERR_INVALID_PARAMETER;
     758             :         }
     759          12 :         if (r->in.provision_bin_data != NULL &&
     760           0 :             r->in.provision_text_data != NULL) {
     761           0 :                 return WERR_INVALID_PARAMETER;
     762             :         }
     763          12 :         if (r->in.provision_bin_data == NULL &&
     764          12 :             r->in.provision_bin_data_size != NULL) {
     765           0 :                 return WERR_INVALID_PARAMETER;
     766             :         }
     767          12 :         if (r->in.provision_bin_data != NULL &&
     768           0 :            r->in.provision_bin_data_size == NULL) {
     769           0 :                 return WERR_INVALID_PARAMETER;
     770             :         }
     771             : 
     772          12 :         if (r->in.domain == NULL) {
     773           0 :                 return WERR_INVALID_PARAMETER;
     774             :         }
     775             : 
     776          12 :         if (r->in.machine_name == NULL) {
     777           0 :                 return WERR_INVALID_PARAMETER;
     778             :         }
     779             : 
     780          12 :         werr = NetProvisionComputerAccount_backend(ctx, r, mem_ctx, &p);
     781          12 :         if (!W_ERROR_IS_OK(werr)) {
     782           0 :                 talloc_free(mem_ctx);
     783           0 :                 return werr;
     784             :         }
     785             : 
     786          12 :         ZERO_STRUCT(odj_provision_data);
     787             : 
     788          12 :         odj_provision_data.s.p = p;
     789             : 
     790          12 :         ndr_err = ndr_push_struct_blob(&blob, ctx, &odj_provision_data,
     791             :                 (ndr_push_flags_fn_t)ndr_push_ODJ_PROVISION_DATA_serialized_ptr);
     792          12 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     793           0 :                 talloc_free(mem_ctx);
     794           0 :                 return W_ERROR(NERR_BadOfflineJoinInfo);
     795             :         }
     796             : 
     797          12 :         talloc_free(mem_ctx);
     798             : 
     799          12 :         if (r->out.provision_text_data != NULL) {
     800          12 :                 b64_bin_data_str = base64_encode_data_blob(ctx, blob);
     801          12 :                 if (b64_bin_data_str == NULL) {
     802           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     803             :                 }
     804          12 :                 *r->out.provision_text_data = b64_bin_data_str;
     805             :         }
     806             : 
     807          12 :         if (r->out.provision_bin_data != NULL &&
     808           0 :             r->out.provision_bin_data_size != NULL) {
     809           0 :                 *r->out.provision_bin_data = blob.data;
     810           0 :                 *r->out.provision_bin_data_size = blob.length;
     811             :         }
     812             : 
     813          12 :         return werr;
     814             : }
     815             : 
     816             : /****************************************************************
     817             : ****************************************************************/
     818             : 
     819           0 : WERROR NetRequestOfflineDomainJoin_r(struct libnetapi_ctx *ctx,
     820             :                                      struct NetRequestOfflineDomainJoin *r)
     821             : {
     822           0 :         return WERR_NOT_SUPPORTED;
     823             : }
     824             : 
     825             : /****************************************************************
     826             : ****************************************************************/
     827             : 
     828          18 : static WERROR NetRequestOfflineDomainJoin_backend(struct libnetapi_ctx *ctx,
     829             :                                                   const struct ODJ_WIN7BLOB *win7blob,
     830             :                                                   const struct ODJ_PROVISION_DATA *odj_provision_data)
     831             : {
     832          18 :         struct libnet_JoinCtx *j = NULL;
     833           0 :         WERROR werr;
     834             : 
     835          18 :         werr = libnet_init_JoinCtx(ctx, &j);
     836          18 :         if (!W_ERROR_IS_OK(werr)) {
     837           0 :                 return werr;
     838             :         }
     839             : 
     840          18 :         j->in.domain_name = talloc_strdup(j, win7blob->lpDomain);
     841          18 :         if (j->in.domain_name == NULL) {
     842           0 :                 talloc_free(j);
     843           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     844             :         }
     845             : 
     846          18 :         talloc_free(discard_const_p(char *, j->in.machine_name));
     847          18 :         j->in.machine_name = talloc_strdup(j, win7blob->lpMachineName);
     848          18 :         if (j->in.machine_name == NULL) {
     849           0 :                 talloc_free(j);
     850           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     851             :         }
     852             : 
     853          18 :         j->in.machine_password = talloc_strdup(j, win7blob->lpMachinePassword);
     854          18 :         if (j->in.machine_password == NULL) {
     855           0 :                 talloc_free(j);
     856           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     857             :         }
     858             : 
     859          18 :         j->in.request_offline_join = true;
     860          18 :         j->in.odj_provision_data = discard_const(odj_provision_data);
     861          18 :         j->in.debug = true;
     862          18 :         j->in.join_flags     = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
     863             :                                   WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
     864             : 
     865          18 :         werr = libnet_Join(j, j);
     866          18 :         if (!W_ERROR_IS_OK(werr)) {
     867           0 :                 if (j->out.error_string != NULL) {
     868           0 :                         libnetapi_set_error_string(ctx, "%s", j->out.error_string);
     869             :                 }
     870           0 :                 talloc_free(j);
     871           0 :                 return werr;
     872             :         }
     873             : 
     874          18 :         TALLOC_FREE(j);
     875             : 
     876          18 :         return WERR_OK;
     877             : }
     878             : 
     879          18 : WERROR NetRequestOfflineDomainJoin_l(struct libnetapi_ctx *ctx,
     880             :                                      struct NetRequestOfflineDomainJoin *r)
     881             : {
     882           0 :         DATA_BLOB blob, blob_base64;
     883           0 :         enum ndr_err_code ndr_err;
     884           0 :         struct ODJ_PROVISION_DATA_serialized_ptr odj_provision_data;
     885           0 :         bool ok;
     886          18 :         struct ODJ_WIN7BLOB win7blob = { 0 };
     887           0 :         WERROR werr;
     888             : 
     889          18 :         if (r->in.provision_bin_data == NULL ||
     890          18 :             r->in.provision_bin_data_size == 0) {
     891           0 :                 return W_ERROR(NERR_NoOfflineJoinInfo);
     892             :         }
     893             : 
     894          18 :         if (r->in.provision_bin_data_size < 2) {
     895           0 :                 return W_ERROR(NERR_BadOfflineJoinInfo);
     896             :         }
     897             : 
     898             :         /*
     899             :          * Windows produces and consumes UTF16/UCS2 encoded blobs. Check for the
     900             :          * unicode BOM mark and convert back to UNIX charset if necessary.
     901             :          */
     902          18 :         if (r->in.provision_bin_data[0] == 0xff &&
     903          18 :             r->in.provision_bin_data[1] == 0xfe) {
     904          18 :                 ok = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX,
     905          18 :                                            r->in.provision_bin_data+2,
     906          18 :                                            r->in.provision_bin_data_size-2,
     907             :                                            &blob_base64.data,
     908             :                                            &blob_base64.length);
     909          18 :                 if (!ok) {
     910           0 :                         return W_ERROR(NERR_BadOfflineJoinInfo);
     911             :                 }
     912             :         } else {
     913           0 :                 blob_base64 = data_blob(r->in.provision_bin_data,
     914             :                                         r->in.provision_bin_data_size);
     915             :         }
     916             : 
     917          18 :         blob = base64_decode_data_blob_talloc(ctx, (const char *)blob_base64.data);
     918             : 
     919          18 :         ndr_err = ndr_pull_struct_blob(&blob, ctx, &odj_provision_data,
     920             :                 (ndr_pull_flags_fn_t)ndr_pull_ODJ_PROVISION_DATA_serialized_ptr);
     921          18 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     922           0 :                 return W_ERROR(NERR_BadOfflineJoinInfo);
     923             :         }
     924             : 
     925          18 :         if (DEBUGLEVEL >= 10) {
     926           0 :                 NDR_PRINT_DEBUG(ODJ_PROVISION_DATA_serialized_ptr, &odj_provision_data);
     927             :         }
     928             : 
     929          18 :         if (odj_provision_data.s.p->ulVersion != 1) {
     930           0 :                 return W_ERROR(NERR_ProvisioningBlobUnsupported);
     931             :         }
     932             : 
     933          18 :         werr = libnet_odj_find_win7blob(odj_provision_data.s.p, &win7blob);
     934          18 :         if (!W_ERROR_IS_OK(werr)) {
     935           0 :                 return werr;
     936             :         }
     937             : 
     938          18 :         if (!(r->in.options & NETSETUP_PROVISION_ONLINE_CALLER)) {
     939           0 :                 return WERR_NERR_SETUPNOTJOINED;
     940             :         }
     941             : 
     942          18 :         werr = NetRequestOfflineDomainJoin_backend(ctx,
     943             :                                                    &win7blob,
     944          18 :                                                    odj_provision_data.s.p);
     945          18 :         if (!W_ERROR_IS_OK(werr)) {
     946           0 :                 return werr;
     947             :         }
     948             : 
     949          18 :         return W_ERROR(NERR_JoinPerformedMustRestart);
     950             : }
     951             : 
     952             : /****************************************************************
     953             : ****************************************************************/
     954             : 
     955           0 : WERROR NetComposeOfflineDomainJoin_r(struct libnetapi_ctx *ctx,
     956             :                                      struct NetComposeOfflineDomainJoin *r)
     957             : {
     958           0 :         return WERR_NOT_SUPPORTED;
     959             : }
     960             : 
     961             : /****************************************************************
     962             : ****************************************************************/
     963             : 
     964           6 : static WERROR NetComposeOfflineDomainJoin_backend(struct libnetapi_ctx *ctx,
     965             :                                                   struct NetComposeOfflineDomainJoin *r,
     966             :                                                   TALLOC_CTX *mem_ctx,
     967             :                                                   struct ODJ_PROVISION_DATA **p)
     968             : {
     969           6 :         struct libnet_JoinCtx *j = NULL;
     970           0 :         WERROR werr;
     971             : 
     972           6 :         werr = libnet_init_JoinCtx(ctx, &j);
     973           6 :         if (!W_ERROR_IS_OK(werr)) {
     974           0 :                 return werr;
     975             :         }
     976             : 
     977           6 :         j->in.domain_name = talloc_strdup(j, r->in.dns_domain_name);
     978           6 :         if (j->in.domain_name == NULL) {
     979           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     980             :         }
     981             : 
     982           6 :         j->in.dc_name = talloc_strdup(j, r->in.dc_name);
     983           6 :         W_ERROR_HAVE_NO_MEMORY(j->in.dc_name);
     984             : 
     985           6 :         j->in.machine_password = talloc_strdup(j, r->in.machine_account_password);
     986           6 :         W_ERROR_HAVE_NO_MEMORY(j->in.machine_password);
     987             : 
     988           6 :         j->out.account_name = talloc_strdup(j, r->in.machine_account_name);
     989           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.account_name);
     990             : 
     991           6 :         j->out.dns_domain_name = talloc_strdup(j, r->in.dns_domain_name);
     992           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.dns_domain_name);
     993             : 
     994           6 :         j->out.netbios_domain_name = talloc_strdup(j, r->in.netbios_domain_name);
     995           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.netbios_domain_name);
     996             : 
     997           6 :         j->out.domain_sid = dom_sid_dup(j, (struct dom_sid *)r->in.domain_sid);
     998           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.domain_sid);
     999             : 
    1000           6 :         j->out.domain_guid = *r->in.domain_guid;
    1001             : 
    1002           6 :         j->out.forest_name = talloc_strdup(j, r->in.forest_name);
    1003           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.forest_name);
    1004             : 
    1005           6 :         j->out.domain_is_ad = r->in.domain_is_ad;
    1006             : 
    1007           6 :         j->out.dcinfo = talloc_zero(j, struct netr_DsRGetDCNameInfo);
    1008           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo);
    1009             : 
    1010           6 :         j->out.dcinfo->dc_unc = talloc_asprintf(j->out.dcinfo, "\\\\%s", r->in.dc_name);
    1011           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->dc_unc);
    1012             : 
    1013           6 :         j->out.dcinfo->dc_address = talloc_asprintf(j->out.dcinfo, "\\\\%s", r->in.dc_address);
    1014           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->dc_address);
    1015             : 
    1016           6 :         j->out.dcinfo->dc_address_type = DS_ADDRESS_TYPE_INET;
    1017             : 
    1018           6 :         j->out.dcinfo->domain_guid = *r->in.domain_guid;
    1019             : 
    1020           6 :         j->out.dcinfo->domain_name = talloc_strdup(j->out.dcinfo, r->in.dns_domain_name);
    1021           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->domain_name);
    1022             : 
    1023           6 :         j->out.dcinfo->forest_name = talloc_strdup(j->out.dcinfo, r->in.forest_name);
    1024           6 :         W_ERROR_HAVE_NO_MEMORY(j->out.dcinfo->forest_name);
    1025             : 
    1026           6 :         werr = libnet_odj_compose_ODJ_PROVISION_DATA(mem_ctx, j, p);
    1027           6 :         if (!W_ERROR_IS_OK(werr)) {
    1028           0 :                 return werr;
    1029             :         }
    1030             : 
    1031           6 :         return WERR_OK;
    1032             : }
    1033             : 
    1034           6 : WERROR NetComposeOfflineDomainJoin_l(struct libnetapi_ctx *ctx,
    1035             :                                      struct NetComposeOfflineDomainJoin *r)
    1036             : {
    1037           0 :         WERROR werr;
    1038           0 :         enum ndr_err_code ndr_err;
    1039           0 :         const char *b64_bin_data_str;
    1040           0 :         DATA_BLOB blob;
    1041           0 :         struct ODJ_PROVISION_DATA_serialized_ptr odj_compose_data;
    1042           0 :         struct ODJ_PROVISION_DATA *p;
    1043           6 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1044             : 
    1045           6 :         if (r->in.compose_bin_data == NULL &&
    1046           6 :             r->in.compose_text_data == NULL) {
    1047           0 :                 werr = WERR_INVALID_PARAMETER;
    1048           0 :                 goto out;
    1049             :         }
    1050           6 :         if (r->in.compose_bin_data != NULL &&
    1051           0 :             r->in.compose_text_data != NULL) {
    1052           0 :                 werr = WERR_INVALID_PARAMETER;
    1053           0 :                 goto out;
    1054             :         }
    1055           6 :         if (r->in.compose_bin_data == NULL &&
    1056           6 :             r->in.compose_bin_data_size != NULL) {
    1057           0 :                 werr = WERR_INVALID_PARAMETER;
    1058           0 :                 goto out;
    1059             :         }
    1060           6 :         if (r->in.compose_bin_data != NULL &&
    1061           0 :             r->in.compose_bin_data_size == NULL) {
    1062           0 :                 werr = WERR_INVALID_PARAMETER;
    1063           0 :                 goto out;
    1064             :         }
    1065             : 
    1066           6 :         if (r->in.dns_domain_name == NULL) {
    1067           0 :                 werr = WERR_INVALID_PARAMETER;
    1068           0 :                 goto out;
    1069             :         }
    1070             : 
    1071           6 :         if (r->in.netbios_domain_name == NULL) {
    1072           0 :                 werr = WERR_INVALID_PARAMETER;
    1073           0 :                 goto out;
    1074             :         }
    1075             : 
    1076           6 :         if (r->in.domain_sid == NULL) {
    1077           0 :                 werr = WERR_INVALID_PARAMETER;
    1078           0 :                 goto out;
    1079             :         }
    1080             : 
    1081           6 :         if (r->in.domain_guid == NULL) {
    1082           0 :                 werr = WERR_INVALID_PARAMETER;
    1083           0 :                 goto out;
    1084             :         }
    1085             : 
    1086           6 :         if (r->in.forest_name == NULL) {
    1087           0 :                 werr = WERR_INVALID_PARAMETER;
    1088           0 :                 goto out;
    1089             :         }
    1090             : 
    1091           6 :         if (r->in.machine_account_name == NULL) {
    1092           0 :                 werr = WERR_INVALID_PARAMETER;
    1093           0 :                 goto out;
    1094             :         }
    1095             : 
    1096           6 :         if (r->in.machine_account_password == NULL) {
    1097           0 :                 werr = WERR_INVALID_PARAMETER;
    1098           0 :                 goto out;
    1099             :         }
    1100             : 
    1101           6 :         if (r->in.dc_name == NULL) {
    1102           0 :                 werr = WERR_INVALID_PARAMETER;
    1103           0 :                 goto out;
    1104             :         }
    1105             : 
    1106           6 :         if (r->in.dc_address == NULL) {
    1107           0 :                 werr = WERR_INVALID_PARAMETER;
    1108           0 :                 goto out;
    1109             :         }
    1110             : 
    1111           6 :         werr = NetComposeOfflineDomainJoin_backend(ctx, r, tmp_ctx, &p);
    1112           6 :         if (!W_ERROR_IS_OK(werr)) {
    1113           0 :                 goto out;
    1114             :         }
    1115             : 
    1116           6 :         ZERO_STRUCT(odj_compose_data);
    1117             : 
    1118           6 :         odj_compose_data.s.p = p;
    1119             : 
    1120           6 :         ndr_err = ndr_push_struct_blob(&blob, ctx, &odj_compose_data,
    1121             :                 (ndr_push_flags_fn_t)ndr_push_ODJ_PROVISION_DATA_serialized_ptr);
    1122           6 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1123           0 :                 werr = W_ERROR(NERR_BadOfflineJoinInfo);
    1124           0 :                 goto out;
    1125             :         }
    1126             : 
    1127           6 :         if (r->out.compose_text_data != NULL) {
    1128           6 :                 b64_bin_data_str = base64_encode_data_blob(ctx, blob);
    1129           6 :                 if (b64_bin_data_str == NULL) {
    1130           0 :                         werr = WERR_NOT_ENOUGH_MEMORY;
    1131             :                 }
    1132           6 :                 *r->out.compose_text_data = b64_bin_data_str;
    1133             :         }
    1134             : 
    1135           6 :         if (r->out.compose_bin_data != NULL &&
    1136           0 :             r->out.compose_bin_data_size != NULL) {
    1137           0 :                 *r->out.compose_bin_data = blob.data;
    1138           0 :                 *r->out.compose_bin_data_size = blob.length;
    1139             :         }
    1140             : 
    1141           6 :         werr = WERR_OK;
    1142           6 : out:
    1143           6 :         talloc_free(tmp_ctx);
    1144           6 :         return werr;
    1145             : }

Generated by: LCOV version 1.14