LCOV - code coverage report
Current view: top level - source3/printing - nt_printing_migrate_internal.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 14 136 10.3 %
Date: 2024-04-21 15:09:00 Functions: 1 3 33.3 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *
       5             :  *  Copyright (c) Andreas Schneider            2010.
       6             :  *
       7             :  *  This program is free software; you can redistribute it and/or modify
       8             :  *  it under the terms of the GNU General Public License as published by
       9             :  *  the Free Software Foundation; either version 3 of the License, or
      10             :  *  (at your option) any later version.
      11             :  *
      12             :  *  This program is distributed in the hope that it will be useful,
      13             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  *  GNU General Public License for more details.
      16             :  *
      17             :  *  You should have received a copy of the GNU General Public License
      18             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #include "includes.h"
      22             : #include "system/filesys.h"
      23             : #include "printing/nt_printing_migrate.h"
      24             : #include "printing/nt_printing_migrate_internal.h"
      25             : 
      26             : #include "rpc_client/rpc_client.h"
      27             : #include "librpc/gen_ndr/ndr_spoolss_c.h"
      28             : #include "librpc/gen_ndr/ndr_winreg.h"
      29             : #include "rpc_server/rpc_ncacn_np.h"
      30             : #include "auth.h"
      31             : #include "util_tdb.h"
      32             : 
      33             : #define FORMS_PREFIX "FORMS/"
      34             : #define DRIVERS_PREFIX "DRIVERS/"
      35             : #define PRINTERS_PREFIX "PRINTERS/"
      36             : #define SECDESC_PREFIX "SECDESC/"
      37             : 
      38           0 : static int rename_file_with_suffix(TALLOC_CTX *mem_ctx,
      39             :                                    const char *path,
      40             :                                    const char *suffix)
      41             : {
      42           0 :         int rc = -1;
      43           0 :         char *dst_path;
      44             : 
      45           0 :         dst_path = talloc_asprintf(mem_ctx, "%s%s", path, suffix);
      46           0 :         if (dst_path == NULL) {
      47           0 :                 DEBUG(3, ("error out of memory\n"));
      48           0 :                 return rc;
      49             :         }
      50             : 
      51           0 :         rc = (rename(path, dst_path) != 0);
      52             : 
      53           0 :         if (rc == 0) {
      54           0 :                 DEBUG(5, ("moved '%s' to '%s'\n", path, dst_path));
      55           0 :         } else if (errno == ENOENT) {
      56           0 :                 DEBUG(3, ("file '%s' does not exist - so not moved\n", path));
      57           0 :                 rc = 0;
      58             :         } else {
      59           0 :                 DEBUG(3, ("error renaming %s to %s: %s\n", path, dst_path,
      60             :                           strerror(errno)));
      61             :         }
      62             : 
      63           0 :         TALLOC_FREE(dst_path);
      64           0 :         return rc;
      65             : }
      66             : 
      67           0 : static NTSTATUS migrate_internal(TALLOC_CTX *mem_ctx,
      68             :                                  const char *tdb_path,
      69             :                                  struct rpc_pipe_client *winreg_pipe)
      70             : {
      71           0 :         const char *backup_suffix = ".bak";
      72           0 :         TDB_DATA kbuf, newkey, dbuf;
      73           0 :         TDB_CONTEXT *tdb;
      74           0 :         NTSTATUS status;
      75           0 :         int rc;
      76             : 
      77           0 :         tdb = tdb_open_log(tdb_path, 0, TDB_DEFAULT, O_RDONLY, 0600);
      78           0 :         if (tdb == NULL && errno == ENOENT) {
      79             :                 /* if we have no printers database then migration is
      80             :                    considered successful */
      81           0 :                 DEBUG(4, ("No printers database to migrate in %s\n", tdb_path));
      82           0 :                 return NT_STATUS_OK;
      83             :         }
      84           0 :         if (tdb == NULL) {
      85           0 :                 DEBUG(2, ("Failed to open tdb file: %s\n", tdb_path));
      86           0 :                 return NT_STATUS_NO_SUCH_FILE;
      87             :         }
      88             : 
      89           0 :         for (kbuf = tdb_firstkey(tdb);
      90           0 :              kbuf.dptr;
      91           0 :              newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
      92             :         {
      93           0 :                 dbuf = tdb_fetch(tdb, kbuf);
      94           0 :                 if (!dbuf.dptr) {
      95           0 :                         continue;
      96             :                 }
      97             : 
      98           0 :                 if (strncmp((const char *) kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
      99           0 :                         status = printing_tdb_migrate_form(mem_ctx,
     100             :                                               winreg_pipe,
     101           0 :                                               (const char *) kbuf.dptr + strlen(FORMS_PREFIX),
     102             :                                               dbuf.dptr,
     103             :                                               dbuf.dsize);
     104           0 :                         SAFE_FREE(dbuf.dptr);
     105           0 :                         if (!NT_STATUS_IS_OK(status)) {
     106           0 :                                 tdb_close(tdb);
     107           0 :                                 return status;
     108             :                         }
     109           0 :                         continue;
     110             :                 }
     111             : 
     112           0 :                 if (strncmp((const char *) kbuf.dptr, DRIVERS_PREFIX, strlen(DRIVERS_PREFIX)) == 0) {
     113           0 :                         status = printing_tdb_migrate_driver(mem_ctx,
     114             :                                                 winreg_pipe,
     115           0 :                                                 (const char *) kbuf.dptr + strlen(DRIVERS_PREFIX),
     116             :                                                 dbuf.dptr,
     117             :                                                 dbuf.dsize,
     118             :                                                 false);
     119           0 :                         SAFE_FREE(dbuf.dptr);
     120           0 :                         if (!NT_STATUS_IS_OK(status)) {
     121           0 :                                 tdb_close(tdb);
     122           0 :                                 return status;
     123             :                         }
     124           0 :                         continue;
     125             :                 }
     126             : 
     127           0 :                 if (strncmp((const char *) kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
     128           0 :                         const char *printer_name = (const char *)(kbuf.dptr
     129             :                                                     + strlen(PRINTERS_PREFIX));
     130           0 :                         status = printing_tdb_migrate_printer(mem_ctx,
     131             :                                                  winreg_pipe,
     132             :                                                  printer_name,
     133             :                                                  dbuf.dptr,
     134             :                                                  dbuf.dsize,
     135             :                                                  false);
     136           0 :                         SAFE_FREE(dbuf.dptr);
     137           0 :                         if (!NT_STATUS_IS_OK(status)) {
     138           0 :                                 tdb_close(tdb);
     139           0 :                                 return status;
     140             :                         }
     141           0 :                         continue;
     142             :                 }
     143           0 :                 SAFE_FREE(dbuf.dptr);
     144             :         }
     145             : 
     146           0 :         for (kbuf = tdb_firstkey(tdb);
     147           0 :              kbuf.dptr;
     148           0 :              newkey = tdb_nextkey(tdb, kbuf), free(kbuf.dptr), kbuf = newkey)
     149             :         {
     150           0 :                 dbuf = tdb_fetch(tdb, kbuf);
     151           0 :                 if (!dbuf.dptr) {
     152           0 :                         continue;
     153             :                 }
     154             : 
     155           0 :                 if (strncmp((const char *) kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
     156           0 :                         const char *secdesc_name = (const char *)(kbuf.dptr
     157             :                                                     + strlen(SECDESC_PREFIX));
     158           0 :                         status = printing_tdb_migrate_secdesc(mem_ctx,
     159             :                                                  winreg_pipe,
     160             :                                                  secdesc_name,
     161             :                                                  dbuf.dptr,
     162             :                                                  dbuf.dsize);
     163           0 :                         SAFE_FREE(dbuf.dptr);
     164           0 :                         if (NT_STATUS_EQUAL(status, werror_to_ntstatus(WERR_FILE_NOT_FOUND))) {
     165           0 :                                 DEBUG(2, ("Skipping secdesc migration for non-existent "
     166             :                                                 "printer: %s\n", secdesc_name));
     167           0 :                         } else if (!NT_STATUS_IS_OK(status)) {
     168           0 :                                 tdb_close(tdb);
     169           0 :                                 return status;
     170             :                         }
     171           0 :                         continue;
     172             :                 }
     173           0 :                 SAFE_FREE(dbuf.dptr);
     174             :         }
     175             : 
     176           0 :         tdb_close(tdb);
     177             : 
     178           0 :         rc = rename_file_with_suffix(mem_ctx, tdb_path, backup_suffix);
     179           0 :         if (rc != 0) {
     180           0 :                 DEBUG(0, ("Error moving tdb to '%s%s'\n",
     181             :                           tdb_path, backup_suffix));
     182             :         }
     183             : 
     184           0 :         return NT_STATUS_OK;
     185             : }
     186             : 
     187          28 : bool nt_printing_tdb_migrate(struct messaging_context *msg_ctx)
     188             : {
     189           0 :         const char *drivers_path;
     190           0 :         const char *printers_path;
     191           0 :         const char *forms_path;
     192           0 :         bool drivers_exists;
     193           0 :         bool printers_exists;
     194           0 :         bool forms_exists;
     195           0 :         struct auth_session_info *session_info;
     196          28 :         struct rpc_pipe_client *winreg_pipe = NULL;
     197          28 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     198           0 :         NTSTATUS status;
     199             : 
     200             :         /* paths talloced on new stackframe */
     201          28 :         drivers_path = state_path(talloc_tos(), "ntdrivers.tdb");
     202          28 :         printers_path = state_path(talloc_tos(), "ntprinters.tdb");
     203          28 :         forms_path = state_path(talloc_tos(), "ntforms.tdb");
     204          28 :         if ((drivers_path == NULL) || (printers_path == NULL)
     205          28 :                                                 || (forms_path == NULL)) {
     206           0 :                 talloc_free(tmp_ctx);
     207           0 :                 return false;
     208             :         }
     209          28 :         drivers_exists = file_exist(drivers_path);
     210          28 :         printers_exists = file_exist(printers_path);
     211          28 :         forms_exists = file_exist(forms_path);
     212             : 
     213          28 :         if (!drivers_exists && !printers_exists && !forms_exists) {
     214          28 :                 talloc_free(tmp_ctx);
     215          28 :                 return true;
     216             :         }
     217             : 
     218           0 :         status = make_session_info_system(tmp_ctx, &session_info);
     219           0 :         if (!NT_STATUS_IS_OK(status)) {
     220           0 :                 DEBUG(0, ("Couldn't create session_info: %s\n",
     221             :                           nt_errstr(status)));
     222           0 :                 talloc_free(tmp_ctx);
     223           0 :                 return false;
     224             :         }
     225             : 
     226           0 :         status = rpc_pipe_open_interface(tmp_ctx,
     227             :                                         &ndr_table_winreg,
     228             :                                         session_info,
     229             :                                         NULL,
     230             :                                         NULL,
     231             :                                         msg_ctx,
     232             :                                         &winreg_pipe);
     233           0 :         if (!NT_STATUS_IS_OK(status)) {
     234           0 :                 DEBUG(0, ("Couldn't open internal winreg pipe: %s\n",
     235             :                           nt_errstr(status)));
     236           0 :                 talloc_free(tmp_ctx);
     237           0 :                 return false;
     238             :         }
     239             : 
     240           0 :         if (drivers_exists) {
     241           0 :                 status = migrate_internal(tmp_ctx, drivers_path, winreg_pipe);
     242           0 :                 if (!NT_STATUS_IS_OK(status)) {
     243           0 :                         DEBUG(0, ("Couldn't migrate drivers tdb file: %s\n",
     244             :                           nt_errstr(status)));
     245           0 :                         talloc_free(tmp_ctx);
     246           0 :                         return false;
     247             :                 }
     248             :         }
     249             : 
     250           0 :         if (printers_exists) {
     251           0 :                 status = migrate_internal(tmp_ctx, printers_path, winreg_pipe);
     252           0 :                 if (!NT_STATUS_IS_OK(status)) {
     253           0 :                         DEBUG(0, ("Couldn't migrate printers tdb file: %s\n",
     254             :                                   nt_errstr(status)));
     255           0 :                         talloc_free(tmp_ctx);
     256           0 :                         return false;
     257             :                 }
     258             :         }
     259             : 
     260           0 :         if (forms_exists) {
     261           0 :                 status = migrate_internal(tmp_ctx, forms_path, winreg_pipe);
     262           0 :                 if (!NT_STATUS_IS_OK(status)) {
     263           0 :                         DEBUG(0, ("Couldn't migrate forms tdb file: %s\n",
     264             :                                   nt_errstr(status)));
     265           0 :                         talloc_free(tmp_ctx);
     266           0 :                         return false;
     267             :                 }
     268             :         }
     269             : 
     270           0 :         talloc_free(tmp_ctx);
     271           0 :         return true;
     272             : }

Generated by: LCOV version 1.14