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

Generated by: LCOV version 1.14