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

          Line data    Source code
       1             : /*
       2             :    Samba Unix/Linux SMB client library
       3             :    net join commands
       4             :    Copyright (C) 2021 Guenther Deschner (gd@samba.org)
       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 "utils/net.h"
      22             : #include <netapi.h>
      23             : #include "netapi/netapi_net.h"
      24             : #include "libcli/registry/util_reg.h"
      25             : 
      26           0 : int net_offlinejoin_usage(struct net_context *c, int argc, const char **argv)
      27             : {
      28           0 :         d_printf(_("\nnet offlinejoin [misc. options]\n"
      29             :                    "\tjoins a computer to a domain\n"));
      30           0 :         d_printf(_("Valid commands:\n"));
      31           0 :         d_printf(_("\tprovision\t\t\tProvision machine account in AD\n"));
      32           0 :         d_printf(_("\trequestodj\t\t\tRequest offline domain join\n"));
      33           0 :         net_common_flags_usage(c, argc, argv);
      34           0 :         return -1;
      35             : }
      36             : 
      37           0 : int net_offlinejoin(struct net_context *c, int argc, const char **argv)
      38             : {
      39             :         int ret;
      40             :         NET_API_STATUS status;
      41             : 
      42           0 :         if ((argc > 0) && (strcasecmp_m(argv[0], "HELP") == 0)) {
      43           0 :                 net_offlinejoin_usage(c, argc, argv);
      44           0 :                 return 0;
      45             :         }
      46             : 
      47           0 :         if (argc == 0) {
      48           0 :                 net_offlinejoin_usage(c, argc, argv);
      49           0 :                 return -1;
      50             :         }
      51             : 
      52           0 :         net_warn_member_options();
      53             : 
      54           0 :         status = libnetapi_net_init(&c->netapi_ctx);
      55           0 :         if (status != 0) {
      56           0 :                 return -1;
      57             :         }
      58             : 
      59           0 :         status = libnetapi_set_creds(c->netapi_ctx, c->creds);
      60           0 :         if (status != 0) {
      61           0 :                 return -1;
      62             :         }
      63             : 
      64           0 :         if (c->opt_kerberos) {
      65           0 :                 libnetapi_set_use_kerberos(c->netapi_ctx);
      66             :         }
      67             : 
      68           0 :         if (strcasecmp_m(argv[0], "provision") == 0) {
      69           0 :                 ret = net_offlinejoin_provision(c, argc, argv);
      70           0 :                 if (ret != 0) {
      71           0 :                         return ret;
      72             :                 }
      73             :         }
      74             : 
      75           0 :         if (strcasecmp_m(argv[0], "requestodj") == 0) {
      76           0 :                 ret = net_offlinejoin_requestodj(c, argc, argv);
      77           0 :                 if (ret != 0) {
      78           0 :                         return ret;
      79             :                 }
      80             :         }
      81             : 
      82           0 :         return 0;
      83             : }
      84             : 
      85           0 : static int net_offlinejoin_provision_usage(struct net_context *c, int argc, const char **argv)
      86             : {
      87           0 :         d_printf(_("\nnet offlinejoin provision [misc. options]\n"
      88             :                    "\tProvisions machine account in AD\n"));
      89           0 :         d_printf(_("Valid options:\n"));
      90           0 :         d_printf(_("\tdomain=<DOMAIN>\t\t\t\tDefines AD Domain to join\n"));
      91           0 :         d_printf(_("\tmachine_name=<MACHINE_NAME>\t\tDefines the machine account name\n"));
      92           0 :         d_printf(_("\tmachine_account_ou=<OU>\t\t\tDefines the machine account organizational unit DN\n"));
      93           0 :         d_printf(_("\tdcname=<DCNAME>\t\t\t\tSpecifices a Domain Controller to join to\n"));
      94           0 :         d_printf(_("\tdefpwd\t\t\t\t\tUse default machine account password\n"));
      95           0 :         d_printf(_("\treuse\t\t\t\t\tReuse existing machine account in AD\n"));
      96           0 :         d_printf(_("\tsavefile=<FILENAME>\t\t\tFile to store the ODJ data\n"));
      97           0 :         d_printf(_("\tprintblob\t\t\t\tPrint the base64 encoded ODJ data on stdout\n"));
      98           0 :         net_common_flags_usage(c, argc, argv);
      99           0 :         return -1;
     100             : }
     101             : 
     102           0 : int net_offlinejoin_provision(struct net_context *c,
     103             :                               int argc, const char **argv)
     104             : {
     105             :         NET_API_STATUS status;
     106           0 :         const char *dcname = NULL;
     107           0 :         const char *domain = NULL;
     108           0 :         const char *machine_name = NULL;
     109           0 :         const char *machine_account_ou = NULL;
     110           0 :         const char *provision_text_data = NULL;
     111           0 :         uint32_t options = 0;
     112           0 :         const char *savefile = NULL;
     113           0 :         bool printblob = false;
     114             :         int i;
     115             : 
     116           0 :         if (c->display_usage || argc == 1) {
     117           0 :                 return net_offlinejoin_provision_usage(c, argc, argv);
     118             :         }
     119             : 
     120             :         /* process additional command line args */
     121             : 
     122           0 :         for (i = 0; i < argc; i++) {
     123             : 
     124           0 :                 if (strnequal(argv[i], "domain", strlen("domain"))) {
     125           0 :                         domain = get_string_param(argv[i]);
     126           0 :                         if (domain == NULL) {
     127           0 :                                 return -1;
     128             :                         }
     129             :                 }
     130           0 :                 if (strnequal(argv[i], "machine_name", strlen("machine_name"))) {
     131           0 :                         machine_name = get_string_param(argv[i]);
     132           0 :                         if (machine_name == NULL) {
     133           0 :                                 return -1;
     134             :                         }
     135             :                 }
     136           0 :                 if (strnequal(argv[i], "machine_account_ou", strlen("machine_account_ou"))) {
     137           0 :                         machine_account_ou = get_string_param(argv[i]);
     138           0 :                         if (machine_account_ou == NULL) {
     139           0 :                                 return -1;
     140             :                         }
     141             :                 }
     142           0 :                 if (strnequal(argv[i], "dcname", strlen("dcname"))) {
     143           0 :                         dcname = get_string_param(argv[i]);
     144           0 :                         if (dcname == NULL) {
     145           0 :                                 return -1;
     146             :                         }
     147             :                 }
     148           0 :                 if (strnequal(argv[i], "defpwd", strlen("defpwd"))) {
     149           0 :                         options |= NETSETUP_PROVISION_USE_DEFAULT_PASSWORD;
     150             :                 }
     151           0 :                 if (strnequal(argv[i], "reuse", strlen("reuse"))) {
     152           0 :                         options |= NETSETUP_PROVISION_REUSE_ACCOUNT;
     153             :                 }
     154           0 :                 if (strnequal(argv[i], "savefile", strlen("savefile"))) {
     155           0 :                         savefile = get_string_param(argv[i]);
     156           0 :                         if (savefile == NULL) {
     157           0 :                                 return -1;
     158             :                         }
     159             :                 }
     160           0 :                 if (strnequal(argv[i], "printblob", strlen("printblob"))) {
     161           0 :                         printblob = true;
     162             :                 }
     163             :         }
     164             : 
     165           0 :         if (domain == NULL) {
     166           0 :                 d_printf("Failed to provision computer account: %s\n",
     167           0 :                          libnetapi_errstr(W_ERROR_V(WERR_INVALID_DOMAINNAME)));
     168           0 :                 return -1;
     169             :         }
     170             : 
     171           0 :         if (machine_name == NULL) {
     172           0 :                 d_printf("Failed to provision computer account: %s\n",
     173           0 :                          libnetapi_errstr(W_ERROR_V(WERR_INVALID_COMPUTERNAME)));
     174           0 :                 return -1;
     175             :         }
     176             : 
     177           0 :         status = NetProvisionComputerAccount(domain,
     178             :                                              machine_name,
     179             :                                              machine_account_ou,
     180             :                                              dcname,
     181             :                                              options,
     182             :                                              NULL,
     183             :                                              0,
     184             :                                              &provision_text_data);
     185           0 :         if (status != 0) {
     186           0 :                 d_printf("Failed to provision computer account: %s\n",
     187             :                         libnetapi_get_error_string(c->netapi_ctx, status));
     188           0 :                 return status;
     189             :         }
     190             : 
     191           0 :         if (savefile != NULL) {
     192             : 
     193             :                 DATA_BLOB ucs2_blob, blob;
     194             :                 bool ok;
     195             : 
     196           0 :                 ok = push_reg_sz(c, &ucs2_blob, provision_text_data);
     197           0 :                 if (!ok) {
     198           0 :                         return -1;
     199             :                 }
     200             : 
     201           0 :                 blob = data_blob_talloc(c, NULL, ucs2_blob.length + 2);
     202             : 
     203           0 :                 blob.data[0] = 0xff;
     204           0 :                 blob.data[1] = 0xfe;
     205             : 
     206           0 :                 memcpy(blob.data + 2, ucs2_blob.data, ucs2_blob.length);
     207             : 
     208           0 :                 ok = file_save(savefile, blob.data, blob.length);
     209           0 :                 if (!ok) {
     210           0 :                         d_printf("Failed to save %s: %s\n", savefile,
     211           0 :                                         strerror(errno));
     212           0 :                         return -1;
     213             :                 }
     214             :         }
     215             : 
     216           0 :         d_printf("Successfully provisioned computer '%s' in domain '%s'\n",
     217             :                         machine_name, domain);
     218             : 
     219           0 :         if (printblob) {
     220           0 :                 printf("%s\n", provision_text_data);
     221             :         }
     222             : 
     223           0 :         return 0;
     224             : }
     225             : 
     226           0 : static int net_offlinejoin_requestodj_usage(struct net_context *c, int argc, const char **argv)
     227             : {
     228           0 :         d_printf(_("\nnet offlinejoin requestodj [misc. options]\n"
     229             :                    "\tRequests offline domain join\n"));
     230           0 :         d_printf(_("Valid options:\n"));
     231           0 :         d_printf(_("\tloadfile=<FILENAME>\t\t\tFile that provides the ODJ data\n"));
     232             :         /*d_printf(_("\tlocalos\t\t\t\t\tModify the local machine\n"));*/
     233           0 :         net_common_flags_usage(c, argc, argv);
     234           0 :         return -1;
     235             : }
     236             : 
     237           0 : int net_offlinejoin_requestodj(struct net_context *c,
     238             :                                int argc, const char **argv)
     239             : {
     240             :         NET_API_STATUS status;
     241           0 :         uint8_t *provision_bin_data = NULL;
     242           0 :         size_t provision_bin_data_size = 0;
     243           0 :         uint32_t options = NETSETUP_PROVISION_ONLINE_CALLER;
     244           0 :         const char *loadfile = NULL;
     245           0 :         const char *windows_path = NULL;
     246             :         int i;
     247             : 
     248           0 :         if (c->display_usage || argc == 1) {
     249           0 :                 return net_offlinejoin_requestodj_usage(c, argc, argv);
     250             :         }
     251             : 
     252             :         /* process additional command line args */
     253             : 
     254           0 :         for (i = 0; i < argc; i++) {
     255             : 
     256           0 :                 if (strnequal(argv[i], "loadfile", strlen("loadfile"))) {
     257           0 :                         loadfile = get_string_param(argv[i]);
     258           0 :                         if (loadfile == NULL) {
     259           0 :                                 return -1;
     260             :                         }
     261             :                 }
     262             : #if 0
     263             :                 if (strnequal(argv[i], "localos", strlen("localos"))) {
     264             :                         options |= NETSETUP_PROVISION_ONLINE_CALLER;
     265             :                 }
     266             : #endif
     267             :         }
     268             : 
     269           0 :         provision_bin_data =
     270           0 :                 (uint8_t *)file_load(loadfile, &provision_bin_data_size, 0, c);
     271           0 :         if (provision_bin_data == NULL) {
     272           0 :                 d_printf("Failed to read loadfile: %s\n", loadfile);
     273           0 :                 return -1;
     274             :         }
     275           0 :         if (provision_bin_data_size > UINT32_MAX) {
     276           0 :                 d_printf("provision binary data size too big: %zu\n",
     277             :                          provision_bin_data_size);
     278           0 :                 return -1;
     279             :         }
     280             : 
     281           0 :         status = NetRequestOfflineDomainJoin(provision_bin_data,
     282             :                                              provision_bin_data_size,
     283             :                                              options,
     284             :                                              windows_path);
     285           0 :         if (status != 0 && status != 0x00000a99) {
     286             :                 /* NERR_JoinPerformedMustRestart */
     287           0 :                 printf("Failed to call NetRequestOfflineDomainJoin: %s\n",
     288             :                         libnetapi_get_error_string(c->netapi_ctx, status));
     289           0 :                 return -1;
     290             :         }
     291             : 
     292           0 :         d_printf("Successfully requested Offline Domain Join\n");
     293             : 
     294           0 :         return 0;
     295             : }

Generated by: LCOV version 1.13