2 * Unix SMB/CIFS implementation.
4 * SPOOLSS RPC Pipe server / winreg client routines
6 * Copyright (c) 2010 Andreas Schneider <asn@samba.org>
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.
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.
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/>.
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"
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"
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"
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
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} }
168 /********************************************************************
169 static helper functions
170 ********************************************************************/
172 /****************************************************************************
173 Update the changeid time.
174 ****************************************************************************/
178 * @brief Update the ChangeID time of a printer.
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
185 * @return The ChangeID.
187 static uint32_t winreg_printer_rev_changeid(void)
191 get_process_uptime(&tv
);
194 /* Return changeid as msec since spooler restart */
195 return tv
.tv_sec
* 1000 + tv
.tv_usec
/ 1000;
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)
202 return tv
.tv_sec
* 10 + tv
.tv_usec
/ 100000;
206 static WERROR
winreg_printer_openkey(TALLOC_CTX
*mem_ctx
,
207 struct dcerpc_binding_handle
*binding_handle
,
211 uint32_t access_mask
,
212 struct policy_handle
*hive_handle
,
213 struct policy_handle
*key_handle
)
215 struct winreg_String wkey
, wkeyclass
;
218 WERROR result
= WERR_OK
;
220 status
= dcerpc_winreg_OpenHKLM(binding_handle
,
226 if (!NT_STATUS_IS_OK(status
)) {
227 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
229 return ntstatus_to_werror(status
);
231 if (!W_ERROR_IS_OK(result
)) {
232 DEBUG(0, ("winreg_printer_openkey: Could not open HKLM hive: %s\n",
233 win_errstr(result
)));
238 keyname
= talloc_asprintf(mem_ctx
, "%s\\%s", path
, key
);
240 keyname
= talloc_strdup(mem_ctx
, path
);
242 if (keyname
== NULL
) {
243 return WERR_NOT_ENOUGH_MEMORY
;
250 enum winreg_CreateAction action
= REG_ACTION_NONE
;
252 ZERO_STRUCT(wkeyclass
);
255 status
= dcerpc_winreg_CreateKey(binding_handle
,
267 case REG_ACTION_NONE
:
268 DEBUG(8, ("winreg_printer_openkey:createkey did nothing -- huh?\n"));
270 case REG_CREATED_NEW_KEY
:
271 DEBUG(8, ("winreg_printer_openkey: createkey created %s\n", keyname
));
273 case REG_OPENED_EXISTING_KEY
:
274 DEBUG(8, ("winreg_printer_openkey: createkey opened existing %s\n", keyname
));
278 status
= dcerpc_winreg_OpenKey(binding_handle
,
287 if (!NT_STATUS_IS_OK(status
)) {
288 result
= ntstatus_to_werror(status
);
290 if (!W_ERROR_IS_OK(result
)) {
293 if (is_valid_policy_hnd(hive_handle
)) {
294 dcerpc_winreg_CloseKey(binding_handle
,
299 ZERO_STRUCTP(hive_handle
);
307 static WERROR
winreg_printer_open_core_driver(TALLOC_CTX
*mem_ctx
,
308 struct dcerpc_binding_handle
*binding_handle
,
309 const char *architecture
,
311 uint32_t access_mask
,
312 struct policy_handle
*hive_handle
,
313 struct policy_handle
*key_handle
)
315 struct winreg_String wkey
, wkeyclass
;
317 WERROR result
= WERR_OK
;
319 enum winreg_CreateAction action
= REG_ACTION_NONE
;
322 status
= dcerpc_winreg_OpenHKLM(binding_handle
,
328 if (!NT_STATUS_IS_OK(status
)) {
329 DEBUG(0,("winreg_printer_open_core_driver: Could not open HKLM hive: %s\n",
331 return ntstatus_to_werror(status
);
333 if (!W_ERROR_IS_OK(result
)) {
334 DEBUG(0,("winreg_printer_open_core_driver: Could not open HKLM hive: %s\n",
335 win_errstr(result
)));
340 wkey
.name
= TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
;
342 ZERO_STRUCT(wkeyclass
);
345 status
= dcerpc_winreg_CreateKey(binding_handle
,
356 if (!NT_STATUS_IS_OK(status
)) {
357 result
= ntstatus_to_werror(status
);
359 if (!W_ERROR_IS_OK(result
)) {
363 dcerpc_winreg_CloseKey(binding_handle
, mem_ctx
, key_handle
, &ignore
);
365 path
= talloc_asprintf(mem_ctx
, "%s\\%s",
366 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
369 result
= WERR_NOT_ENOUGH_MEMORY
;
375 status
= dcerpc_winreg_CreateKey(binding_handle
,
386 if (!NT_STATUS_IS_OK(status
)) {
387 result
= ntstatus_to_werror(status
);
389 if (!W_ERROR_IS_OK(result
)) {
393 dcerpc_winreg_CloseKey(binding_handle
, mem_ctx
, key_handle
, &ignore
);
395 path
= talloc_asprintf(mem_ctx
, "%s\\%s\\CorePrinterDrivers",
396 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
399 result
= WERR_NOT_ENOUGH_MEMORY
;
405 status
= dcerpc_winreg_CreateKey(binding_handle
,
416 if (!NT_STATUS_IS_OK(status
)) {
417 result
= ntstatus_to_werror(status
);
419 if (!W_ERROR_IS_OK(result
)) {
423 dcerpc_winreg_CloseKey(binding_handle
, mem_ctx
, key_handle
, &ignore
);
425 path
= talloc_asprintf(mem_ctx
, "%s\\%s\\CorePrinterDrivers\\%s",
426 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
430 result
= WERR_NOT_ENOUGH_MEMORY
;
436 status
= dcerpc_winreg_CreateKey(binding_handle
,
447 if (!NT_STATUS_IS_OK(status
)) {
448 result
= ntstatus_to_werror(status
);
450 if (!W_ERROR_IS_OK(result
)) {
455 if (is_valid_policy_hnd(hive_handle
)) {
456 dcerpc_winreg_CloseKey(binding_handle
,
461 ZERO_STRUCTP(hive_handle
);
467 * @brief Create the registry keyname for the given printer.
469 * @param[in] mem_ctx The memory context to use.
471 * @param[in] printer The name of the printer to get the registry key.
473 * @return The registry key or NULL on error.
475 static char *winreg_printer_data_keyname(TALLOC_CTX
*mem_ctx
, const char *printer
) {
476 return talloc_asprintf(mem_ctx
, "%s\\%s", TOP_LEVEL_PRINT_PRINTERS_KEY
, printer
);
479 static WERROR
winreg_printer_opendriver(TALLOC_CTX
*mem_ctx
,
480 struct dcerpc_binding_handle
*winreg_handle
,
481 const char *drivername
,
482 const char *architecture
,
484 uint32_t access_mask
,
486 struct policy_handle
*hive_hnd
,
487 struct policy_handle
*key_hnd
)
492 key_name
= talloc_asprintf(mem_ctx
, "%s\\Environments\\%s\\Drivers\\Version-%u",
493 TOP_LEVEL_CONTROL_KEY
,
494 architecture
, version
);
496 return WERR_NOT_ENOUGH_MEMORY
;
499 result
= winreg_printer_openkey(mem_ctx
,
510 static WERROR
winreg_enumval_to_dword(TALLOC_CTX
*mem_ctx
,
511 struct spoolss_PrinterEnumValues
*v
,
512 const char *valuename
, uint32_t *dw
)
514 /* just return if it is not the one we are looking for */
515 if (strcmp(valuename
, v
->value_name
) != 0) {
516 return WERR_NOT_FOUND
;
519 if (v
->type
!= REG_DWORD
) {
520 return WERR_INVALID_DATATYPE
;
523 if (v
->data_length
!= 4) {
528 *dw
= IVAL(v
->data
->data
, 0);
532 static WERROR
winreg_enumval_to_sz(TALLOC_CTX
*mem_ctx
,
533 struct spoolss_PrinterEnumValues
*v
,
534 const char *valuename
, const char **_str
)
536 /* just return if it is not the one we are looking for */
537 if (strcmp(valuename
, v
->value_name
) != 0) {
538 return WERR_NOT_FOUND
;
541 if (v
->type
!= REG_SZ
) {
542 return WERR_INVALID_DATATYPE
;
545 if (v
->data_length
== 0) {
546 *_str
= talloc_strdup(mem_ctx
, "");
548 return WERR_NOT_ENOUGH_MEMORY
;
553 if (!pull_reg_sz(mem_ctx
, v
->data
, _str
)) {
554 return WERR_NOT_ENOUGH_MEMORY
;
560 static WERROR
winreg_enumval_to_multi_sz(TALLOC_CTX
*mem_ctx
,
561 struct spoolss_PrinterEnumValues
*v
,
562 const char *valuename
,
565 /* just return if it is not the one we are looking for */
566 if (strcmp(valuename
, v
->value_name
) != 0) {
567 return WERR_NOT_FOUND
;
570 if (v
->type
!= REG_MULTI_SZ
) {
571 return WERR_INVALID_DATATYPE
;
574 if (v
->data_length
== 0) {
575 *array
= talloc_array(mem_ctx
, const char *, 1);
576 if (*array
== NULL
) {
577 return WERR_NOT_ENOUGH_MEMORY
;
583 if (!pull_reg_multi_sz(mem_ctx
, v
->data
, array
)) {
584 return WERR_NOT_ENOUGH_MEMORY
;
590 static WERROR
winreg_printer_write_date(TALLOC_CTX
*mem_ctx
,
591 struct dcerpc_binding_handle
*winreg_handle
,
592 struct policy_handle
*key_handle
,
596 struct winreg_String wvalue
= { 0, };
598 WERROR result
= WERR_OK
;
605 str
= talloc_strdup(mem_ctx
, "01/01/1601");
607 t
= nt_time_to_unix(data
);
610 return map_werror_from_unix(errno
);
612 str
= talloc_asprintf(mem_ctx
, "%02d/%02d/%04d",
613 tm
->tm_mon
+ 1, tm
->tm_mday
, tm
->tm_year
+ 1900);
616 return WERR_NOT_ENOUGH_MEMORY
;
620 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
621 return WERR_NOT_ENOUGH_MEMORY
;
623 status
= dcerpc_winreg_SetValue(winreg_handle
,
631 if (!NT_STATUS_IS_OK(status
)) {
632 result
= ntstatus_to_werror(status
);
634 if (!W_ERROR_IS_OK(result
)) {
635 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
636 wvalue
.name
, win_errstr(result
)));
642 static WERROR
winreg_printer_date_to_NTTIME(const char *str
, NTTIME
*data
)
646 ok
= spoolss_timestr_to_NTTIME(str
, data
);
648 return WERR_INVALID_PARAMETER
;
654 static WERROR
winreg_printer_write_ver(TALLOC_CTX
*mem_ctx
,
655 struct dcerpc_binding_handle
*winreg_handle
,
656 struct policy_handle
*key_handle
,
660 struct winreg_String wvalue
= { 0, };
662 WERROR result
= WERR_OK
;
667 * this needs to be something like: 6.1.7600.16385
669 str
= talloc_asprintf(mem_ctx
, "%u.%u.%u.%u",
670 (unsigned)((data
>> 48) & 0xFFFF),
671 (unsigned)((data
>> 32) & 0xFFFF),
672 (unsigned)((data
>> 16) & 0xFFFF),
673 (unsigned)(data
& 0xFFFF));
675 return WERR_NOT_ENOUGH_MEMORY
;
679 if (!push_reg_sz(mem_ctx
, &blob
, str
)) {
680 return WERR_NOT_ENOUGH_MEMORY
;
682 status
= dcerpc_winreg_SetValue(winreg_handle
,
690 if (!NT_STATUS_IS_OK(status
)) {
691 result
= ntstatus_to_werror(status
);
693 if (!W_ERROR_IS_OK(result
)) {
694 DEBUG(0, ("winreg_printer_write_date: Could not set value %s: %s\n",
695 wvalue
.name
, win_errstr(result
)));
701 static WERROR
winreg_printer_ver_to_qword(const char *str
, uint64_t *data
)
705 ok
= spoolss_driver_version_to_qword(str
, data
);
707 return WERR_INVALID_PARAMETER
;
713 /********************************************************************
714 Public winreg function for spoolss
715 ********************************************************************/
717 WERROR
winreg_create_printer(TALLOC_CTX
*mem_ctx
,
718 struct dcerpc_binding_handle
*winreg_handle
,
719 const char *sharename
)
721 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
722 struct policy_handle hive_hnd
, key_hnd
;
723 struct spoolss_SetPrinterInfo2
*info2
;
724 struct security_descriptor
*secdesc
;
725 struct winreg_String wkey
, wkeyclass
;
727 const char *subkeys
[] = { SPOOL_DSDRIVER_KEY
, SPOOL_DSSPOOLER_KEY
, SPOOL_PRINTERDATA_KEY
};
728 uint32_t i
, count
= ARRAY_SIZE(subkeys
);
729 uint32_t info2_mask
= 0;
730 WERROR result
= WERR_OK
;
734 tmp_ctx
= talloc_stackframe();
735 if (tmp_ctx
== NULL
) {
736 return WERR_NOT_ENOUGH_MEMORY
;
739 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
741 TALLOC_FREE(tmp_ctx
);
742 return WERR_NOT_ENOUGH_MEMORY
;
745 ZERO_STRUCT(hive_hnd
);
746 ZERO_STRUCT(key_hnd
);
748 result
= winreg_printer_openkey(tmp_ctx
,
756 if (W_ERROR_IS_OK(result
)) {
757 DEBUG(2, ("winreg_create_printer: Skipping, %s already exists\n", path
));
759 } else if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
760 DEBUG(2, ("winreg_create_printer: Creating default values in %s\n", path
));
761 } else if (!W_ERROR_IS_OK(result
)) {
762 DEBUG(0, ("winreg_create_printer: Could not open key %s: %s\n",
763 path
, win_errstr(result
)));
767 if (is_valid_policy_hnd(&key_hnd
)) {
768 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
770 if (is_valid_policy_hnd(&hive_hnd
)) {
771 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
774 /* Create the main key */
775 result
= winreg_printer_openkey(tmp_ctx
,
783 if (!W_ERROR_IS_OK(result
)) {
784 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
785 path
, win_errstr(result
)));
789 if (is_valid_policy_hnd(&key_hnd
)) {
790 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
794 for (i
= 0; i
< count
; i
++) {
796 enum winreg_CreateAction action
= REG_ACTION_NONE
;
798 ZERO_STRUCT(key_hnd
);
801 wkey
.name
= talloc_asprintf(tmp_ctx
, "%s\\%s", path
, subkeys
[i
]);
802 if (wkey
.name
== NULL
) {
803 result
= WERR_NOT_ENOUGH_MEMORY
;
807 ZERO_STRUCT(wkeyclass
);
810 status
= dcerpc_winreg_CreateKey(winreg_handle
,
821 if (!NT_STATUS_IS_OK(status
)) {
822 result
= ntstatus_to_werror(status
);
824 if (!W_ERROR_IS_OK(result
)) {
825 DEBUG(0, ("winreg_create_printer_keys: Could not create key %s: %s\n",
826 wkey
.name
, win_errstr(result
)));
830 if (strequal(subkeys
[i
], SPOOL_DSSPOOLER_KEY
)) {
831 const char *dnssuffix
;
832 const char *longname
;
835 status
= dcerpc_winreg_set_sz(tmp_ctx
,
838 SPOOL_REG_PRINTERNAME
,
841 if (!NT_STATUS_IS_OK(status
)) {
842 result
= ntstatus_to_werror(status
);
844 if (!W_ERROR_IS_OK(result
)) {
848 status
= dcerpc_winreg_set_sz(tmp_ctx
,
851 SPOOL_REG_PRINTSHARENAME
,
854 if (!NT_STATUS_IS_OK(status
)) {
855 result
= ntstatus_to_werror(status
);
857 if (!W_ERROR_IS_OK(result
)) {
861 status
= dcerpc_winreg_set_sz(tmp_ctx
,
864 SPOOL_REG_SHORTSERVERNAME
,
867 if (!NT_STATUS_IS_OK(status
)) {
868 result
= ntstatus_to_werror(status
);
870 if (!W_ERROR_IS_OK(result
)) {
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
878 dnssuffix
= get_mydnsdomname(tmp_ctx
);
879 if (dnssuffix
!= NULL
&& dnssuffix
[0] != '\0') {
880 longname
= talloc_asprintf(tmp_ctx
, "%s.%s", lp_netbios_name(), dnssuffix
);
882 longname
= talloc_strdup(tmp_ctx
, lp_netbios_name());
884 if (longname
== NULL
) {
885 result
= WERR_NOT_ENOUGH_MEMORY
;
889 status
= dcerpc_winreg_set_sz(tmp_ctx
,
892 SPOOL_REG_SERVERNAME
,
895 if (!NT_STATUS_IS_OK(status
)) {
896 result
= ntstatus_to_werror(status
);
898 if (!W_ERROR_IS_OK(result
)) {
902 uncname
= talloc_asprintf(tmp_ctx
, "\\\\%s\\%s",
903 longname
, sharename
);
904 if (uncname
== NULL
) {
905 result
= WERR_NOT_ENOUGH_MEMORY
;
909 status
= dcerpc_winreg_set_sz(tmp_ctx
,
915 if (!NT_STATUS_IS_OK(status
)) {
916 result
= ntstatus_to_werror(status
);
918 if (!W_ERROR_IS_OK(result
)) {
922 status
= dcerpc_winreg_set_dword(tmp_ctx
,
925 SPOOL_REG_VERSIONNUMBER
,
928 if (!NT_STATUS_IS_OK(status
)) {
929 result
= ntstatus_to_werror(status
);
931 if (!W_ERROR_IS_OK(result
)) {
935 status
= dcerpc_winreg_set_dword(tmp_ctx
,
938 SPOOL_REG_PRINTSTARTTIME
,
941 if (!NT_STATUS_IS_OK(status
)) {
942 result
= ntstatus_to_werror(status
);
944 if (!W_ERROR_IS_OK(result
)) {
948 status
= dcerpc_winreg_set_dword(tmp_ctx
,
951 SPOOL_REG_PRINTENDTIME
,
954 if (!NT_STATUS_IS_OK(status
)) {
955 result
= ntstatus_to_werror(status
);
957 if (!W_ERROR_IS_OK(result
)) {
961 status
= dcerpc_winreg_set_dword(tmp_ctx
,
967 if (!NT_STATUS_IS_OK(status
)) {
968 result
= ntstatus_to_werror(status
);
970 if (!W_ERROR_IS_OK(result
)) {
974 status
= dcerpc_winreg_set_dword(tmp_ctx
,
977 SPOOL_REG_PRINTKEEPPRINTEDJOBS
,
980 if (!NT_STATUS_IS_OK(status
)) {
981 result
= ntstatus_to_werror(status
);
983 if (!W_ERROR_IS_OK(result
)) {
988 if (is_valid_policy_hnd(&key_hnd
)) {
989 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
992 info2
= talloc_zero(tmp_ctx
, struct spoolss_SetPrinterInfo2
);
994 result
= WERR_NOT_ENOUGH_MEMORY
;
998 info2
->printername
= sharename
;
999 if (info2
->printername
== NULL
) {
1000 result
= WERR_NOT_ENOUGH_MEMORY
;
1003 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTERNAME
;
1005 info2
->sharename
= sharename
;
1006 info2_mask
|= SPOOLSS_PRINTER_INFO_SHARENAME
;
1008 info2
->portname
= SAMBA_PRINTER_PORT_NAME
;
1009 info2_mask
|= SPOOLSS_PRINTER_INFO_PORTNAME
;
1011 info2
->printprocessor
= "winprint";
1012 info2_mask
|= SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
;
1014 info2
->datatype
= "RAW";
1015 info2_mask
|= SPOOLSS_PRINTER_INFO_DATATYPE
;
1017 info2
->comment
= "";
1018 info2_mask
|= SPOOLSS_PRINTER_INFO_COMMENT
;
1020 info2
->attributes
= PRINTER_ATTRIBUTE_SAMBA
;
1021 info2_mask
|= SPOOLSS_PRINTER_INFO_ATTRIBUTES
;
1023 info2
->starttime
= 0; /* Minutes since 12:00am GMT */
1024 info2_mask
|= SPOOLSS_PRINTER_INFO_STARTTIME
;
1026 info2
->untiltime
= 0; /* Minutes since 12:00am GMT */
1027 info2_mask
|= SPOOLSS_PRINTER_INFO_UNTILTIME
;
1029 info2
->priority
= 1;
1030 info2_mask
|= SPOOLSS_PRINTER_INFO_PRIORITY
;
1032 info2
->defaultpriority
= 1;
1033 info2_mask
|= SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
;
1035 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1036 if (!W_ERROR_IS_OK(result
)) {
1039 info2_mask
|= SPOOLSS_PRINTER_INFO_SECDESC
;
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.
1046 result
= winreg_update_printer(tmp_ctx
,
1055 if (is_valid_policy_hnd(&key_hnd
)) {
1056 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
1058 if (is_valid_policy_hnd(&hive_hnd
)) {
1059 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
1062 talloc_free(tmp_ctx
);
1066 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
)
1074 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1075 struct policy_handle hive_hnd
, key_hnd
;
1076 int snum
= lp_servicenumber(sharename
);
1077 enum ndr_err_code ndr_err
;
1080 WERROR result
= WERR_OK
;
1083 TALLOC_CTX
*tmp_ctx
;
1085 tmp_ctx
= talloc_stackframe();
1086 if (tmp_ctx
== NULL
) {
1087 return WERR_NOT_ENOUGH_MEMORY
;
1090 path
= winreg_printer_data_keyname(tmp_ctx
, sharename
);
1092 TALLOC_FREE(tmp_ctx
);
1093 return WERR_NOT_ENOUGH_MEMORY
;
1096 ZERO_STRUCT(hive_hnd
);
1097 ZERO_STRUCT(key_hnd
);
1099 result
= winreg_printer_openkey(tmp_ctx
,
1107 if (!W_ERROR_IS_OK(result
)) {
1108 DEBUG(0, ("winreg_update_printer: Could not open key %s: %s\n",
1109 path
, win_errstr(result
)));
1113 if (info2_mask
& SPOOLSS_PRINTER_INFO_ATTRIBUTES
) {
1114 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1120 if (!NT_STATUS_IS_OK(status
)) {
1121 result
= ntstatus_to_werror(status
);
1123 if (!W_ERROR_IS_OK(result
)) {
1129 if (info2_mask
& SPOOLSS_PRINTER_INFO_AVERAGEPPM
) {
1130 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1136 if (!NT_STATUS_IS_OK(status
)) {
1137 result
= ntstatus_to_werror(status
);
1139 if (!W_ERROR_IS_OK(result
)) {
1145 if (info2_mask
& SPOOLSS_PRINTER_INFO_COMMENT
) {
1146 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1152 if (!NT_STATUS_IS_OK(status
)) {
1153 result
= ntstatus_to_werror(status
);
1155 if (!W_ERROR_IS_OK(result
)) {
1160 if (info2_mask
& SPOOLSS_PRINTER_INFO_DATATYPE
) {
1161 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1167 if (!NT_STATUS_IS_OK(status
)) {
1168 result
= ntstatus_to_werror(status
);
1170 if (!W_ERROR_IS_OK(result
)) {
1175 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEFAULTPRIORITY
) {
1176 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1180 info2
->defaultpriority
,
1182 if (!NT_STATUS_IS_OK(status
)) {
1183 result
= ntstatus_to_werror(status
);
1185 if (!W_ERROR_IS_OK(result
)) {
1190 if (info2_mask
& SPOOLSS_PRINTER_INFO_DEVMODE
) {
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
1196 if (devmode
== NULL
&& lp_default_devmode(snum
) && info2
!= NULL
) {
1197 result
= spoolss_create_default_devmode(tmp_ctx
,
1200 if (!W_ERROR_IS_OK(result
)) {
1205 if (devmode
->size
!= (ndr_size_spoolss_DeviceMode(devmode
, 0) - devmode
->__driverextra_length
)) {
1206 result
= WERR_INVALID_PARAMETER
;
1210 ndr_err
= ndr_push_struct_blob(&blob
, tmp_ctx
, devmode
,
1211 (ndr_push_flags_fn_t
) ndr_push_spoolss_DeviceMode
);
1212 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1213 DEBUG(0, ("winreg_update_printer: Failed to marshall device mode\n"));
1214 result
= WERR_NOT_ENOUGH_MEMORY
;
1218 status
= dcerpc_winreg_set_binary(tmp_ctx
,
1224 if (!NT_STATUS_IS_OK(status
)) {
1225 result
= ntstatus_to_werror(status
);
1227 if (!W_ERROR_IS_OK(result
)) {
1232 if (info2_mask
& SPOOLSS_PRINTER_INFO_DRIVERNAME
) {
1233 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1239 if (!NT_STATUS_IS_OK(status
)) {
1240 result
= ntstatus_to_werror(status
);
1242 if (!W_ERROR_IS_OK(result
)) {
1247 if (info2_mask
& SPOOLSS_PRINTER_INFO_LOCATION
) {
1248 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1254 if (!NT_STATUS_IS_OK(status
)) {
1255 result
= ntstatus_to_werror(status
);
1257 if (!W_ERROR_IS_OK(result
)) {
1262 if (info2_mask
& SPOOLSS_PRINTER_INFO_PARAMETERS
) {
1263 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1269 if (!NT_STATUS_IS_OK(status
)) {
1270 result
= ntstatus_to_werror(status
);
1272 if (!W_ERROR_IS_OK(result
)) {
1277 if (info2_mask
& SPOOLSS_PRINTER_INFO_PORTNAME
) {
1278 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1284 if (!NT_STATUS_IS_OK(status
)) {
1285 result
= ntstatus_to_werror(status
);
1287 if (!W_ERROR_IS_OK(result
)) {
1292 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTERNAME
) {
1294 * in addprinter: no servername and the printer is the name
1295 * in setprinter: servername is \\server
1296 * and printer is \\server\\printer
1298 * Samba manages only local printers.
1299 * we currently don't support things like i
1300 * path=\\other_server\printer
1302 * We only store the printername, not \\server\printername
1304 const char *p
= strrchr(info2
->printername
, '\\');
1306 p
= info2
->printername
;
1310 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1316 if (!NT_STATUS_IS_OK(status
)) {
1317 result
= ntstatus_to_werror(status
);
1319 if (!W_ERROR_IS_OK(result
)) {
1324 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRINTPROCESSOR
) {
1325 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1329 info2
->printprocessor
,
1331 if (!NT_STATUS_IS_OK(status
)) {
1332 result
= ntstatus_to_werror(status
);
1334 if (!W_ERROR_IS_OK(result
)) {
1339 if (info2_mask
& SPOOLSS_PRINTER_INFO_PRIORITY
) {
1340 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1346 if (!NT_STATUS_IS_OK(status
)) {
1347 result
= ntstatus_to_werror(status
);
1349 if (!W_ERROR_IS_OK(result
)) {
1354 if (info2_mask
& SPOOLSS_PRINTER_INFO_SECDESC
) {
1356 * We need a security descriptor, if it isn't specified by
1357 * AddPrinter{Ex} then create a default descriptor.
1359 if (secdesc
== NULL
) {
1360 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1361 if (!W_ERROR_IS_OK(result
)) {
1365 result
= winreg_set_printer_secdesc(tmp_ctx
,
1369 if (!W_ERROR_IS_OK(result
)) {
1374 if (info2_mask
& SPOOLSS_PRINTER_INFO_SEPFILE
) {
1375 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1381 if (!NT_STATUS_IS_OK(status
)) {
1382 result
= ntstatus_to_werror(status
);
1384 if (!W_ERROR_IS_OK(result
)) {
1389 if (info2_mask
& SPOOLSS_PRINTER_INFO_SHARENAME
) {
1390 status
= dcerpc_winreg_set_sz(tmp_ctx
,
1396 if (!NT_STATUS_IS_OK(status
)) {
1397 result
= ntstatus_to_werror(status
);
1399 if (!W_ERROR_IS_OK(result
)) {
1404 if (info2_mask
& SPOOLSS_PRINTER_INFO_STARTTIME
) {
1405 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1411 if (!NT_STATUS_IS_OK(status
)) {
1412 result
= ntstatus_to_werror(status
);
1414 if (!W_ERROR_IS_OK(result
)) {
1419 if (info2_mask
& SPOOLSS_PRINTER_INFO_STATUS
) {
1420 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1426 if (!NT_STATUS_IS_OK(status
)) {
1427 result
= ntstatus_to_werror(status
);
1429 if (!W_ERROR_IS_OK(result
)) {
1434 if (info2_mask
& SPOOLSS_PRINTER_INFO_UNTILTIME
) {
1435 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1441 if (!NT_STATUS_IS_OK(status
)) {
1442 result
= ntstatus_to_werror(status
);
1444 if (!W_ERROR_IS_OK(result
)) {
1449 status
= dcerpc_winreg_set_dword(tmp_ctx
,
1453 winreg_printer_rev_changeid(),
1455 if (!NT_STATUS_IS_OK(status
)) {
1456 result
= ntstatus_to_werror(status
);
1458 if (!W_ERROR_IS_OK(result
)) {
1464 if (is_valid_policy_hnd(&key_hnd
)) {
1465 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
1467 if (is_valid_policy_hnd(&hive_hnd
)) {
1468 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
1471 TALLOC_FREE(tmp_ctx
);
1475 WERROR
winreg_get_printer(TALLOC_CTX
*mem_ctx
,
1476 struct dcerpc_binding_handle
*winreg_handle
,
1477 const char *printer
,
1478 struct spoolss_PrinterInfo2
**pinfo2
)
1480 struct spoolss_PrinterInfo2
*info2
;
1481 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1482 struct policy_handle hive_hnd
= { .handle_type
= 0 };
1483 struct policy_handle key_hnd
= { .handle_type
= 0 };
1484 struct spoolss_PrinterEnumValues enum_value
;
1485 struct spoolss_PrinterEnumValues
*v
= NULL
;
1486 enum ndr_err_code ndr_err
;
1488 int snum
= lp_servicenumber(printer
);
1489 uint32_t num_values
= 0;
1493 WERROR result
= WERR_OK
;
1495 const char **enum_names
= NULL
;
1496 enum winreg_Type
*enum_types
= NULL
;
1497 DATA_BLOB
*enum_data_blobs
= NULL
;
1498 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1500 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
1502 result
= WERR_NOT_ENOUGH_MEMORY
;
1506 result
= winreg_printer_openkey(tmp_ctx
,
1514 if (!W_ERROR_IS_OK(result
)) {
1515 DEBUG(2, ("winreg_get_printer: Could not open key %s: %s\n",
1516 path
, win_errstr(result
)));
1520 status
= dcerpc_winreg_enumvals(tmp_ctx
,
1528 if (!NT_STATUS_IS_OK(status
)){
1529 result
= ntstatus_to_werror(status
);
1532 if (!W_ERROR_IS_OK(result
)) {
1533 DEBUG(0, ("winreg_get_printer: Could not enumerate values in %s: %s\n",
1534 path
, win_errstr(result
)));
1538 result
= WERR_NOT_ENOUGH_MEMORY
;
1540 info2
= talloc_zero(tmp_ctx
, struct spoolss_PrinterInfo2
);
1541 if (info2
== NULL
) {
1545 info2
->servername
= talloc_strdup(info2
, "");
1546 if (info2
->servername
== NULL
) {
1549 info2
->printername
= talloc_strdup(info2
, "");
1550 if (info2
->printername
== NULL
) {
1553 info2
->sharename
= talloc_strdup(info2
, "");
1554 if (info2
->sharename
== NULL
) {
1557 info2
->portname
= talloc_strdup(info2
, "");
1558 if (info2
->portname
== NULL
) {
1561 info2
->drivername
= talloc_strdup(info2
, "");
1562 if (info2
->drivername
== NULL
) {
1565 info2
->comment
= talloc_strdup(info2
, "");
1566 if (info2
->comment
== NULL
) {
1569 info2
->location
= talloc_strdup(info2
, "");
1570 if (info2
->location
== NULL
) {
1573 info2
->sepfile
= talloc_strdup(info2
, "");
1574 if (info2
->sepfile
== NULL
) {
1577 info2
->printprocessor
= talloc_strdup(info2
, "");
1578 if (info2
->printprocessor
== NULL
) {
1581 info2
->datatype
= talloc_strdup(info2
, "");
1582 if (info2
->datatype
== NULL
) {
1585 info2
->parameters
= talloc_strdup(info2
, "");
1586 if (info2
->parameters
== NULL
) {
1590 for (i
= 0; i
< num_values
; i
++) {
1591 enum_value
.value_name
= enum_names
[i
];
1592 enum_value
.value_name_len
= 2*strlen_m_term(enum_names
[i
]);
1593 enum_value
.type
= enum_types
[i
];
1594 enum_value
.data_length
= enum_data_blobs
[i
].length
;
1595 enum_value
.data
= NULL
;
1596 if (enum_value
.data_length
!= 0){
1597 enum_value
.data
= &enum_data_blobs
[i
];
1601 result
= winreg_enumval_to_sz(info2
,
1604 &info2
->printername
);
1605 CHECK_ERROR(result
);
1607 result
= winreg_enumval_to_sz(info2
,
1611 CHECK_ERROR(result
);
1613 result
= winreg_enumval_to_sz(info2
,
1617 CHECK_ERROR(result
);
1619 result
= winreg_enumval_to_sz(info2
,
1623 CHECK_ERROR(result
);
1625 result
= winreg_enumval_to_sz(info2
,
1629 CHECK_ERROR(result
);
1631 result
= winreg_enumval_to_sz(info2
,
1635 CHECK_ERROR(result
);
1637 result
= winreg_enumval_to_sz(info2
,
1640 &info2
->printprocessor
);
1641 CHECK_ERROR(result
);
1643 result
= winreg_enumval_to_sz(info2
,
1647 CHECK_ERROR(result
);
1649 result
= winreg_enumval_to_sz(info2
,
1652 &info2
->parameters
);
1653 CHECK_ERROR(result
);
1655 result
= winreg_enumval_to_sz(info2
,
1658 &info2
->drivername
);
1659 CHECK_ERROR(result
);
1661 result
= winreg_enumval_to_dword(info2
,
1664 &info2
->attributes
);
1665 CHECK_ERROR(result
);
1667 result
= winreg_enumval_to_dword(info2
,
1671 CHECK_ERROR(result
);
1673 result
= winreg_enumval_to_dword(info2
,
1676 &info2
->defaultpriority
);
1677 CHECK_ERROR(result
);
1679 result
= winreg_enumval_to_dword(info2
,
1683 CHECK_ERROR(result
);
1685 result
= winreg_enumval_to_dword(info2
,
1689 CHECK_ERROR(result
);
1691 result
= winreg_enumval_to_dword(info2
,
1695 CHECK_ERROR(result
);
1697 result
= winreg_enumval_to_dword(info2
,
1701 CHECK_ERROR(result
);
1704 if (!W_ERROR_IS_OK(result
)) {
1705 DEBUG(0, ("winreg_get_printer: winreg_enumval_to_TYPE() failed "
1708 win_errstr(result
)));
1712 /* Construct the Device Mode */
1713 status
= dcerpc_winreg_query_binary(tmp_ctx
,
1719 if (!NT_STATUS_IS_OK(status
)) {
1720 result
= ntstatus_to_werror(status
);
1722 if (W_ERROR_IS_OK(result
)) {
1723 info2
->devmode
= talloc_zero(info2
, struct spoolss_DeviceMode
);
1724 if (info2
->devmode
== NULL
) {
1725 result
= WERR_NOT_ENOUGH_MEMORY
;
1728 ndr_err
= ndr_pull_struct_blob(&blob
,
1731 (ndr_pull_flags_fn_t
) ndr_pull_spoolss_DeviceMode
);
1732 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1733 DEBUG(0, ("winreg_get_printer: Failed to unmarshall device mode\n"));
1734 result
= WERR_NOT_ENOUGH_MEMORY
;
1739 if (info2
->devmode
== NULL
&& lp_default_devmode(snum
)) {
1740 result
= spoolss_create_default_devmode(info2
,
1743 if (!W_ERROR_IS_OK(result
)) {
1748 if (info2
->devmode
) {
1749 info2
->devmode
->size
= ndr_size_spoolss_DeviceMode(info2
->devmode
, 0) - info2
->devmode
->driverextra_data
.length
;
1752 result
= winreg_get_printer_secdesc(info2
,
1756 if (!W_ERROR_IS_OK(result
)) {
1760 /* Fix for OS/2 drivers. */
1761 if (get_remote_arch() == RA_OS2
) {
1762 spoolss_map_to_os2_driver(info2
, &info2
->drivername
);
1766 *pinfo2
= talloc_move(mem_ctx
, &info2
);
1771 if (is_valid_policy_hnd(&key_hnd
)) {
1772 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
1774 if (is_valid_policy_hnd(&hive_hnd
)) {
1775 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
1778 TALLOC_FREE(tmp_ctx
);
1782 static WERROR
winreg_get_secdesc(TALLOC_CTX
*mem_ctx
,
1783 struct dcerpc_binding_handle
*winreg_handle
,
1785 const char *attribute
,
1786 struct spoolss_security_descriptor
**psecdesc
)
1788 struct spoolss_security_descriptor
*secdesc
;
1789 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1790 struct policy_handle hive_hnd
, key_hnd
;
1791 TALLOC_CTX
*tmp_ctx
;
1796 tmp_ctx
= talloc_stackframe();
1797 if (tmp_ctx
== NULL
) {
1798 return WERR_NOT_ENOUGH_MEMORY
;
1801 ZERO_STRUCT(hive_hnd
);
1802 ZERO_STRUCT(key_hnd
);
1804 result
= winreg_printer_openkey(tmp_ctx
,
1812 if (!W_ERROR_IS_OK(result
)) {
1813 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
1814 goto create_default
;
1819 status
= dcerpc_winreg_query_sd(tmp_ctx
,
1825 if (!NT_STATUS_IS_OK(status
)) {
1826 result
= ntstatus_to_werror(status
);
1828 if (!W_ERROR_IS_OK(result
)) {
1829 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
1831 if (is_valid_policy_hnd(&key_hnd
)) {
1832 dcerpc_winreg_CloseKey(winreg_handle
,
1838 if (is_valid_policy_hnd(&hive_hnd
)) {
1839 dcerpc_winreg_CloseKey(winreg_handle
,
1844 goto create_default
;
1850 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
1857 result
= winreg_printer_openkey(tmp_ctx
,
1865 if (!W_ERROR_IS_OK(result
)) {
1869 result
= spoolss_create_default_secdesc(tmp_ctx
, &secdesc
);
1870 if (!W_ERROR_IS_OK(result
)) {
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 if (dom_sid_equal(secdesc
->owner_sid
, &global_sid_World
)) {
1878 struct dom_sid owner_sid
;
1880 /* Change sd owner to workgroup administrator */
1882 if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid
)) {
1883 struct spoolss_security_descriptor
*new_secdesc
;
1887 sid_append_rid(&owner_sid
, DOMAIN_RID_ADMINISTRATOR
);
1889 new_secdesc
= make_sec_desc(tmp_ctx
,
1898 if (new_secdesc
== NULL
) {
1899 result
= WERR_NOT_ENOUGH_MEMORY
;
1903 /* Swap with other one */
1904 secdesc
= new_secdesc
;
1908 status
= dcerpc_winreg_set_sd(tmp_ctx
,
1914 if (!NT_STATUS_IS_OK(status
)) {
1915 result
= ntstatus_to_werror(status
);
1917 if (!W_ERROR_IS_OK(result
)) {
1922 *psecdesc
= talloc_move(mem_ctx
, &secdesc
);
1927 if (is_valid_policy_hnd(&key_hnd
)) {
1928 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
1930 if (is_valid_policy_hnd(&hive_hnd
)) {
1931 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
1934 talloc_free(tmp_ctx
);
1938 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
)
1946 path
= winreg_printer_data_keyname(mem_ctx
, sharename
);
1948 return WERR_NOT_ENOUGH_MEMORY
;
1951 result
= winreg_get_secdesc(mem_ctx
, winreg_handle
,
1960 WERROR
winreg_get_printserver_secdesc(TALLOC_CTX
*mem_ctx
,
1961 struct dcerpc_binding_handle
*winreg_handle
,
1962 struct spoolss_security_descriptor
**psecdesc
)
1964 return winreg_get_secdesc(mem_ctx
, winreg_handle
,
1965 TOP_LEVEL_CONTROL_KEY
,
1966 "ServerSecurityDescriptor",
1970 static WERROR
winreg_set_secdesc(TALLOC_CTX
*mem_ctx
,
1971 struct dcerpc_binding_handle
*winreg_handle
,
1973 const char *attribute
,
1974 const struct spoolss_security_descriptor
*secdesc
)
1976 const struct spoolss_security_descriptor
*new_secdesc
= secdesc
;
1977 struct spoolss_security_descriptor
*old_secdesc
;
1978 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
1979 struct policy_handle hive_hnd
, key_hnd
;
1980 TALLOC_CTX
*tmp_ctx
;
1985 tmp_ctx
= talloc_stackframe();
1986 if (tmp_ctx
== NULL
) {
1987 return WERR_NOT_ENOUGH_MEMORY
;
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.
1996 if (!secdesc
->owner_sid
|| !secdesc
->group_sid
) {
1997 struct dom_sid
*owner_sid
, *group_sid
;
1998 struct security_acl
*dacl
, *sacl
;
2001 result
= winreg_get_secdesc(tmp_ctx
,
2006 if (!W_ERROR_IS_OK(result
)) {
2007 talloc_free(tmp_ctx
);
2011 /* Pick out correct owner and group sids */
2012 owner_sid
= secdesc
->owner_sid
?
2013 secdesc
->owner_sid
:
2014 old_secdesc
->owner_sid
;
2016 group_sid
= secdesc
->group_sid
?
2017 secdesc
->group_sid
:
2018 old_secdesc
->group_sid
;
2020 dacl
= secdesc
->dacl
?
2024 sacl
= secdesc
->sacl
?
2028 /* Make a deep copy of the security descriptor */
2029 new_secdesc
= make_sec_desc(tmp_ctx
,
2037 if (new_secdesc
== NULL
) {
2038 talloc_free(tmp_ctx
);
2039 return WERR_NOT_ENOUGH_MEMORY
;
2043 ZERO_STRUCT(hive_hnd
);
2044 ZERO_STRUCT(key_hnd
);
2046 result
= winreg_printer_openkey(tmp_ctx
,
2054 if (!W_ERROR_IS_OK(result
)) {
2058 status
= dcerpc_winreg_set_sd(tmp_ctx
,
2064 if (!NT_STATUS_IS_OK(status
)) {
2065 result
= ntstatus_to_werror(status
);
2069 if (is_valid_policy_hnd(&key_hnd
)) {
2070 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2072 if (is_valid_policy_hnd(&hive_hnd
)) {
2073 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2076 talloc_free(tmp_ctx
);
2080 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
)
2088 path
= winreg_printer_data_keyname(mem_ctx
, sharename
);
2090 return WERR_NOT_ENOUGH_MEMORY
;
2093 result
= winreg_set_secdesc(mem_ctx
, winreg_handle
,
2095 "Security", secdesc
);
2101 WERROR
winreg_set_printserver_secdesc(TALLOC_CTX
*mem_ctx
,
2102 struct dcerpc_binding_handle
*winreg_handle
,
2103 const struct spoolss_security_descriptor
*secdesc
)
2105 return winreg_set_secdesc(mem_ctx
, winreg_handle
,
2106 TOP_LEVEL_CONTROL_KEY
,
2107 "ServerSecurityDescriptor",
2111 /* Set printer data over the winreg pipe. */
2112 WERROR
winreg_set_printer_dataex(TALLOC_CTX
*mem_ctx
,
2113 struct dcerpc_binding_handle
*winreg_handle
,
2114 const char *printer
,
2117 enum winreg_Type type
,
2121 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2122 struct policy_handle hive_hnd
, key_hnd
;
2123 struct winreg_String wvalue
= { 0, };
2125 WERROR result
= WERR_OK
;
2128 TALLOC_CTX
*tmp_ctx
;
2130 tmp_ctx
= talloc_stackframe();
2131 if (tmp_ctx
== NULL
) {
2132 return WERR_NOT_ENOUGH_MEMORY
;
2135 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2137 TALLOC_FREE(tmp_ctx
);
2138 return WERR_NOT_ENOUGH_MEMORY
;
2141 ZERO_STRUCT(hive_hnd
);
2142 ZERO_STRUCT(key_hnd
);
2144 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 result
= winreg_printer_openkey(tmp_ctx
,
2154 if (!W_ERROR_IS_OK(result
)) {
2155 DEBUG(0, ("winreg_set_printer_dataex: Could not open key %s: %s\n",
2156 key
, win_errstr(result
)));
2160 wvalue
.name
= value
;
2161 status
= dcerpc_winreg_SetValue(winreg_handle
,
2169 if (!NT_STATUS_IS_OK(status
)) {
2170 DEBUG(0, ("winreg_set_printer_dataex: Could not set value %s: %s\n",
2171 value
, nt_errstr(status
)));
2172 result
= ntstatus_to_werror(status
);
2176 if (is_valid_policy_hnd(&key_hnd
)) {
2177 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2179 if (is_valid_policy_hnd(&hive_hnd
)) {
2180 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2183 TALLOC_FREE(tmp_ctx
);
2187 /* Get printer data over a winreg pipe. */
2188 WERROR
winreg_get_printer_dataex(TALLOC_CTX
*mem_ctx
,
2189 struct dcerpc_binding_handle
*winreg_handle
,
2190 const char *printer
,
2193 enum winreg_Type
*type
,
2195 uint32_t *data_size
)
2197 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2198 struct policy_handle hive_hnd
, key_hnd
;
2199 struct winreg_String wvalue
;
2200 enum winreg_Type type_in
= REG_NONE
;
2202 uint8_t *data_in
= NULL
;
2203 uint32_t data_in_size
= 0;
2204 uint32_t value_len
= 0;
2205 WERROR result
= WERR_OK
;
2208 TALLOC_CTX
*tmp_ctx
;
2210 tmp_ctx
= talloc_stackframe();
2211 if (tmp_ctx
== NULL
) {
2212 return WERR_NOT_ENOUGH_MEMORY
;
2215 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2217 TALLOC_FREE(tmp_ctx
);
2218 return WERR_NOT_ENOUGH_MEMORY
;
2221 ZERO_STRUCT(hive_hnd
);
2222 ZERO_STRUCT(key_hnd
);
2224 result
= winreg_printer_openkey(tmp_ctx
,
2232 if (!W_ERROR_IS_OK(result
)) {
2233 DEBUG(2, ("winreg_get_printer_dataex: Could not open key %s: %s\n",
2234 key
, win_errstr(result
)));
2238 wvalue
.name
= value
;
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.
2245 status
= dcerpc_winreg_QueryValue(winreg_handle
,
2254 if (!NT_STATUS_IS_OK(status
)) {
2255 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2256 value
, nt_errstr(status
)));
2257 result
= ntstatus_to_werror(status
);
2260 if (!W_ERROR_IS_OK(result
)) {
2261 DEBUG(2, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2262 value
, win_errstr(result
)));
2266 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
2267 if (data_in
== NULL
) {
2268 result
= WERR_NOT_ENOUGH_MEMORY
;
2273 status
= dcerpc_winreg_QueryValue(winreg_handle
,
2282 if (!NT_STATUS_IS_OK(status
)) {
2283 DEBUG(0, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2284 value
, nt_errstr(status
)));
2285 result
= ntstatus_to_werror(status
);
2288 if (!W_ERROR_IS_OK(result
)) {
2289 DEBUG(2, ("winreg_get_printer_dataex: Could not query value %s: %s\n",
2290 value
, win_errstr(result
)));
2295 *data_size
= data_in_size
;
2297 *data
= talloc_move(mem_ctx
, &data_in
);
2302 if (is_valid_policy_hnd(&key_hnd
)) {
2303 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2305 if (is_valid_policy_hnd(&hive_hnd
)) {
2306 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2309 TALLOC_FREE(tmp_ctx
);
2313 /* Enumerate on the values of a given key and provide the data. */
2314 WERROR
winreg_enum_printer_dataex(TALLOC_CTX
*mem_ctx
,
2315 struct dcerpc_binding_handle
*winreg_handle
,
2316 const char *printer
,
2318 uint32_t *pnum_values
,
2319 struct spoolss_PrinterEnumValues
**penum_values
)
2322 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2323 struct policy_handle hive_hnd
, key_hnd
;
2325 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
2326 uint32_t num_values
= 0;
2328 WERROR result
= WERR_OK
;
2331 const char **enum_names
= NULL
;
2332 enum winreg_Type
*enum_types
= NULL
;
2333 DATA_BLOB
*enum_data_blobs
= NULL
;
2335 TALLOC_CTX
*tmp_ctx
;
2337 tmp_ctx
= talloc_stackframe();
2338 if (tmp_ctx
== NULL
) {
2339 return WERR_NOT_ENOUGH_MEMORY
;
2342 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2344 TALLOC_FREE(tmp_ctx
);
2345 return WERR_NOT_ENOUGH_MEMORY
;
2348 result
= winreg_printer_openkey(tmp_ctx
,
2356 if (!W_ERROR_IS_OK(result
)) {
2357 DEBUG(2, ("winreg_enum_printer_dataex: Could not open key %s: %s\n",
2358 key
, win_errstr(result
)));
2362 status
= dcerpc_winreg_enumvals(tmp_ctx
,
2370 if (!NT_STATUS_IS_OK(status
)){
2371 result
= ntstatus_to_werror(status
);
2374 if (!W_ERROR_IS_OK(result
)) {
2375 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2376 key
, win_errstr(result
)));
2380 enum_values
= talloc_array(tmp_ctx
, struct spoolss_PrinterEnumValues
, num_values
);
2381 if (enum_values
== NULL
){
2382 result
= WERR_NOT_ENOUGH_MEMORY
;
2383 DEBUG(0, ("winreg_enum_printer_dataex: Could not enumerate values in %s: %s\n",
2384 key
, win_errstr(result
)));
2388 for (i
= 0; i
< num_values
; i
++){
2389 enum_values
[i
].value_name
= enum_names
[i
];
2390 enum_values
[i
].value_name_len
= strlen_m_term(enum_names
[i
]) * 2;
2391 enum_values
[i
].type
= enum_types
[i
];
2392 enum_values
[i
].data_length
= enum_data_blobs
[i
].length
;
2393 enum_values
[i
].data
= NULL
;
2395 if (enum_values
[i
].data_length
!= 0){
2396 enum_values
[i
].data
= &enum_data_blobs
[i
];
2400 talloc_steal(enum_values
, enum_names
);
2401 talloc_steal(enum_values
, enum_data_blobs
);
2403 *pnum_values
= num_values
;
2405 *penum_values
= talloc_move(mem_ctx
, &enum_values
);
2410 if (is_valid_policy_hnd(&key_hnd
)) {
2411 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2413 if (is_valid_policy_hnd(&hive_hnd
)) {
2414 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2417 TALLOC_FREE(tmp_ctx
);
2421 /* Delete printer data over a winreg pipe. */
2422 WERROR
winreg_delete_printer_dataex(TALLOC_CTX
*mem_ctx
,
2423 struct dcerpc_binding_handle
*winreg_handle
,
2424 const char *printer
,
2428 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2429 struct policy_handle hive_hnd
, key_hnd
;
2430 struct winreg_String wvalue
= { 0, };
2432 WERROR result
= WERR_OK
;
2436 TALLOC_CTX
*tmp_ctx
;
2438 tmp_ctx
= talloc_stackframe();
2439 if (tmp_ctx
== NULL
) {
2440 return WERR_NOT_ENOUGH_MEMORY
;
2443 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2445 TALLOC_FREE(tmp_ctx
);
2446 return WERR_NOT_ENOUGH_MEMORY
;
2449 ZERO_STRUCT(hive_hnd
);
2450 ZERO_STRUCT(key_hnd
);
2452 result
= winreg_printer_openkey(tmp_ctx
,
2460 if (!W_ERROR_IS_OK(result
)) {
2461 DEBUG(0, ("winreg_delete_printer_dataex: Could not open key %s: %s\n",
2462 key
, win_errstr(result
)));
2466 wvalue
.name
= value
;
2467 status
= dcerpc_winreg_DeleteValue(winreg_handle
,
2472 if (!NT_STATUS_IS_OK(status
)) {
2473 DEBUG(0, ("winreg_delete_printer_dataex: Could not delete value %s: %s\n",
2474 value
, nt_errstr(status
)));
2475 result
= ntstatus_to_werror(status
);
2479 if (is_valid_policy_hnd(&key_hnd
)) {
2480 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2482 if (is_valid_policy_hnd(&hive_hnd
)) {
2483 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2486 TALLOC_FREE(tmp_ctx
);
2490 /* Enumerate on the subkeys of a given key and provide the data. */
2491 WERROR
winreg_enum_printer_key(TALLOC_CTX
*mem_ctx
,
2492 struct dcerpc_binding_handle
*winreg_handle
,
2493 const char *printer
,
2495 uint32_t *pnum_subkeys
,
2496 const char ***psubkeys
)
2498 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2499 struct policy_handle hive_hnd
, key_hnd
;
2501 const char **subkeys
= NULL
;
2502 uint32_t num_subkeys
= -1;
2504 WERROR result
= WERR_OK
;
2508 TALLOC_CTX
*tmp_ctx
;
2510 tmp_ctx
= talloc_stackframe();
2511 if (tmp_ctx
== NULL
) {
2512 return WERR_NOT_ENOUGH_MEMORY
;
2515 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2517 TALLOC_FREE(tmp_ctx
);
2518 return WERR_NOT_ENOUGH_MEMORY
;
2521 ZERO_STRUCT(hive_hnd
);
2522 ZERO_STRUCT(key_hnd
);
2524 result
= winreg_printer_openkey(tmp_ctx
,
2532 if (!W_ERROR_IS_OK(result
)) {
2533 DEBUG(2, ("winreg_enum_printer_key: Could not open key %s: %s\n",
2534 key
, win_errstr(result
)));
2538 status
= dcerpc_winreg_enum_keys(tmp_ctx
,
2544 if (!NT_STATUS_IS_OK(status
)) {
2545 result
= ntstatus_to_werror(status
);
2547 if (!W_ERROR_IS_OK(result
)) {
2548 DEBUG(0, ("winreg_enum_printer_key: Could not enumerate subkeys in %s: %s\n",
2549 key
, win_errstr(result
)));
2553 *pnum_subkeys
= num_subkeys
;
2555 *psubkeys
= talloc_move(mem_ctx
, &subkeys
);
2560 if (is_valid_policy_hnd(&key_hnd
)) {
2561 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2563 if (is_valid_policy_hnd(&hive_hnd
)) {
2564 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2567 TALLOC_FREE(tmp_ctx
);
2571 /* Delete a key with subkeys of a given printer. */
2572 WERROR
winreg_delete_printer_key(TALLOC_CTX
*mem_ctx
,
2573 struct dcerpc_binding_handle
*winreg_handle
,
2574 const char *printer
,
2577 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2578 struct policy_handle hive_hnd
, key_hnd
;
2584 TALLOC_CTX
*tmp_ctx
;
2586 tmp_ctx
= talloc_stackframe();
2587 if (tmp_ctx
== NULL
) {
2588 return WERR_NOT_ENOUGH_MEMORY
;
2591 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2593 TALLOC_FREE(tmp_ctx
);
2594 return WERR_NOT_ENOUGH_MEMORY
;
2597 result
= winreg_printer_openkey(tmp_ctx
,
2605 if (!W_ERROR_IS_OK(result
)) {
2606 /* key doesn't exist */
2607 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
2612 DEBUG(0, ("winreg_delete_printer_key: Could not open key %s: %s\n",
2613 key
, win_errstr(result
)));
2617 if (is_valid_policy_hnd(&key_hnd
)) {
2618 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
2621 if (key
== NULL
|| key
[0] == '\0') {
2624 keyname
= talloc_asprintf(tmp_ctx
,
2628 if (keyname
== NULL
) {
2629 result
= WERR_NOT_ENOUGH_MEMORY
;
2634 status
= dcerpc_winreg_delete_subkeys_recursive(tmp_ctx
,
2641 if (!NT_STATUS_IS_OK(status
)) {
2642 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2643 key
, nt_errstr(status
)));
2644 result
= ntstatus_to_werror(status
);
2648 if (!W_ERROR_IS_OK(result
)) {
2649 DEBUG(0, ("winreg_delete_printer_key: Could not delete key %s: %s\n",
2650 key
, win_errstr(result
)));
2655 if (is_valid_policy_hnd(&key_hnd
)) {
2656 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2658 if (is_valid_policy_hnd(&hive_hnd
)) {
2659 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2662 TALLOC_FREE(tmp_ctx
);
2666 WERROR
winreg_printer_update_changeid(TALLOC_CTX
*mem_ctx
,
2667 struct dcerpc_binding_handle
*winreg_handle
,
2668 const char *printer
)
2670 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2671 struct policy_handle hive_hnd
, key_hnd
;
2676 TALLOC_CTX
*tmp_ctx
;
2678 tmp_ctx
= talloc_stackframe();
2679 if (tmp_ctx
== NULL
) {
2680 return WERR_NOT_ENOUGH_MEMORY
;
2683 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2685 TALLOC_FREE(tmp_ctx
);
2686 return WERR_NOT_ENOUGH_MEMORY
;
2689 ZERO_STRUCT(hive_hnd
);
2690 ZERO_STRUCT(key_hnd
);
2692 result
= winreg_printer_openkey(tmp_ctx
,
2700 if (!W_ERROR_IS_OK(result
)) {
2701 DEBUG(0, ("winreg_printer_update_changeid: Could not open key %s: %s\n",
2702 path
, win_errstr(result
)));
2706 status
= dcerpc_winreg_set_dword(tmp_ctx
,
2710 winreg_printer_rev_changeid(),
2712 if (!NT_STATUS_IS_OK(status
)) {
2713 result
= ntstatus_to_werror(status
);
2715 if (!W_ERROR_IS_OK(result
)) {
2721 if (is_valid_policy_hnd(&key_hnd
)) {
2722 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2724 if (is_valid_policy_hnd(&hive_hnd
)) {
2725 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2728 TALLOC_FREE(tmp_ctx
);
2732 WERROR
winreg_printer_get_changeid(TALLOC_CTX
*mem_ctx
,
2733 struct dcerpc_binding_handle
*winreg_handle
,
2734 const char *printer
,
2735 uint32_t *pchangeid
)
2737 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2738 struct policy_handle hive_hnd
, key_hnd
;
2739 uint32_t changeid
= 0;
2744 TALLOC_CTX
*tmp_ctx
;
2746 tmp_ctx
= talloc_stackframe();
2747 if (tmp_ctx
== NULL
) {
2748 return WERR_NOT_ENOUGH_MEMORY
;
2751 path
= winreg_printer_data_keyname(tmp_ctx
, printer
);
2753 TALLOC_FREE(tmp_ctx
);
2754 return WERR_NOT_ENOUGH_MEMORY
;
2757 ZERO_STRUCT(hive_hnd
);
2758 ZERO_STRUCT(key_hnd
);
2760 result
= winreg_printer_openkey(tmp_ctx
,
2768 if (!W_ERROR_IS_OK(result
)) {
2769 DEBUG(2, ("winreg_printer_get_changeid: Could not open key %s: %s\n",
2770 path
, win_errstr(result
)));
2774 DEBUG(10, ("winreg_printer_get_changeid: get changeid from %s\n", path
));
2776 status
= dcerpc_winreg_query_dword(tmp_ctx
,
2782 if (!NT_STATUS_IS_OK(status
)) {
2783 result
= ntstatus_to_werror(status
);
2785 if (!W_ERROR_IS_OK(result
)) {
2790 *pchangeid
= changeid
;
2795 if (is_valid_policy_hnd(&key_hnd
)) {
2796 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2798 if (is_valid_policy_hnd(&hive_hnd
)) {
2799 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2802 TALLOC_FREE(tmp_ctx
);
2807 * The special behaviour of the spoolss forms is documented at the website:
2809 * Managing Win32 Printserver Forms
2810 * http://unixwiz.net/techtips/winspooler-forms.html
2813 WERROR
winreg_printer_addform1(TALLOC_CTX
*mem_ctx
,
2814 struct dcerpc_binding_handle
*winreg_handle
,
2815 struct spoolss_AddFormInfo1
*form
)
2817 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2818 struct policy_handle hive_hnd
, key_hnd
;
2819 struct winreg_String wvalue
= { 0, };
2821 uint32_t num_info
= 0;
2822 union spoolss_FormInfo
*info
= NULL
;
2827 TALLOC_CTX
*tmp_ctx
;
2829 tmp_ctx
= talloc_stackframe();
2830 if (tmp_ctx
== NULL
) {
2831 return WERR_NOT_ENOUGH_MEMORY
;
2834 ZERO_STRUCT(hive_hnd
);
2835 ZERO_STRUCT(key_hnd
);
2837 result
= winreg_printer_openkey(tmp_ctx
,
2839 TOP_LEVEL_CONTROL_FORMS_KEY
,
2845 if (!W_ERROR_IS_OK(result
)) {
2846 DEBUG(0, ("winreg_printer_addform1: Could not open key %s: %s\n",
2847 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
2851 result
= winreg_printer_enumforms1(tmp_ctx
, winreg_handle
,
2853 if (!W_ERROR_IS_OK(result
)) {
2854 DEBUG(0, ("winreg_printer_addform: Could not enum keys %s: %s\n",
2855 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
2859 /* If form name already exists or is builtin return ALREADY_EXISTS */
2860 for (i
= 0; i
< num_info
; i
++) {
2861 if (strequal(info
[i
].info1
.form_name
, form
->form_name
)) {
2862 result
= WERR_FILE_EXISTS
;
2867 wvalue
.name
= form
->form_name
;
2869 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
2870 SIVAL(blob
.data
, 0, form
->size
.width
);
2871 SIVAL(blob
.data
, 4, form
->size
.height
);
2872 SIVAL(blob
.data
, 8, form
->area
.left
);
2873 SIVAL(blob
.data
, 12, form
->area
.top
);
2874 SIVAL(blob
.data
, 16, form
->area
.right
);
2875 SIVAL(blob
.data
, 20, form
->area
.bottom
);
2876 SIVAL(blob
.data
, 24, num_info
+ 1); /* FIXME */
2877 SIVAL(blob
.data
, 28, form
->flags
);
2879 status
= dcerpc_winreg_SetValue(winreg_handle
,
2887 if (!NT_STATUS_IS_OK(status
)) {
2888 DEBUG(0, ("winreg_printer_addform1: Could not set value %s: %s\n",
2889 wvalue
.name
, nt_errstr(status
)));
2890 result
= ntstatus_to_werror(status
);
2894 if (is_valid_policy_hnd(&key_hnd
)) {
2895 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
2897 if (is_valid_policy_hnd(&hive_hnd
)) {
2898 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
2902 TALLOC_FREE(tmp_ctx
);
2906 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
)
2911 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
2912 struct policy_handle hive_hnd
, key_hnd
;
2913 union spoolss_FormInfo
*info
;
2914 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
2915 uint32_t num_values
= 0;
2916 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
2921 const char **enum_names
= NULL
;
2922 enum winreg_Type
*enum_types
= NULL
;
2923 DATA_BLOB
*enum_data_blobs
= NULL
;
2924 TALLOC_CTX
*tmp_ctx
;
2926 tmp_ctx
= talloc_stackframe();
2927 if (tmp_ctx
== NULL
) {
2928 return WERR_NOT_ENOUGH_MEMORY
;
2931 ZERO_STRUCT(hive_hnd
);
2932 ZERO_STRUCT(key_hnd
);
2934 result
= winreg_printer_openkey(tmp_ctx
,
2936 TOP_LEVEL_CONTROL_FORMS_KEY
,
2942 if (!W_ERROR_IS_OK(result
)) {
2943 /* key doesn't exist */
2944 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
2949 DEBUG(0, ("winreg_printer_enumforms1: Could not open key %s: %s\n",
2950 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
2954 status
= dcerpc_winreg_enumvals(tmp_ctx
,
2962 if (!NT_STATUS_IS_OK(status
)){
2963 result
= ntstatus_to_werror(status
);
2966 if (!W_ERROR_IS_OK(result
)) {
2967 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
2968 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
2972 enum_values
= talloc_zero_array(tmp_ctx
,
2973 struct spoolss_PrinterEnumValues
,
2975 if (enum_values
== NULL
){
2976 result
= WERR_NOT_ENOUGH_MEMORY
;
2980 for (i
= 0; i
< num_values
; i
++){
2981 enum_values
[i
].value_name
= enum_names
[i
];
2982 enum_values
[i
].value_name_len
= strlen_m_term(enum_names
[i
]) * 2;
2983 enum_values
[i
].type
= enum_types
[i
];
2984 enum_values
[i
].data_length
= enum_data_blobs
[i
].length
;
2985 enum_values
[i
].data
= NULL
;
2986 if (enum_values
[i
].data_length
!= 0){
2987 enum_values
[i
].data
= &enum_data_blobs
[i
];
2991 if (!W_ERROR_IS_OK(result
)) {
2992 DEBUG(0, ("winreg_printer_enumforms1: Could not enumerate values in %s: %s\n",
2993 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
2997 info
= talloc_array(tmp_ctx
, union spoolss_FormInfo
, num_builtin
+ num_values
);
2999 result
= WERR_NOT_ENOUGH_MEMORY
;
3003 /* Enumerate BUILTIN forms */
3004 for (i
= 0; i
< num_builtin
; i
++) {
3005 info
[i
].info1
= builtin_forms1
[i
];
3008 /* Enumerate registry forms */
3009 for (i
= 0; i
< num_values
; i
++) {
3010 union spoolss_FormInfo val
;
3012 if (enum_values
[i
].type
!= REG_BINARY
||
3013 enum_values
[i
].data_length
!= 32) {
3017 val
.info1
.form_name
= talloc_strdup(info
, enum_values
[i
].value_name
);
3018 if (val
.info1
.form_name
== NULL
) {
3019 result
= WERR_NOT_ENOUGH_MEMORY
;
3023 val
.info1
.size
.width
= IVAL(enum_values
[i
].data
->data
, 0);
3024 val
.info1
.size
.height
= IVAL(enum_values
[i
].data
->data
, 4);
3025 val
.info1
.area
.left
= IVAL(enum_values
[i
].data
->data
, 8);
3026 val
.info1
.area
.top
= IVAL(enum_values
[i
].data
->data
, 12);
3027 val
.info1
.area
.right
= IVAL(enum_values
[i
].data
->data
, 16);
3028 val
.info1
.area
.bottom
= IVAL(enum_values
[i
].data
->data
, 20);
3029 /* skip form index IVAL(enum_values[i].data->data, 24)));*/
3030 val
.info1
.flags
= (enum spoolss_FormFlags
) IVAL(enum_values
[i
].data
->data
, 28);
3032 info
[i
+ num_builtin
] = val
;
3035 *pnum_info
= num_builtin
+ num_values
;
3037 *pinfo
= talloc_move(mem_ctx
, &info
);
3041 if (is_valid_policy_hnd(&key_hnd
)) {
3042 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3044 if (is_valid_policy_hnd(&hive_hnd
)) {
3045 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3048 TALLOC_FREE(enum_values
);
3049 TALLOC_FREE(tmp_ctx
);
3053 WERROR
winreg_printer_deleteform1(TALLOC_CTX
*mem_ctx
,
3054 struct dcerpc_binding_handle
*winreg_handle
,
3055 const char *form_name
)
3057 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3058 struct policy_handle hive_hnd
, key_hnd
;
3059 struct winreg_String wvalue
= { 0, };
3060 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3062 WERROR result
= WERR_OK
;
3065 TALLOC_CTX
*tmp_ctx
;
3067 for (i
= 0; i
< num_builtin
; i
++) {
3068 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3069 return WERR_INVALID_PARAMETER
;
3073 tmp_ctx
= talloc_stackframe();
3074 if (tmp_ctx
== NULL
) {
3075 return WERR_NOT_ENOUGH_MEMORY
;
3078 ZERO_STRUCT(hive_hnd
);
3079 ZERO_STRUCT(key_hnd
);
3081 result
= winreg_printer_openkey(tmp_ctx
,
3083 TOP_LEVEL_CONTROL_FORMS_KEY
,
3089 if (!W_ERROR_IS_OK(result
)) {
3090 DEBUG(0, ("winreg_printer_deleteform1: Could not open key %s: %s\n",
3091 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3092 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
3093 result
= WERR_INVALID_FORM_NAME
;
3098 wvalue
.name
= form_name
;
3099 status
= dcerpc_winreg_DeleteValue(winreg_handle
,
3104 if (!NT_STATUS_IS_OK(status
)) {
3105 /* If the value doesn't exist, return WERR_INVALID_FORM_NAME */
3106 DEBUG(0, ("winreg_printer_delteform1: Could not delete value %s: %s\n",
3107 wvalue
.name
, nt_errstr(status
)));
3108 result
= ntstatus_to_werror(status
);
3112 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
3113 result
= WERR_INVALID_FORM_NAME
;
3117 if (is_valid_policy_hnd(&key_hnd
)) {
3118 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3120 if (is_valid_policy_hnd(&hive_hnd
)) {
3121 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3124 TALLOC_FREE(tmp_ctx
);
3128 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
)
3133 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3134 struct policy_handle hive_hnd
= { 0, };
3135 struct policy_handle key_hnd
= { 0, };
3136 struct winreg_String wvalue
= { 0, };
3138 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3142 TALLOC_CTX
*tmp_ctx
= NULL
;
3144 for (i
= 0; i
< num_builtin
; i
++) {
3145 if (strequal(builtin_forms1
[i
].form_name
, form
->form_name
)) {
3146 result
= WERR_INVALID_PARAMETER
;
3151 tmp_ctx
= talloc_stackframe();
3152 if (tmp_ctx
== NULL
) {
3153 return WERR_NOT_ENOUGH_MEMORY
;
3156 ZERO_STRUCT(hive_hnd
);
3157 ZERO_STRUCT(key_hnd
);
3159 result
= winreg_printer_openkey(tmp_ctx
,
3161 TOP_LEVEL_CONTROL_FORMS_KEY
,
3167 if (!W_ERROR_IS_OK(result
)) {
3168 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3169 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3173 /* If form_name != form->form_name then we renamed the form */
3174 if (strequal(form_name
, form
->form_name
)) {
3175 result
= winreg_printer_deleteform1(tmp_ctx
, winreg_handle
,
3177 if (!W_ERROR_IS_OK(result
)) {
3178 DEBUG(0, ("winreg_printer_setform1: Could not open key %s: %s\n",
3179 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3184 wvalue
.name
= form
->form_name
;
3186 blob
= data_blob_talloc(tmp_ctx
, NULL
, 32);
3187 SIVAL(blob
.data
, 0, form
->size
.width
);
3188 SIVAL(blob
.data
, 4, form
->size
.height
);
3189 SIVAL(blob
.data
, 8, form
->area
.left
);
3190 SIVAL(blob
.data
, 12, form
->area
.top
);
3191 SIVAL(blob
.data
, 16, form
->area
.right
);
3192 SIVAL(blob
.data
, 20, form
->area
.bottom
);
3193 SIVAL(blob
.data
, 24, 42);
3194 SIVAL(blob
.data
, 28, form
->flags
);
3196 status
= dcerpc_winreg_SetValue(winreg_handle
,
3204 if (!NT_STATUS_IS_OK(status
)) {
3205 DEBUG(0, ("winreg_printer_setform1: Could not set value %s: %s\n",
3206 wvalue
.name
, nt_errstr(status
)));
3207 result
= ntstatus_to_werror(status
);
3211 if (winreg_handle
!= NULL
) {
3214 if (is_valid_policy_hnd(&key_hnd
)) {
3215 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3217 if (is_valid_policy_hnd(&hive_hnd
)) {
3218 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3222 TALLOC_FREE(tmp_ctx
);
3226 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
)
3231 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3232 struct policy_handle hive_hnd
, key_hnd
;
3233 struct winreg_String wvalue
;
3234 enum winreg_Type type_in
= REG_NONE
;
3235 uint8_t *data_in
= NULL
;
3236 uint32_t data_in_size
= 0;
3237 uint32_t value_len
= 0;
3238 uint32_t num_builtin
= ARRAY_SIZE(builtin_forms1
);
3243 TALLOC_CTX
*tmp_ctx
;
3245 /* check builtin forms first */
3246 for (i
= 0; i
< num_builtin
; i
++) {
3247 if (strequal(builtin_forms1
[i
].form_name
, form_name
)) {
3248 *r
= builtin_forms1
[i
];
3253 tmp_ctx
= talloc_stackframe();
3254 if (tmp_ctx
== NULL
) {
3255 return WERR_NOT_ENOUGH_MEMORY
;
3258 ZERO_STRUCT(hive_hnd
);
3259 ZERO_STRUCT(key_hnd
);
3261 result
= winreg_printer_openkey(tmp_ctx
,
3263 TOP_LEVEL_CONTROL_FORMS_KEY
,
3269 if (!W_ERROR_IS_OK(result
)) {
3270 DEBUG(2, ("winreg_printer_getform1: Could not open key %s: %s\n",
3271 TOP_LEVEL_CONTROL_FORMS_KEY
, win_errstr(result
)));
3275 wvalue
.name
= form_name
;
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.
3282 status
= dcerpc_winreg_QueryValue(winreg_handle
,
3291 if (!NT_STATUS_IS_OK(status
)) {
3292 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3293 wvalue
.name
, nt_errstr(status
)));
3294 result
= ntstatus_to_werror(status
);
3297 if (!W_ERROR_IS_OK(result
)) {
3301 data_in
= (uint8_t *) TALLOC(tmp_ctx
, data_in_size
);
3302 if (data_in
== NULL
) {
3303 result
= WERR_NOT_ENOUGH_MEMORY
;
3308 status
= dcerpc_winreg_QueryValue(winreg_handle
,
3317 if (!NT_STATUS_IS_OK(status
)) {
3318 DEBUG(0, ("winreg_printer_getform1: Could not query value %s: %s\n",
3319 wvalue
.name
, nt_errstr(status
)));
3320 result
= ntstatus_to_werror(status
);
3323 if (!W_ERROR_IS_OK(result
)) {
3327 r
->form_name
= talloc_strdup(mem_ctx
, form_name
);
3328 if (r
->form_name
== NULL
) {
3329 result
= WERR_NOT_ENOUGH_MEMORY
;
3333 r
->size
.width
= IVAL(data_in
, 0);
3334 r
->size
.height
= IVAL(data_in
, 4);
3335 r
->area
.left
= IVAL(data_in
, 8);
3336 r
->area
.top
= IVAL(data_in
, 12);
3337 r
->area
.right
= IVAL(data_in
, 16);
3338 r
->area
.bottom
= IVAL(data_in
, 20);
3339 /* skip index IVAL(data_in, 24)));*/
3340 r
->flags
= (enum spoolss_FormFlags
) IVAL(data_in
, 28);
3344 if (is_valid_policy_hnd(&key_hnd
)) {
3345 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3347 if (is_valid_policy_hnd(&hive_hnd
)) {
3348 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3351 TALLOC_FREE(tmp_ctx
);
3355 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
)
3361 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3362 struct policy_handle hive_hnd
, key_hnd
;
3363 struct spoolss_DriverInfo8 info8
;
3364 TALLOC_CTX
*tmp_ctx
= NULL
;
3368 ZERO_STRUCT(hive_hnd
);
3369 ZERO_STRUCT(key_hnd
);
3372 if (!driver_info_ctr_to_info8(r
, &info8
)) {
3373 result
= WERR_INVALID_PARAMETER
;
3377 tmp_ctx
= talloc_stackframe();
3378 if (tmp_ctx
== NULL
) {
3379 return WERR_NOT_ENOUGH_MEMORY
;
3382 result
= winreg_printer_opendriver(tmp_ctx
,
3390 if (!W_ERROR_IS_OK(result
)) {
3391 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
)));
3398 /* TODO: "Attributes" ? */
3400 status
= dcerpc_winreg_set_dword(tmp_ctx
,
3406 if (!NT_STATUS_IS_OK(status
)) {
3407 result
= ntstatus_to_werror(status
);
3409 if (!W_ERROR_IS_OK(result
)) {
3413 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3419 if (!NT_STATUS_IS_OK(status
)) {
3420 result
= ntstatus_to_werror(status
);
3422 if (!W_ERROR_IS_OK(result
)) {
3426 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3432 if (!NT_STATUS_IS_OK(status
)) {
3433 result
= ntstatus_to_werror(status
);
3435 if (!W_ERROR_IS_OK(result
)) {
3439 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3442 "Configuration File",
3445 if (!NT_STATUS_IS_OK(status
)) {
3446 result
= ntstatus_to_werror(status
);
3448 if (!W_ERROR_IS_OK(result
)) {
3452 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3458 if (!NT_STATUS_IS_OK(status
)) {
3459 result
= ntstatus_to_werror(status
);
3461 if (!W_ERROR_IS_OK(result
)) {
3465 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3469 info8
.dependent_files
,
3471 if (!NT_STATUS_IS_OK(status
)) {
3472 result
= ntstatus_to_werror(status
);
3474 if (!W_ERROR_IS_OK(result
)) {
3478 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3484 if (!NT_STATUS_IS_OK(status
)) {
3485 result
= ntstatus_to_werror(status
);
3487 if (!W_ERROR_IS_OK(result
)) {
3491 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3495 info8
.default_datatype
,
3497 if (!NT_STATUS_IS_OK(status
)) {
3498 result
= ntstatus_to_werror(status
);
3500 if (!W_ERROR_IS_OK(result
)) {
3504 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3506 &key_hnd
, "Previous Names",
3507 info8
.previous_names
,
3509 if (!NT_STATUS_IS_OK(status
)) {
3510 result
= ntstatus_to_werror(status
);
3512 if (!W_ERROR_IS_OK(result
)) {
3516 result
= winreg_printer_write_date(tmp_ctx
, winreg_handle
,
3517 &key_hnd
, "DriverDate",
3519 if (!W_ERROR_IS_OK(result
)) {
3523 result
= winreg_printer_write_ver(tmp_ctx
, winreg_handle
,
3524 &key_hnd
, "DriverVersion",
3525 info8
.driver_version
);
3526 if (!W_ERROR_IS_OK(result
)) {
3530 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3534 info8
.manufacturer_name
,
3536 if (!NT_STATUS_IS_OK(status
)) {
3537 result
= ntstatus_to_werror(status
);
3539 if (!W_ERROR_IS_OK(result
)) {
3543 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3547 info8
.manufacturer_url
,
3549 if (!NT_STATUS_IS_OK(status
)) {
3550 result
= ntstatus_to_werror(status
);
3552 if (!W_ERROR_IS_OK(result
)) {
3556 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3562 if (!NT_STATUS_IS_OK(status
)) {
3563 result
= ntstatus_to_werror(status
);
3565 if (!W_ERROR_IS_OK(result
)) {
3569 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3575 if (!NT_STATUS_IS_OK(status
)) {
3576 result
= ntstatus_to_werror(status
);
3578 if (!W_ERROR_IS_OK(result
)) {
3582 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3586 info8
.print_processor
,
3588 if (!NT_STATUS_IS_OK(status
)) {
3589 result
= ntstatus_to_werror(status
);
3591 if (!W_ERROR_IS_OK(result
)) {
3595 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3601 if (!NT_STATUS_IS_OK(status
)) {
3602 result
= ntstatus_to_werror(status
);
3604 if (!W_ERROR_IS_OK(result
)) {
3608 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3612 info8
.color_profiles
,
3614 if (!NT_STATUS_IS_OK(status
)) {
3615 result
= ntstatus_to_werror(status
);
3617 if (!W_ERROR_IS_OK(result
)) {
3621 status
= dcerpc_winreg_set_sz(tmp_ctx
,
3627 if (!NT_STATUS_IS_OK(status
)) {
3628 result
= ntstatus_to_werror(status
);
3630 if (!W_ERROR_IS_OK(result
)) {
3634 status
= dcerpc_winreg_set_dword(tmp_ctx
,
3637 "PrinterDriverAttributes",
3638 info8
.printer_driver_attributes
,
3640 if (!NT_STATUS_IS_OK(status
)) {
3641 result
= ntstatus_to_werror(status
);
3643 if (!W_ERROR_IS_OK(result
)) {
3647 status
= dcerpc_winreg_set_multi_sz(tmp_ctx
,
3651 info8
.core_driver_dependencies
,
3653 if (!NT_STATUS_IS_OK(status
)) {
3654 result
= ntstatus_to_werror(status
);
3656 if (!W_ERROR_IS_OK(result
)) {
3660 result
= winreg_printer_write_date(tmp_ctx
, winreg_handle
,
3661 &key_hnd
, "MinInboxDriverVerDate",
3662 info8
.min_inbox_driver_ver_date
);
3663 if (!W_ERROR_IS_OK(result
)) {
3667 result
= winreg_printer_write_ver(tmp_ctx
, winreg_handle
, &key_hnd
,
3668 "MinInboxDriverVerVersion",
3669 info8
.min_inbox_driver_ver_version
);
3670 if (!W_ERROR_IS_OK(result
)) {
3674 *driver_name
= info8
.driver_name
;
3675 *driver_version
= info8
.version
;
3678 if (winreg_handle
!= NULL
) {
3681 if (is_valid_policy_hnd(&key_hnd
)) {
3682 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3684 if (is_valid_policy_hnd(&hive_hnd
)) {
3685 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3689 TALLOC_FREE(tmp_ctx
);
3693 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
)
3700 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3701 struct policy_handle hive_hnd
, key_hnd
;
3702 struct spoolss_DriverInfo8 i8
, *info8
= NULL
;
3703 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
3704 struct spoolss_PrinterEnumValues
*v
= NULL
;
3705 uint32_t num_values
= 0;
3706 TALLOC_CTX
*tmp_ctx
= NULL
;
3710 const char **enum_names
= NULL
;
3711 enum winreg_Type
*enum_types
= NULL
;
3712 DATA_BLOB
*enum_data_blobs
= NULL
;
3714 ZERO_STRUCT(hive_hnd
);
3715 ZERO_STRUCT(key_hnd
);
3718 tmp_ctx
= talloc_stackframe();
3719 if (tmp_ctx
== NULL
) {
3720 return WERR_NOT_ENOUGH_MEMORY
;
3723 if (driver_version
== DRIVER_ANY_VERSION
) {
3724 /* look for Win2k first and then for NT4 */
3725 result
= winreg_printer_opendriver(tmp_ctx
,
3733 if (!W_ERROR_IS_OK(result
)) {
3734 result
= winreg_printer_opendriver(tmp_ctx
,
3744 /* ok normal case */
3745 result
= winreg_printer_opendriver(tmp_ctx
,
3754 if (!W_ERROR_IS_OK(result
)) {
3755 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
)));
3762 status
= dcerpc_winreg_enumvals(tmp_ctx
,
3770 if (!NT_STATUS_IS_OK(status
)){
3771 result
= ntstatus_to_werror(status
);
3774 if (!W_ERROR_IS_OK(result
)) {
3775 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
)));
3782 enum_values
= talloc_zero_array(tmp_ctx
,
3783 struct spoolss_PrinterEnumValues
,
3785 if (enum_values
== NULL
){
3786 result
= WERR_NOT_ENOUGH_MEMORY
;
3790 for (i
= 0; i
< num_values
; i
++){
3791 enum_values
[i
].value_name
= enum_names
[i
];
3792 enum_values
[i
].value_name_len
= strlen_m_term(enum_names
[i
]) * 2;
3793 enum_values
[i
].type
= enum_types
[i
];
3794 enum_values
[i
].data_length
= enum_data_blobs
[i
].length
;
3795 enum_values
[i
].data
= NULL
;
3796 if (enum_values
[i
].data_length
!= 0){
3797 enum_values
[i
].data
= &enum_data_blobs
[i
];
3801 info8
= talloc_zero(tmp_ctx
, struct spoolss_DriverInfo8
);
3802 if (info8
== NULL
) {
3803 result
= WERR_NOT_ENOUGH_MEMORY
;
3807 info8
->driver_name
= talloc_strdup(info8
, driver_name
);
3808 if (info8
->driver_name
== NULL
) {
3809 result
= WERR_NOT_ENOUGH_MEMORY
;
3813 info8
->architecture
= talloc_strdup(info8
, architecture
);
3814 if (info8
->architecture
== NULL
) {
3815 result
= WERR_NOT_ENOUGH_MEMORY
;
3821 for (i
= 0; i
< num_values
; i
++) {
3822 const char *tmp_str
;
3825 v
= &enum_values
[i
];
3827 result
= winreg_enumval_to_dword(info8
, v
,
3830 if (W_ERROR_IS_OK(result
)) {
3831 info8
->version
= (enum spoolss_DriverOSVersion
) tmp
;
3833 CHECK_ERROR(result
);
3835 result
= winreg_enumval_to_sz(info8
, v
,
3837 &info8
->driver_path
);
3838 CHECK_ERROR(result
);
3840 result
= winreg_enumval_to_sz(info8
, v
,
3843 CHECK_ERROR(result
);
3845 result
= winreg_enumval_to_sz(info8
, v
,
3846 "Configuration File",
3847 &info8
->config_file
);
3848 CHECK_ERROR(result
);
3850 result
= winreg_enumval_to_sz(info8
, v
,
3853 CHECK_ERROR(result
);
3855 result
= winreg_enumval_to_multi_sz(info8
, v
,
3857 &info8
->dependent_files
);
3858 CHECK_ERROR(result
);
3860 result
= winreg_enumval_to_sz(info8
, v
,
3862 &info8
->monitor_name
);
3863 CHECK_ERROR(result
);
3865 result
= winreg_enumval_to_sz(info8
, v
,
3867 &info8
->default_datatype
);
3868 CHECK_ERROR(result
);
3870 result
= winreg_enumval_to_multi_sz(info8
, v
,
3872 &info8
->previous_names
);
3873 CHECK_ERROR(result
);
3875 result
= winreg_enumval_to_sz(info8
, v
,
3878 if (W_ERROR_IS_OK(result
)) {
3879 result
= winreg_printer_date_to_NTTIME(tmp_str
,
3880 &info8
->driver_date
);
3882 CHECK_ERROR(result
);
3884 result
= winreg_enumval_to_sz(info8
, v
,
3887 if (W_ERROR_IS_OK(result
)) {
3888 result
= winreg_printer_ver_to_qword(tmp_str
,
3889 &info8
->driver_version
);
3891 CHECK_ERROR(result
);
3893 result
= winreg_enumval_to_sz(info8
, v
,
3895 &info8
->manufacturer_name
);
3896 CHECK_ERROR(result
);
3898 result
= winreg_enumval_to_sz(info8
, v
,
3900 &info8
->manufacturer_url
);
3901 CHECK_ERROR(result
);
3903 result
= winreg_enumval_to_sz(info8
, v
,
3905 &info8
->hardware_id
);
3906 CHECK_ERROR(result
);
3908 result
= winreg_enumval_to_sz(info8
, v
,
3911 CHECK_ERROR(result
);
3913 result
= winreg_enumval_to_sz(info8
, v
,
3915 &info8
->print_processor
);
3916 CHECK_ERROR(result
);
3918 result
= winreg_enumval_to_sz(info8
, v
,
3920 &info8
->vendor_setup
);
3921 CHECK_ERROR(result
);
3923 result
= winreg_enumval_to_multi_sz(info8
, v
,
3925 &info8
->color_profiles
);
3926 CHECK_ERROR(result
);
3928 result
= winreg_enumval_to_sz(info8
, v
,
3931 CHECK_ERROR(result
);
3933 result
= winreg_enumval_to_dword(info8
, v
,
3934 "PrinterDriverAttributes",
3935 &info8
->printer_driver_attributes
);
3936 CHECK_ERROR(result
);
3938 result
= winreg_enumval_to_multi_sz(info8
, v
,
3940 &info8
->core_driver_dependencies
);
3941 CHECK_ERROR(result
);
3943 result
= winreg_enumval_to_sz(info8
, v
,
3944 "MinInboxDriverVerDate",
3946 if (W_ERROR_IS_OK(result
)) {
3947 result
= winreg_printer_date_to_NTTIME(tmp_str
,
3948 &info8
->min_inbox_driver_ver_date
);
3950 CHECK_ERROR(result
);
3952 result
= winreg_enumval_to_sz(info8
, v
,
3953 "MinInboxDriverVerVersion",
3955 if (W_ERROR_IS_OK(result
)) {
3956 result
= winreg_printer_ver_to_qword(tmp_str
,
3957 &info8
->min_inbox_driver_ver_version
);
3959 CHECK_ERROR(result
);
3962 if (!W_ERROR_IS_OK(result
)) {
3963 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
3964 "for %s: %s\n", v
->value_name
,
3965 win_errstr(result
)));
3969 *_info8
= talloc_steal(mem_ctx
, info8
);
3972 if (winreg_handle
!= NULL
) {
3975 if (is_valid_policy_hnd(&key_hnd
)) {
3976 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
3978 if (is_valid_policy_hnd(&hive_hnd
)) {
3979 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
3983 TALLOC_FREE(tmp_ctx
);
3987 WERROR
winreg_del_driver(TALLOC_CTX
*mem_ctx
,
3988 struct dcerpc_binding_handle
*winreg_handle
,
3989 struct spoolss_DriverInfo8
*info8
,
3992 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
3993 struct policy_handle hive_hnd
, key_hnd
;
3994 TALLOC_CTX
*tmp_ctx
;
3999 ZERO_STRUCT(hive_hnd
);
4000 ZERO_STRUCT(key_hnd
);
4002 tmp_ctx
= talloc_stackframe();
4003 if (tmp_ctx
== NULL
) {
4004 return WERR_NOT_ENOUGH_MEMORY
;
4007 /* test that the key exists */
4008 result
= winreg_printer_opendriver(tmp_ctx
,
4011 info8
->architecture
,
4016 if (!W_ERROR_IS_OK(result
)) {
4017 /* key doesn't exist */
4018 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
4023 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
)));
4031 if (is_valid_policy_hnd(&key_hnd
)) {
4032 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
4035 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 if (key_name
== NULL
) {
4041 result
= WERR_NOT_ENOUGH_MEMORY
;
4045 status
= dcerpc_winreg_delete_subkeys_recursive(tmp_ctx
,
4052 if (!NT_STATUS_IS_OK(status
)){
4053 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
)));
4060 if (!W_ERROR_IS_OK(result
)) {
4061 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
)));
4070 if (winreg_handle
!= NULL
) {
4073 if (is_valid_policy_hnd(&key_hnd
)) {
4074 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4076 if (is_valid_policy_hnd(&hive_hnd
)) {
4077 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4081 TALLOC_FREE(tmp_ctx
);
4085 WERROR
winreg_get_driver_list(TALLOC_CTX
*mem_ctx
,
4086 struct dcerpc_binding_handle
*winreg_handle
,
4087 const char *architecture
,
4089 uint32_t *num_drivers
,
4090 const char ***drivers_p
)
4092 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4093 struct policy_handle hive_hnd
, key_hnd
;
4094 const char **drivers
;
4095 TALLOC_CTX
*tmp_ctx
;
4102 ZERO_STRUCT(hive_hnd
);
4103 ZERO_STRUCT(key_hnd
);
4105 tmp_ctx
= talloc_stackframe();
4106 if (tmp_ctx
== NULL
) {
4107 return WERR_NOT_ENOUGH_MEMORY
;
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 result
= winreg_printer_opendriver(tmp_ctx
,
4120 if (!W_ERROR_IS_OK(result
)) {
4121 DEBUG(5, ("winreg_get_driver_list: "
4122 "Could not open key (%s,%u): %s\n",
4123 architecture
, version
, win_errstr(result
)));
4128 status
= dcerpc_winreg_enum_keys(tmp_ctx
,
4134 if (!NT_STATUS_IS_OK(status
)) {
4135 result
= ntstatus_to_werror(status
);
4137 if (!W_ERROR_IS_OK(result
)) {
4138 DEBUG(0, ("winreg_get_driver_list: "
4139 "Could not enumerate drivers for (%s,%u): %s\n",
4140 architecture
, version
, win_errstr(result
)));
4144 *drivers_p
= talloc_steal(mem_ctx
, drivers
);
4148 if (winreg_handle
!= NULL
) {
4151 if (is_valid_policy_hnd(&key_hnd
)) {
4152 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4154 if (is_valid_policy_hnd(&hive_hnd
)) {
4155 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4159 TALLOC_FREE(tmp_ctx
);
4163 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
)
4169 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4170 struct policy_handle hive_hnd
, key_hnd
;
4171 struct spoolss_CorePrinterDriver
*c
= NULL
;
4172 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
4173 struct spoolss_PrinterEnumValues
*v
= NULL
;
4174 uint32_t num_values
= 0;
4175 TALLOC_CTX
*tmp_ctx
= NULL
;
4178 const char *path
= NULL
;
4179 const char *guid_str
= NULL
;
4181 const char **enum_names
= NULL
;
4182 enum winreg_Type
*enum_types
= NULL
;
4183 DATA_BLOB
*enum_data_blobs
= NULL
;
4185 ZERO_STRUCT(hive_hnd
);
4186 ZERO_STRUCT(key_hnd
);
4188 tmp_ctx
= talloc_stackframe();
4189 if (tmp_ctx
== NULL
) {
4190 return WERR_NOT_ENOUGH_MEMORY
;
4193 path
= talloc_asprintf(tmp_ctx
, "%s\\%s\\CorePrinterDrivers",
4194 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
4197 result
= WERR_NOT_ENOUGH_MEMORY
;
4201 guid_str
= GUID_string2(tmp_ctx
, core_driver_guid
);
4202 if (guid_str
== NULL
) {
4203 result
= WERR_NOT_ENOUGH_MEMORY
;
4207 result
= winreg_printer_openkey(tmp_ctx
,
4216 if (!W_ERROR_IS_OK(result
)) {
4217 DEBUG(5, ("winreg_get_core_driver: "
4218 "Could not open core driver key (%s,%s): %s\n",
4219 guid_str
, architecture
, win_errstr(result
)));
4223 status
= dcerpc_winreg_enumvals(tmp_ctx
,
4231 if (!NT_STATUS_IS_OK(status
)){
4232 result
= ntstatus_to_werror(status
);
4235 if (!W_ERROR_IS_OK(result
)) {
4236 DEBUG(0, ("winreg_get_core_driver: "
4237 "Could not enumerate values for (%s,%s): %s\n",
4238 guid_str
, architecture
, win_errstr(result
)));
4242 enum_values
= talloc_zero_array(tmp_ctx
,
4243 struct spoolss_PrinterEnumValues
,
4245 if (enum_values
== NULL
){
4246 result
= WERR_NOT_ENOUGH_MEMORY
;
4250 for (i
= 0; i
< num_values
; i
++){
4251 enum_values
[i
].value_name
= enum_names
[i
];
4252 enum_values
[i
].value_name_len
= strlen_m_term(enum_names
[i
]) * 2;
4253 enum_values
[i
].type
= enum_types
[i
];
4254 enum_values
[i
].data_length
= enum_data_blobs
[i
].length
;
4255 enum_values
[i
].data
= NULL
;
4256 if (enum_values
[i
].data_length
!= 0){
4257 enum_values
[i
].data
= &enum_data_blobs
[i
];
4261 c
= talloc_zero(tmp_ctx
, struct spoolss_CorePrinterDriver
);
4263 result
= WERR_NOT_ENOUGH_MEMORY
;
4267 c
->core_driver_guid
= *core_driver_guid
;
4271 for (i
= 0; i
< num_values
; i
++) {
4272 const char *tmp_str
;
4274 v
= &enum_values
[i
];
4276 result
= winreg_enumval_to_sz(c
, v
,
4279 CHECK_ERROR(result
);
4281 result
= winreg_enumval_to_sz(c
, v
,
4284 if (W_ERROR_IS_OK(result
)) {
4285 result
= winreg_printer_date_to_NTTIME(tmp_str
,
4288 CHECK_ERROR(result
);
4290 result
= winreg_enumval_to_sz(c
, v
,
4293 if (W_ERROR_IS_OK(result
)) {
4294 result
= winreg_printer_ver_to_qword(tmp_str
,
4295 &c
->driver_version
);
4297 CHECK_ERROR(result
);
4300 if (!W_ERROR_IS_OK(result
)) {
4301 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
4302 "for %s: %s\n", v
->value_name
,
4303 win_errstr(result
)));
4307 *_core_printer_driver
= talloc_steal(mem_ctx
, c
);
4310 if (winreg_handle
!= NULL
) {
4313 if (is_valid_policy_hnd(&key_hnd
)) {
4314 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4316 if (is_valid_policy_hnd(&hive_hnd
)) {
4317 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4321 TALLOC_FREE(tmp_ctx
);
4325 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
)
4330 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4331 struct policy_handle hive_hnd
, key_hnd
;
4332 TALLOC_CTX
*tmp_ctx
= NULL
;
4335 const char *guid_str
;
4337 ZERO_STRUCT(hive_hnd
);
4338 ZERO_STRUCT(key_hnd
);
4340 tmp_ctx
= talloc_stackframe();
4341 if (tmp_ctx
== NULL
) {
4342 return WERR_NOT_ENOUGH_MEMORY
;
4345 guid_str
= GUID_string2(tmp_ctx
, &r
->core_driver_guid
);
4346 if (guid_str
== NULL
) {
4347 result
= WERR_NOT_ENOUGH_MEMORY
;
4351 result
= winreg_printer_open_core_driver(tmp_ctx
,
4358 if (!W_ERROR_IS_OK(result
)) {
4359 DEBUG(0, ("winreg_add_core_driver: "
4360 "Could not open core driver key (%s,%s): %s\n",
4361 guid_str
, architecture
, win_errstr(result
)));
4365 result
= winreg_printer_write_date(tmp_ctx
, winreg_handle
,
4366 &key_hnd
, "DriverDate",
4368 if (!W_ERROR_IS_OK(result
)) {
4372 result
= winreg_printer_write_ver(tmp_ctx
, winreg_handle
,
4373 &key_hnd
, "DriverVersion",
4375 if (!W_ERROR_IS_OK(result
)) {
4379 status
= dcerpc_winreg_set_sz(tmp_ctx
,
4385 if (!NT_STATUS_IS_OK(status
)) {
4386 result
= ntstatus_to_werror(status
);
4388 if (!W_ERROR_IS_OK(result
)) {
4394 if (winreg_handle
!= NULL
) {
4397 if (is_valid_policy_hnd(&key_hnd
)) {
4398 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4400 if (is_valid_policy_hnd(&hive_hnd
)) {
4401 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4405 TALLOC_FREE(tmp_ctx
);
4409 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
)
4416 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4417 struct policy_handle hive_hnd
, key_hnd
;
4418 TALLOC_CTX
*tmp_ctx
= NULL
;
4423 ZERO_STRUCT(hive_hnd
);
4424 ZERO_STRUCT(key_hnd
);
4426 tmp_ctx
= talloc_stackframe();
4427 if (tmp_ctx
== NULL
) {
4428 return WERR_NOT_ENOUGH_MEMORY
;
4431 path
= talloc_asprintf(tmp_ctx
, "%s\\%s\\DriverPackages",
4432 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
4435 result
= WERR_NOT_ENOUGH_MEMORY
;
4439 result
= winreg_printer_openkey(tmp_ctx
,
4442 package_id
, /* key */
4448 if (!W_ERROR_IS_OK(result
)) {
4449 DEBUG(0, ("winreg_add_driver_package: "
4450 "Could not open driver package key (%s,%s): %s\n",
4451 package_id
, architecture
, win_errstr(result
)));
4455 status
= dcerpc_winreg_set_sz(tmp_ctx
,
4461 if (!NT_STATUS_IS_OK(status
)) {
4462 result
= ntstatus_to_werror(status
);
4464 if (!W_ERROR_IS_OK(result
)) {
4468 status
= dcerpc_winreg_set_sz(tmp_ctx
,
4474 if (!NT_STATUS_IS_OK(status
)) {
4475 result
= ntstatus_to_werror(status
);
4477 if (!W_ERROR_IS_OK(result
)) {
4483 if (winreg_handle
!= NULL
) {
4486 if (is_valid_policy_hnd(&key_hnd
)) {
4487 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4489 if (is_valid_policy_hnd(&hive_hnd
)) {
4490 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4494 TALLOC_FREE(tmp_ctx
);
4498 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
)
4505 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4506 struct policy_handle hive_hnd
, key_hnd
;
4507 struct spoolss_PrinterEnumValues
*enum_values
= NULL
;
4508 struct spoolss_PrinterEnumValues
*v
= NULL
;
4509 uint32_t num_values
= 0;
4510 TALLOC_CTX
*tmp_ctx
= NULL
;
4513 const char *path
= NULL
;
4515 const char **enum_names
= NULL
;
4516 enum winreg_Type
*enum_types
= NULL
;
4517 DATA_BLOB
*enum_data_blobs
= NULL
;
4519 ZERO_STRUCT(hive_hnd
);
4520 ZERO_STRUCT(key_hnd
);
4522 tmp_ctx
= talloc_stackframe();
4523 if (tmp_ctx
== NULL
) {
4524 return WERR_NOT_ENOUGH_MEMORY
;
4527 path
= talloc_asprintf(tmp_ctx
, "%s\\%s\\DriverPackages",
4528 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
4531 result
= WERR_NOT_ENOUGH_MEMORY
;
4535 result
= winreg_printer_openkey(tmp_ctx
,
4538 package_id
, /* key */
4544 if (!W_ERROR_IS_OK(result
)) {
4545 DEBUG(5, ("winreg_get_driver_package: "
4546 "Could not open driver package key (%s,%s): %s\n",
4547 package_id
, architecture
, win_errstr(result
)));
4551 status
= dcerpc_winreg_enumvals(tmp_ctx
,
4559 if (!NT_STATUS_IS_OK(status
)){
4560 result
= ntstatus_to_werror(status
);
4563 if (!W_ERROR_IS_OK(result
)) {
4564 DEBUG(0, ("winreg_get_driver_package: "
4565 "Could not enumerate values for (%s,%s): %s\n",
4566 package_id
, architecture
, win_errstr(result
)));
4570 enum_values
= talloc_zero_array(tmp_ctx
,
4571 struct spoolss_PrinterEnumValues
,
4573 if (enum_values
== NULL
){
4574 result
= WERR_NOT_ENOUGH_MEMORY
;
4578 for (i
= 0; i
< num_values
; i
++){
4579 enum_values
[i
].value_name
= enum_names
[i
];
4580 enum_values
[i
].value_name_len
= strlen_m_term(enum_names
[i
]) * 2;
4581 enum_values
[i
].type
= enum_types
[i
];
4582 enum_values
[i
].data_length
= enum_data_blobs
[i
].length
;
4583 enum_values
[i
].data
= NULL
;
4584 if (enum_values
[i
].data_length
!= 0){
4585 enum_values
[i
].data
= &enum_data_blobs
[i
];
4591 for (i
= 0; i
< num_values
; i
++) {
4593 v
= &enum_values
[i
];
4595 result
= winreg_enumval_to_sz(mem_ctx
, v
,
4598 CHECK_ERROR(result
);
4600 result
= winreg_enumval_to_sz(mem_ctx
, v
,
4603 CHECK_ERROR(result
);
4606 if (!W_ERROR_IS_OK(result
)) {
4607 DEBUG(0, ("winreg_enumval_to_TYPE() failed "
4608 "for %s: %s\n", v
->value_name
,
4609 win_errstr(result
)));
4615 if (winreg_handle
!= NULL
) {
4618 if (is_valid_policy_hnd(&key_hnd
)) {
4619 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4621 if (is_valid_policy_hnd(&hive_hnd
)) {
4622 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4626 TALLOC_FREE(tmp_ctx
);
4630 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
)
4635 uint32_t access_mask
= SEC_FLAG_MAXIMUM_ALLOWED
;
4636 struct policy_handle hive_hnd
, key_hnd
;
4637 TALLOC_CTX
*tmp_ctx
;
4642 ZERO_STRUCT(hive_hnd
);
4643 ZERO_STRUCT(key_hnd
);
4645 tmp_ctx
= talloc_stackframe();
4646 if (tmp_ctx
== NULL
) {
4647 return WERR_NOT_ENOUGH_MEMORY
;
4650 path
= talloc_asprintf(tmp_ctx
, "%s\\%s\\DriverPackages",
4651 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
4654 result
= WERR_NOT_ENOUGH_MEMORY
;
4658 result
= winreg_printer_openkey(tmp_ctx
,
4661 package_id
, /* key */
4666 if (!W_ERROR_IS_OK(result
)) {
4667 /* key doesn't exist */
4668 if (W_ERROR_EQUAL(result
, WERR_FILE_NOT_FOUND
)) {
4673 DEBUG(5, ("winreg_del_driver_package: "
4674 "Could not open driver package key (%s,%s): %s\n",
4675 package_id
, architecture
, win_errstr(result
)));
4680 if (is_valid_policy_hnd(&key_hnd
)) {
4681 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &result
);
4684 path
= talloc_asprintf(tmp_ctx
, "%s\\%s\\DriverPackages\\%s",
4685 TOP_LEVEL_PRINT_PACKAGEINSTALLATION_KEY
,
4689 result
= WERR_NOT_ENOUGH_MEMORY
;
4693 status
= dcerpc_winreg_delete_subkeys_recursive(tmp_ctx
,
4699 if (!NT_STATUS_IS_OK(status
)) {
4700 result
= ntstatus_to_werror(status
);
4701 DEBUG(5, ("winreg_del_driver_package: "
4702 "Could not delete driver package key (%s,%s): %s\n",
4703 package_id
, architecture
, nt_errstr(status
)));
4707 if (!W_ERROR_IS_OK(result
)) {
4708 DEBUG(5, ("winreg_del_driver_package: "
4709 "Could not delete driver package key (%s,%s): %s\n",
4710 package_id
, architecture
, win_errstr(result
)));
4716 if (winreg_handle
!= NULL
) {
4719 if (is_valid_policy_hnd(&key_hnd
)) {
4720 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &key_hnd
, &ignore
);
4722 if (is_valid_policy_hnd(&hive_hnd
)) {
4723 dcerpc_winreg_CloseKey(winreg_handle
, tmp_ctx
, &hive_hnd
, &ignore
);
4727 TALLOC_FREE(tmp_ctx
);