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