LCOV - code coverage report
Current view: top level - source3/rpc_client - cli_winreg_spoolss.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 934 1937 48.2 %
Date: 2021-09-23 10:06:22 Functions: 29 45 64.4 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *
       4             :  *  SPOOLSS RPC Pipe server / winreg client routines
       5             :  *
       6             :  *  Copyright (c) 2010      Andreas Schneider <asn@samba.org>
       7             :  *
       8             :  *  This program is free software; you can redistribute it and/or modify
       9             :  *  it under the terms of the GNU General Public License as published by
      10             :  *  the Free Software Foundation; either version 3 of the License, or
      11             :  *  (at your option) any later version.
      12             :  *
      13             :  *  This program is distributed in the hope that it will be useful,
      14             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  *  GNU General Public License for more details.
      17             :  *
      18             :  *  You should have received a copy of the GNU General Public License
      19             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include "includes.h"
      23             : #include "nt_printing.h"
      24             : #include "../librpc/gen_ndr/ndr_spoolss.h"
      25             : #include "../librpc/gen_ndr/ndr_winreg_c.h"
      26             : #include "../librpc/gen_ndr/ndr_security.h"
      27             : #include "secrets.h"
      28             : #include "../libcli/security/security.h"
      29             : #include "rpc_client/cli_winreg.h"
      30             : #include "../libcli/registry/util_reg.h"
      31             : #include "rpc_client/cli_winreg_spoolss.h"
      32             : #include "printing/nt_printing_os2.h"
      33             : #include "rpc_client/init_spoolss.h"
      34             : 
      35             : #define TOP_LEVEL_PRINT_KEY "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Print"
      36             : #define TOP_LEVEL_PRINT_PRINTERS_KEY TOP_LEVEL_PRINT_KEY "\\Printers"
      37             : #define TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY TOP_LEVEL_PRINT_KEY "\\PackageInstallation"
      38             : #define TOP_LEVEL_CONTROL_KEY "SYSTEM\\CurrentControlSet\\Control\\Print"
      39             : #define TOP_LEVEL_CONTROL_FORMS_KEY TOP_LEVEL_CONTROL_KEY "\\Forms"
      40             : 
      41             : #define CHECK_ERROR(result) \
      42             :         if (W_ERROR_IS_OK(result)) continue; \
      43             :         if (W_ERROR_EQUAL(result, WERR_NOT_FOUND)) result = WERR_OK; \
      44             :         if (!W_ERROR_IS_OK(result)) break
      45             : 
      46             : /*        FLAGS,                NAME,                              with,   height,   left, top, right, bottom */
      47             : static const struct spoolss_FormInfo1 builtin_forms1[] = {
      48             :         { SPOOLSS_FORM_BUILTIN, "Letter",                         {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
      49             :         { SPOOLSS_FORM_BUILTIN, "Letter Small",                   {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
      50             :         { SPOOLSS_FORM_BUILTIN, "Tabloid",                        {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
      51             :         { SPOOLSS_FORM_BUILTIN, "Ledger",                         {0x696b8,0x44368}, {0x0,0x0,0x696b8,0x44368} },
      52             :         { SPOOLSS_FORM_BUILTIN, "Legal",                          {0x34b5c,0x56d10}, {0x0,0x0,0x34b5c,0x56d10} },
      53             :         { SPOOLSS_FORM_BUILTIN, "Statement",                      {0x221b4,0x34b5c}, {0x0,0x0,0x221b4,0x34b5c} },
      54             :         { SPOOLSS_FORM_BUILTIN, "Executive",                      {0x2cf56,0x411cc}, {0x0,0x0,0x2cf56,0x411cc} },
      55             :         { SPOOLSS_FORM_BUILTIN, "A3",                             {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
      56             :         { SPOOLSS_FORM_BUILTIN, "A4",                             {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
      57             :         { SPOOLSS_FORM_BUILTIN, "A4 Small",                       {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
      58             :         { SPOOLSS_FORM_BUILTIN, "A5",                             {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
      59             :         { SPOOLSS_FORM_BUILTIN, "B4 (JIS)",                       {0x3ebe8,0x58de0}, {0x0,0x0,0x3ebe8,0x58de0} },
      60             :         { SPOOLSS_FORM_BUILTIN, "B5 (JIS)",                       {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
      61             :         { SPOOLSS_FORM_BUILTIN, "Folio",                          {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
      62             :         { SPOOLSS_FORM_BUILTIN, "Quarto",                         {0x347d8,0x43238}, {0x0,0x0,0x347d8,0x43238} },
      63             :         { SPOOLSS_FORM_BUILTIN, "10x14",                          {0x3e030,0x56d10}, {0x0,0x0,0x3e030,0x56d10} },
      64             :         { SPOOLSS_FORM_BUILTIN, "11x17",                          {0x44368,0x696b8}, {0x0,0x0,0x44368,0x696b8} },
      65             :         { SPOOLSS_FORM_BUILTIN, "Note",                           {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
      66             :         { SPOOLSS_FORM_BUILTIN, "Envelope #9",                    {0x18079,0x37091}, {0x0,0x0,0x18079,0x37091} },
      67             :         { SPOOLSS_FORM_BUILTIN, "Envelope #10",                   {0x19947,0x3ae94}, {0x0,0x0,0x19947,0x3ae94} },
      68             :         { SPOOLSS_FORM_BUILTIN, "Envelope #11",                   {0x1be7c,0x40565}, {0x0,0x0,0x1be7c,0x40565} },
      69             :         { SPOOLSS_FORM_BUILTIN, "Envelope #12",                   {0x1d74a,0x44368}, {0x0,0x0,0x1d74a,0x44368} },
      70             :         { SPOOLSS_FORM_BUILTIN, "Envelope #14",                   {0x1f018,0x47504}, {0x0,0x0,0x1f018,0x47504} },
      71             :         { SPOOLSS_FORM_BUILTIN, "C size sheet",                   {0x696b8,0x886d0}, {0x0,0x0,0x696b8,0x886d0} },
      72             :         { SPOOLSS_FORM_BUILTIN, "D size sheet",                   {0x886d0,0xd2d70}, {0x0,0x0,0x886d0,0xd2d70} },
      73             :         { SPOOLSS_FORM_BUILTIN, "E size sheet",                   {0xd2d70,0x110da0},{0x0,0x0,0xd2d70,0x110da0} },
      74             :         { SPOOLSS_FORM_BUILTIN, "Envelope DL",                    {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
      75             :         { SPOOLSS_FORM_BUILTIN, "Envelope C5",                    {0x278d0,0x37e88}, {0x0,0x0,0x278d0,0x37e88} },
      76             :         { SPOOLSS_FORM_BUILTIN, "Envelope C3",                    {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
      77             :         { SPOOLSS_FORM_BUILTIN, "Envelope C4",                    {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
      78             :         { SPOOLSS_FORM_BUILTIN, "Envelope C6",                    {0x1bd50,0x278d0}, {0x0,0x0,0x1bd50,0x278d0} },
      79             :         { SPOOLSS_FORM_BUILTIN, "Envelope C65",                   {0x1bd50,0x37e88}, {0x0,0x0,0x1bd50,0x37e88} },
      80             :         { SPOOLSS_FORM_BUILTIN, "Envelope B4",                    {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
      81             :         { SPOOLSS_FORM_BUILTIN, "Envelope B5",                    {0x2af80,0x3d090}, {0x0,0x0,0x2af80,0x3d090} },
      82             :         { SPOOLSS_FORM_BUILTIN, "Envelope B6",                    {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
      83             :         { SPOOLSS_FORM_BUILTIN, "Envelope",                       {0x1adb0,0x38270}, {0x0,0x0,0x1adb0,0x38270} },
      84             :         { SPOOLSS_FORM_BUILTIN, "Envelope Monarch",               {0x18079,0x2e824}, {0x0,0x0,0x18079,0x2e824} },
      85             :         { SPOOLSS_FORM_BUILTIN, "6 3/4 Envelope",                 {0x167ab,0x284ec}, {0x0,0x0,0x167ab,0x284ec} },
      86             :         { SPOOLSS_FORM_BUILTIN, "US Std Fanfold",                 {0x5c3e1,0x44368}, {0x0,0x0,0x5c3e1,0x44368} },
      87             :         { SPOOLSS_FORM_BUILTIN, "German Std Fanfold",             {0x34b5c,0x4a6a0}, {0x0,0x0,0x34b5c,0x4a6a0} },
      88             :         { SPOOLSS_FORM_BUILTIN, "German Legal Fanfold",           {0x34b5c,0x509d8}, {0x0,0x0,0x34b5c,0x509d8} },
      89             :         { SPOOLSS_FORM_BUILTIN, "B4 (ISO)",                       {0x3d090,0x562e8}, {0x0,0x0,0x3d090,0x562e8} },
      90             :         { SPOOLSS_FORM_BUILTIN, "Japanese Postcard",              {0x186a0,0x24220}, {0x0,0x0,0x186a0,0x24220} },
      91             :         { SPOOLSS_FORM_BUILTIN, "9x11",                           {0x37cf8,0x44368}, {0x0,0x0,0x37cf8,0x44368} },
      92             :         { SPOOLSS_FORM_BUILTIN, "10x11",                          {0x3e030,0x44368}, {0x0,0x0,0x3e030,0x44368} },
      93             :         { SPOOLSS_FORM_BUILTIN, "15x11",                          {0x5d048,0x44368}, {0x0,0x0,0x5d048,0x44368} },
      94             :         { SPOOLSS_FORM_BUILTIN, "Envelope Invite",                {0x35b60,0x35b60}, {0x0,0x0,0x35b60,0x35b60} },
      95             :         { SPOOLSS_FORM_BUILTIN, "Reserved48",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
      96             :         { SPOOLSS_FORM_BUILTIN, "Reserved49",                     {0x1,0x1},         {0x0,0x0,0x1,0x1} },
      97             :         { SPOOLSS_FORM_BUILTIN, "Letter Extra",                   {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
      98             :         { SPOOLSS_FORM_BUILTIN, "Legal Extra",                    {0x3ae94,0x5d048}, {0x0,0x0,0x3ae94,0x5d048} },
      99             :         { SPOOLSS_FORM_BUILTIN, "Tabloid Extra",                  {0x4a6a0,0x6f9f0}, {0x0,0x0,0x4a6a0,0x6f9f0} },
     100             :         { SPOOLSS_FORM_BUILTIN, "A4 Extra",                       {0x397c2,0x4eb16}, {0x0,0x0,0x397c2,0x4eb16} },
     101             :         { SPOOLSS_FORM_BUILTIN, "Letter Transverse",              {0x34b5c,0x44368}, {0x0,0x0,0x34b5c,0x44368} },
     102             :         { SPOOLSS_FORM_BUILTIN, "A4 Transverse",                  {0x33450,0x48828}, {0x0,0x0,0x33450,0x48828} },
     103             :         { SPOOLSS_FORM_BUILTIN, "Letter Extra Transverse",        {0x3ae94,0x4a6a0}, {0x0,0x0,0x3ae94,0x4a6a0} },
     104             :         { SPOOLSS_FORM_BUILTIN, "Super A",                        {0x376b8,0x56ea0}, {0x0,0x0,0x376b8,0x56ea0} },
     105             :         { SPOOLSS_FORM_BUILTIN, "Super B",                        {0x4a768,0x76e58}, {0x0,0x0,0x4a768,0x76e58} },
     106             :         { SPOOLSS_FORM_BUILTIN, "Letter Plus",                    {0x34b5c,0x4eb16}, {0x0,0x0,0x34b5c,0x4eb16} },
     107             :         { SPOOLSS_FORM_BUILTIN, "A4 Plus",                        {0x33450,0x50910}, {0x0,0x0,0x33450,0x50910} },
     108             :         { SPOOLSS_FORM_BUILTIN, "A5 Transverse",                  {0x24220,0x33450}, {0x0,0x0,0x24220,0x33450} },
     109             :         { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Transverse",            {0x2c6f0,0x3ebe8}, {0x0,0x0,0x2c6f0,0x3ebe8} },
     110             :         { SPOOLSS_FORM_BUILTIN, "A3 Extra",                       {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
     111             :         { SPOOLSS_FORM_BUILTIN, "A5 Extra",                       {0x2a7b0,0x395f8}, {0x0,0x0,0x2a7b0,0x395f8} },
     112             :         { SPOOLSS_FORM_BUILTIN, "B5 (ISO) Extra",                 {0x31128,0x43620}, {0x0,0x0,0x31128,0x43620} },
     113             :         { SPOOLSS_FORM_BUILTIN, "A2",                             {0x668a0,0x91050}, {0x0,0x0,0x668a0,0x91050} },
     114             :         { SPOOLSS_FORM_BUILTIN, "A3 Transverse",                  {0x48828,0x668a0}, {0x0,0x0,0x48828,0x668a0} },
     115             :         { SPOOLSS_FORM_BUILTIN, "A3 Extra Transverse",            {0x4e9d0,0x6ca48}, {0x0,0x0,0x4e9d0,0x6ca48} },
     116             :         { SPOOLSS_FORM_BUILTIN, "Japanese Double Postcard",       {0x30d40,0x24220}, {0x0,0x0,0x30d40,0x24220} },
     117             :         { SPOOLSS_FORM_BUILTIN, "A6",                             {0x19a28,0x24220}, {0x0,0x0,0x19a28,0x24220} },
     118             :         { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #2 Rotated", {0x510e0,0x3a980}, {0x0,0x0,0x510e0,0x3a980} },
     119             :         { SPOOLSS_FORM_BUILTIN, "Japan Envelope Kaku #3 Rotated", {0x43a08,0x34bc0}, {0x0,0x0,0x43a08,0x34bc0} },
     120             :         { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #3 Rotated", {0x395f8,0x1d4c0}, {0x0,0x0,0x395f8,0x1d4c0} },
     121             :         { SPOOLSS_FORM_BUILTIN, "Japan Envelope Chou #4 Rotated", {0x320c8,0x15f90}, {0x0,0x0,0x320c8,0x15f90} },
     122             :         { SPOOLSS_FORM_BUILTIN, "Letter Rotated",                 {0x44368,0x34b5c}, {0x0,0x0,0x44368,0x34b5c} },
     123             :         { SPOOLSS_FORM_BUILTIN, "A3 Rotated",                     {0x668a0,0x48828}, {0x0,0x0,0x668a0,0x48828} },
     124             :         { SPOOLSS_FORM_BUILTIN, "A4 Rotated",                     {0x48828,0x33450}, {0x0,0x0,0x48828,0x33450} },
     125             :         { SPOOLSS_FORM_BUILTIN, "A5 Rotated",                     {0x33450,0x24220}, {0x0,0x0,0x33450,0x24220} },
     126             :         { SPOOLSS_FORM_BUILTIN, "B4 (JIS) Rotated",               {0x58de0,0x3ebe8}, {0x0,0x0,0x58de0,0x3ebe8} },
     127             :         { SPOOLSS_FORM_BUILTIN, "B5 (JIS) Rotated",               {0x3ebe8,0x2c6f0}, {0x0,0x0,0x3ebe8,0x2c6f0} },
     128             :         { SPOOLSS_FORM_BUILTIN, "Japanese Postcard Rotated",      {0x24220,0x186a0}, {0x0,0x0,0x24220,0x186a0} },
     129             :         { SPOOLSS_FORM_BUILTIN, "Double Japan Postcard Rotated",  {0x24220,0x30d40}, {0x0,0x0,0x24220,0x30d40} },
     130             :         { SPOOLSS_FORM_BUILTIN, "A6 Rotated",                     {0x24220,0x19a28}, {0x0,0x0,0x24220,0x19a28} },
     131             :         { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #2",      {0x3a980,0x510e0}, {0x0,0x0,0x3a980,0x510e0} },
     132             :         { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Kaku #3",      {0x34bc0,0x43a08}, {0x0,0x0,0x34bc0,0x43a08} },
     133             :         { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #3",      {0x1d4c0,0x395f8}, {0x0,0x0,0x1d4c0,0x395f8} },
     134             :         { SPOOLSS_FORM_BUILTIN, "Japanese Envelope Chou #4",      {0x15f90,0x320c8}, {0x0,0x0,0x15f90,0x320c8} },
     135             :         { SPOOLSS_FORM_BUILTIN, "B6 (JIS)",                       {0x1f400,0x2c6f0}, {0x0,0x0,0x1f400,0x2c6f0} },
     136             :         { SPOOLSS_FORM_BUILTIN, "B6 (JIS) Rotated",               {0x2c6f0,0x1f400}, {0x0,0x0,0x2c6f0,0x1f400} },
     137             :         { SPOOLSS_FORM_BUILTIN, "12x11",                          {0x4a724,0x443e1}, {0x0,0x0,0x4a724,0x443e1} },
     138             :         { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4",          {0x19a28,0x395f8}, {0x0,0x0,0x19a28,0x395f8} },
     139             :         { SPOOLSS_FORM_BUILTIN, "Japan Envelope You #4 Rotated",  {0x395f8,0x19a28}, {0x0,0x0,0x395f8,0x19a28} },
     140             :         { SPOOLSS_FORM_BUILTIN, "PRC 16K",                        {0x2de60,0x3f7a0}, {0x0,0x0,0x2de60,0x3f7a0} },
     141             :         { SPOOLSS_FORM_BUILTIN, "PRC 32K",                        {0x1fbd0,0x2cec0}, {0x0,0x0,0x1fbd0,0x2cec0} },
     142             :         { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big)",                   {0x222e0,0x318f8}, {0x0,0x0,0x222e0,0x318f8} },
     143             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1",                {0x18e70,0x28488}, {0x0,0x0,0x18e70,0x28488} },
     144             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2",                {0x18e70,0x2af80}, {0x0,0x0,0x18e70,0x2af80} },
     145             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3",                {0x1e848,0x2af80}, {0x0,0x0,0x1e848,0x2af80} },
     146             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4",                {0x1adb0,0x32c80}, {0x0,0x0,0x1adb0,0x32c80} },
     147             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5",                {0x1adb0,0x35b60}, {0x0,0x0,0x1adb0,0x35b60} },
     148             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6",                {0x1d4c0,0x38270}, {0x0,0x0,0x1d4c0,0x38270} },
     149             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7",                {0x27100,0x38270}, {0x0,0x0,0x27100,0x38270} },
     150             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8",                {0x1d4c0,0x4b708}, {0x0,0x0,0x1d4c0,0x4b708} },
     151             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9",                {0x37e88,0x4f1a0}, {0x0,0x0,0x37e88,0x4f1a0} },
     152             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10",               {0x4f1a0,0x6fd10}, {0x0,0x0,0x4f1a0,0x6fd10} },
     153             :         { SPOOLSS_FORM_BUILTIN, "PRC 16K Rotated",                {0x3f7a0,0x2de60}, {0x0,0x0,0x3f7a0,0x2de60} },
     154             :         { SPOOLSS_FORM_BUILTIN, "PRC 32K Rotated",                {0x2cec0,0x1fbd0}, {0x0,0x0,0x2cec0,0x1fbd0} },
     155             :         { SPOOLSS_FORM_BUILTIN, "PRC 32K(Big) Rotated",           {0x318f8,0x222e0}, {0x0,0x0,0x318f8,0x222e0} },
     156             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #1 Rotated",        {0x28488,0x18e70}, {0x0,0x0,0x28488,0x18e70} },
     157             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #2 Rotated",        {0x2af80,0x18e70}, {0x0,0x0,0x2af80,0x18e70} },
     158             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #3 Rotated",        {0x2af80,0x1e848}, {0x0,0x0,0x2af80,0x1e848} },
     159             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #4 Rotated",        {0x32c80,0x1adb0}, {0x0,0x0,0x32c80,0x1adb0} },
     160             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #5 Rotated",        {0x35b60,0x1adb0}, {0x0,0x0,0x35b60,0x1adb0} },
     161             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #6 Rotated",        {0x38270,0x1d4c0}, {0x0,0x0,0x38270,0x1d4c0} },
     162             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #7 Rotated",        {0x38270,0x27100}, {0x0,0x0,0x38270,0x27100} },
     163             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #8 Rotated",        {0x4b708,0x1d4c0}, {0x0,0x0,0x4b708,0x1d4c0} },
     164             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #9 Rotated",        {0x4f1a0,0x37e88}, {0x0,0x0,0x4f1a0,0x37e88} },
     165             :         { SPOOLSS_FORM_BUILTIN, "PRC Envelope #10 Rotated",       {0x6fd10,0x4f1a0}, {0x0,0x0,0x6fd10,0x4f1a0} }
     166             : };
     167             : 
     168             : /********************************************************************
     169             :  static helper functions
     170             : ********************************************************************/
     171             : 
     172             : /****************************************************************************
     173             :  Update the changeid time.
     174             : ****************************************************************************/
     175             : /**
     176             :  * @internal
     177             :  *
     178             :  * @brief Update the ChangeID time of a printer.
     179             :  *
     180             :  * This is SO NASTY as some drivers need this to change, others need it
     181             :  * static. This value will change every second, and I must hope that this
     182             :  * is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
     183             :  * UTAH ! JRA.
     184             :  *
     185             :  * @return              The ChangeID.
     186             :  */
     187        3588 : static uint32_t winreg_printer_rev_changeid(void)
     188             : {
     189             :         struct timeval tv;
     190             : 
     191        3588 :         get_process_uptime(&tv);
     192             : 
     193             : #if 1   /* JERRY */
     194             :         /* Return changeid as msec since spooler restart */
     195        3588 :         return tv.tv_sec * 1000 + tv.tv_usec / 1000;
     196             : #else
     197             :         /*
     198             :          * This setting seems to work well but is too untested
     199             :          * to replace the above calculation.  Left in for experimentation
     200             :          * of the reader            --jerry (Tue Mar 12 09:15:05 CST 2002)
     201             :          */
     202             :         return tv.tv_sec * 10 + tv.tv_usec / 100000;
     203             : #endif
     204             : }
     205             : 
     206       42899 : static WERROR winreg_printer_openkey(TALLOC_CTX *mem_ctx,
     207             :                               struct dcerpc_binding_handle *binding_handle,
     208             :                               const char *path,
     209             :                               const char *key,
     210             :                               bool create_key,
     211             :                               uint32_t access_mask,
     212             :                               struct policy_handle *hive_handle,
     213             :                               struct policy_handle *key_handle)
     214             : {
     215             :         struct winreg_String wkey, wkeyclass;
     216             :         char *keyname;
     217             :         NTSTATUS status;
     218       42899 :         WERROR result = WERR_OK;
     219             : 
     220       42899 :         status = dcerpc_winreg_OpenHKLM(binding_handle,
     221             :                                         mem_ctx,
     222             :                                         NULL,
     223             :                                         access_mask,
     224             :                                         hive_handle,
     225             :                                         &result);
     226       42899 :         if (!NT_STATUS_IS_OK(status)) {
     227           0 :                 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
     228             :                           nt_errstr(status)));
     229           0 :                 return ntstatus_to_werror(status);
     230             :         }
     231       42899 :         if (!W_ERROR_IS_OK(result)) {
     232           0 :                 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
     233             :                           win_errstr(result)));
     234           0 :                 return result;
     235             :         }
     236             : 
     237       42899 :         if (key && *key) {
     238       11650 :                 keyname = talloc_asprintf(mem_ctx, "%s\\%s", path, key);
     239             :         } else {
     240       31249 :                 keyname = talloc_strdup(mem_ctx, path);
     241             :         }
     242       42899 :         if (keyname == NULL) {
     243           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     244             :         }
     245             : 
     246       42899 :         ZERO_STRUCT(wkey);
     247       42899 :         wkey.name = keyname;
     248             : 
     249       42899 :         if (create_key) {
     250        4276 :                 enum winreg_CreateAction action = REG_ACTION_NONE;
     251             : 
     252        4276 :                 ZERO_STRUCT(wkeyclass);
     253        4276 :                 wkeyclass.name = "";
     254             : 
     255        4276 :                 status = dcerpc_winreg_CreateKey(binding_handle,
     256             :                                                  mem_ctx,
     257             :                                                  hive_handle,
     258             :                                                  wkey,
     259             :                                                  wkeyclass,
     260             :                                                  0,
     261             :                                                  access_mask,
     262             :                                                  NULL,
     263             :                                                  key_handle,
     264             :                                                  &action,
     265             :                                                  &result);
     266        4276 :                 switch (action) {
     267           0 :                         case REG_ACTION_NONE:
     268           0 :                                 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
     269           0 :                                 break;
     270         238 :                         case REG_CREATED_NEW_KEY:
     271         238 :                                 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname));
     272         238 :                                 break;
     273        4038 :                         case REG_OPENED_EXISTING_KEY:
     274        4038 :                                 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname));
     275        4038 :                                 break;
     276             :                 }
     277             :         } else {
     278       38623 :                 status = dcerpc_winreg_OpenKey(binding_handle,
     279             :                                                mem_ctx,
     280             :                                                hive_handle,
     281             :                                                wkey,
     282             :                                                0,
     283             :                                                access_mask,
     284             :                                                key_handle,
     285             :                                                &result);
     286             :         }
     287       42899 :         if (!NT_STATUS_IS_OK(status)) {
     288           0 :                 result = ntstatus_to_werror(status);
     289             :         }
     290       42899 :         if (!W_ERROR_IS_OK(result)) {
     291             :                 WERROR ignore;
     292             : 
     293        1978 :                 if (is_valid_policy_hnd(hive_handle)) {
     294        1978 :                         dcerpc_winreg_CloseKey(binding_handle,
     295             :                                                mem_ctx,
     296             :                                                hive_handle,
     297             :                                                &ignore);
     298             :                 }
     299        1978 :                 ZERO_STRUCTP(hive_handle);
     300             : 
     301        1978 :                 return result;
     302             :         }
     303             : 
     304       40921 :         return WERR_OK;
     305             : }
     306             : 
     307           0 : static WERROR winreg_printer_open_core_driver(TALLOC_CTX *mem_ctx,
     308             :                                               struct dcerpc_binding_handle *binding_handle,
     309             :                                               const char *architecture,
     310             :                                               const char *key,
     311             :                                               uint32_t access_mask,
     312             :                                               struct policy_handle *hive_handle,
     313             :                                               struct policy_handle *key_handle)
     314             : {
     315             :         struct winreg_String wkey, wkeyclass;
     316             :         NTSTATUS status;
     317           0 :         WERROR result = WERR_OK;
     318             :         WERROR ignore;
     319           0 :         enum winreg_CreateAction action = REG_ACTION_NONE;
     320             :         const char *path;
     321             : 
     322           0 :         status = dcerpc_winreg_OpenHKLM(binding_handle,
     323             :                                         mem_ctx,
     324             :                                         NULL,
     325             :                                         access_mask,
     326             :                                         hive_handle,
     327             :                                         &result);
     328           0 :         if (!NT_STATUS_IS_OK(status)) {
     329           0 :                 DEBUG(0,("winreg_printer_open_core_driver: Could not open HKLM hive: %s\n",
     330             :                           nt_errstr(status)));
     331           0 :                 return ntstatus_to_werror(status);
     332             :         }
     333           0 :         if (!W_ERROR_IS_OK(result)) {
     334           0 :                 DEBUG(0,("winreg_printer_open_core_driver: Could not open HKLM hive: %s\n",
     335             :                           win_errstr(result)));
     336           0 :                 return result;
     337             :         }
     338             : 
     339           0 :         ZERO_STRUCT(wkey);
     340           0 :         wkey.name = TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY;
     341             : 
     342           0 :         ZERO_STRUCT(wkeyclass);
     343           0 :         wkeyclass.name = "";
     344             : 
     345           0 :         status = dcerpc_winreg_CreateKey(binding_handle,
     346             :                                          mem_ctx,
     347             :                                          hive_handle,
     348             :                                          wkey,
     349             :                                          wkeyclass,
     350             :                                          0,
     351             :                                          access_mask,
     352             :                                          NULL,
     353             :                                          key_handle,
     354             :                                          &action,
     355             :                                          &result);
     356           0 :         if (!NT_STATUS_IS_OK(status)) {
     357           0 :                 result = ntstatus_to_werror(status);
     358             :         }
     359           0 :         if (!W_ERROR_IS_OK(result)) {
     360           0 :                 goto done;
     361             :         }
     362             : 
     363           0 :         dcerpc_winreg_CloseKey(binding_handle, mem_ctx, key_handle, &ignore);
     364             : 
     365           0 :         path = talloc_asprintf(mem_ctx, "%s\\%s",
     366             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
     367             :                                         architecture);
     368           0 :         if (path == NULL) {
     369           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
     370           0 :                 goto done;
     371             :         }
     372             : 
     373           0 :         wkey.name = path;
     374             : 
     375           0 :         status = dcerpc_winreg_CreateKey(binding_handle,
     376             :                                          mem_ctx,
     377             :                                          hive_handle,
     378             :                                          wkey,
     379             :                                          wkeyclass,
     380             :                                          0,
     381             :                                          access_mask,
     382             :                                          NULL,
     383             :                                          key_handle,
     384             :                                          &action,
     385             :                                          &result);
     386           0 :         if (!NT_STATUS_IS_OK(status)) {
     387           0 :                 result = ntstatus_to_werror(status);
     388             :         }
     389           0 :         if (!W_ERROR_IS_OK(result)) {
     390           0 :                 goto done;
     391             :         }
     392             : 
     393           0 :         dcerpc_winreg_CloseKey(binding_handle, mem_ctx, key_handle, &ignore);
     394             : 
     395           0 :         path = talloc_asprintf(mem_ctx, "%s\\%s\\CorePrinterDrivers",
     396             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
     397             :                                         architecture);
     398           0 :         if (path == NULL) {
     399           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
     400           0 :                 goto done;
     401             :         }
     402             : 
     403           0 :         wkey.name = path;
     404             : 
     405           0 :         status = dcerpc_winreg_CreateKey(binding_handle,
     406             :                                          mem_ctx,
     407             :                                          hive_handle,
     408             :                                          wkey,
     409             :                                          wkeyclass,
     410             :                                          0,
     411             :                                          access_mask,
     412             :                                          NULL,
     413             :                                          key_handle,
     414             :                                          &action,
     415             :                                          &result);
     416           0 :         if (!NT_STATUS_IS_OK(status)) {
     417           0 :                 result = ntstatus_to_werror(status);
     418             :         }
     419           0 :         if (!W_ERROR_IS_OK(result)) {
     420           0 :                 goto done;
     421             :         }
     422             : 
     423           0 :         dcerpc_winreg_CloseKey(binding_handle, mem_ctx, key_handle, &ignore);
     424             : 
     425           0 :         path = talloc_asprintf(mem_ctx, "%s\\%s\\CorePrinterDrivers\\%s",
     426             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
     427             :                                         architecture,
     428             :                                         key);
     429           0 :         if (path == NULL) {
     430           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
     431           0 :                 goto done;
     432             :         }
     433             : 
     434           0 :         wkey.name = path;
     435             : 
     436           0 :         status = dcerpc_winreg_CreateKey(binding_handle,
     437             :                                          mem_ctx,
     438             :                                          hive_handle,
     439             :                                          wkey,
     440             :                                          wkeyclass,
     441             :                                          0,
     442             :                                          access_mask,
     443             :                                          NULL,
     444             :                                          key_handle,
     445             :                                          &action,
     446             :                                          &result);
     447           0 :         if (!NT_STATUS_IS_OK(status)) {
     448           0 :                 result = ntstatus_to_werror(status);
     449             :         }
     450           0 :         if (!W_ERROR_IS_OK(result)) {
     451           0 :                 goto done;
     452             :         }
     453             : 
     454           0 :  done:
     455           0 :         if (is_valid_policy_hnd(hive_handle)) {
     456           0 :                 dcerpc_winreg_CloseKey(binding_handle,
     457             :                                        mem_ctx,
     458             :                                        hive_handle,
     459             :                                        &ignore);
     460             :         }
     461           0 :         ZERO_STRUCTP(hive_handle);
     462             : 
     463           0 :         return result;
     464             : }
     465             : 
     466             : /**
     467             :  * @brief Create the registry keyname for the given printer.
     468             :  *
     469             :  * @param[in]  mem_ctx  The memory context to use.
     470             :  *
     471             :  * @param[in]  printer  The name of the printer to get the registry key.
     472             :  *
     473             :  * @return     The registry key or NULL on error.
     474             :  */
     475       38749 : static char *winreg_printer_data_keyname(TALLOC_CTX *mem_ctx, const char *printer) {
     476       38749 :         return talloc_asprintf(mem_ctx, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY, printer);
     477             : }
     478             : 
     479        1840 : static WERROR winreg_printer_opendriver(TALLOC_CTX *mem_ctx,
     480             :                                         struct dcerpc_binding_handle *winreg_handle,
     481             :                                         const char *drivername,
     482             :                                         const char *architecture,
     483             :                                         uint32_t version,
     484             :                                         uint32_t access_mask,
     485             :                                         bool create,
     486             :                                         struct policy_handle *hive_hnd,
     487             :                                         struct policy_handle *key_hnd)
     488             : {
     489             :         WERROR result;
     490             :         char *key_name;
     491             : 
     492        1840 :         key_name = talloc_asprintf(mem_ctx, "%s\\Environments\\%s\\Drivers\\Version-%u",
     493             :                                    TOP_LEVEL_CONTROL_KEY,
     494             :                                    architecture, version);
     495        1840 :         if (!key_name) {
     496           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     497             :         }
     498             : 
     499        1840 :         result = winreg_printer_openkey(mem_ctx,
     500             :                                         winreg_handle,
     501             :                                         key_name,
     502             :                                         drivername,
     503             :                                         create,
     504             :                                         access_mask,
     505             :                                         hive_hnd,
     506             :                                         key_hnd);
     507        1840 :         return result;
     508             : }
     509             : 
     510      373037 : static WERROR winreg_enumval_to_dword(TALLOC_CTX *mem_ctx,
     511             :                                       struct spoolss_PrinterEnumValues *v,
     512             :                                       const char *valuename, uint32_t *dw)
     513             : {
     514             :         /* just return if it is not the one we are looking for */
     515      373037 :         if (strcmp(valuename, v->value_name) != 0) {
     516      312550 :                 return WERR_NOT_FOUND;
     517             :         }
     518             : 
     519       60487 :         if (v->type != REG_DWORD) {
     520           0 :                 return WERR_INVALID_DATATYPE;
     521             :         }
     522             : 
     523       60487 :         if (v->data_length != 4) {
     524           0 :                 *dw = 0;
     525           0 :                 return WERR_OK;
     526             :         }
     527             : 
     528       60487 :         *dw = IVAL(v->data->data, 0);
     529       60487 :         return WERR_OK;
     530             : }
     531             : 
     532     1363105 : static WERROR winreg_enumval_to_sz(TALLOC_CTX *mem_ctx,
     533             :                                    struct spoolss_PrinterEnumValues *v,
     534             :                                    const char *valuename, const char **_str)
     535             : {
     536             :         /* just return if it is not the one we are looking for */
     537     1363105 :         if (strcmp(valuename, v->value_name) != 0) {
     538     1265903 :                 return WERR_NOT_FOUND;
     539             :         }
     540             : 
     541       97202 :         if (v->type != REG_SZ) {
     542           0 :                 return WERR_INVALID_DATATYPE;
     543             :         }
     544             : 
     545       97202 :         if (v->data_length == 0) {
     546        7380 :                 *_str = talloc_strdup(mem_ctx, "");
     547        7380 :                 if (*_str == NULL) {
     548           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     549             :                 }
     550        7380 :                 return WERR_OK;
     551             :         }
     552             : 
     553       89822 :         if (!pull_reg_sz(mem_ctx, v->data, _str)) {
     554           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     555             :         }
     556             : 
     557       89822 :         return WERR_OK;
     558             : }
     559             : 
     560           0 : static WERROR winreg_enumval_to_multi_sz(TALLOC_CTX *mem_ctx,
     561             :                                          struct spoolss_PrinterEnumValues *v,
     562             :                                          const char *valuename,
     563             :                                          const char ***array)
     564             : {
     565             :         /* just return if it is not the one we are looking for */
     566           0 :         if (strcmp(valuename, v->value_name) != 0) {
     567           0 :                 return WERR_NOT_FOUND;
     568             :         }
     569             : 
     570           0 :         if (v->type != REG_MULTI_SZ) {
     571           0 :                 return WERR_INVALID_DATATYPE;
     572             :         }
     573             : 
     574           0 :         if (v->data_length == 0) {
     575           0 :                 *array = talloc_array(mem_ctx, const char *, 1);
     576           0 :                 if (*array == NULL) {
     577           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     578             :                 }
     579           0 :                 *array[0] = NULL;
     580           0 :                 return WERR_OK;
     581             :         }
     582             : 
     583           0 :         if (!pull_reg_multi_sz(mem_ctx, v->data, array)) {
     584           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     585             :         }
     586             : 
     587           0 :         return WERR_OK;
     588             : }
     589             : 
     590           0 : static WERROR winreg_printer_write_date(TALLOC_CTX *mem_ctx,
     591             :                                         struct dcerpc_binding_handle *winreg_handle,
     592             :                                         struct policy_handle *key_handle,
     593             :                                         const char *value,
     594             :                                         NTTIME data)
     595             : {
     596           0 :         struct winreg_String wvalue = { 0, };
     597             :         DATA_BLOB blob;
     598           0 :         WERROR result = WERR_OK;
     599             :         NTSTATUS status;
     600             :         const char *str;
     601             :         struct tm *tm;
     602             :         time_t t;
     603             : 
     604           0 :         if (data == 0) {
     605           0 :                 str = talloc_strdup(mem_ctx, "01/01/1601");
     606             :         } else {
     607           0 :                 t = nt_time_to_unix(data);
     608           0 :                 tm = localtime(&t);
     609           0 :                 if (tm == NULL) {
     610           0 :                         return map_werror_from_unix(errno);
     611             :                 }
     612           0 :                 str = talloc_asprintf(mem_ctx, "%02d/%02d/%04d",
     613           0 :                                       tm->tm_mon + 1, tm->tm_mday, tm->tm_year + 1900);
     614             :         }
     615           0 :         if (!str) {
     616           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     617             :         }
     618             : 
     619           0 :         wvalue.name = value;
     620           0 :         if (!push_reg_sz(mem_ctx, &blob, str)) {
     621           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     622             :         }
     623           0 :         status = dcerpc_winreg_SetValue(winreg_handle,
     624             :                                         mem_ctx,
     625             :                                         key_handle,
     626             :                                         wvalue,
     627             :                                         REG_SZ,
     628             :                                         blob.data,
     629           0 :                                         blob.length,
     630             :                                         &result);
     631           0 :         if (!NT_STATUS_IS_OK(status)) {
     632           0 :                 result = ntstatus_to_werror(status);
     633             :         }
     634           0 :         if (!W_ERROR_IS_OK(result)) {
     635           0 :                 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
     636             :                         wvalue.name, win_errstr(result)));
     637             :         }
     638             : 
     639           0 :         return result;
     640             : }
     641             : 
     642           0 : static WERROR winreg_printer_date_to_NTTIME(const char *str, NTTIME *data)
     643             : {
     644             :         bool ok;
     645             : 
     646           0 :         ok = spoolss_timestr_to_NTTIME(str, data);
     647           0 :         if (!ok) {
     648           0 :                 return WERR_INVALID_PARAMETER;
     649             :         }
     650             : 
     651           0 :         return WERR_OK;
     652             : }
     653             : 
     654           0 : static WERROR winreg_printer_write_ver(TALLOC_CTX *mem_ctx,
     655             :                                        struct dcerpc_binding_handle *winreg_handle,
     656             :                                        struct policy_handle *key_handle,
     657             :                                        const char *value,
     658             :                                        uint64_t data)
     659             : {
     660           0 :         struct winreg_String wvalue = { 0, };
     661             :         DATA_BLOB blob;
     662           0 :         WERROR result = WERR_OK;
     663             :         NTSTATUS status;
     664             :         char *str;
     665             : 
     666             :         /*
     667             :          * this needs to be something like: 6.1.7600.16385
     668             :          */
     669           0 :         str = talloc_asprintf(mem_ctx, "%u.%u.%u.%u",
     670           0 :                               (unsigned)((data >> 48) & 0xFFFF),
     671           0 :                               (unsigned)((data >> 32) & 0xFFFF),
     672           0 :                               (unsigned)((data >> 16) & 0xFFFF),
     673             :                               (unsigned)(data & 0xFFFF));
     674           0 :         if (!str) {
     675           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     676             :         }
     677             : 
     678           0 :         wvalue.name = value;
     679           0 :         if (!push_reg_sz(mem_ctx, &blob, str)) {
     680           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     681             :         }
     682           0 :         status = dcerpc_winreg_SetValue(winreg_handle,
     683             :                                         mem_ctx,
     684             :                                         key_handle,
     685             :                                         wvalue,
     686             :                                         REG_SZ,
     687             :                                         blob.data,
     688           0 :                                         blob.length,
     689             :                                         &result);
     690           0 :         if (!NT_STATUS_IS_OK(status)) {
     691           0 :                 result = ntstatus_to_werror(status);
     692             :         }
     693           0 :         if (!W_ERROR_IS_OK(result)) {
     694           0 :                 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
     695             :                         wvalue.name, win_errstr(result)));
     696             :         }
     697             : 
     698           0 :         return result;
     699             : }
     700             : 
     701           0 : static WERROR winreg_printer_ver_to_qword(const char *str, uint64_t *data)
     702             : {
     703             :         bool ok;
     704             : 
     705           0 :         ok = spoolss_driver_version_to_qword(str, data);
     706           0 :         if (!ok) {
     707           0 :                 return WERR_INVALID_PARAMETER;
     708             :         }
     709             : 
     710           0 :         return WERR_OK;
     711             : }
     712             : 
     713             : /********************************************************************
     714             :  Public winreg function for spoolss
     715             : ********************************************************************/
     716             : 
     717        1369 : WERROR winreg_create_printer(TALLOC_CTX *mem_ctx,
     718             :                              struct dcerpc_binding_handle *winreg_handle,
     719             :                              const char *sharename)
     720             : {
     721        1369 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
     722             :         struct policy_handle hive_hnd, key_hnd;
     723             :         struct spoolss_SetPrinterInfo2 *info2;
     724             :         struct security_descriptor *secdesc;
     725             :         struct winreg_String wkey, wkeyclass;
     726             :         const char *path;
     727        1369 :         const char *subkeys[] = { SPOOL_DSDRIVER_KEY, SPOOL_DSSPOOLER_KEY, SPOOL_PRINTERDATA_KEY };
     728        1369 :         uint32_t i, count = ARRAY_SIZE(subkeys);
     729        1369 :         uint32_t info2_mask = 0;
     730        1369 :         WERROR result = WERR_OK;
     731             :         WERROR ignore;
     732             :         TALLOC_CTX *tmp_ctx;
     733             : 
     734        1369 :         tmp_ctx = talloc_stackframe();
     735        1369 :         if (tmp_ctx == NULL) {
     736           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     737             :         }
     738             : 
     739        1369 :         path = winreg_printer_data_keyname(tmp_ctx, sharename);
     740        1369 :         if (path == NULL) {
     741           0 :                 TALLOC_FREE(tmp_ctx);
     742           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     743             :         }
     744             : 
     745        1369 :         ZERO_STRUCT(hive_hnd);
     746        1369 :         ZERO_STRUCT(key_hnd);
     747             : 
     748        1369 :         result = winreg_printer_openkey(tmp_ctx,
     749             :                                         winreg_handle,
     750             :                                         path,
     751             :                                         "",
     752             :                                         false,
     753             :                                         access_mask,
     754             :                                         &hive_hnd,
     755             :                                         &key_hnd);
     756        1369 :         if (W_ERROR_IS_OK(result)) {
     757        1337 :                 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path));
     758        1337 :                 goto done;
     759          32 :         } else if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
     760          32 :                 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path));
     761           0 :         } else if (!W_ERROR_IS_OK(result)) {
     762           0 :                 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
     763             :                         path, win_errstr(result)));
     764           0 :                 goto done;
     765             :         }
     766             : 
     767          32 :         if (is_valid_policy_hnd(&key_hnd)) {
     768           0 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
     769             :         }
     770          32 :         if (is_valid_policy_hnd(&hive_hnd)) {
     771           0 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
     772             :         }
     773             : 
     774             :         /* Create the main key */
     775          32 :         result = winreg_printer_openkey(tmp_ctx,
     776             :                                         winreg_handle,
     777             :                                         path,
     778             :                                         "",
     779             :                                         true,
     780             :                                         access_mask,
     781             :                                         &hive_hnd,
     782             :                                         &key_hnd);
     783          32 :         if (!W_ERROR_IS_OK(result)) {
     784           0 :                 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
     785             :                         path, win_errstr(result)));
     786           0 :                 goto done;
     787             :         }
     788             : 
     789          32 :         if (is_valid_policy_hnd(&key_hnd)) {
     790          32 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
     791             :         }
     792             : 
     793             :         /* Create subkeys */
     794         212 :         for (i = 0; i < count; i++) {
     795             :                 NTSTATUS status;
     796          96 :                 enum winreg_CreateAction action = REG_ACTION_NONE;
     797             : 
     798          96 :                 ZERO_STRUCT(key_hnd);
     799          96 :                 ZERO_STRUCT(wkey);
     800             : 
     801          96 :                 wkey.name = talloc_asprintf(tmp_ctx, "%s\\%s", path, subkeys[i]);
     802          96 :                 if (wkey.name == NULL) {
     803           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
     804           0 :                         goto done;
     805             :                 }
     806             : 
     807          96 :                 ZERO_STRUCT(wkeyclass);
     808          96 :                 wkeyclass.name = "";
     809             : 
     810          96 :                 status = dcerpc_winreg_CreateKey(winreg_handle,
     811             :                                                  tmp_ctx,
     812             :                                                  &hive_hnd,
     813             :                                                  wkey,
     814             :                                                  wkeyclass,
     815             :                                                  0,
     816             :                                                  access_mask,
     817             :                                                  NULL,
     818             :                                                  &key_hnd,
     819             :                                                  &action,
     820             :                                                  &result);
     821          96 :                 if (!NT_STATUS_IS_OK(status)) {
     822           0 :                         result = ntstatus_to_werror(status);
     823             :                 }
     824          96 :                 if (!W_ERROR_IS_OK(result)) {
     825           0 :                         DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
     826             :                                 wkey.name, win_errstr(result)));
     827           0 :                         goto done;
     828             :                 }
     829             : 
     830          96 :                 if (strequal(subkeys[i], SPOOL_DSSPOOLER_KEY)) {
     831             :                         const char *dnssuffix;
     832             :                         const char *longname;
     833             :                         const char *uncname;
     834             : 
     835          32 :                         status = dcerpc_winreg_set_sz(tmp_ctx,
     836             :                                                       winreg_handle,
     837             :                                                       &key_hnd,
     838             :                                                       SPOOL_REG_PRINTERNAME,
     839             :                                                       sharename,
     840             :                                                       &result);
     841          32 :                         if (!NT_STATUS_IS_OK(status)) {
     842           0 :                                 result = ntstatus_to_werror(status);
     843             :                         }
     844          32 :                         if (!W_ERROR_IS_OK(result)) {
     845           0 :                                 goto done;
     846             :                         }
     847             : 
     848          32 :                         status = dcerpc_winreg_set_sz(tmp_ctx,
     849             :                                                       winreg_handle,
     850             :                                                       &key_hnd,
     851             :                                                       SPOOL_REG_PRINTSHARENAME,
     852             :                                                       sharename,
     853             :                                                       &result);
     854          32 :                         if (!NT_STATUS_IS_OK(status)) {
     855           0 :                                 result = ntstatus_to_werror(status);
     856             :                         }
     857          32 :                         if (!W_ERROR_IS_OK(result)) {
     858           0 :                                 goto done;
     859             :                         }
     860             : 
     861          32 :                         status = dcerpc_winreg_set_sz(tmp_ctx,
     862             :                                                       winreg_handle,
     863             :                                                       &key_hnd,
     864             :                                                       SPOOL_REG_SHORTSERVERNAME,
     865             :                                                       lp_netbios_name(),
     866             :                                                       &result);
     867          32 :                         if (!NT_STATUS_IS_OK(status)) {
     868           0 :                                 result = ntstatus_to_werror(status);
     869             :                         }
     870          32 :                         if (!W_ERROR_IS_OK(result)) {
     871           0 :                                 goto done;
     872             :                         }
     873             : 
     874             :                         /* We make the assumption that the netbios name
     875             :                          * is the same as the DNS name since the former
     876             :                          * will be what we used to join the domain
     877             :                          */
     878          32 :                         dnssuffix = get_mydnsdomname(tmp_ctx);
     879          32 :                         if (dnssuffix != NULL && dnssuffix[0] != '\0') {
     880          32 :                                 longname = talloc_asprintf(tmp_ctx, "%s.%s", lp_netbios_name(), dnssuffix);
     881             :                         } else {
     882           0 :                                 longname = talloc_strdup(tmp_ctx, lp_netbios_name());
     883             :                         }
     884          32 :                         if (longname == NULL) {
     885           0 :                                 result = WERR_NOT_ENOUGH_MEMORY;
     886           0 :                                 goto done;
     887             :                         }
     888             : 
     889          32 :                         status = dcerpc_winreg_set_sz(tmp_ctx,
     890             :                                                       winreg_handle,
     891             :                                                       &key_hnd,
     892             :                                                       SPOOL_REG_SERVERNAME,
     893             :                                                       longname,
     894             :                                                       &result);
     895          32 :                         if (!NT_STATUS_IS_OK(status)) {
     896           0 :                                 result = ntstatus_to_werror(status);
     897             :                         }
     898          32 :                         if (!W_ERROR_IS_OK(result)) {
     899           0 :                                 goto done;
     900             :                         }
     901             : 
     902          32 :                         uncname = talloc_asprintf(tmp_ctx, "\\\\%s\\%s",
     903             :                                                   longname, sharename);
     904          32 :                         if (uncname == NULL) {
     905           0 :                                 result = WERR_NOT_ENOUGH_MEMORY;
     906           0 :                                 goto done;
     907             :                         }
     908             : 
     909          32 :                         status = dcerpc_winreg_set_sz(tmp_ctx,
     910             :                                                       winreg_handle,
     911             :                                                       &key_hnd,
     912             :                                                       SPOOL_REG_UNCNAME,
     913             :                                                       uncname,
     914             :                                                       &result);
     915          32 :                         if (!NT_STATUS_IS_OK(status)) {
     916           0 :                                 result = ntstatus_to_werror(status);
     917             :                         }
     918          32 :                         if (!W_ERROR_IS_OK(result)) {
     919           0 :                                 goto done;
     920             :                         }
     921             : 
     922          32 :                         status = dcerpc_winreg_set_dword(tmp_ctx,
     923             :                                                          winreg_handle,
     924             :                                                          &key_hnd,
     925             :                                                          SPOOL_REG_VERSIONNUMBER,
     926             :                                                          4,
     927             :                                                          &result);
     928          32 :                         if (!NT_STATUS_IS_OK(status)) {
     929           0 :                                 result = ntstatus_to_werror(status);
     930             :                         }
     931          32 :                         if (!W_ERROR_IS_OK(result)) {
     932           0 :                                 goto done;
     933             :                         }
     934             : 
     935          32 :                         status = dcerpc_winreg_set_dword(tmp_ctx,
     936             :                                                          winreg_handle,
     937             :                                                          &key_hnd,
     938             :                                                          SPOOL_REG_PRINTSTARTTIME,
     939             :                                                          0,
     940             :                                                          &result);
     941          32 :                         if (!NT_STATUS_IS_OK(status)) {
     942           0 :                                 result = ntstatus_to_werror(status);
     943             :                         }
     944          32 :                         if (!W_ERROR_IS_OK(result)) {
     945           0 :                                 goto done;
     946             :                         }
     947             : 
     948          32 :                         status = dcerpc_winreg_set_dword(tmp_ctx,
     949             :                                                          winreg_handle,
     950             :                                                          &key_hnd,
     951             :                                                          SPOOL_REG_PRINTENDTIME,
     952             :                                                          0,
     953             :                                                          &result);
     954          32 :                         if (!NT_STATUS_IS_OK(status)) {
     955           0 :                                 result = ntstatus_to_werror(status);
     956             :                         }
     957          32 :                         if (!W_ERROR_IS_OK(result)) {
     958           0 :                                 goto done;
     959             :                         }
     960             : 
     961          32 :                         status = dcerpc_winreg_set_dword(tmp_ctx,
     962             :                                                          winreg_handle,
     963             :                                                          &key_hnd,
     964             :                                                          SPOOL_REG_PRIORITY,
     965             :                                                          1,
     966             :                                                          &result);
     967          32 :                         if (!NT_STATUS_IS_OK(status)) {
     968           0 :                                 result = ntstatus_to_werror(status);
     969             :                         }
     970          32 :                         if (!W_ERROR_IS_OK(result)) {
     971           0 :                                 goto done;
     972             :                         }
     973             : 
     974          32 :                         status = dcerpc_winreg_set_dword(tmp_ctx,
     975             :                                                          winreg_handle,
     976             :                                                          &key_hnd,
     977             :                                                          SPOOL_REG_PRINTKEEPPRINTEDJOBS,
     978             :                                                          0,
     979             :                                                          &result);
     980          32 :                         if (!NT_STATUS_IS_OK(status)) {
     981           0 :                                 result = ntstatus_to_werror(status);
     982             :                         }
     983          32 :                         if (!W_ERROR_IS_OK(result)) {
     984           0 :                                 goto done;
     985             :                         }
     986             :                 }
     987             : 
     988          96 :                 if (is_valid_policy_hnd(&key_hnd)) {
     989          96 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
     990             :                 }
     991             :         }
     992          32 :         info2 = talloc_zero(tmp_ctx, struct spoolss_SetPrinterInfo2);
     993          32 :         if (info2 == NULL) {
     994           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
     995           0 :                 goto done;
     996             :         }
     997             : 
     998          32 :         info2->printername = sharename;
     999          32 :         if (info2->printername == NULL) {
    1000           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    1001           0 :                 goto done;
    1002             :         }
    1003          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_PRINTERNAME;
    1004             : 
    1005          32 :         info2->sharename = sharename;
    1006          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_SHARENAME;
    1007             : 
    1008          32 :         info2->portname = SAMBA_PRINTER_PORT_NAME;
    1009          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_PORTNAME;
    1010             : 
    1011          32 :         info2->printprocessor = "winprint";
    1012          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR;
    1013             : 
    1014          32 :         info2->datatype = "RAW";
    1015          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_DATATYPE;
    1016             : 
    1017          32 :         info2->comment = "";
    1018          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_COMMENT;
    1019             : 
    1020          32 :         info2->attributes = PRINTER_ATTRIBUTE_SAMBA;
    1021          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_ATTRIBUTES;
    1022             : 
    1023          32 :         info2->starttime = 0; /* Minutes since 12:00am GMT */
    1024          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_STARTTIME;
    1025             : 
    1026          32 :         info2->untiltime = 0; /* Minutes since 12:00am GMT */
    1027          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_UNTILTIME;
    1028             : 
    1029          32 :         info2->priority = 1;
    1030          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_PRIORITY;
    1031             : 
    1032          32 :         info2->defaultpriority = 1;
    1033          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY;
    1034             : 
    1035          32 :         result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
    1036          32 :         if (!W_ERROR_IS_OK(result)) {
    1037           0 :                 goto done;
    1038             :         }
    1039          32 :         info2_mask |= SPOOLSS_PRINTER_INFO_SECDESC;
    1040             : 
    1041             :         /*
    1042             :          * Don't write a default Device Mode to the registry! The Device Mode is
    1043             :          * only written to disk with a SetPrinter level 2 or 8.
    1044             :          */
    1045             : 
    1046          32 :         result = winreg_update_printer(tmp_ctx,
    1047             :                                        winreg_handle,
    1048             :                                        sharename,
    1049             :                                        info2_mask,
    1050             :                                        info2,
    1051             :                                        NULL,
    1052             :                                        secdesc);
    1053             : 
    1054        1369 : done:
    1055        1369 :         if (is_valid_policy_hnd(&key_hnd)) {
    1056        1337 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    1057             :         }
    1058        1369 :         if (is_valid_policy_hnd(&hive_hnd)) {
    1059        1369 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1060             :         }
    1061             : 
    1062        1369 :         talloc_free(tmp_ctx);
    1063        1369 :         return result;
    1064             : }
    1065             : 
    1066         428 : WERROR winreg_update_printer(TALLOC_CTX *mem_ctx,
    1067             :                              struct dcerpc_binding_handle *winreg_handle,
    1068             :                              const char *sharename,
    1069             :                              uint32_t info2_mask,
    1070             :                              struct spoolss_SetPrinterInfo2 *info2,
    1071             :                              struct spoolss_DeviceMode *devmode,
    1072             :                              struct security_descriptor *secdesc)
    1073             : {
    1074         428 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1075             :         struct policy_handle hive_hnd, key_hnd;
    1076         428 :         int snum = lp_servicenumber(sharename);
    1077             :         enum ndr_err_code ndr_err;
    1078             :         DATA_BLOB blob;
    1079             :         char *path;
    1080         428 :         WERROR result = WERR_OK;
    1081             :         WERROR ignore;
    1082             :         NTSTATUS status;
    1083             :         TALLOC_CTX *tmp_ctx;
    1084             : 
    1085         428 :         tmp_ctx = talloc_stackframe();
    1086         428 :         if (tmp_ctx == NULL) {
    1087           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1088             :         }
    1089             : 
    1090         428 :         path = winreg_printer_data_keyname(tmp_ctx, sharename);
    1091         428 :         if (path == NULL) {
    1092           0 :                 TALLOC_FREE(tmp_ctx);
    1093           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1094             :         }
    1095             : 
    1096         428 :         ZERO_STRUCT(hive_hnd);
    1097         428 :         ZERO_STRUCT(key_hnd);
    1098             : 
    1099         428 :         result = winreg_printer_openkey(tmp_ctx,
    1100             :                                         winreg_handle,
    1101             :                                         path,
    1102             :                                         "",
    1103             :                                         true,
    1104             :                                         access_mask,
    1105             :                                         &hive_hnd,
    1106             :                                         &key_hnd);
    1107         428 :         if (!W_ERROR_IS_OK(result)) {
    1108           0 :                 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
    1109             :                         path, win_errstr(result)));
    1110           0 :                 goto done;
    1111             :         }
    1112             : 
    1113         428 :         if (info2_mask & SPOOLSS_PRINTER_INFO_ATTRIBUTES) {
    1114         132 :                 status = dcerpc_winreg_set_dword(tmp_ctx,
    1115             :                                                  winreg_handle,
    1116             :                                                  &key_hnd,
    1117             :                                                  "Attributes",
    1118             :                                                  info2->attributes,
    1119             :                                                  &result);
    1120         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1121           0 :                         result = ntstatus_to_werror(status);
    1122             :                 }
    1123         132 :                 if (!W_ERROR_IS_OK(result)) {
    1124           0 :                         goto done;
    1125             :                 }
    1126             :         }
    1127             : 
    1128             : #if 0
    1129             :         if (info2_mask & SPOOLSS_PRINTER_INFO_AVERAGEPPM) {
    1130             :                 status = dcerpc_winreg_set_dword(tmp_ctx,
    1131             :                                                  winreg_handle,
    1132             :                                                  &key_hnd,
    1133             :                                                  "AveragePpm",
    1134             :                                                  info2->attributes,
    1135             :                                                  &result);
    1136             :                 if (!NT_STATUS_IS_OK(status)) {
    1137             :                         result = ntstatus_to_werror(status);
    1138             :                 }
    1139             :                 if (!W_ERROR_IS_OK(result)) {
    1140             :                         goto done;
    1141             :                 }
    1142             :         }
    1143             : #endif
    1144             : 
    1145         428 :         if (info2_mask & SPOOLSS_PRINTER_INFO_COMMENT) {
    1146         132 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1147             :                                               winreg_handle,
    1148             :                                               &key_hnd,
    1149             :                                               "Description",
    1150             :                                               info2->comment,
    1151             :                                               &result);
    1152         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1153           0 :                         result = ntstatus_to_werror(status);
    1154             :                 }
    1155         132 :                 if (!W_ERROR_IS_OK(result)) {
    1156           0 :                         goto done;
    1157             :                 }
    1158             :         }
    1159             : 
    1160         428 :         if (info2_mask & SPOOLSS_PRINTER_INFO_DATATYPE) {
    1161         132 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1162             :                                               winreg_handle,
    1163             :                                               &key_hnd,
    1164             :                                               "Datatype",
    1165             :                                               info2->datatype,
    1166             :                                               &result);
    1167         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1168           0 :                         result = ntstatus_to_werror(status);
    1169             :                 }
    1170         132 :                 if (!W_ERROR_IS_OK(result)) {
    1171           0 :                         goto done;
    1172             :                 }
    1173             :         }
    1174             : 
    1175         428 :         if (info2_mask & SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY) {
    1176         132 :                 status = dcerpc_winreg_set_dword(tmp_ctx,
    1177             :                                                  winreg_handle,
    1178             :                                                  &key_hnd,
    1179             :                                                  "Default Priority",
    1180             :                                                  info2->defaultpriority,
    1181             :                                                  &result);
    1182         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1183           0 :                         result = ntstatus_to_werror(status);
    1184             :                 }
    1185         132 :                 if (!W_ERROR_IS_OK(result)) {
    1186           0 :                         goto done;
    1187             :                 }
    1188             :         }
    1189             : 
    1190         428 :         if (info2_mask & SPOOLSS_PRINTER_INFO_DEVMODE) {
    1191             :                 /*
    1192             :                  * Some client drivers freak out if there is a NULL devmode
    1193             :                  * (probably the driver is not checking before accessing
    1194             :                  * the devmode pointer)   --jerry
    1195             :                  */
    1196         304 :                 if (devmode == NULL && lp_default_devmode(snum) && info2 != NULL) {
    1197           0 :                         result = spoolss_create_default_devmode(tmp_ctx,
    1198             :                                                                 info2->printername,
    1199             :                                                                 &devmode);
    1200           0 :                         if (!W_ERROR_IS_OK(result)) {
    1201           0 :                                 goto done;
    1202             :                         }
    1203             :                 }
    1204             : 
    1205         304 :                 if (devmode->size != (ndr_size_spoolss_DeviceMode(devmode, 0) - devmode->__driverextra_length)) {
    1206          32 :                         result = WERR_INVALID_PARAMETER;
    1207          32 :                         goto done;
    1208             :                 }
    1209             : 
    1210         272 :                 ndr_err = ndr_push_struct_blob(&blob, tmp_ctx, devmode,
    1211             :                                 (ndr_push_flags_fn_t) ndr_push_spoolss_DeviceMode);
    1212         272 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1213           0 :                         DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
    1214           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
    1215           0 :                         goto done;
    1216             :                 }
    1217             : 
    1218         272 :                 status = dcerpc_winreg_set_binary(tmp_ctx,
    1219             :                                                   winreg_handle,
    1220             :                                                   &key_hnd,
    1221             :                                                   "Default DevMode",
    1222             :                                                   &blob,
    1223             :                                                   &result);
    1224         272 :                 if (!NT_STATUS_IS_OK(status)) {
    1225           0 :                         result = ntstatus_to_werror(status);
    1226             :                 }
    1227         272 :                 if (!W_ERROR_IS_OK(result)) {
    1228           0 :                         goto done;
    1229             :                 }
    1230             :         }
    1231             : 
    1232         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_DRIVERNAME) {
    1233         100 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1234             :                                               winreg_handle,
    1235             :                                               &key_hnd,
    1236             :                                               "Printer Driver",
    1237             :                                               info2->drivername,
    1238             :                                               &result);
    1239         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1240           0 :                         result = ntstatus_to_werror(status);
    1241             :                 }
    1242         100 :                 if (!W_ERROR_IS_OK(result)) {
    1243           0 :                         goto done;
    1244             :                 }
    1245             :         }
    1246             : 
    1247         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_LOCATION) {
    1248         100 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1249             :                                               winreg_handle,
    1250             :                                               &key_hnd,
    1251             :                                               "Location",
    1252             :                                               info2->location,
    1253             :                                               &result);
    1254         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1255           0 :                         result = ntstatus_to_werror(status);
    1256             :                 }
    1257         100 :                 if (!W_ERROR_IS_OK(result)) {
    1258           0 :                         goto done;
    1259             :                 }
    1260             :         }
    1261             : 
    1262         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_PARAMETERS) {
    1263         100 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1264             :                                               winreg_handle,
    1265             :                                               &key_hnd,
    1266             :                                               "Parameters",
    1267             :                                               info2->parameters,
    1268             :                                               &result);
    1269         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1270           0 :                         result = ntstatus_to_werror(status);
    1271             :                 }
    1272         100 :                 if (!W_ERROR_IS_OK(result)) {
    1273           0 :                         goto done;
    1274             :                 }
    1275             :         }
    1276             : 
    1277         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_PORTNAME) {
    1278         132 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1279             :                                               winreg_handle,
    1280             :                                               &key_hnd,
    1281             :                                               "Port",
    1282             :                                               info2->portname,
    1283             :                                               &result);
    1284         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1285           0 :                         result = ntstatus_to_werror(status);
    1286             :                 }
    1287         132 :                 if (!W_ERROR_IS_OK(result)) {
    1288           0 :                         goto done;
    1289             :                 }
    1290             :         }
    1291             : 
    1292         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTERNAME) {
    1293             :                 /*
    1294             :                  * in addprinter: no servername and the printer is the name
    1295             :                  * in setprinter: servername is \\server
    1296             :                  *                and printer is \\server\\printer
    1297             :                  *
    1298             :                  * Samba manages only local printers.
    1299             :                  * we currently don't support things like i
    1300             :                  * path=\\other_server\printer
    1301             :                  *
    1302             :                  * We only store the printername, not \\server\printername
    1303             :                  */
    1304         132 :                 const char *p = strrchr(info2->printername, '\\');
    1305         132 :                 if (p == NULL) {
    1306          32 :                         p = info2->printername;
    1307             :                 } else {
    1308         100 :                         p++;
    1309             :                 }
    1310         132 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1311             :                                               winreg_handle,
    1312             :                                               &key_hnd,
    1313             :                                               "Name",
    1314             :                                               p,
    1315             :                                               &result);
    1316         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1317           0 :                         result = ntstatus_to_werror(status);
    1318             :                 }
    1319         132 :                 if (!W_ERROR_IS_OK(result)) {
    1320           0 :                         goto done;
    1321             :                 }
    1322             :         }
    1323             : 
    1324         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_PRINTPROCESSOR) {
    1325         132 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1326             :                                               winreg_handle,
    1327             :                                               &key_hnd,
    1328             :                                               "Print Processor",
    1329             :                                               info2->printprocessor,
    1330             :                                               &result);
    1331         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1332           0 :                         result = ntstatus_to_werror(status);
    1333             :                 }
    1334         132 :                 if (!W_ERROR_IS_OK(result)) {
    1335           0 :                         goto done;
    1336             :                 }
    1337             :         }
    1338             : 
    1339         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_PRIORITY) {
    1340         132 :                 status = dcerpc_winreg_set_dword(tmp_ctx,
    1341             :                                                  winreg_handle,
    1342             :                                                  &key_hnd,
    1343             :                                                  "Priority",
    1344             :                                                  info2->priority,
    1345             :                                                  &result);
    1346         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1347           0 :                         result = ntstatus_to_werror(status);
    1348             :                 }
    1349         132 :                 if (!W_ERROR_IS_OK(result)) {
    1350           0 :                         goto done;
    1351             :                 }
    1352             :         }
    1353             : 
    1354         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_SECDESC) {
    1355             :                 /*
    1356             :                  * We need a security descriptor, if it isn't specified by
    1357             :                  * AddPrinter{Ex} then create a default descriptor.
    1358             :                  */
    1359          48 :                 if (secdesc == NULL) {
    1360          16 :                         result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
    1361          16 :                         if (!W_ERROR_IS_OK(result)) {
    1362           0 :                                 goto done;
    1363             :                         }
    1364             :                 }
    1365          48 :                 result = winreg_set_printer_secdesc(tmp_ctx,
    1366             :                                                     winreg_handle,
    1367             :                                                     sharename,
    1368             :                                                     secdesc);
    1369          48 :                 if (!W_ERROR_IS_OK(result)) {
    1370           0 :                         goto done;
    1371             :                 }
    1372             :         }
    1373             : 
    1374         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_SEPFILE) {
    1375         100 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1376             :                                               winreg_handle,
    1377             :                                               &key_hnd,
    1378             :                                               "Separator File",
    1379             :                                               info2->sepfile,
    1380             :                                               &result);
    1381         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1382           0 :                         result = ntstatus_to_werror(status);
    1383             :                 }
    1384         100 :                 if (!W_ERROR_IS_OK(result)) {
    1385           0 :                         goto done;
    1386             :                 }
    1387             :         }
    1388             : 
    1389         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_SHARENAME) {
    1390         132 :                 status = dcerpc_winreg_set_sz(tmp_ctx,
    1391             :                                               winreg_handle,
    1392             :                                               &key_hnd,
    1393             :                                               "Share Name",
    1394             :                                               info2->sharename,
    1395             :                                               &result);
    1396         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1397           0 :                         result = ntstatus_to_werror(status);
    1398             :                 }
    1399         132 :                 if (!W_ERROR_IS_OK(result)) {
    1400           0 :                         goto done;
    1401             :                 }
    1402             :         }
    1403             : 
    1404         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_STARTTIME) {
    1405         132 :                 status = dcerpc_winreg_set_dword(tmp_ctx,
    1406             :                                                  winreg_handle,
    1407             :                                                  &key_hnd,
    1408             :                                                  "StartTime",
    1409             :                                                  info2->starttime,
    1410             :                                                  &result);
    1411         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1412           0 :                         result = ntstatus_to_werror(status);
    1413             :                 }
    1414         132 :                 if (!W_ERROR_IS_OK(result)) {
    1415           0 :                         goto done;
    1416             :                 }
    1417             :         }
    1418             : 
    1419         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_STATUS) {
    1420         100 :                 status = dcerpc_winreg_set_dword(tmp_ctx,
    1421             :                                                  winreg_handle,
    1422             :                                                  &key_hnd,
    1423             :                                                  "Status",
    1424             :                                                  info2->status,
    1425             :                                                  &result);
    1426         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1427           0 :                         result = ntstatus_to_werror(status);
    1428             :                 }
    1429         100 :                 if (!W_ERROR_IS_OK(result)) {
    1430           0 :                         goto done;
    1431             :                 }
    1432             :         }
    1433             : 
    1434         396 :         if (info2_mask & SPOOLSS_PRINTER_INFO_UNTILTIME) {
    1435         132 :                 status = dcerpc_winreg_set_dword(tmp_ctx,
    1436             :                                                  winreg_handle,
    1437             :                                                  &key_hnd,
    1438             :                                                  "UntilTime",
    1439             :                                                  info2->untiltime,
    1440             :                                                  &result);
    1441         132 :                 if (!NT_STATUS_IS_OK(status)) {
    1442           0 :                         result = ntstatus_to_werror(status);
    1443             :                 }
    1444         132 :                 if (!W_ERROR_IS_OK(result)) {
    1445           0 :                         goto done;
    1446             :                 }
    1447             :         }
    1448             : 
    1449         396 :         status = dcerpc_winreg_set_dword(tmp_ctx,
    1450             :                                          winreg_handle,
    1451             :                                          &key_hnd,
    1452             :                                          "ChangeID",
    1453             :                                          winreg_printer_rev_changeid(),
    1454             :                                          &result);
    1455         396 :         if (!NT_STATUS_IS_OK(status)) {
    1456           0 :                 result = ntstatus_to_werror(status);
    1457             :         }
    1458         396 :         if (!W_ERROR_IS_OK(result)) {
    1459           0 :                 goto done;
    1460             :         }
    1461             : 
    1462         396 :         result = WERR_OK;
    1463         428 : done:
    1464         428 :         if (is_valid_policy_hnd(&key_hnd)) {
    1465         428 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    1466             :         }
    1467         428 :         if (is_valid_policy_hnd(&hive_hnd)) {
    1468         428 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1469             :         }
    1470             : 
    1471         428 :         TALLOC_FREE(tmp_ctx);
    1472         428 :         return result;
    1473             : }
    1474             : 
    1475       10437 : WERROR winreg_get_printer(TALLOC_CTX *mem_ctx,
    1476             :                           struct dcerpc_binding_handle *winreg_handle,
    1477             :                           const char *printer,
    1478             :                           struct spoolss_PrinterInfo2 **pinfo2)
    1479             : {
    1480             :         struct spoolss_PrinterInfo2 *info2;
    1481       10437 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1482       10437 :         struct policy_handle hive_hnd = { .handle_type = 0 };
    1483       10437 :         struct policy_handle key_hnd = { .handle_type = 0 };
    1484             :         struct spoolss_PrinterEnumValues enum_value;
    1485       10437 :         struct spoolss_PrinterEnumValues *v = NULL;
    1486             :         enum ndr_err_code ndr_err;
    1487             :         DATA_BLOB blob;
    1488       10437 :         int snum = lp_servicenumber(printer);
    1489       10437 :         uint32_t num_values = 0;
    1490             :         uint32_t i;
    1491             :         char *path;
    1492             :         NTSTATUS status;
    1493       10437 :         WERROR result = WERR_OK;
    1494             :         WERROR ignore;
    1495       10437 :         const char **enum_names = NULL;
    1496       10437 :         enum winreg_Type *enum_types = NULL;
    1497       10437 :         DATA_BLOB *enum_data_blobs = NULL;
    1498       10437 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1499             : 
    1500       10437 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    1501       10437 :         if (path == NULL) {
    1502           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    1503           0 :                 goto done;
    1504             :         }
    1505             : 
    1506       10437 :         result = winreg_printer_openkey(tmp_ctx,
    1507             :                                         winreg_handle,
    1508             :                                         path,
    1509             :                                         "",
    1510             :                                         false,
    1511             :                                         access_mask,
    1512             :                                         &hive_hnd,
    1513             :                                         &key_hnd);
    1514       10437 :         if (!W_ERROR_IS_OK(result)) {
    1515          88 :                 DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
    1516             :                           path, win_errstr(result)));
    1517          88 :                 goto done;
    1518             :         }
    1519             : 
    1520       10349 :         status = dcerpc_winreg_enumvals(tmp_ctx,
    1521             :                                         winreg_handle,
    1522             :                                         &key_hnd,
    1523             :                                         &num_values,
    1524             :                                         &enum_names,
    1525             :                                         &enum_types,
    1526             :                                         &enum_data_blobs,
    1527             :                                         &result);
    1528       10349 :         if (!NT_STATUS_IS_OK(status)){
    1529           0 :                 result = ntstatus_to_werror(status);
    1530             :         }
    1531             : 
    1532       10349 :         if (!W_ERROR_IS_OK(result)) {
    1533           0 :                 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
    1534             :                           path, win_errstr(result)));
    1535           0 :                 goto done;
    1536             :         }
    1537             : 
    1538       10349 :         result = WERR_NOT_ENOUGH_MEMORY;
    1539             : 
    1540       10349 :         info2 = talloc_zero(tmp_ctx, struct spoolss_PrinterInfo2);
    1541       10349 :         if (info2 == NULL) {
    1542           0 :                 goto done;
    1543             :         }
    1544             : 
    1545       10349 :         info2->servername = talloc_strdup(info2, "");
    1546       10349 :         if (info2->servername == NULL) {
    1547           0 :                 goto done;
    1548             :         }
    1549       10349 :         info2->printername = talloc_strdup(info2, "");
    1550       10349 :         if (info2->printername == NULL) {
    1551           0 :                 goto done;
    1552             :         }
    1553       10349 :         info2->sharename = talloc_strdup(info2, "");
    1554       10349 :         if (info2->sharename == NULL) {
    1555           0 :                 goto done;
    1556             :         }
    1557       10349 :         info2->portname = talloc_strdup(info2, "");
    1558       10349 :         if (info2->portname == NULL) {
    1559           0 :                 goto done;
    1560             :         }
    1561       10349 :         info2->drivername = talloc_strdup(info2, "");
    1562       10349 :         if (info2->drivername == NULL) {
    1563           0 :                 goto done;
    1564             :         }
    1565       10349 :         info2->comment = talloc_strdup(info2, "");
    1566       10349 :         if (info2->comment == NULL) {
    1567           0 :                 goto done;
    1568             :         }
    1569       10349 :         info2->location = talloc_strdup(info2, "");
    1570       10349 :         if (info2->location == NULL) {
    1571           0 :                 goto done;
    1572             :         }
    1573       10349 :         info2->sepfile = talloc_strdup(info2, "");
    1574       10349 :         if (info2->sepfile == NULL) {
    1575           0 :                 goto done;
    1576             :         }
    1577       10349 :         info2->printprocessor = talloc_strdup(info2, "");
    1578       10349 :         if (info2->printprocessor == NULL) {
    1579           0 :                 goto done;
    1580             :         }
    1581       10349 :         info2->datatype = talloc_strdup(info2, "");
    1582       10349 :         if (info2->datatype == NULL) {
    1583           0 :                 goto done;
    1584             :         }
    1585       10349 :         info2->parameters = talloc_strdup(info2, "");
    1586       10349 :         if (info2->parameters == NULL) {
    1587           0 :                 goto done;
    1588             :         }
    1589             : 
    1590      191638 :         for (i = 0; i < num_values; i++) {
    1591      181289 :                 enum_value.value_name = enum_names[i];
    1592      181289 :                 enum_value.value_name_len = 2*strlen_m_term(enum_names[i]);
    1593      181289 :                 enum_value.type = enum_types[i];
    1594      181289 :                 enum_value.data_length = enum_data_blobs[i].length;
    1595      181289 :                 enum_value.data = NULL;
    1596      181289 :                 if (enum_value.data_length != 0){
    1597      173909 :                         enum_value.data = &enum_data_blobs[i];
    1598             :                 }
    1599      181289 :                 v = &enum_value;
    1600             : 
    1601      181289 :                 result = winreg_enumval_to_sz(info2,
    1602             :                                               v,
    1603             :                                               "Name",
    1604      181289 :                                               &info2->printername);
    1605      181289 :                 CHECK_ERROR(result);
    1606             : 
    1607      170950 :                 result = winreg_enumval_to_sz(info2,
    1608             :                                               v,
    1609             :                                               "Share Name",
    1610      170950 :                                               &info2->sharename);
    1611      170950 :                 CHECK_ERROR(result);
    1612             : 
    1613      160611 :                 result = winreg_enumval_to_sz(info2,
    1614             :                                               v,
    1615             :                                               "Port",
    1616      160611 :                                               &info2->portname);
    1617      160611 :                 CHECK_ERROR(result);
    1618             : 
    1619      150272 :                 result = winreg_enumval_to_sz(info2,
    1620             :                                               v,
    1621             :                                               "Description",
    1622      150272 :                                               &info2->comment);
    1623      150272 :                 CHECK_ERROR(result);
    1624             : 
    1625      139933 :                 result = winreg_enumval_to_sz(info2,
    1626             :                                               v,
    1627             :                                               "Location",
    1628      139933 :                                               &info2->location);
    1629      139933 :                 CHECK_ERROR(result);
    1630             : 
    1631      131141 :                 result = winreg_enumval_to_sz(info2,
    1632             :                                               v,
    1633             :                                               "Separator File",
    1634      131141 :                                               &info2->sepfile);
    1635      131141 :                 CHECK_ERROR(result);
    1636             : 
    1637      122349 :                 result = winreg_enumval_to_sz(info2,
    1638             :                                               v,
    1639             :                                               "Print Processor",
    1640      122349 :                                               &info2->printprocessor);
    1641      122349 :                 CHECK_ERROR(result);
    1642             : 
    1643      112010 :                 result = winreg_enumval_to_sz(info2,
    1644             :                                               v,
    1645             :                                               "Datatype",
    1646      112010 :                                               &info2->datatype);
    1647      112010 :                 CHECK_ERROR(result);
    1648             : 
    1649      101671 :                 result = winreg_enumval_to_sz(info2,
    1650             :                                               v,
    1651             :                                               "Parameters",
    1652      101671 :                                               &info2->parameters);
    1653      101671 :                 CHECK_ERROR(result);
    1654             : 
    1655       92879 :                 result = winreg_enumval_to_sz(info2,
    1656             :                                               v,
    1657             :                                               "Printer Driver",
    1658       92879 :                                               &info2->drivername);
    1659       92879 :                 CHECK_ERROR(result);
    1660             : 
    1661       84087 :                 result = winreg_enumval_to_dword(info2,
    1662             :                                                  v,
    1663             :                                                  "Attributes",
    1664       84087 :                                                  &info2->attributes);
    1665       84087 :                 CHECK_ERROR(result);
    1666             : 
    1667       73748 :                 result = winreg_enumval_to_dword(info2,
    1668             :                                                  v,
    1669             :                                                  "Priority",
    1670       73748 :                                                  &info2->priority);
    1671       73748 :                 CHECK_ERROR(result);
    1672             : 
    1673       63409 :                 result = winreg_enumval_to_dword(info2,
    1674             :                                                  v,
    1675             :                                                  "Default Priority",
    1676       63409 :                                                  &info2->defaultpriority);
    1677       63409 :                 CHECK_ERROR(result);
    1678             : 
    1679       53070 :                 result = winreg_enumval_to_dword(info2,
    1680             :                                                  v,
    1681             :                                                  "StartTime",
    1682       53070 :                                                  &info2->starttime);
    1683       53070 :                 CHECK_ERROR(result);
    1684             : 
    1685       42731 :                 result = winreg_enumval_to_dword(info2,
    1686             :                                                  v,
    1687             :                                                  "UntilTime",
    1688       42731 :                                                  &info2->untiltime);
    1689       42731 :                 CHECK_ERROR(result);
    1690             : 
    1691       32392 :                 result = winreg_enumval_to_dword(info2,
    1692             :                                                  v,
    1693             :                                                  "Status",
    1694       32392 :                                                  &info2->status);
    1695       32392 :                 CHECK_ERROR(result);
    1696             : 
    1697       23600 :                 result = winreg_enumval_to_dword(info2,
    1698             :                                                  v,
    1699             :                                                  "StartTime",
    1700       23600 :                                                  &info2->starttime);
    1701       23600 :                 CHECK_ERROR(result);
    1702             :         }
    1703             : 
    1704       10349 :         if (!W_ERROR_IS_OK(result)) {
    1705           0 :                 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
    1706             :                                         "for %s: %s\n",
    1707             :                                         v->value_name,
    1708             :                                         win_errstr(result)));
    1709           0 :                 goto done;
    1710             :         }
    1711             : 
    1712             :         /* Construct the Device Mode */
    1713       10349 :         status = dcerpc_winreg_query_binary(tmp_ctx,
    1714             :                                             winreg_handle,
    1715             :                                             &key_hnd,
    1716             :                                             "Default DevMode",
    1717             :                                             &blob,
    1718             :                                             &result);
    1719       10349 :         if (!NT_STATUS_IS_OK(status)) {
    1720           0 :                 result = ntstatus_to_werror(status);
    1721             :         }
    1722       10349 :         if (W_ERROR_IS_OK(result)) {
    1723        2912 :                 info2->devmode = talloc_zero(info2, struct spoolss_DeviceMode);
    1724        2912 :                 if (info2->devmode == NULL) {
    1725           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
    1726           0 :                         goto done;
    1727             :                 }
    1728        2912 :                 ndr_err = ndr_pull_struct_blob(&blob,
    1729        2912 :                                                info2->devmode,
    1730        2912 :                                                info2->devmode,
    1731             :                                                (ndr_pull_flags_fn_t) ndr_pull_spoolss_DeviceMode);
    1732        2912 :                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1733           0 :                         DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
    1734           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
    1735           0 :                         goto done;
    1736             :                 }
    1737             :         }
    1738             : 
    1739       10349 :         if (info2->devmode == NULL && lp_default_devmode(snum)) {
    1740       11820 :                 result = spoolss_create_default_devmode(info2,
    1741        6877 :                                                         info2->printername,
    1742        6877 :                                                         &info2->devmode);
    1743        6877 :                 if (!W_ERROR_IS_OK(result)) {
    1744           0 :                         goto done;
    1745             :                 }
    1746             :         }
    1747             : 
    1748       10349 :         if (info2->devmode) {
    1749        9789 :                 info2->devmode->size = ndr_size_spoolss_DeviceMode(info2->devmode, 0) - info2->devmode->driverextra_data.length;
    1750             :         }
    1751             : 
    1752       10349 :         result = winreg_get_printer_secdesc(info2,
    1753             :                                             winreg_handle,
    1754             :                                             printer,
    1755       10349 :                                             &info2->secdesc);
    1756       10349 :         if (!W_ERROR_IS_OK(result)) {
    1757           0 :                 goto done;
    1758             :         }
    1759             : 
    1760             :         /* Fix for OS/2 drivers. */
    1761       10349 :         if (get_remote_arch() == RA_OS2) {
    1762           0 :                 spoolss_map_to_os2_driver(info2, &info2->drivername);
    1763             :         }
    1764             : 
    1765       10349 :         if (pinfo2) {
    1766       10349 :                 *pinfo2 = talloc_move(mem_ctx, &info2);
    1767             :         }
    1768             : 
    1769       10349 :         result = WERR_OK;
    1770       10437 : done:
    1771       10437 :         if (is_valid_policy_hnd(&key_hnd)) {
    1772       10349 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    1773             :         }
    1774       10437 :         if (is_valid_policy_hnd(&hive_hnd)) {
    1775       10349 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1776             :         }
    1777             : 
    1778       10437 :         TALLOC_FREE(tmp_ctx);
    1779       10437 :         return result;
    1780             : }
    1781             : 
    1782       10513 : static WERROR winreg_get_secdesc(TALLOC_CTX *mem_ctx,
    1783             :                                  struct dcerpc_binding_handle *winreg_handle,
    1784             :                                  const char *path,
    1785             :                                  const char *attribute,
    1786             :                                  struct spoolss_security_descriptor **psecdesc)
    1787             : {
    1788             :         struct spoolss_security_descriptor *secdesc;
    1789       10513 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1790             :         struct policy_handle hive_hnd, key_hnd;
    1791             :         TALLOC_CTX *tmp_ctx;
    1792             :         NTSTATUS status;
    1793             :         WERROR result;
    1794             :         WERROR ignore;
    1795             : 
    1796       10513 :         tmp_ctx = talloc_stackframe();
    1797       10513 :         if (tmp_ctx == NULL) {
    1798           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1799             :         }
    1800             : 
    1801       10513 :         ZERO_STRUCT(hive_hnd);
    1802       10513 :         ZERO_STRUCT(key_hnd);
    1803             : 
    1804       10513 :         result = winreg_printer_openkey(tmp_ctx,
    1805             :                                         winreg_handle,
    1806             :                                         path,
    1807             :                                         "",
    1808             :                                         false,
    1809             :                                         access_mask,
    1810             :                                         &hive_hnd,
    1811             :                                         &key_hnd);
    1812       10513 :         if (!W_ERROR_IS_OK(result)) {
    1813           2 :                 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    1814           2 :                         goto create_default;
    1815             :                 }
    1816           0 :                 goto done;
    1817             :         }
    1818             : 
    1819       10511 :         status = dcerpc_winreg_query_sd(tmp_ctx,
    1820             :                                         winreg_handle,
    1821             :                                         &key_hnd,
    1822             :                                         attribute,
    1823             :                                         &secdesc,
    1824             :                                         &result);
    1825       10511 :         if (!NT_STATUS_IS_OK(status)) {
    1826           0 :                 result = ntstatus_to_werror(status);
    1827             :         }
    1828       10511 :         if (!W_ERROR_IS_OK(result)) {
    1829           4 :                 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    1830             : 
    1831           4 :                         if (is_valid_policy_hnd(&key_hnd)) {
    1832           4 :                                 dcerpc_winreg_CloseKey(winreg_handle,
    1833             :                                                        tmp_ctx,
    1834             :                                                        &key_hnd,
    1835             :                                                        &ignore);
    1836             :                         }
    1837             : 
    1838           4 :                         if (is_valid_policy_hnd(&hive_hnd)) {
    1839           4 :                                 dcerpc_winreg_CloseKey(winreg_handle,
    1840             :                                                        tmp_ctx,
    1841             :                                                        &hive_hnd,
    1842             :                                                        &ignore);
    1843             :                         }
    1844           4 :                         goto create_default;
    1845             :                 }
    1846           0 :                 goto done;
    1847             :         }
    1848             : 
    1849       10507 :         if (psecdesc) {
    1850       10507 :                 *psecdesc = talloc_move(mem_ctx, &secdesc);
    1851             :         }
    1852             : 
    1853       10507 :         result = WERR_OK;
    1854       10507 :         goto done;
    1855             : 
    1856           6 : create_default:
    1857           6 :         result = winreg_printer_openkey(tmp_ctx,
    1858             :                                         winreg_handle,
    1859             :                                         path,
    1860             :                                         "",
    1861             :                                         true,
    1862             :                                         access_mask,
    1863             :                                         &hive_hnd,
    1864             :                                         &key_hnd);
    1865           6 :         if (!W_ERROR_IS_OK(result)) {
    1866           0 :                 goto done;
    1867             :         }
    1868             : 
    1869           6 :         result = spoolss_create_default_secdesc(tmp_ctx, &secdesc);
    1870           6 :         if (!W_ERROR_IS_OK(result)) {
    1871           0 :                 goto done;
    1872             :         }
    1873             : 
    1874             :         /* If security descriptor is owned by S-1-1-0 and winbindd is up,
    1875             :            this security descriptor has been created when winbindd was
    1876             :            down.  Take ownership of security descriptor. */
    1877           6 :         if (dom_sid_equal(secdesc->owner_sid, &global_sid_World)) {
    1878             :                 struct dom_sid owner_sid;
    1879             : 
    1880             :                 /* Change sd owner to workgroup administrator */
    1881             : 
    1882           0 :                 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
    1883             :                         struct spoolss_security_descriptor *new_secdesc;
    1884             :                         size_t size;
    1885             : 
    1886             :                         /* Create new sd */
    1887           0 :                         sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
    1888             : 
    1889           0 :                         new_secdesc = make_sec_desc(tmp_ctx,
    1890           0 :                                                     secdesc->revision,
    1891           0 :                                                     secdesc->type,
    1892             :                                                     &owner_sid,
    1893           0 :                                                     secdesc->group_sid,
    1894           0 :                                                     secdesc->sacl,
    1895           0 :                                                     secdesc->dacl,
    1896             :                                                     &size);
    1897             : 
    1898           0 :                         if (new_secdesc == NULL) {
    1899           0 :                                 result = WERR_NOT_ENOUGH_MEMORY;
    1900           0 :                                 goto done;
    1901             :                         }
    1902             : 
    1903             :                         /* Swap with other one */
    1904           0 :                         secdesc = new_secdesc;
    1905             :                 }
    1906             :         }
    1907             : 
    1908           6 :         status = dcerpc_winreg_set_sd(tmp_ctx,
    1909             :                                           winreg_handle,
    1910             :                                           &key_hnd,
    1911             :                                           attribute,
    1912             :                                           secdesc,
    1913             :                                           &result);
    1914           6 :         if (!NT_STATUS_IS_OK(status)) {
    1915           0 :                 result = ntstatus_to_werror(status);
    1916             :         }
    1917           6 :         if (!W_ERROR_IS_OK(result)) {
    1918           0 :                 return result;
    1919             :         }
    1920             : 
    1921           6 :         if (psecdesc) {
    1922           6 :                 *psecdesc = talloc_move(mem_ctx, &secdesc);
    1923             :         }
    1924             : 
    1925           6 :         result = WERR_OK;
    1926       10513 : done:
    1927       10513 :         if (is_valid_policy_hnd(&key_hnd)) {
    1928       10513 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    1929             :         }
    1930       10513 :         if (is_valid_policy_hnd(&hive_hnd)) {
    1931       10513 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    1932             :         }
    1933             : 
    1934       10513 :         talloc_free(tmp_ctx);
    1935       10513 :         return result;
    1936             : }
    1937             : 
    1938       10465 : WERROR winreg_get_printer_secdesc(TALLOC_CTX *mem_ctx,
    1939             :                                   struct dcerpc_binding_handle *winreg_handle,
    1940             :                                   const char *sharename,
    1941             :                                   struct spoolss_security_descriptor **psecdesc)
    1942             : {
    1943             :         WERROR result;
    1944             :         char *path;
    1945             : 
    1946       10465 :         path = winreg_printer_data_keyname(mem_ctx, sharename);
    1947       10465 :         if (path == NULL) {
    1948           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1949             :         }
    1950             : 
    1951       10465 :         result = winreg_get_secdesc(mem_ctx, winreg_handle,
    1952             :                                     path,
    1953             :                                     "Security",
    1954             :                                     psecdesc);
    1955       10465 :         talloc_free(path);
    1956             : 
    1957       10465 :         return result;
    1958             : }
    1959             : 
    1960          48 : WERROR winreg_get_printserver_secdesc(TALLOC_CTX *mem_ctx,
    1961             :                                       struct dcerpc_binding_handle *winreg_handle,
    1962             :                                       struct spoolss_security_descriptor **psecdesc)
    1963             : {
    1964          48 :         return winreg_get_secdesc(mem_ctx, winreg_handle,
    1965             :                                   TOP_LEVEL_CONTROL_KEY,
    1966             :                                   "ServerSecurityDescriptor",
    1967             :                                   psecdesc);
    1968             : }
    1969             : 
    1970         112 : static WERROR winreg_set_secdesc(TALLOC_CTX *mem_ctx,
    1971             :                                  struct dcerpc_binding_handle *winreg_handle,
    1972             :                                  const char *path,
    1973             :                                  const char *attribute,
    1974             :                                  const struct spoolss_security_descriptor *secdesc)
    1975             : {
    1976         112 :         const struct spoolss_security_descriptor *new_secdesc = secdesc;
    1977             :         struct spoolss_security_descriptor *old_secdesc;
    1978         112 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    1979             :         struct policy_handle hive_hnd, key_hnd;
    1980             :         TALLOC_CTX *tmp_ctx;
    1981             :         NTSTATUS status;
    1982             :         WERROR result;
    1983             :         WERROR ignore;
    1984             : 
    1985         112 :         tmp_ctx = talloc_stackframe();
    1986         112 :         if (tmp_ctx == NULL) {
    1987           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    1988             :         }
    1989             : 
    1990             :         /*
    1991             :          * The old owner and group sids of the security descriptor are not
    1992             :          * present when new ACEs are added or removed by changing printer
    1993             :          * permissions through NT.  If they are NULL in the new security
    1994             :          * descriptor then copy them over from the old one.
    1995             :          */
    1996         112 :         if (!secdesc->owner_sid || !secdesc->group_sid) {
    1997             :                 struct dom_sid *owner_sid, *group_sid;
    1998             :                 struct security_acl *dacl, *sacl;
    1999             :                 size_t size;
    2000             : 
    2001           0 :                 result = winreg_get_secdesc(tmp_ctx,
    2002             :                                             winreg_handle,
    2003             :                                             path,
    2004             :                                             attribute,
    2005             :                                             &old_secdesc);
    2006           0 :                 if (!W_ERROR_IS_OK(result)) {
    2007           0 :                         talloc_free(tmp_ctx);
    2008           0 :                         return result;
    2009             :                 }
    2010             : 
    2011             :                 /* Pick out correct owner and group sids */
    2012           0 :                 owner_sid = secdesc->owner_sid ?
    2013           0 :                             secdesc->owner_sid :
    2014           0 :                             old_secdesc->owner_sid;
    2015             : 
    2016           0 :                 group_sid = secdesc->group_sid ?
    2017           0 :                             secdesc->group_sid :
    2018           0 :                             old_secdesc->group_sid;
    2019             : 
    2020           0 :                 dacl = secdesc->dacl ?
    2021           0 :                        secdesc->dacl :
    2022           0 :                        old_secdesc->dacl;
    2023             : 
    2024           0 :                 sacl = secdesc->sacl ?
    2025           0 :                        secdesc->sacl :
    2026           0 :                        old_secdesc->sacl;
    2027             : 
    2028             :                 /* Make a deep copy of the security descriptor */
    2029           0 :                 new_secdesc = make_sec_desc(tmp_ctx,
    2030           0 :                                             secdesc->revision,
    2031           0 :                                             secdesc->type,
    2032             :                                             owner_sid,
    2033             :                                             group_sid,
    2034             :                                             sacl,
    2035             :                                             dacl,
    2036             :                                             &size);
    2037           0 :                 if (new_secdesc == NULL) {
    2038           0 :                         talloc_free(tmp_ctx);
    2039           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    2040             :                 }
    2041             :         }
    2042             : 
    2043         112 :         ZERO_STRUCT(hive_hnd);
    2044         112 :         ZERO_STRUCT(key_hnd);
    2045             : 
    2046         112 :         result = winreg_printer_openkey(tmp_ctx,
    2047             :                                         winreg_handle,
    2048             :                                         path,
    2049             :                                         "",
    2050             :                                         false,
    2051             :                                         access_mask,
    2052             :                                         &hive_hnd,
    2053             :                                         &key_hnd);
    2054         112 :         if (!W_ERROR_IS_OK(result)) {
    2055           0 :                 goto done;
    2056             :         }
    2057             : 
    2058         112 :         status = dcerpc_winreg_set_sd(tmp_ctx,
    2059             :                                       winreg_handle,
    2060             :                                       &key_hnd,
    2061             :                                       attribute,
    2062             :                                       new_secdesc,
    2063             :                                       &result);
    2064         112 :         if (!NT_STATUS_IS_OK(status)) {
    2065           0 :                 result = ntstatus_to_werror(status);
    2066             :         }
    2067             : 
    2068         193 : done:
    2069         112 :         if (is_valid_policy_hnd(&key_hnd)) {
    2070         112 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2071             :         }
    2072         112 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2073         112 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2074             :         }
    2075             : 
    2076         112 :         talloc_free(tmp_ctx);
    2077         112 :         return result;
    2078             : }
    2079             : 
    2080         104 : WERROR winreg_set_printer_secdesc(TALLOC_CTX *mem_ctx,
    2081             :                                   struct dcerpc_binding_handle *winreg_handle,
    2082             :                                   const char *sharename,
    2083             :                                   const struct spoolss_security_descriptor *secdesc)
    2084             : {
    2085             :         char *path;
    2086             :         WERROR result;
    2087             : 
    2088         104 :         path = winreg_printer_data_keyname(mem_ctx, sharename);
    2089         104 :         if (path == NULL) {
    2090           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2091             :         }
    2092             : 
    2093         104 :         result = winreg_set_secdesc(mem_ctx, winreg_handle,
    2094             :                                     path,
    2095             :                                     "Security", secdesc);
    2096         104 :         talloc_free(path);
    2097             : 
    2098         104 :         return result;
    2099             : }
    2100             : 
    2101           8 : WERROR winreg_set_printserver_secdesc(TALLOC_CTX *mem_ctx,
    2102             :                                       struct dcerpc_binding_handle *winreg_handle,
    2103             :                                       const struct spoolss_security_descriptor *secdesc)
    2104             : {
    2105           8 :         return winreg_set_secdesc(mem_ctx, winreg_handle,
    2106             :                                   TOP_LEVEL_CONTROL_KEY,
    2107             :                                   "ServerSecurityDescriptor",
    2108             :                                   secdesc);
    2109             : }
    2110             : 
    2111             : /* Set printer data over the winreg pipe. */
    2112        1914 : WERROR winreg_set_printer_dataex(TALLOC_CTX *mem_ctx,
    2113             :                                  struct dcerpc_binding_handle *winreg_handle,
    2114             :                                  const char *printer,
    2115             :                                  const char *key,
    2116             :                                  const char *value,
    2117             :                                  enum winreg_Type type,
    2118             :                                  uint8_t *data,
    2119             :                                  uint32_t data_size)
    2120             : {
    2121        1914 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2122             :         struct policy_handle hive_hnd, key_hnd;
    2123        1914 :         struct winreg_String wvalue = { 0, };
    2124             :         char *path;
    2125        1914 :         WERROR result = WERR_OK;
    2126             :         WERROR ignore;
    2127             :         NTSTATUS status;
    2128             :         TALLOC_CTX *tmp_ctx;
    2129             : 
    2130        1914 :         tmp_ctx = talloc_stackframe();
    2131        1914 :         if (tmp_ctx == NULL) {
    2132           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2133             :         }
    2134             : 
    2135        1914 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2136        1914 :         if (path == NULL) {
    2137           0 :                 TALLOC_FREE(tmp_ctx);
    2138           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2139             :         }
    2140             : 
    2141        1914 :         ZERO_STRUCT(hive_hnd);
    2142        1914 :         ZERO_STRUCT(key_hnd);
    2143             : 
    2144        1914 :         DEBUG(8, ("winreg_set_printer_dataex: Open printer key %s, value %s, access_mask: 0x%05x for [%s]\n",
    2145             :                         key, value, access_mask, printer));
    2146        1914 :         result = winreg_printer_openkey(tmp_ctx,
    2147             :                                         winreg_handle,
    2148             :                                         path,
    2149             :                                         key,
    2150             :                                         true,
    2151             :                                         access_mask,
    2152             :                                         &hive_hnd,
    2153             :                                         &key_hnd);
    2154        1914 :         if (!W_ERROR_IS_OK(result)) {
    2155           0 :                 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
    2156             :                           key, win_errstr(result)));
    2157           0 :                 goto done;
    2158             :         }
    2159             : 
    2160        1914 :         wvalue.name = value;
    2161        1914 :         status = dcerpc_winreg_SetValue(winreg_handle,
    2162             :                                         tmp_ctx,
    2163             :                                         &key_hnd,
    2164             :                                         wvalue,
    2165             :                                         type,
    2166             :                                         data,
    2167             :                                         data_size,
    2168             :                                         &result);
    2169        1914 :         if (!NT_STATUS_IS_OK(status)) {
    2170           0 :                 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
    2171             :                           value, nt_errstr(status)));
    2172           0 :                 result = ntstatus_to_werror(status);
    2173             :         }
    2174             : 
    2175        3352 : done:
    2176        1914 :         if (is_valid_policy_hnd(&key_hnd)) {
    2177        1914 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2178             :         }
    2179        1914 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2180        1914 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2181             :         }
    2182             : 
    2183        1914 :         TALLOC_FREE(tmp_ctx);
    2184        1914 :         return result;
    2185             : }
    2186             : 
    2187             : /* Get printer data over a winreg pipe. */
    2188        2648 : WERROR winreg_get_printer_dataex(TALLOC_CTX *mem_ctx,
    2189             :                                  struct dcerpc_binding_handle *winreg_handle,
    2190             :                                  const char *printer,
    2191             :                                  const char *key,
    2192             :                                  const char *value,
    2193             :                                  enum winreg_Type *type,
    2194             :                                  uint8_t **data,
    2195             :                                  uint32_t *data_size)
    2196             : {
    2197        2648 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2198             :         struct policy_handle hive_hnd, key_hnd;
    2199             :         struct winreg_String wvalue;
    2200        2648 :         enum winreg_Type type_in = REG_NONE;
    2201             :         char *path;
    2202        2648 :         uint8_t *data_in = NULL;
    2203        2648 :         uint32_t data_in_size = 0;
    2204        2648 :         uint32_t value_len = 0;
    2205        2648 :         WERROR result = WERR_OK;
    2206             :         WERROR ignore;
    2207             :         NTSTATUS status;
    2208             :         TALLOC_CTX *tmp_ctx;
    2209             : 
    2210        2648 :         tmp_ctx = talloc_stackframe();
    2211        2648 :         if (tmp_ctx == NULL) {
    2212           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2213             :         }
    2214             : 
    2215        2648 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2216        2648 :         if (path == NULL) {
    2217           0 :                 TALLOC_FREE(tmp_ctx);
    2218           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2219             :         }
    2220             : 
    2221        2648 :         ZERO_STRUCT(hive_hnd);
    2222        2648 :         ZERO_STRUCT(key_hnd);
    2223             : 
    2224        2648 :         result = winreg_printer_openkey(tmp_ctx,
    2225             :                                         winreg_handle,
    2226             :                                         path,
    2227             :                                         key,
    2228             :                                         false,
    2229             :                                         access_mask,
    2230             :                                         &hive_hnd,
    2231             :                                         &key_hnd);
    2232        2648 :         if (!W_ERROR_IS_OK(result)) {
    2233           0 :                 DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
    2234             :                           key, win_errstr(result)));
    2235           0 :                 goto done;
    2236             :         }
    2237             : 
    2238        2648 :         wvalue.name = value;
    2239             : 
    2240             :         /*
    2241             :          * call QueryValue once with data == NULL to get the
    2242             :          * needed memory size to be allocated, then allocate
    2243             :          * data buffer and call again.
    2244             :          */
    2245        2648 :         status = dcerpc_winreg_QueryValue(winreg_handle,
    2246             :                                           tmp_ctx,
    2247             :                                           &key_hnd,
    2248             :                                           &wvalue,
    2249             :                                           &type_in,
    2250             :                                           NULL,
    2251             :                                           &data_in_size,
    2252             :                                           &value_len,
    2253             :                                           &result);
    2254        2648 :         if (!NT_STATUS_IS_OK(status)) {
    2255           0 :                 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
    2256             :                           value, nt_errstr(status)));
    2257           0 :                 result = ntstatus_to_werror(status);
    2258           0 :                 goto done;
    2259             :         }
    2260        2648 :         if (!W_ERROR_IS_OK(result)) {
    2261           4 :                 DEBUG(2, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
    2262             :                           value, win_errstr(result)));
    2263           4 :                 goto done;
    2264             :         }
    2265             : 
    2266        2644 :         data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
    2267        2644 :         if (data_in == NULL) {
    2268           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    2269           0 :                 goto done;
    2270             :         }
    2271        2644 :         value_len = 0;
    2272             : 
    2273        2644 :         status = dcerpc_winreg_QueryValue(winreg_handle,
    2274             :                                           tmp_ctx,
    2275             :                                           &key_hnd,
    2276             :                                           &wvalue,
    2277             :                                           &type_in,
    2278             :                                           data_in,
    2279             :                                           &data_in_size,
    2280             :                                           &value_len,
    2281             :                                           &result);
    2282        2644 :         if (!NT_STATUS_IS_OK(status)) {
    2283           0 :                 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
    2284             :                           value, nt_errstr(status)));
    2285           0 :                 result = ntstatus_to_werror(status);
    2286           0 :                 goto done;
    2287             :         }
    2288        2644 :         if (!W_ERROR_IS_OK(result)) {
    2289           0 :                 DEBUG(2, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
    2290             :                           value, win_errstr(result)));
    2291           0 :                 goto done;
    2292             :         }
    2293             : 
    2294        2644 :         *type = type_in;
    2295        2644 :         *data_size = data_in_size;
    2296        2644 :         if (data_in_size) {
    2297        2608 :                 *data = talloc_move(mem_ctx, &data_in);
    2298             :         }
    2299             : 
    2300        2644 :         result = WERR_OK;
    2301        2648 : done:
    2302        2648 :         if (is_valid_policy_hnd(&key_hnd)) {
    2303        2648 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2304             :         }
    2305        2648 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2306        2648 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2307             :         }
    2308             : 
    2309        2648 :         TALLOC_FREE(tmp_ctx);
    2310        2648 :         return result;
    2311             : }
    2312             : 
    2313             : /* Enumerate on the values of a given key and provide the data. */
    2314        2856 : WERROR winreg_enum_printer_dataex(TALLOC_CTX *mem_ctx,
    2315             :                                   struct dcerpc_binding_handle *winreg_handle,
    2316             :                                   const char *printer,
    2317             :                                   const char *key,
    2318             :                                   uint32_t *pnum_values,
    2319             :                                   struct spoolss_PrinterEnumValues **penum_values)
    2320             : {
    2321             :         uint32_t i;
    2322        2856 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2323             :         struct policy_handle hive_hnd, key_hnd;
    2324             : 
    2325        2856 :         struct spoolss_PrinterEnumValues *enum_values = NULL;
    2326        2856 :         uint32_t num_values = 0;
    2327             :         char *path;
    2328        2856 :         WERROR result = WERR_OK;
    2329             :         WERROR ignore;
    2330             :         NTSTATUS status;
    2331        2856 :         const char **enum_names = NULL;
    2332        2856 :         enum winreg_Type *enum_types = NULL;
    2333        2856 :         DATA_BLOB *enum_data_blobs = NULL;
    2334             : 
    2335             :         TALLOC_CTX *tmp_ctx;
    2336             : 
    2337        2856 :         tmp_ctx = talloc_stackframe();
    2338        2856 :         if (tmp_ctx == NULL) {
    2339           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2340             :         }
    2341             : 
    2342        2856 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2343        2856 :         if (path == NULL) {
    2344           0 :                 TALLOC_FREE(tmp_ctx);
    2345           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2346             :         }
    2347             : 
    2348        2856 :         result = winreg_printer_openkey(tmp_ctx,
    2349             :                                         winreg_handle,
    2350             :                                         path,
    2351             :                                         key,
    2352             :                                         false,
    2353             :                                         access_mask,
    2354             :                                         &hive_hnd,
    2355             :                                         &key_hnd);
    2356        2856 :         if (!W_ERROR_IS_OK(result)) {
    2357           0 :                 DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
    2358             :                           key, win_errstr(result)));
    2359           0 :                 goto done;
    2360             :         }
    2361             : 
    2362        2856 :         status = dcerpc_winreg_enumvals(tmp_ctx,
    2363             :                                         winreg_handle,
    2364             :                                         &key_hnd,
    2365             :                                         &num_values,
    2366             :                                         &enum_names,
    2367             :                                         &enum_types,
    2368             :                                         &enum_data_blobs,
    2369             :                                         &result);
    2370        2856 :         if (!NT_STATUS_IS_OK(status)){
    2371           0 :                 result = ntstatus_to_werror(status);
    2372             :         }
    2373             : 
    2374        2856 :         if (!W_ERROR_IS_OK(result)) {
    2375           0 :                 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
    2376             :                           key, win_errstr(result)));
    2377           0 :                 goto done;
    2378             :         }
    2379             : 
    2380        2856 :         enum_values = talloc_array(tmp_ctx, struct spoolss_PrinterEnumValues, num_values);
    2381        2856 :         if (enum_values == NULL){
    2382           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    2383           0 :                 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
    2384             :                           key, win_errstr(result)));
    2385           0 :                 goto done;
    2386             :         }
    2387             : 
    2388        6776 :         for (i = 0; i < num_values; i++){
    2389        3920 :                 enum_values[i].value_name = enum_names[i];
    2390        3920 :                 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
    2391        3920 :                 enum_values[i].type = enum_types[i];
    2392        3920 :                 enum_values[i].data_length = enum_data_blobs[i].length;
    2393        3920 :                 enum_values[i].data = NULL;
    2394             : 
    2395        3920 :                 if (enum_values[i].data_length != 0){
    2396        3848 :                         enum_values[i].data = &enum_data_blobs[i];
    2397             :                 }
    2398             :         }
    2399             : 
    2400        2856 :         talloc_steal(enum_values, enum_names);
    2401        2856 :         talloc_steal(enum_values, enum_data_blobs);
    2402             : 
    2403        2856 :         *pnum_values = num_values;
    2404        2856 :         if (penum_values) {
    2405        2856 :                 *penum_values = talloc_move(mem_ctx, &enum_values);
    2406             :         }
    2407             : 
    2408        2856 :         result = WERR_OK;
    2409        2856 : done:
    2410        2856 :         if (is_valid_policy_hnd(&key_hnd)) {
    2411        2856 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2412             :         }
    2413        2856 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2414        2856 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2415             :         }
    2416             : 
    2417        2856 :         TALLOC_FREE(tmp_ctx);
    2418        2856 :         return result;
    2419             : }
    2420             : 
    2421             : /* Delete printer data over a winreg pipe. */
    2422        1368 : WERROR winreg_delete_printer_dataex(TALLOC_CTX *mem_ctx,
    2423             :                                     struct dcerpc_binding_handle *winreg_handle,
    2424             :                                     const char *printer,
    2425             :                                     const char *key,
    2426             :                                     const char *value)
    2427             : {
    2428        1368 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2429             :         struct policy_handle hive_hnd, key_hnd;
    2430        1368 :         struct winreg_String wvalue = { 0, };
    2431             :         char *path;
    2432        1368 :         WERROR result = WERR_OK;
    2433             :         WERROR ignore;
    2434             :         NTSTATUS status;
    2435             : 
    2436             :         TALLOC_CTX *tmp_ctx;
    2437             : 
    2438        1368 :         tmp_ctx = talloc_stackframe();
    2439        1368 :         if (tmp_ctx == NULL) {
    2440           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2441             :         }
    2442             : 
    2443        1368 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2444        1368 :         if (path == NULL) {
    2445           0 :                 TALLOC_FREE(tmp_ctx);
    2446           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2447             :         }
    2448             : 
    2449        1368 :         ZERO_STRUCT(hive_hnd);
    2450        1368 :         ZERO_STRUCT(key_hnd);
    2451             : 
    2452        1368 :         result = winreg_printer_openkey(tmp_ctx,
    2453             :                                         winreg_handle,
    2454             :                                         path,
    2455             :                                         key,
    2456             :                                         false,
    2457             :                                         access_mask,
    2458             :                                         &hive_hnd,
    2459             :                                         &key_hnd);
    2460        1368 :         if (!W_ERROR_IS_OK(result)) {
    2461           0 :                 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
    2462             :                           key, win_errstr(result)));
    2463           0 :                 goto done;
    2464             :         }
    2465             : 
    2466        1368 :         wvalue.name = value;
    2467        1368 :         status = dcerpc_winreg_DeleteValue(winreg_handle,
    2468             :                                            tmp_ctx,
    2469             :                                            &key_hnd,
    2470             :                                            wvalue,
    2471             :                                            &result);
    2472        1368 :         if (!NT_STATUS_IS_OK(status)) {
    2473           0 :                 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
    2474             :                           value, nt_errstr(status)));
    2475           0 :                 result = ntstatus_to_werror(status);
    2476             :         }
    2477             : 
    2478        2394 : done:
    2479        1368 :         if (is_valid_policy_hnd(&key_hnd)) {
    2480        1368 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2481             :         }
    2482        1368 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2483        1368 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2484             :         }
    2485             : 
    2486        1368 :         TALLOC_FREE(tmp_ctx);
    2487        1368 :         return result;
    2488             : }
    2489             : 
    2490             : /* Enumerate on the subkeys of a given key and provide the data. */
    2491        3384 : WERROR winreg_enum_printer_key(TALLOC_CTX *mem_ctx,
    2492             :                                struct dcerpc_binding_handle *winreg_handle,
    2493             :                                const char *printer,
    2494             :                                const char *key,
    2495             :                                uint32_t *pnum_subkeys,
    2496             :                                const char ***psubkeys)
    2497             : {
    2498        3384 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2499             :         struct policy_handle hive_hnd, key_hnd;
    2500             :         char *path;
    2501        3384 :         const char **subkeys = NULL;
    2502        3384 :         uint32_t num_subkeys = -1;
    2503             : 
    2504        3384 :         WERROR result = WERR_OK;
    2505             :         WERROR ignore;
    2506             :         NTSTATUS status;
    2507             : 
    2508             :         TALLOC_CTX *tmp_ctx;
    2509             : 
    2510        3384 :         tmp_ctx = talloc_stackframe();
    2511        3384 :         if (tmp_ctx == NULL) {
    2512           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2513             :         }
    2514             : 
    2515        3384 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2516        3384 :         if (path == NULL) {
    2517           0 :                 TALLOC_FREE(tmp_ctx);
    2518           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2519             :         }
    2520             : 
    2521        3384 :         ZERO_STRUCT(hive_hnd);
    2522        3384 :         ZERO_STRUCT(key_hnd);
    2523             : 
    2524        3384 :         result = winreg_printer_openkey(tmp_ctx,
    2525             :                                         winreg_handle,
    2526             :                                         path,
    2527             :                                         key,
    2528             :                                         false,
    2529             :                                         access_mask,
    2530             :                                         &hive_hnd,
    2531             :                                         &key_hnd);
    2532        3384 :         if (!W_ERROR_IS_OK(result)) {
    2533           0 :                 DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
    2534             :                           key, win_errstr(result)));
    2535           0 :                 goto done;
    2536             :         }
    2537             : 
    2538        3384 :         status = dcerpc_winreg_enum_keys(tmp_ctx,
    2539             :                                          winreg_handle,
    2540             :                                          &key_hnd,
    2541             :                                          &num_subkeys,
    2542             :                                          &subkeys,
    2543             :                                          &result);
    2544        3384 :         if (!NT_STATUS_IS_OK(status)) {
    2545           0 :                 result = ntstatus_to_werror(status);
    2546             :         }
    2547        3384 :         if (!W_ERROR_IS_OK(result)) {
    2548           0 :                 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
    2549             :                           key, win_errstr(result)));
    2550           0 :                 goto done;
    2551             :         }
    2552             : 
    2553        3384 :         *pnum_subkeys = num_subkeys;
    2554        3384 :         if (psubkeys) {
    2555        3384 :                 *psubkeys = talloc_move(mem_ctx, &subkeys);
    2556             :         }
    2557             : 
    2558        3384 :         result = WERR_OK;
    2559        3384 : done:
    2560        3384 :         if (is_valid_policy_hnd(&key_hnd)) {
    2561        3384 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2562             :         }
    2563        3384 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2564        3384 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2565             :         }
    2566             : 
    2567        3384 :         TALLOC_FREE(tmp_ctx);
    2568        3384 :         return result;
    2569             : }
    2570             : 
    2571             : /* Delete a key with subkeys of a given printer. */
    2572         248 : WERROR winreg_delete_printer_key(TALLOC_CTX *mem_ctx,
    2573             :                                  struct dcerpc_binding_handle *winreg_handle,
    2574             :                                  const char *printer,
    2575             :                                  const char *key)
    2576             : {
    2577         248 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2578             :         struct policy_handle hive_hnd, key_hnd;
    2579             :         char *keyname;
    2580             :         char *path;
    2581             :         WERROR result;
    2582             :         WERROR ignore;
    2583             :         NTSTATUS status;
    2584             :         TALLOC_CTX *tmp_ctx;
    2585             : 
    2586         248 :         tmp_ctx = talloc_stackframe();
    2587         248 :         if (tmp_ctx == NULL) {
    2588           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2589             :         }
    2590             : 
    2591         248 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2592         248 :         if (path == NULL) {
    2593           0 :                 TALLOC_FREE(tmp_ctx);
    2594           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2595             :         }
    2596             : 
    2597         248 :         result = winreg_printer_openkey(tmp_ctx,
    2598             :                                         winreg_handle,
    2599             :                                         path,
    2600             :                                         key,
    2601             :                                         false,
    2602             :                                         access_mask,
    2603             :                                         &hive_hnd,
    2604             :                                         &key_hnd);
    2605         248 :         if (!W_ERROR_IS_OK(result)) {
    2606             :                 /* key doesn't exist */
    2607          16 :                 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    2608          16 :                         result = WERR_OK;
    2609          16 :                         goto done;
    2610             :                 }
    2611             : 
    2612           0 :                 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
    2613             :                           key, win_errstr(result)));
    2614           0 :                 goto done;
    2615             :         }
    2616             : 
    2617         232 :         if (is_valid_policy_hnd(&key_hnd)) {
    2618         232 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
    2619             :         }
    2620             : 
    2621         232 :         if (key == NULL || key[0] == '\0') {
    2622          16 :                 keyname = path;
    2623             :         } else {
    2624         216 :                 keyname = talloc_asprintf(tmp_ctx,
    2625             :                                           "%s\\%s",
    2626             :                                           path,
    2627             :                                           key);
    2628         216 :                 if (keyname == NULL) {
    2629           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
    2630           0 :                         goto done;
    2631             :                 }
    2632             :         }
    2633             : 
    2634         232 :         status = dcerpc_winreg_delete_subkeys_recursive(tmp_ctx,
    2635             :                                                         winreg_handle,
    2636             :                                                         &hive_hnd,
    2637             :                                                         access_mask,
    2638             :                                                         keyname,
    2639             :                                                         &result);
    2640             : 
    2641         232 :         if (!NT_STATUS_IS_OK(status)) {
    2642           0 :                 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
    2643             :                           key, nt_errstr(status)));
    2644           0 :                 result = ntstatus_to_werror(status);
    2645           0 :                 goto done;
    2646             :         }
    2647             : 
    2648         232 :         if (!W_ERROR_IS_OK(result)) {
    2649           0 :                 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
    2650             :                           key, win_errstr(result)));
    2651           0 :                 goto done;
    2652             :         }
    2653             : 
    2654         418 : done:
    2655         248 :         if (is_valid_policy_hnd(&key_hnd)) {
    2656           0 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2657             :         }
    2658         248 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2659         232 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2660             :         }
    2661             : 
    2662         248 :         TALLOC_FREE(tmp_ctx);
    2663         248 :         return result;
    2664             : }
    2665             : 
    2666        3192 : WERROR winreg_printer_update_changeid(TALLOC_CTX *mem_ctx,
    2667             :                                       struct dcerpc_binding_handle *winreg_handle,
    2668             :                                       const char *printer)
    2669             : {
    2670        3192 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2671             :         struct policy_handle hive_hnd, key_hnd;
    2672             :         char *path;
    2673             :         NTSTATUS status;
    2674             :         WERROR result;
    2675             :         WERROR ignore;
    2676             :         TALLOC_CTX *tmp_ctx;
    2677             : 
    2678        3192 :         tmp_ctx = talloc_stackframe();
    2679        3192 :         if (tmp_ctx == NULL) {
    2680           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2681             :         }
    2682             : 
    2683        3192 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2684        3192 :         if (path == NULL) {
    2685           0 :                 TALLOC_FREE(tmp_ctx);
    2686           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2687             :         }
    2688             : 
    2689        3192 :         ZERO_STRUCT(hive_hnd);
    2690        3192 :         ZERO_STRUCT(key_hnd);
    2691             : 
    2692        3192 :         result = winreg_printer_openkey(tmp_ctx,
    2693             :                                         winreg_handle,
    2694             :                                         path,
    2695             :                                         "",
    2696             :                                         false,
    2697             :                                         access_mask,
    2698             :                                         &hive_hnd,
    2699             :                                         &key_hnd);
    2700        3192 :         if (!W_ERROR_IS_OK(result)) {
    2701           0 :                 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
    2702             :                           path, win_errstr(result)));
    2703           0 :                 goto done;
    2704             :         }
    2705             : 
    2706        3192 :         status = dcerpc_winreg_set_dword(tmp_ctx,
    2707             :                                          winreg_handle,
    2708             :                                          &key_hnd,
    2709             :                                          "ChangeID",
    2710             :                                          winreg_printer_rev_changeid(),
    2711             :                                          &result);
    2712        3192 :         if (!NT_STATUS_IS_OK(status)) {
    2713           0 :                 result = ntstatus_to_werror(status);
    2714             :         }
    2715        3192 :         if (!W_ERROR_IS_OK(result)) {
    2716           0 :                 goto done;
    2717             :         }
    2718             : 
    2719        3192 :         result = WERR_OK;
    2720        3192 : done:
    2721        3192 :         if (is_valid_policy_hnd(&key_hnd)) {
    2722        3192 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2723             :         }
    2724        3192 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2725        3192 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2726             :         }
    2727             : 
    2728        3192 :         TALLOC_FREE(tmp_ctx);
    2729        3192 :         return result;
    2730             : }
    2731             : 
    2732         336 : WERROR winreg_printer_get_changeid(TALLOC_CTX *mem_ctx,
    2733             :                                    struct dcerpc_binding_handle *winreg_handle,
    2734             :                                    const char *printer,
    2735             :                                    uint32_t *pchangeid)
    2736             : {
    2737         336 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2738             :         struct policy_handle hive_hnd, key_hnd;
    2739         336 :         uint32_t changeid = 0;
    2740             :         char *path;
    2741             :         NTSTATUS status;
    2742             :         WERROR result;
    2743             :         WERROR ignore;
    2744             :         TALLOC_CTX *tmp_ctx;
    2745             : 
    2746         336 :         tmp_ctx = talloc_stackframe();
    2747         336 :         if (tmp_ctx == NULL) {
    2748           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2749             :         }
    2750             : 
    2751         336 :         path = winreg_printer_data_keyname(tmp_ctx, printer);
    2752         336 :         if (path == NULL) {
    2753           0 :                 TALLOC_FREE(tmp_ctx);
    2754           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2755             :         }
    2756             : 
    2757         336 :         ZERO_STRUCT(hive_hnd);
    2758         336 :         ZERO_STRUCT(key_hnd);
    2759             : 
    2760         336 :         result = winreg_printer_openkey(tmp_ctx,
    2761             :                                         winreg_handle,
    2762             :                                         path,
    2763             :                                         "",
    2764             :                                         false,
    2765             :                                         access_mask,
    2766             :                                         &hive_hnd,
    2767             :                                         &key_hnd);
    2768         336 :         if (!W_ERROR_IS_OK(result)) {
    2769           0 :                 DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
    2770             :                           path, win_errstr(result)));
    2771           0 :                 goto done;
    2772             :         }
    2773             : 
    2774         336 :         DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path));
    2775             : 
    2776         336 :         status = dcerpc_winreg_query_dword(tmp_ctx,
    2777             :                                            winreg_handle,
    2778             :                                            &key_hnd,
    2779             :                                            "ChangeID",
    2780             :                                            &changeid,
    2781             :                                            &result);
    2782         336 :         if (!NT_STATUS_IS_OK(status)) {
    2783           0 :                 result = ntstatus_to_werror(status);
    2784             :         }
    2785         336 :         if (!W_ERROR_IS_OK(result)) {
    2786           0 :                 goto done;
    2787             :         }
    2788             : 
    2789         336 :         if (pchangeid) {
    2790         336 :                 *pchangeid = changeid;
    2791             :         }
    2792             : 
    2793         336 :         result = WERR_OK;
    2794         336 : done:
    2795         336 :         if (is_valid_policy_hnd(&key_hnd)) {
    2796         336 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2797             :         }
    2798         336 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2799         336 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2800             :         }
    2801             : 
    2802         336 :         TALLOC_FREE(tmp_ctx);
    2803         336 :         return result;
    2804             : }
    2805             : 
    2806             : /*
    2807             :  * The special behaviour of the spoolss forms is documented at the website:
    2808             :  *
    2809             :  * Managing Win32 Printserver Forms
    2810             :  * http://unixwiz.net/techtips/winspooler-forms.html
    2811             :  */
    2812             : 
    2813         480 : WERROR winreg_printer_addform1(TALLOC_CTX *mem_ctx,
    2814             :                                struct dcerpc_binding_handle *winreg_handle,
    2815             :                                struct spoolss_AddFormInfo1 *form)
    2816             : {
    2817         480 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2818             :         struct policy_handle hive_hnd, key_hnd;
    2819         480 :         struct winreg_String wvalue = { 0, };
    2820             :         DATA_BLOB blob;
    2821         480 :         uint32_t num_info = 0;
    2822         480 :         union spoolss_FormInfo *info = NULL;
    2823             :         uint32_t i;
    2824             :         WERROR result;
    2825             :         WERROR ignore;
    2826             :         NTSTATUS status;
    2827             :         TALLOC_CTX *tmp_ctx;
    2828             : 
    2829         480 :         tmp_ctx = talloc_stackframe();
    2830         480 :         if (tmp_ctx == NULL) {
    2831           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2832             :         }
    2833             : 
    2834         480 :         ZERO_STRUCT(hive_hnd);
    2835         480 :         ZERO_STRUCT(key_hnd);
    2836             : 
    2837         480 :         result = winreg_printer_openkey(tmp_ctx,
    2838             :                                         winreg_handle,
    2839             :                                         TOP_LEVEL_CONTROL_FORMS_KEY,
    2840             :                                         "",
    2841             :                                         true,
    2842             :                                         access_mask,
    2843             :                                         &hive_hnd,
    2844             :                                         &key_hnd);
    2845         480 :         if (!W_ERROR_IS_OK(result)) {
    2846           0 :                 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
    2847             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    2848           0 :                 goto done;
    2849             :         }
    2850             : 
    2851         480 :         result = winreg_printer_enumforms1(tmp_ctx, winreg_handle,
    2852             :                                            &num_info, &info);
    2853         480 :         if (!W_ERROR_IS_OK(result)) {
    2854           0 :                 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
    2855             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    2856           0 :                 goto done;
    2857             :         }
    2858             : 
    2859             :         /* If form name already exists or is builtin return ALREADY_EXISTS */
    2860       23136 :         for (i = 0; i < num_info; i++) {
    2861       23040 :                 if (strequal(info[i].info1.form_name, form->form_name)) {
    2862         384 :                         result = WERR_FILE_EXISTS;
    2863         384 :                         goto done;
    2864             :                 }
    2865             :         }
    2866             : 
    2867          96 :         wvalue.name = form->form_name;
    2868             : 
    2869          96 :         blob = data_blob_talloc(tmp_ctx, NULL, 32);
    2870          96 :         SIVAL(blob.data,  0, form->size.width);
    2871          96 :         SIVAL(blob.data,  4, form->size.height);
    2872          96 :         SIVAL(blob.data,  8, form->area.left);
    2873          96 :         SIVAL(blob.data, 12, form->area.top);
    2874          96 :         SIVAL(blob.data, 16, form->area.right);
    2875          96 :         SIVAL(blob.data, 20, form->area.bottom);
    2876          96 :         SIVAL(blob.data, 24, num_info + 1); /* FIXME */
    2877          96 :         SIVAL(blob.data, 28, form->flags);
    2878             : 
    2879          96 :         status = dcerpc_winreg_SetValue(winreg_handle,
    2880             :                                         tmp_ctx,
    2881             :                                         &key_hnd,
    2882             :                                         wvalue,
    2883             :                                         REG_BINARY,
    2884             :                                         blob.data,
    2885          96 :                                         blob.length,
    2886             :                                         &result);
    2887          96 :         if (!NT_STATUS_IS_OK(status)) {
    2888           0 :                 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
    2889             :                           wvalue.name, nt_errstr(status)));
    2890           0 :                 result = ntstatus_to_werror(status);
    2891             :         }
    2892             : 
    2893         456 : done:
    2894         480 :         if (is_valid_policy_hnd(&key_hnd)) {
    2895         480 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    2896             :         }
    2897         480 :         if (is_valid_policy_hnd(&hive_hnd)) {
    2898         480 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    2899             :         }
    2900             : 
    2901         480 :         TALLOC_FREE(info);
    2902         480 :         TALLOC_FREE(tmp_ctx);
    2903         480 :         return result;
    2904             : }
    2905             : 
    2906        1016 : WERROR winreg_printer_enumforms1(TALLOC_CTX *mem_ctx,
    2907             :                                  struct dcerpc_binding_handle *winreg_handle,
    2908             :                                  uint32_t *pnum_info,
    2909             :                                  union spoolss_FormInfo **pinfo)
    2910             : {
    2911        1016 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2912             :         struct policy_handle hive_hnd, key_hnd;
    2913             :         union spoolss_FormInfo *info;
    2914        1016 :         struct spoolss_PrinterEnumValues *enum_values = NULL;
    2915        1016 :         uint32_t num_values = 0;
    2916        1016 :         uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
    2917             :         uint32_t i;
    2918             :         WERROR result;
    2919             :         WERROR ignore;
    2920             :         NTSTATUS status;
    2921        1016 :         const char **enum_names = NULL;
    2922        1016 :         enum winreg_Type *enum_types = NULL;
    2923        1016 :         DATA_BLOB *enum_data_blobs = NULL;
    2924             :         TALLOC_CTX *tmp_ctx;
    2925             : 
    2926        1016 :         tmp_ctx = talloc_stackframe();
    2927        1016 :         if (tmp_ctx == NULL) {
    2928           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2929             :         }
    2930             : 
    2931        1016 :         ZERO_STRUCT(hive_hnd);
    2932        1016 :         ZERO_STRUCT(key_hnd);
    2933             : 
    2934        1016 :         result = winreg_printer_openkey(tmp_ctx,
    2935             :                                         winreg_handle,
    2936             :                                         TOP_LEVEL_CONTROL_FORMS_KEY,
    2937             :                                         "",
    2938             :                                         true,
    2939             :                                         access_mask,
    2940             :                                         &hive_hnd,
    2941             :                                         &key_hnd);
    2942        1016 :         if (!W_ERROR_IS_OK(result)) {
    2943             :                 /* key doesn't exist */
    2944           0 :                 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    2945           0 :                         result = WERR_OK;
    2946           0 :                         goto done;
    2947             :                 }
    2948             : 
    2949           0 :                 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
    2950             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    2951           0 :                 goto done;
    2952             :         }
    2953             : 
    2954        1016 :         status = dcerpc_winreg_enumvals(tmp_ctx,
    2955             :                                         winreg_handle,
    2956             :                                         &key_hnd,
    2957             :                                         &num_values,
    2958             :                                         &enum_names,
    2959             :                                         &enum_types,
    2960             :                                         &enum_data_blobs,
    2961             :                                         &result);
    2962        1016 :         if (!NT_STATUS_IS_OK(status)){
    2963           0 :                 result = ntstatus_to_werror(status);
    2964             :         }
    2965             : 
    2966        1016 :         if (!W_ERROR_IS_OK(result)) {
    2967           0 :                 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
    2968             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    2969           0 :                 goto done;
    2970             :         }
    2971             : 
    2972        1016 :         enum_values = talloc_zero_array(tmp_ctx,
    2973             :                                         struct spoolss_PrinterEnumValues,
    2974             :                                         num_values);
    2975        1016 :         if (enum_values == NULL){
    2976           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    2977           0 :                 goto done;
    2978             :         }
    2979             : 
    2980        1304 :         for (i = 0; i < num_values; i++){
    2981         288 :                 enum_values[i].value_name = enum_names[i];
    2982         288 :                 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
    2983         288 :                 enum_values[i].type = enum_types[i];
    2984         288 :                 enum_values[i].data_length = enum_data_blobs[i].length;
    2985         288 :                 enum_values[i].data = NULL;
    2986         288 :                 if (enum_values[i].data_length != 0){
    2987         288 :                         enum_values[i].data = &enum_data_blobs[i];
    2988             :                 }
    2989             :         }
    2990             : 
    2991        1016 :         if (!W_ERROR_IS_OK(result)) {
    2992           0 :                 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
    2993             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    2994           0 :                 goto done;
    2995             :         }
    2996             : 
    2997        1016 :         info = talloc_array(tmp_ctx, union spoolss_FormInfo, num_builtin + num_values);
    2998        1016 :         if (info == NULL) {
    2999           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    3000           0 :                 goto done;
    3001             :         }
    3002             : 
    3003             :         /* Enumerate BUILTIN forms */
    3004      120904 :         for (i = 0; i < num_builtin; i++) {
    3005      119888 :                 info[i].info1 = builtin_forms1[i];
    3006             :         }
    3007             : 
    3008             :         /* Enumerate registry forms */
    3009        1304 :         for (i = 0; i < num_values; i++) {
    3010             :                 union spoolss_FormInfo val;
    3011             : 
    3012         504 :                 if (enum_values[i].type != REG_BINARY ||
    3013         288 :                     enum_values[i].data_length != 32) {
    3014           0 :                         continue;
    3015             :                 }
    3016             : 
    3017         288 :                 val.info1.form_name = talloc_strdup(info, enum_values[i].value_name);
    3018         288 :                 if (val.info1.form_name == NULL) {
    3019           0 :                         result = WERR_NOT_ENOUGH_MEMORY;
    3020           0 :                         goto done;
    3021             :                 }
    3022             : 
    3023         288 :                 val.info1.size.width  = IVAL(enum_values[i].data->data,  0);
    3024         288 :                 val.info1.size.height = IVAL(enum_values[i].data->data,  4);
    3025         288 :                 val.info1.area.left   = IVAL(enum_values[i].data->data,  8);
    3026         288 :                 val.info1.area.top    = IVAL(enum_values[i].data->data, 12);
    3027         288 :                 val.info1.area.right  = IVAL(enum_values[i].data->data, 16);
    3028         288 :                 val.info1.area.bottom = IVAL(enum_values[i].data->data, 20);
    3029             :                 /* skip form index      IVAL(enum_values[i].data->data, 24)));*/
    3030         288 :                 val.info1.flags       = (enum spoolss_FormFlags) IVAL(enum_values[i].data->data, 28);
    3031             : 
    3032         288 :                 info[i + num_builtin] = val;
    3033             :         }
    3034             : 
    3035        1016 :         *pnum_info = num_builtin + num_values;
    3036        1016 :         if (pinfo) {
    3037        1016 :                 *pinfo = talloc_move(mem_ctx, &info);
    3038             :         }
    3039             : 
    3040         762 : done:
    3041        1016 :         if (is_valid_policy_hnd(&key_hnd)) {
    3042        1016 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3043             :         }
    3044        1016 :         if (is_valid_policy_hnd(&hive_hnd)) {
    3045        1016 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3046             :         }
    3047             : 
    3048        1016 :         TALLOC_FREE(enum_values);
    3049        1016 :         TALLOC_FREE(tmp_ctx);
    3050        1016 :         return result;
    3051             : }
    3052             : 
    3053         464 : WERROR winreg_printer_deleteform1(TALLOC_CTX *mem_ctx,
    3054             :                                   struct dcerpc_binding_handle *winreg_handle,
    3055             :                                   const char *form_name)
    3056             : {
    3057         464 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3058             :         struct policy_handle hive_hnd, key_hnd;
    3059         464 :         struct winreg_String wvalue = { 0, };
    3060         464 :         uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
    3061             :         uint32_t i;
    3062         464 :         WERROR result = WERR_OK;
    3063             :         WERROR ignore;
    3064             :         NTSTATUS status;
    3065             :         TALLOC_CTX *tmp_ctx;
    3066             : 
    3067       38224 :         for (i = 0; i < num_builtin; i++) {
    3068       37904 :                 if (strequal(builtin_forms1[i].form_name, form_name)) {
    3069         144 :                         return WERR_INVALID_PARAMETER;
    3070             :                 }
    3071             :         }
    3072             : 
    3073         320 :         tmp_ctx = talloc_stackframe();
    3074         320 :         if (tmp_ctx == NULL) {
    3075           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    3076             :         }
    3077             : 
    3078         320 :         ZERO_STRUCT(hive_hnd);
    3079         320 :         ZERO_STRUCT(key_hnd);
    3080             : 
    3081         320 :         result = winreg_printer_openkey(tmp_ctx,
    3082             :                                         winreg_handle,
    3083             :                                         TOP_LEVEL_CONTROL_FORMS_KEY,
    3084             :                                         "",
    3085             :                                         false,
    3086             :                                         access_mask,
    3087             :                                         &hive_hnd,
    3088             :                                         &key_hnd);
    3089         320 :         if (!W_ERROR_IS_OK(result)) {
    3090           0 :                 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
    3091             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    3092           0 :                 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    3093           0 :                         result = WERR_INVALID_FORM_NAME;
    3094             :                 }
    3095           0 :                 goto done;
    3096             :         }
    3097             : 
    3098         320 :         wvalue.name = form_name;
    3099         320 :         status = dcerpc_winreg_DeleteValue(winreg_handle,
    3100             :                                            tmp_ctx,
    3101             :                                            &key_hnd,
    3102             :                                            wvalue,
    3103             :                                            &result);
    3104         320 :         if (!NT_STATUS_IS_OK(status)) {
    3105             :                 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
    3106           0 :                 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
    3107             :                           wvalue.name, nt_errstr(status)));
    3108           0 :                 result = ntstatus_to_werror(status);
    3109           0 :                 goto done;
    3110             :         }
    3111             : 
    3112         320 :         if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    3113         144 :                 result = WERR_INVALID_FORM_NAME;
    3114             :         }
    3115             : 
    3116         452 : done:
    3117         320 :         if (is_valid_policy_hnd(&key_hnd)) {
    3118         320 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3119             :         }
    3120         320 :         if (is_valid_policy_hnd(&hive_hnd)) {
    3121         320 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3122             :         }
    3123             : 
    3124         320 :         TALLOC_FREE(tmp_ctx);
    3125         320 :         return result;
    3126             : }
    3127             : 
    3128          80 : WERROR winreg_printer_setform1(TALLOC_CTX *mem_ctx,
    3129             :                                struct dcerpc_binding_handle *winreg_handle,
    3130             :                                const char *form_name,
    3131             :                                struct spoolss_AddFormInfo1 *form)
    3132             : {
    3133          80 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3134          80 :         struct policy_handle hive_hnd = { 0, };
    3135          80 :         struct policy_handle key_hnd = { 0, };
    3136          80 :         struct winreg_String wvalue = { 0, };
    3137             :         DATA_BLOB blob;
    3138          80 :         uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
    3139             :         uint32_t i;
    3140             :         WERROR result;
    3141             :         NTSTATUS status;
    3142          80 :         TALLOC_CTX *tmp_ctx = NULL;
    3143             : 
    3144        9520 :         for (i = 0; i < num_builtin; i++) {
    3145        9440 :                 if (strequal(builtin_forms1[i].form_name, form->form_name)) {
    3146           0 :                         result = WERR_INVALID_PARAMETER;
    3147           0 :                         goto done;
    3148             :                 }
    3149             :         }
    3150             : 
    3151          80 :         tmp_ctx = talloc_stackframe();
    3152          80 :         if (tmp_ctx == NULL) {
    3153           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    3154             :         }
    3155             : 
    3156          80 :         ZERO_STRUCT(hive_hnd);
    3157          80 :         ZERO_STRUCT(key_hnd);
    3158             : 
    3159          80 :         result = winreg_printer_openkey(tmp_ctx,
    3160             :                                         winreg_handle,
    3161             :                                         TOP_LEVEL_CONTROL_FORMS_KEY,
    3162             :                                         "",
    3163             :                                         true,
    3164             :                                         access_mask,
    3165             :                                         &hive_hnd,
    3166             :                                         &key_hnd);
    3167          80 :         if (!W_ERROR_IS_OK(result)) {
    3168           0 :                 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
    3169             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    3170           0 :                 goto done;
    3171             :         }
    3172             : 
    3173             :         /* If form_name != form->form_name then we renamed the form */
    3174          80 :         if (strequal(form_name, form->form_name)) {
    3175          80 :                 result = winreg_printer_deleteform1(tmp_ctx, winreg_handle,
    3176             :                                                     form_name);
    3177          80 :                 if (!W_ERROR_IS_OK(result)) {
    3178           0 :                         DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
    3179             :                                   TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    3180           0 :                         goto done;
    3181             :                 }
    3182             :         }
    3183             : 
    3184          80 :         wvalue.name = form->form_name;
    3185             : 
    3186          80 :         blob = data_blob_talloc(tmp_ctx, NULL, 32);
    3187          80 :         SIVAL(blob.data,  0, form->size.width);
    3188          80 :         SIVAL(blob.data,  4, form->size.height);
    3189          80 :         SIVAL(blob.data,  8, form->area.left);
    3190          80 :         SIVAL(blob.data, 12, form->area.top);
    3191          80 :         SIVAL(blob.data, 16, form->area.right);
    3192          80 :         SIVAL(blob.data, 20, form->area.bottom);
    3193          80 :         SIVAL(blob.data, 24, 42);
    3194          80 :         SIVAL(blob.data, 28, form->flags);
    3195             : 
    3196          80 :         status = dcerpc_winreg_SetValue(winreg_handle,
    3197             :                                         tmp_ctx,
    3198             :                                         &key_hnd,
    3199             :                                         wvalue,
    3200             :                                         REG_BINARY,
    3201             :                                         blob.data,
    3202          80 :                                         blob.length,
    3203             :                                         &result);
    3204          80 :         if (!NT_STATUS_IS_OK(status)) {
    3205           0 :                 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
    3206             :                           wvalue.name, nt_errstr(status)));
    3207           0 :                 result = ntstatus_to_werror(status);
    3208             :         }
    3209             : 
    3210         140 : done:
    3211          80 :         if (winreg_handle != NULL) {
    3212             :                 WERROR ignore;
    3213             : 
    3214          80 :                 if (is_valid_policy_hnd(&key_hnd)) {
    3215          80 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3216             :                 }
    3217          80 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    3218          80 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3219             :                 }
    3220             :         }
    3221             : 
    3222          80 :         TALLOC_FREE(tmp_ctx);
    3223          80 :         return result;
    3224             : }
    3225             : 
    3226        5040 : WERROR winreg_printer_getform1(TALLOC_CTX *mem_ctx,
    3227             :                                struct dcerpc_binding_handle *winreg_handle,
    3228             :                                const char *form_name,
    3229             :                                struct spoolss_FormInfo1 *r)
    3230             : {
    3231        5040 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3232             :         struct policy_handle hive_hnd, key_hnd;
    3233             :         struct winreg_String wvalue;
    3234        5040 :         enum winreg_Type type_in = REG_NONE;
    3235        5040 :         uint8_t *data_in = NULL;
    3236        5040 :         uint32_t data_in_size = 0;
    3237        5040 :         uint32_t value_len = 0;
    3238        5040 :         uint32_t num_builtin = ARRAY_SIZE(builtin_forms1);
    3239             :         uint32_t i;
    3240             :         WERROR result;
    3241             :         WERROR ignore;
    3242             :         NTSTATUS status;
    3243             :         TALLOC_CTX *tmp_ctx;
    3244             : 
    3245             :         /* check builtin forms first */
    3246      318920 :         for (i = 0; i < num_builtin; i++) {
    3247      318600 :                 if (strequal(builtin_forms1[i].form_name, form_name)) {
    3248        4720 :                         *r = builtin_forms1[i];
    3249        4720 :                         return WERR_OK;
    3250             :                 }
    3251             :         }
    3252             : 
    3253         320 :         tmp_ctx = talloc_stackframe();
    3254         320 :         if (tmp_ctx == NULL) {
    3255           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    3256             :         }
    3257             : 
    3258         320 :         ZERO_STRUCT(hive_hnd);
    3259         320 :         ZERO_STRUCT(key_hnd);
    3260             : 
    3261         320 :         result = winreg_printer_openkey(tmp_ctx,
    3262             :                                         winreg_handle,
    3263             :                                         TOP_LEVEL_CONTROL_FORMS_KEY,
    3264             :                                         "",
    3265             :                                         true,
    3266             :                                         access_mask,
    3267             :                                         &hive_hnd,
    3268             :                                         &key_hnd);
    3269         320 :         if (!W_ERROR_IS_OK(result)) {
    3270           0 :                 DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
    3271             :                           TOP_LEVEL_CONTROL_FORMS_KEY, win_errstr(result)));
    3272           0 :                 goto done;
    3273             :         }
    3274             : 
    3275         320 :         wvalue.name = form_name;
    3276             : 
    3277             :         /*
    3278             :          * call QueryValue once with data == NULL to get the
    3279             :          * needed memory size to be allocated, then allocate
    3280             :          * data buffer and call again.
    3281             :          */
    3282         320 :         status = dcerpc_winreg_QueryValue(winreg_handle,
    3283             :                                           tmp_ctx,
    3284             :                                           &key_hnd,
    3285             :                                           &wvalue,
    3286             :                                           &type_in,
    3287             :                                           NULL,
    3288             :                                           &data_in_size,
    3289             :                                           &value_len,
    3290             :                                           &result);
    3291         320 :         if (!NT_STATUS_IS_OK(status)) {
    3292           0 :                 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
    3293             :                           wvalue.name, nt_errstr(status)));
    3294           0 :                 result = ntstatus_to_werror(status);
    3295           0 :                 goto done;
    3296             :         }
    3297         320 :         if (!W_ERROR_IS_OK(result)) {
    3298           0 :                 goto done;
    3299             :         }
    3300             : 
    3301         320 :         data_in = (uint8_t *) TALLOC(tmp_ctx, data_in_size);
    3302         320 :         if (data_in == NULL) {
    3303           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    3304           0 :                 goto done;
    3305             :         }
    3306         320 :         value_len = 0;
    3307             : 
    3308         320 :         status = dcerpc_winreg_QueryValue(winreg_handle,
    3309             :                                           tmp_ctx,
    3310             :                                           &key_hnd,
    3311             :                                           &wvalue,
    3312             :                                           &type_in,
    3313             :                                           data_in,
    3314             :                                           &data_in_size,
    3315             :                                           &value_len,
    3316             :                                           &result);
    3317         320 :         if (!NT_STATUS_IS_OK(status)) {
    3318           0 :                 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
    3319             :                           wvalue.name, nt_errstr(status)));
    3320           0 :                 result = ntstatus_to_werror(status);
    3321           0 :                 goto done;
    3322             :         }
    3323         320 :         if (!W_ERROR_IS_OK(result)) {
    3324           0 :                 goto done;
    3325             :         }
    3326             : 
    3327         320 :         r->form_name = talloc_strdup(mem_ctx, form_name);
    3328         320 :         if (r->form_name == NULL) {
    3329           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    3330           0 :                 goto done;
    3331             :         }
    3332             : 
    3333         320 :         r->size.width  = IVAL(data_in,  0);
    3334         320 :         r->size.height = IVAL(data_in,  4);
    3335         320 :         r->area.left   = IVAL(data_in,  8);
    3336         320 :         r->area.top    = IVAL(data_in, 12);
    3337         320 :         r->area.right  = IVAL(data_in, 16);
    3338         320 :         r->area.bottom = IVAL(data_in, 20);
    3339             :         /* skip index    IVAL(data_in, 24)));*/
    3340         320 :         r->flags       = (enum spoolss_FormFlags) IVAL(data_in, 28);
    3341             : 
    3342         320 :         result = WERR_OK;
    3343         320 : done:
    3344         320 :         if (is_valid_policy_hnd(&key_hnd)) {
    3345         320 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3346             :         }
    3347         320 :         if (is_valid_policy_hnd(&hive_hnd)) {
    3348         320 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3349             :         }
    3350             : 
    3351         320 :         TALLOC_FREE(tmp_ctx);
    3352         320 :         return result;
    3353             : }
    3354             : 
    3355           0 : WERROR winreg_add_driver(TALLOC_CTX *mem_ctx,
    3356             :                          struct dcerpc_binding_handle *winreg_handle,
    3357             :                          struct spoolss_AddDriverInfoCtr *r,
    3358             :                          const char **driver_name,
    3359             :                          uint32_t *driver_version)
    3360             : {
    3361           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3362             :         struct policy_handle hive_hnd, key_hnd;
    3363             :         struct spoolss_DriverInfo8 info8;
    3364           0 :         TALLOC_CTX *tmp_ctx = NULL;
    3365             :         NTSTATUS status;
    3366             :         WERROR result;
    3367             : 
    3368           0 :         ZERO_STRUCT(hive_hnd);
    3369           0 :         ZERO_STRUCT(key_hnd);
    3370           0 :         ZERO_STRUCT(info8);
    3371             : 
    3372           0 :         if (!driver_info_ctr_to_info8(r, &info8)) {
    3373           0 :                 result = WERR_INVALID_PARAMETER;
    3374           0 :                 goto done;
    3375             :         }
    3376             : 
    3377           0 :         tmp_ctx = talloc_stackframe();
    3378           0 :         if (tmp_ctx == NULL) {
    3379           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    3380             :         }
    3381             : 
    3382           0 :         result = winreg_printer_opendriver(tmp_ctx,
    3383             :                                            winreg_handle,
    3384             :                                            info8.driver_name,
    3385             :                                            info8.architecture,
    3386           0 :                                            info8.version,
    3387             :                                            access_mask, true,
    3388             :                                            &hive_hnd,
    3389             :                                            &key_hnd);
    3390           0 :         if (!W_ERROR_IS_OK(result)) {
    3391           0 :                 DEBUG(0, ("winreg_add_driver: "
    3392             :                           "Could not open driver key (%s,%s,%d): %s\n",
    3393             :                           info8.driver_name, info8.architecture,
    3394             :                           info8.version, win_errstr(result)));
    3395           0 :                 goto done;
    3396             :         }
    3397             : 
    3398             :         /* TODO: "Attributes" ? */
    3399             : 
    3400           0 :         status = dcerpc_winreg_set_dword(tmp_ctx,
    3401             :                                          winreg_handle,
    3402             :                                          &key_hnd,
    3403             :                                          "Version",
    3404           0 :                                          info8.version,
    3405             :                                          &result);
    3406           0 :         if (!NT_STATUS_IS_OK(status)) {
    3407           0 :                 result = ntstatus_to_werror(status);
    3408             :         }
    3409           0 :         if (!W_ERROR_IS_OK(result)) {
    3410           0 :                 goto done;
    3411             :         }
    3412             : 
    3413           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3414             :                                       winreg_handle,
    3415             :                                       &key_hnd,
    3416             :                                       "Driver",
    3417             :                                       info8.driver_path,
    3418             :                                       &result);
    3419           0 :         if (!NT_STATUS_IS_OK(status)) {
    3420           0 :                 result = ntstatus_to_werror(status);
    3421             :         }
    3422           0 :         if (!W_ERROR_IS_OK(result)) {
    3423           0 :                 goto done;
    3424             :         }
    3425             : 
    3426           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3427             :                                       winreg_handle,
    3428             :                                       &key_hnd,
    3429             :                                       "Data File",
    3430             :                                       info8.data_file,
    3431             :                                       &result);
    3432           0 :         if (!NT_STATUS_IS_OK(status)) {
    3433           0 :                 result = ntstatus_to_werror(status);
    3434             :         }
    3435           0 :         if (!W_ERROR_IS_OK(result)) {
    3436           0 :                 goto done;
    3437             :         }
    3438             : 
    3439           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3440             :                                       winreg_handle,
    3441             :                                       &key_hnd,
    3442             :                                       "Configuration File",
    3443             :                                       info8.config_file,
    3444             :                                       &result);
    3445           0 :         if (!NT_STATUS_IS_OK(status)) {
    3446           0 :                 result = ntstatus_to_werror(status);
    3447             :         }
    3448           0 :         if (!W_ERROR_IS_OK(result)) {
    3449           0 :                 goto done;
    3450             :         }
    3451             : 
    3452           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3453             :                                       winreg_handle,
    3454             :                                       &key_hnd,
    3455             :                                       "Help File",
    3456             :                                       info8.help_file,
    3457             :                                       &result);
    3458           0 :         if (!NT_STATUS_IS_OK(status)) {
    3459           0 :                 result = ntstatus_to_werror(status);
    3460             :         }
    3461           0 :         if (!W_ERROR_IS_OK(result)) {
    3462           0 :                 goto done;
    3463             :         }
    3464             : 
    3465           0 :         status = dcerpc_winreg_set_multi_sz(tmp_ctx,
    3466             :                                             winreg_handle,
    3467             :                                             &key_hnd,
    3468             :                                             "Dependent Files",
    3469             :                                             info8.dependent_files,
    3470             :                                             &result);
    3471           0 :         if (!NT_STATUS_IS_OK(status)) {
    3472           0 :                 result = ntstatus_to_werror(status);
    3473             :         }
    3474           0 :         if (!W_ERROR_IS_OK(result)) {
    3475           0 :                 goto done;
    3476             :         }
    3477             : 
    3478           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3479             :                                       winreg_handle,
    3480             :                                       &key_hnd,
    3481             :                                       "Monitor",
    3482             :                                       info8.monitor_name,
    3483             :                                       &result);
    3484           0 :         if (!NT_STATUS_IS_OK(status)) {
    3485           0 :                 result = ntstatus_to_werror(status);
    3486             :         }
    3487           0 :         if (!W_ERROR_IS_OK(result)) {
    3488           0 :                 goto done;
    3489             :         }
    3490             : 
    3491           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3492             :                                       winreg_handle,
    3493             :                                       &key_hnd,
    3494             :                                       "Datatype",
    3495             :                                       info8.default_datatype,
    3496             :                                       &result);
    3497           0 :         if (!NT_STATUS_IS_OK(status)) {
    3498           0 :                 result = ntstatus_to_werror(status);
    3499             :         }
    3500           0 :         if (!W_ERROR_IS_OK(result)) {
    3501           0 :                 goto done;
    3502             :         }
    3503             : 
    3504           0 :         status = dcerpc_winreg_set_multi_sz(tmp_ctx,
    3505             :                                             winreg_handle,
    3506             :                                             &key_hnd, "Previous Names",
    3507             :                                             info8.previous_names,
    3508             :                                             &result);
    3509           0 :         if (!NT_STATUS_IS_OK(status)) {
    3510           0 :                 result = ntstatus_to_werror(status);
    3511             :         }
    3512           0 :         if (!W_ERROR_IS_OK(result)) {
    3513           0 :                 goto done;
    3514             :         }
    3515             : 
    3516           0 :         result = winreg_printer_write_date(tmp_ctx, winreg_handle,
    3517             :                                            &key_hnd, "DriverDate",
    3518             :                                            info8.driver_date);
    3519           0 :         if (!W_ERROR_IS_OK(result)) {
    3520           0 :                 goto done;
    3521             :         }
    3522             : 
    3523           0 :         result = winreg_printer_write_ver(tmp_ctx, winreg_handle,
    3524             :                                           &key_hnd, "DriverVersion",
    3525             :                                           info8.driver_version);
    3526           0 :         if (!W_ERROR_IS_OK(result)) {
    3527           0 :                 goto done;
    3528             :         }
    3529             : 
    3530           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3531             :                                       winreg_handle,
    3532             :                                       &key_hnd,
    3533             :                                       "Manufacturer",
    3534             :                                       info8.manufacturer_name,
    3535             :                                       &result);
    3536           0 :         if (!NT_STATUS_IS_OK(status)) {
    3537           0 :                 result = ntstatus_to_werror(status);
    3538             :         }
    3539           0 :         if (!W_ERROR_IS_OK(result)) {
    3540           0 :                 goto done;
    3541             :         }
    3542             : 
    3543           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3544             :                                       winreg_handle,
    3545             :                                       &key_hnd,
    3546             :                                       "OEM URL",
    3547             :                                       info8.manufacturer_url,
    3548             :                                       &result);
    3549           0 :         if (!NT_STATUS_IS_OK(status)) {
    3550           0 :                 result = ntstatus_to_werror(status);
    3551             :         }
    3552           0 :         if (!W_ERROR_IS_OK(result)) {
    3553           0 :                 goto done;
    3554             :         }
    3555             : 
    3556           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3557             :                                       winreg_handle,
    3558             :                                       &key_hnd,
    3559             :                                       "HardwareID",
    3560             :                                       info8.hardware_id,
    3561             :                                       &result);
    3562           0 :         if (!NT_STATUS_IS_OK(status)) {
    3563           0 :                 result = ntstatus_to_werror(status);
    3564             :         }
    3565           0 :         if (!W_ERROR_IS_OK(result)) {
    3566           0 :                 goto done;
    3567             :         }
    3568             : 
    3569           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3570             :                                       winreg_handle,
    3571             :                                       &key_hnd,
    3572             :                                       "Provider",
    3573             :                                       info8.provider,
    3574             :                                       &result);
    3575           0 :         if (!NT_STATUS_IS_OK(status)) {
    3576           0 :                 result = ntstatus_to_werror(status);
    3577             :         }
    3578           0 :         if (!W_ERROR_IS_OK(result)) {
    3579           0 :                 goto done;
    3580             :         }
    3581             : 
    3582           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3583             :                                       winreg_handle,
    3584             :                                       &key_hnd,
    3585             :                                       "Print Processor",
    3586             :                                       info8.print_processor,
    3587             :                                       &result);
    3588           0 :         if (!NT_STATUS_IS_OK(status)) {
    3589           0 :                 result = ntstatus_to_werror(status);
    3590             :         }
    3591           0 :         if (!W_ERROR_IS_OK(result)) {
    3592           0 :                 goto done;
    3593             :         }
    3594             : 
    3595           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3596             :                                       winreg_handle,
    3597             :                                       &key_hnd,
    3598             :                                       "VendorSetup",
    3599             :                                       info8.vendor_setup,
    3600             :                                       &result);
    3601           0 :         if (!NT_STATUS_IS_OK(status)) {
    3602           0 :                 result = ntstatus_to_werror(status);
    3603             :         }
    3604           0 :         if (!W_ERROR_IS_OK(result)) {
    3605           0 :                 goto done;
    3606             :         }
    3607             : 
    3608           0 :         status = dcerpc_winreg_set_multi_sz(tmp_ctx,
    3609             :                                             winreg_handle,
    3610             :                                             &key_hnd,
    3611             :                                             "Color Profiles",
    3612             :                                             info8.color_profiles,
    3613             :                                             &result);
    3614           0 :         if (!NT_STATUS_IS_OK(status)) {
    3615           0 :                 result = ntstatus_to_werror(status);
    3616             :         }
    3617           0 :         if (!W_ERROR_IS_OK(result)) {
    3618           0 :                 goto done;
    3619             :         }
    3620             : 
    3621           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    3622             :                                       winreg_handle,
    3623             :                                       &key_hnd,
    3624             :                                       "InfPath",
    3625             :                                       info8.inf_path,
    3626             :                                       &result);
    3627           0 :         if (!NT_STATUS_IS_OK(status)) {
    3628           0 :                 result = ntstatus_to_werror(status);
    3629             :         }
    3630           0 :         if (!W_ERROR_IS_OK(result)) {
    3631           0 :                 goto done;
    3632             :         }
    3633             : 
    3634           0 :         status = dcerpc_winreg_set_dword(tmp_ctx,
    3635             :                                          winreg_handle,
    3636             :                                          &key_hnd,
    3637             :                                          "PrinterDriverAttributes",
    3638             :                                          info8.printer_driver_attributes,
    3639             :                                          &result);
    3640           0 :         if (!NT_STATUS_IS_OK(status)) {
    3641           0 :                 result = ntstatus_to_werror(status);
    3642             :         }
    3643           0 :         if (!W_ERROR_IS_OK(result)) {
    3644           0 :                 goto done;
    3645             :         }
    3646             : 
    3647           0 :         status = dcerpc_winreg_set_multi_sz(tmp_ctx,
    3648             :                                             winreg_handle,
    3649             :                                             &key_hnd,
    3650             :                                             "CoreDependencies",
    3651             :                                             info8.core_driver_dependencies,
    3652             :                                             &result);
    3653           0 :         if (!NT_STATUS_IS_OK(status)) {
    3654           0 :                 result = ntstatus_to_werror(status);
    3655             :         }
    3656           0 :         if (!W_ERROR_IS_OK(result)) {
    3657           0 :                 goto done;
    3658             :         }
    3659             : 
    3660           0 :         result = winreg_printer_write_date(tmp_ctx, winreg_handle,
    3661             :                                            &key_hnd, "MinInboxDriverVerDate",
    3662             :                                            info8.min_inbox_driver_ver_date);
    3663           0 :         if (!W_ERROR_IS_OK(result)) {
    3664           0 :                 goto done;
    3665             :         }
    3666             : 
    3667           0 :         result = winreg_printer_write_ver(tmp_ctx, winreg_handle, &key_hnd,
    3668             :                                           "MinInboxDriverVerVersion",
    3669             :                                           info8.min_inbox_driver_ver_version);
    3670           0 :         if (!W_ERROR_IS_OK(result)) {
    3671           0 :                 goto done;
    3672             :         }
    3673             : 
    3674           0 :         *driver_name = info8.driver_name;
    3675           0 :         *driver_version = info8.version;
    3676           0 :         result = WERR_OK;
    3677           0 : done:
    3678           0 :         if (winreg_handle != NULL) {
    3679             :                 WERROR ignore;
    3680             : 
    3681           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    3682           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3683             :                 }
    3684           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    3685           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3686             :                 }
    3687             :         }
    3688             : 
    3689           0 :         TALLOC_FREE(tmp_ctx);
    3690           0 :         return result;
    3691             : }
    3692             : 
    3693           0 : WERROR winreg_get_driver(TALLOC_CTX *mem_ctx,
    3694             :                          struct dcerpc_binding_handle *winreg_handle,
    3695             :                          const char *architecture,
    3696             :                          const char *driver_name,
    3697             :                          uint32_t driver_version,
    3698             :                          struct spoolss_DriverInfo8 **_info8)
    3699             : {
    3700           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3701             :         struct policy_handle hive_hnd, key_hnd;
    3702           0 :         struct spoolss_DriverInfo8 i8, *info8 = NULL;
    3703           0 :         struct spoolss_PrinterEnumValues *enum_values = NULL;
    3704           0 :         struct spoolss_PrinterEnumValues *v = NULL;
    3705           0 :         uint32_t num_values = 0;
    3706           0 :         TALLOC_CTX *tmp_ctx = NULL;
    3707             :         WERROR result;
    3708             :         NTSTATUS status;
    3709             :         uint32_t i;
    3710           0 :         const char **enum_names = NULL;
    3711           0 :         enum winreg_Type *enum_types = NULL;
    3712           0 :         DATA_BLOB *enum_data_blobs = NULL;
    3713             : 
    3714           0 :         ZERO_STRUCT(hive_hnd);
    3715           0 :         ZERO_STRUCT(key_hnd);
    3716           0 :         ZERO_STRUCT(i8);
    3717             : 
    3718           0 :         tmp_ctx = talloc_stackframe();
    3719           0 :         if (tmp_ctx == NULL) {
    3720           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    3721             :         }
    3722             : 
    3723           0 :         if (driver_version == DRIVER_ANY_VERSION) {
    3724             :                 /* look for Win2k first and then for NT4 */
    3725           0 :                 result = winreg_printer_opendriver(tmp_ctx,
    3726             :                                                    winreg_handle,
    3727             :                                                    driver_name,
    3728             :                                                    architecture,
    3729             :                                                    3,
    3730             :                                                    access_mask, false,
    3731             :                                                    &hive_hnd,
    3732             :                                                    &key_hnd);
    3733           0 :                 if (!W_ERROR_IS_OK(result)) {
    3734           0 :                         result = winreg_printer_opendriver(tmp_ctx,
    3735             :                                                            winreg_handle,
    3736             :                                                            driver_name,
    3737             :                                                            architecture,
    3738             :                                                            2,
    3739             :                                                            access_mask, false,
    3740             :                                                            &hive_hnd,
    3741             :                                                            &key_hnd);
    3742             :                 }
    3743             :         } else {
    3744             :                 /* ok normal case */
    3745           0 :                 result = winreg_printer_opendriver(tmp_ctx,
    3746             :                                                    winreg_handle,
    3747             :                                                    driver_name,
    3748             :                                                    architecture,
    3749             :                                                    driver_version,
    3750             :                                                    access_mask, false,
    3751             :                                                    &hive_hnd,
    3752             :                                                    &key_hnd);
    3753             :         }
    3754           0 :         if (!W_ERROR_IS_OK(result)) {
    3755           0 :                 DEBUG(5, ("winreg_get_driver: "
    3756             :                           "Could not open driver key (%s,%s,%d): %s\n",
    3757             :                           driver_name, architecture,
    3758             :                           driver_version, win_errstr(result)));
    3759           0 :                 goto done;
    3760             :         }
    3761             : 
    3762           0 :         status = dcerpc_winreg_enumvals(tmp_ctx,
    3763             :                                         winreg_handle,
    3764             :                                         &key_hnd,
    3765             :                                         &num_values,
    3766             :                                         &enum_names,
    3767             :                                         &enum_types,
    3768             :                                         &enum_data_blobs,
    3769             :                                         &result);
    3770           0 :         if (!NT_STATUS_IS_OK(status)){
    3771           0 :                 result = ntstatus_to_werror(status);
    3772             :         }
    3773             : 
    3774           0 :         if (!W_ERROR_IS_OK(result)) {
    3775           0 :                 DEBUG(0, ("winreg_get_driver: "
    3776             :                           "Could not enumerate values for (%s,%s,%d): %s\n",
    3777             :                           driver_name, architecture,
    3778             :                           driver_version, win_errstr(result)));
    3779           0 :                 goto done;
    3780             :         }
    3781             : 
    3782           0 :         enum_values = talloc_zero_array(tmp_ctx,
    3783             :                                         struct spoolss_PrinterEnumValues,
    3784             :                                         num_values);
    3785           0 :         if (enum_values == NULL){
    3786           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    3787           0 :                 goto done;
    3788             :         }
    3789             : 
    3790           0 :         for (i = 0; i < num_values; i++){
    3791           0 :                 enum_values[i].value_name = enum_names[i];
    3792           0 :                 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
    3793           0 :                 enum_values[i].type = enum_types[i];
    3794           0 :                 enum_values[i].data_length = enum_data_blobs[i].length;
    3795           0 :                 enum_values[i].data = NULL;
    3796           0 :                 if (enum_values[i].data_length != 0){
    3797           0 :                         enum_values[i].data = &enum_data_blobs[i];
    3798             :                 }
    3799             :         }
    3800             : 
    3801           0 :         info8 = talloc_zero(tmp_ctx, struct spoolss_DriverInfo8);
    3802           0 :         if (info8 == NULL) {
    3803           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    3804           0 :                 goto done;
    3805             :         }
    3806             : 
    3807           0 :         info8->driver_name = talloc_strdup(info8, driver_name);
    3808           0 :         if (info8->driver_name == NULL) {
    3809           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    3810           0 :                 goto done;
    3811             :         }
    3812             : 
    3813           0 :         info8->architecture = talloc_strdup(info8, architecture);
    3814           0 :         if (info8->architecture == NULL) {
    3815           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    3816           0 :                 goto done;
    3817             :         }
    3818             : 
    3819           0 :         result = WERR_OK;
    3820             : 
    3821           0 :         for (i = 0; i < num_values; i++) {
    3822             :                 const char *tmp_str;
    3823           0 :                 uint32_t tmp = 0;
    3824             : 
    3825           0 :                 v = &enum_values[i];
    3826             : 
    3827           0 :                 result = winreg_enumval_to_dword(info8, v,
    3828             :                                                  "Version",
    3829             :                                                  &tmp);
    3830           0 :                 if (W_ERROR_IS_OK(result)) {
    3831           0 :                         info8->version = (enum spoolss_DriverOSVersion) tmp;
    3832             :                 }
    3833           0 :                 CHECK_ERROR(result);
    3834             : 
    3835           0 :                 result = winreg_enumval_to_sz(info8, v,
    3836             :                                               "Driver",
    3837             :                                               &info8->driver_path);
    3838           0 :                 CHECK_ERROR(result);
    3839             : 
    3840           0 :                 result = winreg_enumval_to_sz(info8, v,
    3841             :                                               "Data File",
    3842             :                                               &info8->data_file);
    3843           0 :                 CHECK_ERROR(result);
    3844             : 
    3845           0 :                 result = winreg_enumval_to_sz(info8, v,
    3846             :                                               "Configuration File",
    3847             :                                               &info8->config_file);
    3848           0 :                 CHECK_ERROR(result);
    3849             : 
    3850           0 :                 result = winreg_enumval_to_sz(info8, v,
    3851             :                                               "Help File",
    3852             :                                               &info8->help_file);
    3853           0 :                 CHECK_ERROR(result);
    3854             : 
    3855           0 :                 result = winreg_enumval_to_multi_sz(info8, v,
    3856             :                                                     "Dependent Files",
    3857             :                                                     &info8->dependent_files);
    3858           0 :                 CHECK_ERROR(result);
    3859             : 
    3860           0 :                 result = winreg_enumval_to_sz(info8, v,
    3861             :                                               "Monitor",
    3862             :                                               &info8->monitor_name);
    3863           0 :                 CHECK_ERROR(result);
    3864             : 
    3865           0 :                 result = winreg_enumval_to_sz(info8, v,
    3866             :                                               "Datatype",
    3867             :                                               &info8->default_datatype);
    3868           0 :                 CHECK_ERROR(result);
    3869             : 
    3870           0 :                 result = winreg_enumval_to_multi_sz(info8, v,
    3871             :                                                     "Previous Names",
    3872             :                                                     &info8->previous_names);
    3873           0 :                 CHECK_ERROR(result);
    3874             : 
    3875           0 :                 result = winreg_enumval_to_sz(info8, v,
    3876             :                                               "DriverDate",
    3877             :                                               &tmp_str);
    3878           0 :                 if (W_ERROR_IS_OK(result)) {
    3879           0 :                         result = winreg_printer_date_to_NTTIME(tmp_str,
    3880             :                                                 &info8->driver_date);
    3881             :                 }
    3882           0 :                 CHECK_ERROR(result);
    3883             : 
    3884           0 :                 result = winreg_enumval_to_sz(info8, v,
    3885             :                                               "DriverVersion",
    3886             :                                               &tmp_str);
    3887           0 :                 if (W_ERROR_IS_OK(result)) {
    3888           0 :                         result = winreg_printer_ver_to_qword(tmp_str,
    3889             :                                                 &info8->driver_version);
    3890             :                 }
    3891           0 :                 CHECK_ERROR(result);
    3892             : 
    3893           0 :                 result = winreg_enumval_to_sz(info8, v,
    3894             :                                               "Manufacturer",
    3895             :                                               &info8->manufacturer_name);
    3896           0 :                 CHECK_ERROR(result);
    3897             : 
    3898           0 :                 result = winreg_enumval_to_sz(info8, v,
    3899             :                                               "OEM URL",
    3900             :                                               &info8->manufacturer_url);
    3901           0 :                 CHECK_ERROR(result);
    3902             : 
    3903           0 :                 result = winreg_enumval_to_sz(info8, v,
    3904             :                                               "HardwareID",
    3905             :                                               &info8->hardware_id);
    3906           0 :                 CHECK_ERROR(result);
    3907             : 
    3908           0 :                 result = winreg_enumval_to_sz(info8, v,
    3909             :                                               "Provider",
    3910             :                                               &info8->provider);
    3911           0 :                 CHECK_ERROR(result);
    3912             : 
    3913           0 :                 result = winreg_enumval_to_sz(info8, v,
    3914             :                                               "Print Processor",
    3915             :                                               &info8->print_processor);
    3916           0 :                 CHECK_ERROR(result);
    3917             : 
    3918           0 :                 result = winreg_enumval_to_sz(info8, v,
    3919             :                                               "VendorSetup",
    3920             :                                               &info8->vendor_setup);
    3921           0 :                 CHECK_ERROR(result);
    3922             : 
    3923           0 :                 result = winreg_enumval_to_multi_sz(info8, v,
    3924             :                                                     "Color Profiles",
    3925             :                                                     &info8->color_profiles);
    3926           0 :                 CHECK_ERROR(result);
    3927             : 
    3928           0 :                 result = winreg_enumval_to_sz(info8, v,
    3929             :                                               "InfPath",
    3930             :                                               &info8->inf_path);
    3931           0 :                 CHECK_ERROR(result);
    3932             : 
    3933           0 :                 result = winreg_enumval_to_dword(info8, v,
    3934             :                                                  "PrinterDriverAttributes",
    3935             :                                                  &info8->printer_driver_attributes);
    3936           0 :                 CHECK_ERROR(result);
    3937             : 
    3938           0 :                 result = winreg_enumval_to_multi_sz(info8, v,
    3939             :                                                     "CoreDependencies",
    3940             :                                                     &info8->core_driver_dependencies);
    3941           0 :                 CHECK_ERROR(result);
    3942             : 
    3943           0 :                 result = winreg_enumval_to_sz(info8, v,
    3944             :                                               "MinInboxDriverVerDate",
    3945             :                                               &tmp_str);
    3946           0 :                 if (W_ERROR_IS_OK(result)) {
    3947           0 :                         result = winreg_printer_date_to_NTTIME(tmp_str,
    3948             :                                         &info8->min_inbox_driver_ver_date);
    3949             :                 }
    3950           0 :                 CHECK_ERROR(result);
    3951             : 
    3952           0 :                 result = winreg_enumval_to_sz(info8, v,
    3953             :                                               "MinInboxDriverVerVersion",
    3954             :                                               &tmp_str);
    3955           0 :                 if (W_ERROR_IS_OK(result)) {
    3956           0 :                         result = winreg_printer_ver_to_qword(tmp_str,
    3957             :                                         &info8->min_inbox_driver_ver_version);
    3958             :                 }
    3959           0 :                 CHECK_ERROR(result);
    3960             :         }
    3961             : 
    3962           0 :         if (!W_ERROR_IS_OK(result)) {
    3963           0 :                 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
    3964             :                           "for %s: %s\n", v->value_name,
    3965             :                           win_errstr(result)));
    3966           0 :                 goto done;
    3967             :         }
    3968             : 
    3969           0 :         *_info8 = talloc_steal(mem_ctx, info8);
    3970           0 :         result = WERR_OK;
    3971           0 : done:
    3972           0 :         if (winreg_handle != NULL) {
    3973             :                 WERROR ignore;
    3974             : 
    3975           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    3976           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    3977             :                 }
    3978           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    3979           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    3980             :                 }
    3981             :         }
    3982             : 
    3983           0 :         TALLOC_FREE(tmp_ctx);
    3984           0 :         return result;
    3985             : }
    3986             : 
    3987           0 : WERROR winreg_del_driver(TALLOC_CTX *mem_ctx,
    3988             :                          struct dcerpc_binding_handle *winreg_handle,
    3989             :                          struct spoolss_DriverInfo8 *info8,
    3990             :                          uint32_t version)
    3991             : {
    3992           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    3993             :         struct policy_handle hive_hnd, key_hnd;
    3994             :         TALLOC_CTX *tmp_ctx;
    3995             :         char *key_name;
    3996             :         WERROR result;
    3997             :         NTSTATUS status;
    3998             : 
    3999           0 :         ZERO_STRUCT(hive_hnd);
    4000           0 :         ZERO_STRUCT(key_hnd);
    4001             : 
    4002           0 :         tmp_ctx = talloc_stackframe();
    4003           0 :         if (tmp_ctx == NULL) {
    4004           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    4005             :         }
    4006             : 
    4007             :         /* test that the key exists */
    4008           0 :         result = winreg_printer_opendriver(tmp_ctx,
    4009             :                                            winreg_handle,
    4010             :                                            info8->driver_name,
    4011             :                                            info8->architecture,
    4012             :                                            version,
    4013             :                                            access_mask, false,
    4014             :                                            &hive_hnd,
    4015             :                                            &key_hnd);
    4016           0 :         if (!W_ERROR_IS_OK(result)) {
    4017             :                 /* key doesn't exist */
    4018           0 :                 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    4019           0 :                         result = WERR_OK;
    4020           0 :                         goto done;
    4021             :                 }
    4022             : 
    4023           0 :                 DEBUG(5, ("winreg_del_driver: "
    4024             :                           "Could not open driver (%s,%s,%u): %s\n",
    4025             :                           info8->driver_name, info8->architecture,
    4026             :                           version, win_errstr(result)));
    4027           0 :                 goto done;
    4028             :         }
    4029             : 
    4030             : 
    4031           0 :         if (is_valid_policy_hnd(&key_hnd)) {
    4032           0 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
    4033             :         }
    4034             : 
    4035           0 :         key_name = talloc_asprintf(tmp_ctx,
    4036             :                                    "%s\\Environments\\%s\\Drivers\\Version-%u\\%s",
    4037             :                                    TOP_LEVEL_CONTROL_KEY,
    4038             :                                    info8->architecture, version,
    4039             :                                    info8->driver_name);
    4040           0 :         if (key_name == NULL) {
    4041           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4042           0 :                 goto done;
    4043             :         }
    4044             : 
    4045           0 :         status = dcerpc_winreg_delete_subkeys_recursive(tmp_ctx,
    4046             :                                                         winreg_handle,
    4047             :                                                         &hive_hnd,
    4048             :                                                         access_mask,
    4049             :                                                         key_name,
    4050             :                                                         &result);
    4051             : 
    4052           0 :         if (!NT_STATUS_IS_OK(status)){
    4053           0 :                 DEBUG(0, ("winreg_del_driver: "
    4054             :                           "Could not open driver (%s,%s,%u): %s\n",
    4055             :                           info8->driver_name, info8->architecture,
    4056             :                           version, nt_errstr(status)));
    4057           0 :                 goto done;
    4058             :         }
    4059             : 
    4060           0 :         if (!W_ERROR_IS_OK(result)) {
    4061           0 :                 DEBUG(0, ("winreg_del_driver: "
    4062             :                           "Could not open driver (%s,%s,%u): %s\n",
    4063             :                           info8->driver_name, info8->architecture,
    4064             :                           version, win_errstr(result)));
    4065           0 :                 goto done;
    4066             :         }
    4067             : 
    4068           0 :         result = WERR_OK;
    4069           0 : done:
    4070           0 :         if (winreg_handle != NULL) {
    4071             :                 WERROR ignore;
    4072             : 
    4073           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    4074           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    4075             :                 }
    4076           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    4077           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    4078             :                 }
    4079             :         }
    4080             : 
    4081           0 :         TALLOC_FREE(tmp_ctx);
    4082           0 :         return result;
    4083             : }
    4084             : 
    4085        1840 : WERROR winreg_get_driver_list(TALLOC_CTX *mem_ctx,
    4086             :                               struct dcerpc_binding_handle *winreg_handle,
    4087             :                               const char *architecture,
    4088             :                               uint32_t version,
    4089             :                               uint32_t *num_drivers,
    4090             :                               const char ***drivers_p)
    4091             : {
    4092        1840 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4093             :         struct policy_handle hive_hnd, key_hnd;
    4094             :         const char **drivers;
    4095             :         TALLOC_CTX *tmp_ctx;
    4096             :         WERROR result;
    4097             :         NTSTATUS status;
    4098             : 
    4099        1840 :         *num_drivers = 0;
    4100        1840 :         *drivers_p = NULL;
    4101             : 
    4102        1840 :         ZERO_STRUCT(hive_hnd);
    4103        1840 :         ZERO_STRUCT(key_hnd);
    4104             : 
    4105        1840 :         tmp_ctx = talloc_stackframe();
    4106        1840 :         if (tmp_ctx == NULL) {
    4107           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    4108             :         }
    4109             : 
    4110             :         /* use NULL for the driver name so we open the key that is
    4111             :          * parent of all drivers for this architecture and version */
    4112        1840 :         result = winreg_printer_opendriver(tmp_ctx,
    4113             :                                            winreg_handle,
    4114             :                                            NULL,
    4115             :                                            architecture,
    4116             :                                            version,
    4117             :                                            access_mask, false,
    4118             :                                            &hive_hnd,
    4119             :                                            &key_hnd);
    4120        1840 :         if (!W_ERROR_IS_OK(result)) {
    4121        1840 :                 DEBUG(5, ("winreg_get_driver_list: "
    4122             :                           "Could not open key (%s,%u): %s\n",
    4123             :                           architecture, version, win_errstr(result)));
    4124        1840 :                 result = WERR_OK;
    4125        1840 :                 goto done;
    4126             :         }
    4127             : 
    4128           0 :         status = dcerpc_winreg_enum_keys(tmp_ctx,
    4129             :                                          winreg_handle,
    4130             :                                          &key_hnd,
    4131             :                                          num_drivers,
    4132             :                                          &drivers,
    4133             :                                          &result);
    4134           0 :         if (!NT_STATUS_IS_OK(status)) {
    4135           0 :                 result = ntstatus_to_werror(status);
    4136             :         }
    4137           0 :         if (!W_ERROR_IS_OK(result)) {
    4138           0 :                 DEBUG(0, ("winreg_get_driver_list: "
    4139             :                           "Could not enumerate drivers for (%s,%u): %s\n",
    4140             :                           architecture, version, win_errstr(result)));
    4141           0 :                 goto done;
    4142             :         }
    4143             : 
    4144           0 :         *drivers_p = talloc_steal(mem_ctx, drivers);
    4145             : 
    4146           0 :         result = WERR_OK;
    4147        1840 : done:
    4148        1840 :         if (winreg_handle != NULL) {
    4149             :                 WERROR ignore;
    4150             : 
    4151        1840 :                 if (is_valid_policy_hnd(&key_hnd)) {
    4152           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    4153             :                 }
    4154        1840 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    4155           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    4156             :                 }
    4157             :         }
    4158             : 
    4159        1840 :         TALLOC_FREE(tmp_ctx);
    4160        1840 :         return result;
    4161             : }
    4162             : 
    4163           0 : WERROR winreg_get_core_driver(TALLOC_CTX *mem_ctx,
    4164             :                               struct dcerpc_binding_handle *winreg_handle,
    4165             :                               const char *architecture,
    4166             :                               const struct GUID *core_driver_guid,
    4167             :                               struct spoolss_CorePrinterDriver **_core_printer_driver)
    4168             : {
    4169           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4170             :         struct policy_handle hive_hnd, key_hnd;
    4171           0 :         struct spoolss_CorePrinterDriver *c = NULL;
    4172           0 :         struct spoolss_PrinterEnumValues *enum_values = NULL;
    4173           0 :         struct spoolss_PrinterEnumValues *v = NULL;
    4174           0 :         uint32_t num_values = 0;
    4175           0 :         TALLOC_CTX *tmp_ctx = NULL;
    4176             :         WERROR result;
    4177             :         NTSTATUS status;
    4178           0 :         const char *path = NULL;
    4179           0 :         const char *guid_str = NULL;
    4180             :         uint32_t i;
    4181           0 :         const char **enum_names = NULL;
    4182           0 :         enum winreg_Type *enum_types = NULL;
    4183           0 :         DATA_BLOB *enum_data_blobs = NULL;
    4184             : 
    4185           0 :         ZERO_STRUCT(hive_hnd);
    4186           0 :         ZERO_STRUCT(key_hnd);
    4187             : 
    4188           0 :         tmp_ctx = talloc_stackframe();
    4189           0 :         if (tmp_ctx == NULL) {
    4190           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    4191             :         }
    4192             : 
    4193           0 :         path = talloc_asprintf(tmp_ctx, "%s\\%s\\CorePrinterDrivers",
    4194             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
    4195             :                                         architecture);
    4196           0 :         if (path == NULL) {
    4197           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4198           0 :                 goto done;
    4199             :         }
    4200             : 
    4201           0 :         guid_str = GUID_string2(tmp_ctx, core_driver_guid);
    4202           0 :         if (guid_str == NULL) {
    4203           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4204           0 :                 goto done;
    4205             :         }
    4206             : 
    4207           0 :         result = winreg_printer_openkey(tmp_ctx,
    4208             :                                         winreg_handle,
    4209             :                                         path,
    4210             :                                         guid_str, /* key */
    4211             :                                         false,
    4212             :                                         access_mask,
    4213             :                                         &hive_hnd,
    4214             :                                         &key_hnd);
    4215             : 
    4216           0 :         if (!W_ERROR_IS_OK(result)) {
    4217           0 :                 DEBUG(5, ("winreg_get_core_driver: "
    4218             :                           "Could not open core driver key (%s,%s): %s\n",
    4219             :                           guid_str, architecture, win_errstr(result)));
    4220           0 :                 goto done;
    4221             :         }
    4222             : 
    4223           0 :         status = dcerpc_winreg_enumvals(tmp_ctx,
    4224             :                                         winreg_handle,
    4225             :                                         &key_hnd,
    4226             :                                         &num_values,
    4227             :                                         &enum_names,
    4228             :                                         &enum_types,
    4229             :                                         &enum_data_blobs,
    4230             :                                         &result);
    4231           0 :         if (!NT_STATUS_IS_OK(status)){
    4232           0 :                 result = ntstatus_to_werror(status);
    4233             :         }
    4234             : 
    4235           0 :         if (!W_ERROR_IS_OK(result)) {
    4236           0 :                 DEBUG(0, ("winreg_get_core_driver: "
    4237             :                           "Could not enumerate values for (%s,%s): %s\n",
    4238             :                           guid_str, architecture, win_errstr(result)));
    4239           0 :                 goto done;
    4240             :         }
    4241             : 
    4242           0 :         enum_values = talloc_zero_array(tmp_ctx,
    4243             :                                         struct spoolss_PrinterEnumValues,
    4244             :                                         num_values);
    4245           0 :         if (enum_values == NULL){
    4246           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4247           0 :                 goto done;
    4248             :         }
    4249             : 
    4250           0 :         for (i = 0; i < num_values; i++){
    4251           0 :                 enum_values[i].value_name = enum_names[i];
    4252           0 :                 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
    4253           0 :                 enum_values[i].type = enum_types[i];
    4254           0 :                 enum_values[i].data_length = enum_data_blobs[i].length;
    4255           0 :                 enum_values[i].data = NULL;
    4256           0 :                 if (enum_values[i].data_length != 0){
    4257           0 :                         enum_values[i].data = &enum_data_blobs[i];
    4258             :                 }
    4259             :         }
    4260             : 
    4261           0 :         c = talloc_zero(tmp_ctx, struct spoolss_CorePrinterDriver);
    4262           0 :         if (c == NULL) {
    4263           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4264           0 :                 goto done;
    4265             :         }
    4266             : 
    4267           0 :         c->core_driver_guid = *core_driver_guid;
    4268             : 
    4269           0 :         result = WERR_OK;
    4270             : 
    4271           0 :         for (i = 0; i < num_values; i++) {
    4272             :                 const char *tmp_str;
    4273             : 
    4274           0 :                 v = &enum_values[i];
    4275             : 
    4276           0 :                 result = winreg_enumval_to_sz(c, v,
    4277             :                                               "InfPath",
    4278             :                                               &c->szPackageID);
    4279           0 :                 CHECK_ERROR(result);
    4280             : 
    4281           0 :                 result = winreg_enumval_to_sz(c, v,
    4282             :                                               "DriverDate",
    4283             :                                               &tmp_str);
    4284           0 :                 if (W_ERROR_IS_OK(result)) {
    4285           0 :                         result = winreg_printer_date_to_NTTIME(tmp_str,
    4286             :                                                 &c->driver_date);
    4287             :                 }
    4288           0 :                 CHECK_ERROR(result);
    4289             : 
    4290           0 :                 result = winreg_enumval_to_sz(c, v,
    4291             :                                               "DriverVersion",
    4292             :                                               &tmp_str);
    4293           0 :                 if (W_ERROR_IS_OK(result)) {
    4294           0 :                         result = winreg_printer_ver_to_qword(tmp_str,
    4295             :                                                 &c->driver_version);
    4296             :                 }
    4297           0 :                 CHECK_ERROR(result);
    4298             :         }
    4299             : 
    4300           0 :         if (!W_ERROR_IS_OK(result)) {
    4301           0 :                 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
    4302             :                           "for %s: %s\n", v->value_name,
    4303             :                           win_errstr(result)));
    4304           0 :                 goto done;
    4305             :         }
    4306             : 
    4307           0 :         *_core_printer_driver = talloc_steal(mem_ctx, c);
    4308           0 :         result = WERR_OK;
    4309           0 : done:
    4310           0 :         if (winreg_handle != NULL) {
    4311             :                 WERROR ignore;
    4312             : 
    4313           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    4314           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    4315             :                 }
    4316           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    4317           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    4318             :                 }
    4319             :         }
    4320             : 
    4321           0 :         TALLOC_FREE(tmp_ctx);
    4322           0 :         return result;
    4323             : }
    4324             : 
    4325           0 : WERROR winreg_add_core_driver(TALLOC_CTX *mem_ctx,
    4326             :                               struct dcerpc_binding_handle *winreg_handle,
    4327             :                               const char *architecture,
    4328             :                               const struct spoolss_CorePrinterDriver *r)
    4329             : {
    4330           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4331             :         struct policy_handle hive_hnd, key_hnd;
    4332           0 :         TALLOC_CTX *tmp_ctx = NULL;
    4333             :         NTSTATUS status;
    4334             :         WERROR result;
    4335             :         const char *guid_str;
    4336             : 
    4337           0 :         ZERO_STRUCT(hive_hnd);
    4338           0 :         ZERO_STRUCT(key_hnd);
    4339             : 
    4340           0 :         tmp_ctx = talloc_stackframe();
    4341           0 :         if (tmp_ctx == NULL) {
    4342           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    4343             :         }
    4344             : 
    4345           0 :         guid_str = GUID_string2(tmp_ctx, &r->core_driver_guid);
    4346           0 :         if (guid_str == NULL) {
    4347           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4348           0 :                 goto done;
    4349             :         }
    4350             : 
    4351           0 :         result = winreg_printer_open_core_driver(tmp_ctx,
    4352             :                                                  winreg_handle,
    4353             :                                                  architecture,
    4354             :                                                  guid_str,
    4355             :                                                  access_mask,
    4356             :                                                  &hive_hnd,
    4357             :                                                  &key_hnd);
    4358           0 :         if (!W_ERROR_IS_OK(result)) {
    4359           0 :                 DEBUG(0, ("winreg_add_core_driver: "
    4360             :                           "Could not open core driver key (%s,%s): %s\n",
    4361             :                           guid_str, architecture, win_errstr(result)));
    4362           0 :                 goto done;
    4363             :         }
    4364             : 
    4365           0 :         result = winreg_printer_write_date(tmp_ctx, winreg_handle,
    4366             :                                            &key_hnd, "DriverDate",
    4367           0 :                                            r->driver_date);
    4368           0 :         if (!W_ERROR_IS_OK(result)) {
    4369           0 :                 goto done;
    4370             :         }
    4371             : 
    4372           0 :         result = winreg_printer_write_ver(tmp_ctx, winreg_handle,
    4373             :                                           &key_hnd, "DriverVersion",
    4374           0 :                                           r->driver_version);
    4375           0 :         if (!W_ERROR_IS_OK(result)) {
    4376           0 :                 goto done;
    4377             :         }
    4378             : 
    4379           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    4380             :                                       winreg_handle,
    4381             :                                       &key_hnd,
    4382             :                                       "InfPath",
    4383           0 :                                       r->szPackageID,
    4384             :                                       &result);
    4385           0 :         if (!NT_STATUS_IS_OK(status)) {
    4386           0 :                 result = ntstatus_to_werror(status);
    4387             :         }
    4388           0 :         if (!W_ERROR_IS_OK(result)) {
    4389           0 :                 goto done;
    4390             :         }
    4391             : 
    4392           0 :         result = WERR_OK;
    4393           0 : done:
    4394           0 :         if (winreg_handle != NULL) {
    4395             :                 WERROR ignore;
    4396             : 
    4397           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    4398           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    4399             :                 }
    4400           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    4401           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    4402             :                 }
    4403             :         }
    4404             : 
    4405           0 :         TALLOC_FREE(tmp_ctx);
    4406           0 :         return result;
    4407             : }
    4408             : 
    4409           0 : WERROR winreg_add_driver_package(TALLOC_CTX *mem_ctx,
    4410             :                                  struct dcerpc_binding_handle *winreg_handle,
    4411             :                                  const char *package_id,
    4412             :                                  const char *architecture,
    4413             :                                  const char *driver_store_path,
    4414             :                                  const char *cab_path)
    4415             : {
    4416           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4417             :         struct policy_handle hive_hnd, key_hnd;
    4418           0 :         TALLOC_CTX *tmp_ctx = NULL;
    4419             :         NTSTATUS status;
    4420             :         WERROR result;
    4421             :         const char *path;
    4422             : 
    4423           0 :         ZERO_STRUCT(hive_hnd);
    4424           0 :         ZERO_STRUCT(key_hnd);
    4425             : 
    4426           0 :         tmp_ctx = talloc_stackframe();
    4427           0 :         if (tmp_ctx == NULL) {
    4428           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    4429             :         }
    4430             : 
    4431           0 :         path = talloc_asprintf(tmp_ctx, "%s\\%s\\DriverPackages",
    4432             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
    4433             :                                         architecture);
    4434           0 :         if (path == NULL) {
    4435           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4436           0 :                 goto done;
    4437             :         }
    4438             : 
    4439           0 :         result = winreg_printer_openkey(tmp_ctx,
    4440             :                                         winreg_handle,
    4441             :                                         path,
    4442             :                                         package_id, /* key */
    4443             :                                         true,
    4444             :                                         access_mask,
    4445             :                                         &hive_hnd,
    4446             :                                         &key_hnd);
    4447             : 
    4448           0 :         if (!W_ERROR_IS_OK(result)) {
    4449           0 :                 DEBUG(0, ("winreg_add_driver_package: "
    4450             :                           "Could not open driver package key (%s,%s): %s\n",
    4451             :                           package_id, architecture, win_errstr(result)));
    4452           0 :                 goto done;
    4453             :         }
    4454             : 
    4455           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    4456             :                                       winreg_handle,
    4457             :                                       &key_hnd,
    4458             :                                       "CabPath",
    4459             :                                       cab_path,
    4460             :                                       &result);
    4461           0 :         if (!NT_STATUS_IS_OK(status)) {
    4462           0 :                 result = ntstatus_to_werror(status);
    4463             :         }
    4464           0 :         if (!W_ERROR_IS_OK(result)) {
    4465           0 :                 goto done;
    4466             :         }
    4467             : 
    4468           0 :         status = dcerpc_winreg_set_sz(tmp_ctx,
    4469             :                                       winreg_handle,
    4470             :                                       &key_hnd,
    4471             :                                       "DriverStorePath",
    4472             :                                       driver_store_path,
    4473             :                                       &result);
    4474           0 :         if (!NT_STATUS_IS_OK(status)) {
    4475           0 :                 result = ntstatus_to_werror(status);
    4476             :         }
    4477           0 :         if (!W_ERROR_IS_OK(result)) {
    4478           0 :                 goto done;
    4479             :         }
    4480             : 
    4481           0 :         result = WERR_OK;
    4482           0 : done:
    4483           0 :         if (winreg_handle != NULL) {
    4484             :                 WERROR ignore;
    4485             : 
    4486           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    4487           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    4488             :                 }
    4489           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    4490           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    4491             :                 }
    4492             :         }
    4493             : 
    4494           0 :         TALLOC_FREE(tmp_ctx);
    4495           0 :         return result;
    4496             : }
    4497             : 
    4498           0 : WERROR winreg_get_driver_package(TALLOC_CTX *mem_ctx,
    4499             :                                  struct dcerpc_binding_handle *winreg_handle,
    4500             :                                  const char *package_id,
    4501             :                                  const char *architecture,
    4502             :                                  const char **driver_store_path,
    4503             :                                  const char **cab_path)
    4504             : {
    4505           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4506             :         struct policy_handle hive_hnd, key_hnd;
    4507           0 :         struct spoolss_PrinterEnumValues *enum_values = NULL;
    4508           0 :         struct spoolss_PrinterEnumValues *v = NULL;
    4509           0 :         uint32_t num_values = 0;
    4510           0 :         TALLOC_CTX *tmp_ctx = NULL;
    4511             :         WERROR result;
    4512             :         NTSTATUS status;
    4513           0 :         const char *path = NULL;
    4514             :         uint32_t i;
    4515           0 :         const char **enum_names = NULL;
    4516           0 :         enum winreg_Type *enum_types = NULL;
    4517           0 :         DATA_BLOB *enum_data_blobs = NULL;
    4518             : 
    4519           0 :         ZERO_STRUCT(hive_hnd);
    4520           0 :         ZERO_STRUCT(key_hnd);
    4521             : 
    4522           0 :         tmp_ctx = talloc_stackframe();
    4523           0 :         if (tmp_ctx == NULL) {
    4524           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    4525             :         }
    4526             : 
    4527           0 :         path = talloc_asprintf(tmp_ctx, "%s\\%s\\DriverPackages",
    4528             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
    4529             :                                         architecture);
    4530           0 :         if (path == NULL) {
    4531           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4532           0 :                 goto done;
    4533             :         }
    4534             : 
    4535           0 :         result = winreg_printer_openkey(tmp_ctx,
    4536             :                                         winreg_handle,
    4537             :                                         path,
    4538             :                                         package_id, /* key */
    4539             :                                         false,
    4540             :                                         access_mask,
    4541             :                                         &hive_hnd,
    4542             :                                         &key_hnd);
    4543             : 
    4544           0 :         if (!W_ERROR_IS_OK(result)) {
    4545           0 :                 DEBUG(5, ("winreg_get_driver_package: "
    4546             :                           "Could not open driver package key (%s,%s): %s\n",
    4547             :                           package_id, architecture, win_errstr(result)));
    4548           0 :                 goto done;
    4549             :         }
    4550             : 
    4551           0 :         status = dcerpc_winreg_enumvals(tmp_ctx,
    4552             :                                         winreg_handle,
    4553             :                                         &key_hnd,
    4554             :                                         &num_values,
    4555             :                                         &enum_names,
    4556             :                                         &enum_types,
    4557             :                                         &enum_data_blobs,
    4558             :                                         &result);
    4559           0 :         if (!NT_STATUS_IS_OK(status)){
    4560           0 :                 result = ntstatus_to_werror(status);
    4561             :         }
    4562             : 
    4563           0 :         if (!W_ERROR_IS_OK(result)) {
    4564           0 :                 DEBUG(0, ("winreg_get_driver_package: "
    4565             :                           "Could not enumerate values for (%s,%s): %s\n",
    4566             :                           package_id, architecture, win_errstr(result)));
    4567           0 :                 goto done;
    4568             :         }
    4569             : 
    4570           0 :         enum_values = talloc_zero_array(tmp_ctx,
    4571             :                                         struct spoolss_PrinterEnumValues,
    4572             :                                         num_values);
    4573           0 :         if (enum_values == NULL){
    4574           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4575           0 :                 goto done;
    4576             :         }
    4577             : 
    4578           0 :         for (i = 0; i < num_values; i++){
    4579           0 :                 enum_values[i].value_name = enum_names[i];
    4580           0 :                 enum_values[i].value_name_len = strlen_m_term(enum_names[i]) * 2;
    4581           0 :                 enum_values[i].type = enum_types[i];
    4582           0 :                 enum_values[i].data_length = enum_data_blobs[i].length;
    4583           0 :                 enum_values[i].data = NULL;
    4584           0 :                 if (enum_values[i].data_length != 0){
    4585           0 :                         enum_values[i].data = &enum_data_blobs[i];
    4586             :                 }
    4587             :         }
    4588             : 
    4589           0 :         result = WERR_OK;
    4590             : 
    4591           0 :         for (i = 0; i < num_values; i++) {
    4592             : 
    4593           0 :                 v = &enum_values[i];
    4594             : 
    4595           0 :                 result = winreg_enumval_to_sz(mem_ctx, v,
    4596             :                                               "CabPath",
    4597             :                                               cab_path);
    4598           0 :                 CHECK_ERROR(result);
    4599             : 
    4600           0 :                 result = winreg_enumval_to_sz(mem_ctx, v,
    4601             :                                               "DriverStorePath",
    4602             :                                               driver_store_path);
    4603           0 :                 CHECK_ERROR(result);
    4604             :         }
    4605             : 
    4606           0 :         if (!W_ERROR_IS_OK(result)) {
    4607           0 :                 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
    4608             :                           "for %s: %s\n", v->value_name,
    4609             :                           win_errstr(result)));
    4610           0 :                 goto done;
    4611             :         }
    4612             : 
    4613           0 :         result = WERR_OK;
    4614           0 : done:
    4615           0 :         if (winreg_handle != NULL) {
    4616             :                 WERROR ignore;
    4617             : 
    4618           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    4619           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    4620             :                 }
    4621           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    4622           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    4623             :                 }
    4624             :         }
    4625             : 
    4626           0 :         TALLOC_FREE(tmp_ctx);
    4627           0 :         return result;
    4628             : }
    4629             : 
    4630           0 : WERROR winreg_del_driver_package(TALLOC_CTX *mem_ctx,
    4631             :                                  struct dcerpc_binding_handle *winreg_handle,
    4632             :                                  const char *package_id,
    4633             :                                  const char *architecture)
    4634             : {
    4635           0 :         uint32_t access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    4636             :         struct policy_handle hive_hnd, key_hnd;
    4637             :         TALLOC_CTX *tmp_ctx;
    4638             :         WERROR result;
    4639             :         NTSTATUS status;
    4640             :         const char *path;
    4641             : 
    4642           0 :         ZERO_STRUCT(hive_hnd);
    4643           0 :         ZERO_STRUCT(key_hnd);
    4644             : 
    4645           0 :         tmp_ctx = talloc_stackframe();
    4646           0 :         if (tmp_ctx == NULL) {
    4647           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    4648             :         }
    4649             : 
    4650           0 :         path = talloc_asprintf(tmp_ctx, "%s\\%s\\DriverPackages",
    4651             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
    4652             :                                         architecture);
    4653           0 :         if (path == NULL) {
    4654           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4655           0 :                 goto done;
    4656             :         }
    4657             : 
    4658           0 :         result = winreg_printer_openkey(tmp_ctx,
    4659             :                                         winreg_handle,
    4660             :                                         path,
    4661             :                                         package_id, /* key */
    4662             :                                         false,
    4663             :                                         access_mask,
    4664             :                                         &hive_hnd,
    4665             :                                         &key_hnd);
    4666           0 :         if (!W_ERROR_IS_OK(result)) {
    4667             :                 /* key doesn't exist */
    4668           0 :                 if (W_ERROR_EQUAL(result, WERR_FILE_NOT_FOUND)) {
    4669           0 :                         result = WERR_OK;
    4670           0 :                         goto done;
    4671             :                 }
    4672             : 
    4673           0 :                 DEBUG(5, ("winreg_del_driver_package: "
    4674             :                           "Could not open driver package key (%s,%s): %s\n",
    4675             :                           package_id, architecture, win_errstr(result)));
    4676           0 :                 goto done;
    4677             :         }
    4678             : 
    4679             : 
    4680           0 :         if (is_valid_policy_hnd(&key_hnd)) {
    4681           0 :                 dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &result);
    4682             :         }
    4683             : 
    4684           0 :         path = talloc_asprintf(tmp_ctx, "%s\\%s\\DriverPackages\\%s",
    4685             :                                         TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY,
    4686             :                                         architecture,
    4687             :                                         package_id);
    4688           0 :         if (path == NULL) {
    4689           0 :                 result = WERR_NOT_ENOUGH_MEMORY;
    4690           0 :                 goto done;
    4691             :         }
    4692             : 
    4693           0 :         status = dcerpc_winreg_delete_subkeys_recursive(tmp_ctx,
    4694             :                                                         winreg_handle,
    4695             :                                                         &hive_hnd,
    4696             :                                                         access_mask,
    4697             :                                                         path,
    4698             :                                                         &result);
    4699           0 :         if (!NT_STATUS_IS_OK(status)) {
    4700           0 :                 result = ntstatus_to_werror(status);
    4701           0 :                 DEBUG(5, ("winreg_del_driver_package: "
    4702             :                           "Could not delete driver package key (%s,%s): %s\n",
    4703             :                           package_id, architecture, nt_errstr(status)));
    4704           0 :                 goto done;
    4705             :         }
    4706             : 
    4707           0 :         if (!W_ERROR_IS_OK(result)) {
    4708           0 :                 DEBUG(5, ("winreg_del_driver_package: "
    4709             :                           "Could not delete driver package key (%s,%s): %s\n",
    4710             :                           package_id, architecture, win_errstr(result)));
    4711           0 :                 goto done;
    4712             :         }
    4713             : 
    4714           0 :         result = WERR_OK;
    4715           0 : done:
    4716           0 :         if (winreg_handle != NULL) {
    4717             :                 WERROR ignore;
    4718             : 
    4719           0 :                 if (is_valid_policy_hnd(&key_hnd)) {
    4720           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &key_hnd, &ignore);
    4721             :                 }
    4722           0 :                 if (is_valid_policy_hnd(&hive_hnd)) {
    4723           0 :                         dcerpc_winreg_CloseKey(winreg_handle, tmp_ctx, &hive_hnd, &ignore);
    4724             :                 }
    4725             :         }
    4726             : 
    4727           0 :         TALLOC_FREE(tmp_ctx);
    4728           0 :         return result;
    4729             : }

Generated by: LCOV version 1.13