LCOV - code coverage report
Current view: top level - source3/lib/netapi - joindomain.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 441 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 16 0.0 %

          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             : 
      37             : /****************************************************************
      38             : ****************************************************************/
      39             : 
      40           0 : WERROR NetJoinDomain_l(struct libnetapi_ctx *mem_ctx,
      41             :                        struct NetJoinDomain *r)
      42             : {
      43           0 :         struct libnet_JoinCtx *j = NULL;
      44             :         struct libnetapi_private_ctx *priv;
      45             :         WERROR werr;
      46             : 
      47           0 :         priv = talloc_get_type_abort(mem_ctx->private_data,
      48             :                 struct libnetapi_private_ctx);
      49             : 
      50           0 :         if (!r->in.domain) {
      51           0 :                 return WERR_INVALID_PARAMETER;
      52             :         }
      53             : 
      54           0 :         werr = libnet_init_JoinCtx(mem_ctx, &j);
      55           0 :         W_ERROR_NOT_OK_RETURN(werr);
      56             : 
      57           0 :         j->in.domain_name = talloc_strdup(mem_ctx, r->in.domain);
      58           0 :         W_ERROR_HAVE_NO_MEMORY(j->in.domain_name);
      59             : 
      60           0 :         if (r->in.join_flags & WKSSVC_JOIN_FLAGS_JOIN_TYPE) {
      61             :                 NTSTATUS status;
      62           0 :                 struct netr_DsRGetDCNameInfo *info = NULL;
      63           0 :                 const char *dc = NULL;
      64           0 :                 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
      65             :                                  DS_WRITABLE_REQUIRED |
      66             :                                  DS_RETURN_DNS_NAME;
      67           0 :                 status = dsgetdcname(mem_ctx, priv->msg_ctx, r->in.domain,
      68             :                                      NULL, NULL, flags, &info);
      69           0 :                 if (!NT_STATUS_IS_OK(status)) {
      70           0 :                         libnetapi_set_error_string(mem_ctx,
      71             :                                 "%s", get_friendly_nt_error_msg(status));
      72           0 :                         return ntstatus_to_werror(status);
      73             :                 }
      74             : 
      75           0 :                 dc = strip_hostname(info->dc_unc);
      76           0 :                 j->in.dc_name = talloc_strdup(mem_ctx, dc);
      77           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.dc_name);
      78             :         }
      79             : 
      80           0 :         if (r->in.account_ou) {
      81           0 :                 j->in.account_ou = talloc_strdup(mem_ctx, r->in.account_ou);
      82           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.account_ou);
      83             :         }
      84             : 
      85           0 :         if (r->in.account) {
      86           0 :                 j->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
      87           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.admin_account);
      88             :         }
      89             : 
      90           0 :         if (r->in.password) {
      91           0 :                 j->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
      92           0 :                 W_ERROR_HAVE_NO_MEMORY(j->in.admin_password);
      93             :         }
      94             : 
      95           0 :         j->in.join_flags = r->in.join_flags;
      96           0 :         j->in.modify_config = true;
      97           0 :         j->in.debug = true;
      98             : 
      99           0 :         werr = libnet_Join(mem_ctx, j);
     100           0 :         if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
     101           0 :                 libnetapi_set_error_string(mem_ctx, "%s", j->out.error_string);
     102             :         }
     103           0 :         TALLOC_FREE(j);
     104             : 
     105           0 :         return werr;
     106             : }
     107             : 
     108             : /****************************************************************
     109             : ****************************************************************/
     110             : 
     111           0 : WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx,
     112             :                        struct NetJoinDomain *r)
     113             : {
     114           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     115           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     116             :         NTSTATUS status;
     117             :         WERROR werr;
     118           0 :         unsigned int old_timeout = 0;
     119             :         struct dcerpc_binding_handle *b;
     120             :         DATA_BLOB session_key;
     121             : 
     122           0 :         if (IS_DC) {
     123           0 :                 return WERR_NERR_SETUPDOMAINCONTROLLER;
     124             :         }
     125             : 
     126           0 :         werr = libnetapi_open_pipe(ctx, r->in.server,
     127             :                                    &ndr_table_wkssvc,
     128             :                                    &pipe_cli);
     129           0 :         if (!W_ERROR_IS_OK(werr)) {
     130           0 :                 goto done;
     131             :         }
     132             : 
     133           0 :         b = pipe_cli->binding_handle;
     134             : 
     135           0 :         if (r->in.password) {
     136             : 
     137           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     138           0 :                 if (!NT_STATUS_IS_OK(status)) {
     139           0 :                         werr = ntstatus_to_werror(status);
     140           0 :                         goto done;
     141             :                 }
     142             : 
     143           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     144             :                                                           r->in.password,
     145             :                                                           &session_key,
     146             :                                                           &encrypted_password);
     147           0 :                 if (!W_ERROR_IS_OK(werr)) {
     148           0 :                         goto done;
     149             :                 }
     150             :         }
     151             : 
     152           0 :         old_timeout = rpccli_set_timeout(pipe_cli, 600000);
     153             : 
     154           0 :         status = dcerpc_wkssvc_NetrJoinDomain2(b, talloc_tos(),
     155             :                                                r->in.server,
     156             :                                                r->in.domain,
     157             :                                                r->in.account_ou,
     158             :                                                r->in.account,
     159             :                                                encrypted_password,
     160             :                                                r->in.join_flags,
     161             :                                                &werr);
     162           0 :         if (!NT_STATUS_IS_OK(status)) {
     163           0 :                 werr = ntstatus_to_werror(status);
     164           0 :                 goto done;
     165             :         }
     166             : 
     167           0 :  done:
     168           0 :         if (pipe_cli && old_timeout) {
     169           0 :                 rpccli_set_timeout(pipe_cli, old_timeout);
     170             :         }
     171             : 
     172           0 :         return werr;
     173             : }
     174             : /****************************************************************
     175             : ****************************************************************/
     176             : 
     177           0 : WERROR NetUnjoinDomain_l(struct libnetapi_ctx *mem_ctx,
     178             :                          struct NetUnjoinDomain *r)
     179             : {
     180           0 :         struct libnet_UnjoinCtx *u = NULL;
     181             :         struct dom_sid domain_sid;
     182           0 :         const char *domain = NULL;
     183             :         WERROR werr;
     184             :         struct libnetapi_private_ctx *priv;
     185           0 :         const char *realm = lp_realm();
     186             : 
     187           0 :         priv = talloc_get_type_abort(mem_ctx->private_data,
     188             :                 struct libnetapi_private_ctx);
     189             : 
     190           0 :         if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
     191           0 :                 return WERR_NERR_SETUPNOTJOINED;
     192             :         }
     193             : 
     194           0 :         werr = libnet_init_UnjoinCtx(mem_ctx, &u);
     195           0 :         W_ERROR_NOT_OK_RETURN(werr);
     196             : 
     197           0 :         if (realm[0] != '\0') {
     198           0 :                 domain = realm;
     199             :         } else {
     200           0 :                 domain = lp_workgroup();
     201             :         }
     202             : 
     203           0 :         if (r->in.server_name) {
     204           0 :                 u->in.dc_name = talloc_strdup(mem_ctx, r->in.server_name);
     205           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
     206             :         } else {
     207             :                 NTSTATUS status;
     208           0 :                 struct netr_DsRGetDCNameInfo *info = NULL;
     209           0 :                 const char *dc = NULL;
     210           0 :                 uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
     211             :                                  DS_WRITABLE_REQUIRED |
     212             :                                  DS_RETURN_DNS_NAME;
     213           0 :                 status = dsgetdcname(mem_ctx, priv->msg_ctx, domain,
     214             :                                      NULL, NULL, flags, &info);
     215           0 :                 if (!NT_STATUS_IS_OK(status)) {
     216           0 :                         libnetapi_set_error_string(mem_ctx,
     217             :                                 "failed to find DC for domain %s: %s",
     218             :                                 domain,
     219             :                                 get_friendly_nt_error_msg(status));
     220           0 :                         return ntstatus_to_werror(status);
     221             :                 }
     222             : 
     223           0 :                 dc = strip_hostname(info->dc_unc);
     224           0 :                 u->in.dc_name = talloc_strdup(mem_ctx, dc);
     225           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.dc_name);
     226             : 
     227           0 :                 u->in.domain_name = domain;
     228             :         }
     229             : 
     230           0 :         if (r->in.account) {
     231           0 :                 u->in.admin_account = talloc_strdup(mem_ctx, r->in.account);
     232           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.admin_account);
     233             :         }
     234             : 
     235           0 :         if (r->in.password) {
     236           0 :                 u->in.admin_password = talloc_strdup(mem_ctx, r->in.password);
     237           0 :                 W_ERROR_HAVE_NO_MEMORY(u->in.admin_password);
     238             :         }
     239             : 
     240           0 :         u->in.domain_name = domain;
     241           0 :         u->in.unjoin_flags = r->in.unjoin_flags;
     242           0 :         u->in.delete_machine_account = false;
     243           0 :         u->in.modify_config = true;
     244           0 :         u->in.debug = true;
     245             : 
     246           0 :         u->in.domain_sid = &domain_sid;
     247             : 
     248           0 :         werr = libnet_Unjoin(mem_ctx, u);
     249           0 :         if (!W_ERROR_IS_OK(werr) && u->out.error_string) {
     250           0 :                 libnetapi_set_error_string(mem_ctx, "%s", u->out.error_string);
     251             :         }
     252           0 :         TALLOC_FREE(u);
     253             : 
     254           0 :         return werr;
     255             : }
     256             : 
     257             : /****************************************************************
     258             : ****************************************************************/
     259             : 
     260           0 : WERROR NetUnjoinDomain_r(struct libnetapi_ctx *ctx,
     261             :                          struct NetUnjoinDomain *r)
     262             : {
     263           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     264           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     265             :         NTSTATUS status;
     266             :         WERROR werr;
     267           0 :         unsigned int old_timeout = 0;
     268             :         struct dcerpc_binding_handle *b;
     269             :         DATA_BLOB session_key;
     270             : 
     271           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     272             :                                    &ndr_table_wkssvc,
     273             :                                    &pipe_cli);
     274           0 :         if (!W_ERROR_IS_OK(werr)) {
     275           0 :                 goto done;
     276             :         }
     277             : 
     278           0 :         b = pipe_cli->binding_handle;
     279             : 
     280           0 :         if (r->in.password) {
     281             : 
     282           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     283           0 :                 if (!NT_STATUS_IS_OK(status)) {
     284           0 :                         werr = ntstatus_to_werror(status);
     285           0 :                         goto done;
     286             :                 }
     287             : 
     288           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     289             :                                                           r->in.password,
     290             :                                                           &session_key,
     291             :                                                           &encrypted_password);
     292           0 :                 if (!W_ERROR_IS_OK(werr)) {
     293           0 :                         goto done;
     294             :                 }
     295             :         }
     296             : 
     297           0 :         old_timeout = rpccli_set_timeout(pipe_cli, 60000);
     298             : 
     299           0 :         status = dcerpc_wkssvc_NetrUnjoinDomain2(b, talloc_tos(),
     300             :                                                  r->in.server_name,
     301             :                                                  r->in.account,
     302             :                                                  encrypted_password,
     303             :                                                  r->in.unjoin_flags,
     304             :                                                  &werr);
     305           0 :         if (!NT_STATUS_IS_OK(status)) {
     306           0 :                 werr = ntstatus_to_werror(status);
     307           0 :                 goto done;
     308             :         }
     309             : 
     310           0 :  done:
     311           0 :         if (pipe_cli && old_timeout) {
     312           0 :                 rpccli_set_timeout(pipe_cli, old_timeout);
     313             :         }
     314             : 
     315           0 :         return werr;
     316             : }
     317             : 
     318             : /****************************************************************
     319             : ****************************************************************/
     320             : 
     321           0 : WERROR NetGetJoinInformation_r(struct libnetapi_ctx *ctx,
     322             :                                struct NetGetJoinInformation *r)
     323             : {
     324           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     325             :         NTSTATUS status;
     326             :         WERROR werr;
     327           0 :         const char *buffer = NULL;
     328             :         struct dcerpc_binding_handle *b;
     329             : 
     330           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     331             :                                    &ndr_table_wkssvc,
     332             :                                    &pipe_cli);
     333           0 :         if (!W_ERROR_IS_OK(werr)) {
     334           0 :                 goto done;
     335             :         }
     336             : 
     337           0 :         b = pipe_cli->binding_handle;
     338             : 
     339           0 :         status = dcerpc_wkssvc_NetrGetJoinInformation(b, talloc_tos(),
     340             :                                                       r->in.server_name,
     341             :                                                       &buffer,
     342           0 :                                                       (enum wkssvc_NetJoinStatus *)r->out.name_type,
     343             :                                                       &werr);
     344           0 :         if (!NT_STATUS_IS_OK(status)) {
     345           0 :                 werr = ntstatus_to_werror(status);
     346           0 :                 goto done;
     347             :         }
     348             : 
     349           0 :         if (!W_ERROR_IS_OK(werr)) {
     350           0 :                 goto done;
     351             :         }
     352             : 
     353           0 :         *r->out.name_buffer = talloc_strdup(ctx, buffer);
     354           0 :         W_ERROR_HAVE_NO_MEMORY(*r->out.name_buffer);
     355             : 
     356           0 :  done:
     357           0 :         return werr;
     358             : }
     359             : 
     360             : /****************************************************************
     361             : ****************************************************************/
     362             : 
     363           0 : WERROR NetGetJoinInformation_l(struct libnetapi_ctx *ctx,
     364             :                                struct NetGetJoinInformation *r)
     365             : {
     366           0 :         const char *realm = lp_realm();
     367             : 
     368           0 :         if ((lp_security() == SEC_ADS) && realm[0] != '\0') {
     369           0 :                 *r->out.name_buffer = talloc_strdup(ctx, realm);
     370             :         } else {
     371           0 :                 *r->out.name_buffer = talloc_strdup(ctx, lp_workgroup());
     372             :         }
     373           0 :         if (!*r->out.name_buffer) {
     374           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     375             :         }
     376             : 
     377           0 :         switch (lp_server_role()) {
     378           0 :                 case ROLE_DOMAIN_MEMBER:
     379             :                 case ROLE_DOMAIN_PDC:
     380             :                 case ROLE_DOMAIN_BDC:
     381             :                 case ROLE_IPA_DC:
     382           0 :                         *r->out.name_type = NetSetupDomainName;
     383           0 :                         break;
     384           0 :                 case ROLE_STANDALONE:
     385             :                 default:
     386           0 :                         *r->out.name_type = NetSetupWorkgroupName;
     387           0 :                         break;
     388             :         }
     389             : 
     390           0 :         return WERR_OK;
     391             : }
     392             : 
     393             : /****************************************************************
     394             : ****************************************************************/
     395             : 
     396           0 : WERROR NetGetJoinableOUs_l(struct libnetapi_ctx *ctx,
     397             :                            struct NetGetJoinableOUs *r)
     398             : {
     399             : #ifdef HAVE_ADS
     400           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     401             :         WERROR ret;
     402             :         NTSTATUS status;
     403             :         ADS_STATUS ads_status;
     404           0 :         ADS_STRUCT *ads = NULL;
     405           0 :         struct netr_DsRGetDCNameInfo *info = NULL;
     406           0 :         const char *dc = NULL;
     407           0 :         uint32_t flags = DS_DIRECTORY_SERVICE_REQUIRED |
     408             :                          DS_RETURN_DNS_NAME;
     409             :         struct libnetapi_private_ctx *priv;
     410             :         char **p;
     411             :         size_t s;
     412             : 
     413           0 :         priv = talloc_get_type_abort(ctx->private_data,
     414             :                 struct libnetapi_private_ctx);
     415             : 
     416           0 :         status = dsgetdcname(tmp_ctx, priv->msg_ctx, r->in.domain,
     417             :                              NULL, NULL, flags, &info);
     418           0 :         if (!NT_STATUS_IS_OK(status)) {
     419           0 :                 libnetapi_set_error_string(ctx, "%s",
     420             :                         get_friendly_nt_error_msg(status));
     421           0 :                 ret = ntstatus_to_werror(status);
     422           0 :                 goto out;
     423             :         }
     424             : 
     425           0 :         dc = strip_hostname(info->dc_unc);
     426             : 
     427           0 :         ads = ads_init(tmp_ctx,
     428           0 :                        info->domain_name,
     429           0 :                        info->domain_name,
     430             :                        dc,
     431             :                        ADS_SASL_PLAIN);
     432           0 :         if (!ads) {
     433           0 :                 ret = WERR_GEN_FAILURE;
     434           0 :                 goto out;
     435             :         }
     436             : 
     437           0 :         TALLOC_FREE(ads->auth.user_name);
     438           0 :         if (r->in.account) {
     439           0 :                 ads->auth.user_name = talloc_strdup(ads, r->in.account);
     440           0 :                 if (ads->auth.user_name == NULL) {
     441           0 :                         ret = WERR_NOT_ENOUGH_MEMORY;
     442           0 :                         goto out;
     443             :                 }
     444             :         } else {
     445           0 :                 const char *username = NULL;
     446             : 
     447           0 :                 libnetapi_get_username(ctx, &username);
     448           0 :                 if (username != NULL) {
     449           0 :                         ads->auth.user_name = talloc_strdup(ads, username);
     450           0 :                         if (ads->auth.user_name == NULL) {
     451           0 :                                 ret = WERR_NOT_ENOUGH_MEMORY;
     452           0 :                                 goto out;
     453             :                         }
     454             :                 }
     455             :         }
     456             : 
     457           0 :         TALLOC_FREE(ads->auth.password);
     458           0 :         if (r->in.password) {
     459           0 :                 ads->auth.password = talloc_strdup(ads, r->in.password);
     460           0 :                 if (ads->auth.password == NULL) {
     461           0 :                         ret = WERR_NOT_ENOUGH_MEMORY;
     462           0 :                         goto out;
     463             :                 }
     464             :         } else {
     465           0 :                 const char *password = NULL;
     466             : 
     467           0 :                 libnetapi_get_password(ctx, &password);
     468           0 :                 if (password != NULL) {
     469           0 :                         ads->auth.password = talloc_strdup(ads, password);
     470           0 :                         if (ads->auth.password == NULL) {
     471           0 :                                 ret = WERR_NOT_ENOUGH_MEMORY;
     472           0 :                                 goto out;
     473             :                         }
     474             :                 }
     475             :         }
     476             : 
     477           0 :         ads_status = ads_connect_user_creds(ads);
     478           0 :         if (!ADS_ERR_OK(ads_status)) {
     479           0 :                 ret = WERR_NERR_DEFAULTJOINREQUIRED;
     480           0 :                 goto out;
     481             :         }
     482             : 
     483           0 :         ads_status = ads_get_joinable_ous(ads, ctx, &p, &s);
     484           0 :         if (!ADS_ERR_OK(ads_status)) {
     485           0 :                 ret = WERR_NERR_DEFAULTJOINREQUIRED;
     486           0 :                 goto out;
     487             :         }
     488           0 :         *r->out.ous = discard_const_p(const char *, p);
     489           0 :         *r->out.ou_count = s;
     490             : 
     491           0 :         ret = WERR_OK;
     492           0 : out:
     493           0 :         TALLOC_FREE(tmp_ctx);
     494             : 
     495           0 :         return ret;
     496             : #else
     497             :         return WERR_NOT_SUPPORTED;
     498             : #endif
     499             : }
     500             : 
     501             : /****************************************************************
     502             : ****************************************************************/
     503             : 
     504           0 : WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx,
     505             :                            struct NetGetJoinableOUs *r)
     506             : {
     507           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     508           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     509             :         NTSTATUS status;
     510             :         WERROR werr;
     511             :         struct dcerpc_binding_handle *b;
     512             :         DATA_BLOB session_key;
     513             : 
     514           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     515             :                                    &ndr_table_wkssvc,
     516             :                                    &pipe_cli);
     517           0 :         if (!W_ERROR_IS_OK(werr)) {
     518           0 :                 goto done;
     519             :         }
     520             : 
     521           0 :         b = pipe_cli->binding_handle;
     522             : 
     523           0 :         if (r->in.password) {
     524             : 
     525           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     526           0 :                 if (!NT_STATUS_IS_OK(status)) {
     527           0 :                         werr = ntstatus_to_werror(status);
     528           0 :                         goto done;
     529             :                 }
     530             : 
     531           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     532             :                                                           r->in.password,
     533             :                                                           &session_key,
     534             :                                                           &encrypted_password);
     535           0 :                 if (!W_ERROR_IS_OK(werr)) {
     536           0 :                         goto done;
     537             :                 }
     538             :         }
     539             : 
     540           0 :         status = dcerpc_wkssvc_NetrGetJoinableOus2(b, talloc_tos(),
     541             :                                                    r->in.server_name,
     542             :                                                    r->in.domain,
     543             :                                                    r->in.account,
     544             :                                                    encrypted_password,
     545             :                                                    r->out.ou_count,
     546             :                                                    r->out.ous,
     547             :                                                    &werr);
     548           0 :         if (!NT_STATUS_IS_OK(status)) {
     549           0 :                 werr = ntstatus_to_werror(status);
     550           0 :                 goto done;
     551             :         }
     552             : 
     553           0 :  done:
     554           0 :         return werr;
     555             : }
     556             : 
     557             : /****************************************************************
     558             : ****************************************************************/
     559             : 
     560           0 : WERROR NetRenameMachineInDomain_r(struct libnetapi_ctx *ctx,
     561             :                                   struct NetRenameMachineInDomain *r)
     562             : {
     563           0 :         struct rpc_pipe_client *pipe_cli = NULL;
     564           0 :         struct wkssvc_PasswordBuffer *encrypted_password = NULL;
     565             :         NTSTATUS status;
     566             :         WERROR werr;
     567             :         struct dcerpc_binding_handle *b;
     568             :         DATA_BLOB session_key;
     569             : 
     570           0 :         werr = libnetapi_open_pipe(ctx, r->in.server_name,
     571             :                                    &ndr_table_wkssvc,
     572             :                                    &pipe_cli);
     573           0 :         if (!W_ERROR_IS_OK(werr)) {
     574           0 :                 goto done;
     575             :         }
     576             : 
     577           0 :         b = pipe_cli->binding_handle;
     578             : 
     579           0 :         if (r->in.password) {
     580             : 
     581           0 :                 status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
     582           0 :                 if (!NT_STATUS_IS_OK(status)) {
     583           0 :                         werr = ntstatus_to_werror(status);
     584           0 :                         goto done;
     585             :                 }
     586             : 
     587           0 :                 werr = encode_wkssvc_join_password_buffer(ctx,
     588             :                                                           r->in.password,
     589             :                                                           &session_key,
     590             :                                                           &encrypted_password);
     591           0 :                 if (!W_ERROR_IS_OK(werr)) {
     592           0 :                         goto done;
     593             :                 }
     594             :         }
     595             : 
     596           0 :         status = dcerpc_wkssvc_NetrRenameMachineInDomain2(b, talloc_tos(),
     597             :                                                           r->in.server_name,
     598             :                                                           r->in.new_machine_name,
     599             :                                                           r->in.account,
     600             :                                                           encrypted_password,
     601             :                                                           r->in.rename_options,
     602             :                                                           &werr);
     603           0 :         if (!NT_STATUS_IS_OK(status)) {
     604           0 :                 werr = ntstatus_to_werror(status);
     605           0 :                 goto done;
     606             :         }
     607             : 
     608           0 :  done:
     609           0 :         return werr;
     610             : }
     611             : 
     612             : /****************************************************************
     613             : ****************************************************************/
     614             : 
     615           0 : WERROR NetRenameMachineInDomain_l(struct libnetapi_ctx *ctx,
     616             :                                   struct NetRenameMachineInDomain *r)
     617             : {
     618           0 :         LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetRenameMachineInDomain);
     619             : }
     620             : 
     621             : /****************************************************************
     622             : ****************************************************************/
     623             : 
     624           0 : WERROR NetProvisionComputerAccount_r(struct libnetapi_ctx *ctx,
     625             :                                      struct NetProvisionComputerAccount *r)
     626             : {
     627           0 :         return NetProvisionComputerAccount_l(ctx, r);
     628             : }
     629             : 
     630             : /****************************************************************
     631             : ****************************************************************/
     632             : 
     633           0 : static WERROR NetProvisionComputerAccount_backend(struct libnetapi_ctx *ctx,
     634             :                                                   struct NetProvisionComputerAccount *r,
     635             :                                                   TALLOC_CTX *mem_ctx,
     636             :                                                   struct ODJ_PROVISION_DATA **p)
     637             : {
     638             :         WERROR werr;
     639           0 :         struct libnet_JoinCtx *j = NULL;
     640           0 :         int use_kerberos = 0;
     641           0 :         const char *username = NULL;
     642             : 
     643           0 :         werr = libnet_init_JoinCtx(mem_ctx, &j);
     644           0 :         if (!W_ERROR_IS_OK(werr)) {
     645           0 :                 return werr;
     646             :         }
     647             : 
     648           0 :         j->in.domain_name = talloc_strdup(j, r->in.domain);
     649           0 :         if (j->in.domain_name == NULL) {
     650           0 :                 talloc_free(j);
     651           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     652             :         }
     653             : 
     654           0 :         talloc_free(discard_const_p(char *, j->in.machine_name));
     655           0 :         j->in.machine_name = talloc_strdup(j, r->in.machine_name);
     656           0 :         if (j->in.machine_name == NULL) {
     657           0 :                 talloc_free(j);
     658           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     659             :         }
     660             : 
     661           0 :         if (r->in.dcname) {
     662           0 :                 j->in.dc_name = talloc_strdup(j, r->in.dcname);
     663           0 :                 if (j->in.dc_name == NULL) {
     664           0 :                         talloc_free(j);
     665           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     666             :                 }
     667             :         }
     668             : 
     669           0 :         if (r->in.machine_account_ou) {
     670           0 :                 j->in.account_ou = talloc_strdup(j, r->in.machine_account_ou);
     671           0 :                 if (j->in.account_ou == NULL) {
     672           0 :                         talloc_free(j);
     673           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     674             :                 }
     675             :         }
     676             : 
     677           0 :         libnetapi_get_username(ctx, &username);
     678           0 :         if (username == NULL) {
     679           0 :                 talloc_free(j);
     680           0 :                 return WERR_NERR_BADUSERNAME;
     681             :         }
     682             : 
     683           0 :         j->in.admin_account = talloc_strdup(j, username);
     684           0 :         if (j->in.admin_account == NULL) {
     685           0 :                 talloc_free(j);
     686           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     687             :         }
     688             : 
     689           0 :         libnetapi_get_use_kerberos(ctx, &use_kerberos);
     690           0 :         if (!use_kerberos) {
     691           0 :                 const char *password = NULL;
     692             : 
     693           0 :                 libnetapi_get_password(ctx, &password);
     694           0 :                 if (password == NULL) {
     695           0 :                         talloc_free(j);
     696           0 :                         return WERR_NERR_BADPASSWORD;
     697             :                 }
     698           0 :                 j->in.admin_password = talloc_strdup(j, password);
     699           0 :                 if (j->in.admin_password == NULL) {
     700           0 :                         talloc_free(j);
     701           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     702             :                 }
     703             :         }
     704             : 
     705           0 :         j->in.use_kerberos = use_kerberos;
     706           0 :         j->in.debug = true;
     707           0 :         j->in.join_flags     = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
     708             :                                   WKSSVC_JOIN_FLAGS_ACCOUNT_CREATE;
     709             : 
     710           0 :         if (r->in.options & NETSETUP_PROVISION_REUSE_ACCOUNT) {
     711           0 :                 j->in.join_flags |= WKSSVC_JOIN_FLAGS_DOMAIN_JOIN_IF_JOINED;
     712             :         }
     713             : 
     714           0 :         if (r->in.options & NETSETUP_PROVISION_USE_DEFAULT_PASSWORD) {
     715           0 :                 j->in.join_flags |= WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
     716           0 :                 j->in.machine_password = talloc_strdup(j, r->in.machine_name);
     717           0 :                 if (j->in.machine_password == NULL) {
     718           0 :                         talloc_free(j);
     719           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     720             :                 }
     721             :         }
     722             : 
     723           0 :         j->in.provision_computer_account_only = true;
     724             : 
     725           0 :         werr = libnet_Join(mem_ctx, j);
     726           0 :         if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
     727           0 :                 libnetapi_set_error_string(ctx, "%s", j->out.error_string);
     728           0 :                 talloc_free(j);
     729           0 :                 return werr;
     730             :         }
     731             : 
     732           0 :         werr = libnet_odj_compose_ODJ_PROVISION_DATA(mem_ctx, j, p);
     733           0 :         if (!W_ERROR_IS_OK(werr)) {
     734           0 :                 talloc_free(j);
     735           0 :                 return werr;
     736             :         }
     737             : 
     738           0 :         TALLOC_FREE(j);
     739             : 
     740           0 :         return WERR_OK;
     741             : }
     742             : 
     743           0 : WERROR NetProvisionComputerAccount_l(struct libnetapi_ctx *ctx,
     744             :                                      struct NetProvisionComputerAccount *r)
     745             : {
     746             :         WERROR werr;
     747             :         enum ndr_err_code ndr_err;
     748             :         const char *b64_bin_data_str;
     749             :         DATA_BLOB blob;
     750             :         struct ODJ_PROVISION_DATA_serialized_ptr odj_provision_data;
     751             :         struct ODJ_PROVISION_DATA *p;
     752           0 :         TALLOC_CTX *mem_ctx = talloc_new(ctx);
     753             : 
     754           0 :         if (r->in.provision_bin_data == NULL &&
     755           0 :             r->in.provision_text_data == NULL) {
     756           0 :                 return WERR_INVALID_PARAMETER;
     757             :         }
     758           0 :         if (r->in.provision_bin_data != NULL &&
     759           0 :             r->in.provision_text_data != NULL) {
     760           0 :                 return WERR_INVALID_PARAMETER;
     761             :         }
     762           0 :         if (r->in.provision_bin_data == NULL &&
     763           0 :             r->in.provision_bin_data_size != NULL) {
     764           0 :                 return WERR_INVALID_PARAMETER;
     765             :         }
     766           0 :         if (r->in.provision_bin_data != NULL &&
     767           0 :            r->in.provision_bin_data_size == NULL) {
     768           0 :                 return WERR_INVALID_PARAMETER;
     769             :         }
     770             : 
     771           0 :         if (r->in.domain == NULL) {
     772           0 :                 return WERR_INVALID_PARAMETER;
     773             :         }
     774             : 
     775           0 :         if (r->in.machine_name == NULL) {
     776           0 :                 return WERR_INVALID_PARAMETER;
     777             :         }
     778             : 
     779           0 :         werr = NetProvisionComputerAccount_backend(ctx, r, mem_ctx, &p);
     780           0 :         if (!W_ERROR_IS_OK(werr)) {
     781           0 :                 talloc_free(mem_ctx);
     782           0 :                 return werr;
     783             :         }
     784             : 
     785           0 :         ZERO_STRUCT(odj_provision_data);
     786             : 
     787           0 :         odj_provision_data.s.p = p;
     788             : 
     789           0 :         ndr_err = ndr_push_struct_blob(&blob, ctx, &odj_provision_data,
     790             :                 (ndr_push_flags_fn_t)ndr_push_ODJ_PROVISION_DATA_serialized_ptr);
     791           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     792           0 :                 talloc_free(mem_ctx);
     793           0 :                 return W_ERROR(NERR_BadOfflineJoinInfo);
     794             :         }
     795             : 
     796           0 :         talloc_free(mem_ctx);
     797             : 
     798           0 :         if (r->out.provision_text_data != NULL) {
     799           0 :                 b64_bin_data_str = base64_encode_data_blob(ctx, blob);
     800           0 :                 if (b64_bin_data_str == NULL) {
     801           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     802             :                 }
     803           0 :                 *r->out.provision_text_data = b64_bin_data_str;
     804             :         }
     805             : 
     806           0 :         if (r->out.provision_bin_data != NULL &&
     807           0 :             r->out.provision_bin_data_size != NULL) {
     808           0 :                 *r->out.provision_bin_data = blob.data;
     809           0 :                 *r->out.provision_bin_data_size = blob.length;
     810             :         }
     811             : 
     812           0 :         return werr;
     813             : }
     814             : 
     815             : /****************************************************************
     816             : ****************************************************************/
     817             : 
     818           0 : WERROR NetRequestOfflineDomainJoin_r(struct libnetapi_ctx *ctx,
     819             :                                      struct NetRequestOfflineDomainJoin *r)
     820             : {
     821           0 :         return WERR_NOT_SUPPORTED;
     822             : }
     823             : 
     824             : /****************************************************************
     825             : ****************************************************************/
     826             : 
     827           0 : static WERROR NetRequestOfflineDomainJoin_backend(struct libnetapi_ctx *ctx,
     828             :                                                   const struct ODJ_WIN7BLOB *win7blob,
     829             :                                                   const struct ODJ_PROVISION_DATA *odj_provision_data)
     830             : {
     831           0 :         struct libnet_JoinCtx *j = NULL;
     832             :         WERROR werr;
     833             : 
     834           0 :         werr = libnet_init_JoinCtx(ctx, &j);
     835           0 :         if (!W_ERROR_IS_OK(werr)) {
     836           0 :                 return werr;
     837             :         }
     838             : 
     839           0 :         j->in.domain_name = talloc_strdup(j, win7blob->lpDomain);
     840           0 :         if (j->in.domain_name == NULL) {
     841           0 :                 talloc_free(j);
     842           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     843             :         }
     844             : 
     845           0 :         talloc_free(discard_const_p(char *, j->in.machine_name));
     846           0 :         j->in.machine_name = talloc_strdup(j, win7blob->lpMachineName);
     847           0 :         if (j->in.machine_name == NULL) {
     848           0 :                 talloc_free(j);
     849           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     850             :         }
     851             : 
     852           0 :         j->in.machine_password = talloc_strdup(j, win7blob->lpMachinePassword);
     853           0 :         if (j->in.machine_password == NULL) {
     854           0 :                 talloc_free(j);
     855           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     856             :         }
     857             : 
     858           0 :         j->in.request_offline_join = true;
     859           0 :         j->in.odj_provision_data = discard_const(odj_provision_data);
     860           0 :         j->in.debug = true;
     861           0 :         j->in.join_flags     = WKSSVC_JOIN_FLAGS_JOIN_TYPE |
     862             :                                   WKSSVC_JOIN_FLAGS_MACHINE_PWD_PASSED;
     863             : 
     864           0 :         werr = libnet_Join(j, j);
     865           0 :         if (!W_ERROR_IS_OK(werr) && j->out.error_string) {
     866           0 :                 libnetapi_set_error_string(ctx, "%s", j->out.error_string);
     867           0 :                 talloc_free(j);
     868           0 :                 return werr;
     869             :         }
     870             : 
     871           0 :         TALLOC_FREE(j);
     872             : 
     873           0 :         return WERR_OK;
     874             : }
     875             : 
     876           0 : WERROR NetRequestOfflineDomainJoin_l(struct libnetapi_ctx *ctx,
     877             :                                      struct NetRequestOfflineDomainJoin *r)
     878             : {
     879             :         DATA_BLOB blob, blob_base64;
     880             :         enum ndr_err_code ndr_err;
     881             :         struct ODJ_PROVISION_DATA_serialized_ptr odj_provision_data;
     882             :         bool ok;
     883           0 :         struct ODJ_WIN7BLOB win7blob = { 0 };
     884             :         WERROR werr;
     885             : 
     886           0 :         if (r->in.provision_bin_data == NULL ||
     887           0 :             r->in.provision_bin_data_size == 0) {
     888           0 :                 return W_ERROR(NERR_NoOfflineJoinInfo);
     889             :         }
     890             : 
     891           0 :         if (r->in.provision_bin_data_size < 2) {
     892           0 :                 return W_ERROR(NERR_BadOfflineJoinInfo);
     893             :         }
     894             : 
     895           0 :         if (r->in.provision_bin_data[0] == 0xff &&
     896           0 :             r->in.provision_bin_data[1] == 0xfe) {
     897           0 :                 ok = convert_string_talloc(ctx, CH_UTF16LE, CH_UNIX,
     898           0 :                                            r->in.provision_bin_data+2,
     899           0 :                                            r->in.provision_bin_data_size-2,
     900             :                                            &blob_base64.data,
     901             :                                            &blob_base64.length);
     902           0 :                 if (!ok) {
     903           0 :                         return W_ERROR(NERR_BadOfflineJoinInfo);
     904             :                 }
     905             :         } else {
     906           0 :                 blob_base64 = data_blob(r->in.provision_bin_data,
     907             :                                         r->in.provision_bin_data_size);
     908             :         }
     909             : 
     910           0 :         blob = base64_decode_data_blob_talloc(ctx, (const char *)blob_base64.data);
     911             : 
     912           0 :         ndr_err = ndr_pull_struct_blob(&blob, ctx, &odj_provision_data,
     913             :                 (ndr_pull_flags_fn_t)ndr_pull_ODJ_PROVISION_DATA_serialized_ptr);
     914           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     915           0 :                 return W_ERROR(NERR_BadOfflineJoinInfo);
     916             :         }
     917             : 
     918           0 :         if (DEBUGLEVEL >= 10) {
     919           0 :                 NDR_PRINT_DEBUG(ODJ_PROVISION_DATA_serialized_ptr, &odj_provision_data);
     920             :         }
     921             : 
     922           0 :         if (odj_provision_data.s.p->ulVersion != 1) {
     923           0 :                 return W_ERROR(NERR_ProvisioningBlobUnsupported);
     924             :         }
     925             : 
     926           0 :         werr = libnet_odj_find_win7blob(odj_provision_data.s.p, &win7blob);
     927           0 :         if (!W_ERROR_IS_OK(werr)) {
     928           0 :                 return werr;
     929             :         }
     930             : 
     931           0 :         if (!(r->in.options & NETSETUP_PROVISION_ONLINE_CALLER)) {
     932           0 :                 return WERR_NERR_SETUPNOTJOINED;
     933             :         }
     934             : 
     935           0 :         werr = NetRequestOfflineDomainJoin_backend(ctx,
     936             :                                                    &win7blob,
     937           0 :                                                    odj_provision_data.s.p);
     938           0 :         if (!W_ERROR_IS_OK(werr)) {
     939           0 :                 return werr;
     940             :         }
     941             : 
     942           0 :         return W_ERROR(NERR_JoinPerformedMustRestart);
     943             : }

Generated by: LCOV version 1.13