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